]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_pcmcia.c
4c799a52ddeb31932c4f8c483049e1dfec3cf890
[karo-tx-uboot.git] / common / cmd_pcmcia.c
1 /*
2  * (C) Copyright 2000-2002
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  *
23  ********************************************************************
24  *
25  * Lots of code copied from:
26  *
27  * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
28  * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
29  *
30  * "The ExCA standard specifies that socket controllers should provide
31  * two IO and five memory windows per socket, which can be independently
32  * configured and positioned in the host address space and mapped to
33  * arbitrary segments of card address space. " - David A Hinds. 1999
34  *
35  * This controller does _not_ meet the ExCA standard.
36  *
37  * m8xx pcmcia controller brief info:
38  * + 8 windows (attrib, mem, i/o)
39  * + up to two slots (SLOT_A and SLOT_B)
40  * + inputpins, outputpins, event and mask registers.
41  * - no offset register. sigh.
42  *
43  * Because of the lacking offset register we must map the whole card.
44  * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
45  * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
46  * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
47  * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
48  * They are maximum 64KByte each...
49  */
50
51 /* #define DEBUG        1       */
52
53 /*
54  * PCMCIA support
55  */
56 #include <common.h>
57 #include <command.h>
58 #include <config.h>
59 #include <pcmcia.h>
60 #include <cmd_pcmcia.h>
61 #if defined(CONFIG_IDE_8xx_PCCARD) && defined(CONFIG_8xx)
62 #include <mpc8xx.h>
63 #endif
64 #if defined(CONFIG_LWMON)
65 #include <i2c.h>
66 #endif
67
68 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
69     ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
70
71 int pcmcia_on (void);
72
73 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
74 static int  pcmcia_off (void);
75 static int  hardware_disable(int slot);
76 #endif
77 static int  hardware_enable (int slot);
78 static int  voltage_set(int slot, int vcc, int vpp);
79 #ifdef CONFIG_IDE_8xx_PCCARD
80 static void print_funcid (int func);
81 static void print_fixed  (volatile uchar *p);
82 static int  identify     (volatile uchar *p);
83 static int  check_ide_device (int slot);
84 #endif  /* CONFIG_IDE_8xx_PCCARD */
85
86 static u_int m8xx_get_graycode(u_int size);
87 #if 0
88 static u_int m8xx_get_speed(u_int ns, u_int is_io);
89 #endif
90
91 /* ------------------------------------------------------------------------- */
92
93 /* look up table for pgcrx registers */
94
95 static u_int *pcmcia_pgcrx[2] = {
96         &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
97         &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
98 };
99
100 #define PCMCIA_PGCRX(slot)      (*pcmcia_pgcrx[slot])
101
102 const char *indent = "\t   ";
103
104 /* ------------------------------------------------------------------------- */
105
106 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
107
108 int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
109 {
110         int rcode = 0;
111
112         if (argc != 2) {
113                 printf ("Usage: pinit {on | off}\n");
114                 return 1;
115         }
116         if (strcmp(argv[1],"on") == 0) {
117                 rcode = pcmcia_on ();
118         } else if (strcmp(argv[1],"off") == 0) {
119                 rcode = pcmcia_off ();
120         } else {
121                 printf ("Usage: pinit {on | off}\n");
122                 return 1;
123         }
124
125         return rcode;
126 }
127 #endif  /* CFG_CMD_PCMCIA */
128
129 /* ------------------------------------------------------------------------- */
130
131 #if defined(CONFIG_LWMON)
132 # define  CFG_PCMCIA_TIMING     (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
133 #else
134 # define  CFG_PCMCIA_TIMING     (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
135 #endif
136
137 int pcmcia_on (void)
138 {
139         int i;
140         u_long reg, base;
141         pcmcia_win_t *win;
142         u_int slotbit;
143         u_int rc, slot;
144
145         debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
146
147         /* intialize the fixed memory windows */
148         win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
149         base = CFG_PCMCIA_MEM_ADDR;
150
151         if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
152                 printf ("Cannot set window size to 0x%08x\n",
153                         CFG_PCMCIA_MEM_SIZE);
154                 return (1);
155         }
156
157         slotbit = PCMCIA_SLOT_x;
158         for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
159                 win->br = base;
160
161 #if (PCMCIA_SOCKETS_NO == 2)
162                 if (i == 4) /* Another slot starting from win 4 */
163                         slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
164 #endif
165                 switch (i) {
166 #ifdef CONFIG_IDE_8xx_PCCARD
167                 case 4:
168                 case 0: {       /* map attribute memory */
169                         win->or = (     PCMCIA_BSIZE_64M
170                                 |       PCMCIA_PPS_8
171                                 |       PCMCIA_PRS_ATTR
172                                 |       slotbit
173                                 |       PCMCIA_PV
174                                 |       CFG_PCMCIA_TIMING );
175                         break;
176                     }
177                 case 5:
178                 case 1: {       /* map I/O window for data reg */
179                         win->or = (     PCMCIA_BSIZE_1K
180                                 |       PCMCIA_PPS_16
181                                 |       PCMCIA_PRS_IO
182                                 |       slotbit
183                                 |       PCMCIA_PV
184                                 |       CFG_PCMCIA_TIMING );
185                         break;
186                     }
187                 case 6:
188                 case 2: {       /* map I/O window for command/ctrl reg block */
189                         win->or = (     PCMCIA_BSIZE_1K
190                                 |       PCMCIA_PPS_8
191                                 |       PCMCIA_PRS_IO
192                                 |       slotbit
193                                 |       PCMCIA_PV
194                                 |       CFG_PCMCIA_TIMING );
195                         break;
196                     }
197 #endif  /* CONFIG_IDE_8xx_PCCARD */
198                 default:        /* set to not valid */
199                         win->or = 0;
200                         break;
201                 }
202
203                 debug ("MemWin %d: PBR 0x%08lX  POR %08lX\n",
204                         i, win->br, win->or);
205                 base += CFG_PCMCIA_MEM_SIZE;
206                 ++win;
207         }
208
209         for (i = 0, rc = 0, slot = _slot_; i < PCMCIA_SOCKETS_NO; i++, slot = !slot) {
210                 /* turn off voltage */
211                 if ((rc = voltage_set(slot, 0, 0)))
212                         continue;
213                 
214                 /* Enable external hardware */
215                 if ((rc = hardware_enable(slot)))
216                         continue;
217                 
218 #ifdef CONFIG_IDE_8xx_PCCARD
219                 if ((rc = check_ide_device(i)))
220                         continue;
221 #endif
222         }
223         return (rc);
224 }
225
226 /* ------------------------------------------------------------------------- */
227
228 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
229
230 static int pcmcia_off (void)
231 {
232         int i;
233         pcmcia_win_t *win;
234
235         printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
236
237         /* clear interrupt state, and disable interrupts */
238         ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr =  PCMCIA_MASK(_slot_);
239         ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
240
241         /* turn off interrupt and disable CxOE */
242         PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
243
244         /* turn off memory windows */
245         win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
246
247         for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
248                 /* disable memory window */
249                 win->or = 0;
250                 ++win;
251         }
252
253         /* turn off voltage */
254         voltage_set(_slot_, 0, 0);
255
256         /* disable external hardware */
257         printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
258         hardware_disable(_slot_);
259         return 0;
260 }
261
262 #endif  /* CFG_CMD_PCMCIA */
263
264 /* ------------------------------------------------------------------------- */
265
266 #ifdef CONFIG_IDE_8xx_PCCARD
267
268 #define MAX_TUPEL_SZ    512
269 #define MAX_FEATURES    4
270
271 static int check_ide_device (int slot)
272 {
273         volatile uchar *ident = NULL;
274         volatile uchar *feature_p[MAX_FEATURES];
275         volatile uchar *p, *start, *addr;
276         int n_features = 0;
277         uchar func_id = ~0;
278         uchar code, len;
279         ushort config_base = 0;
280         int found = 0;
281         int i;
282
283         addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR + 
284                                                           CFG_PCMCIA_MEM_SIZE * (slot * 4));
285         debug ("PCMCIA MEM: %08X\n", addr);
286
287         start = p = (volatile uchar *) addr;
288
289         while ((p - start) < MAX_TUPEL_SZ) {
290
291                 code = *p; p += 2;
292
293                 if (code == 0xFF) { /* End of chain */
294                         break;
295                 }
296
297                 len = *p; p += 2;
298 #if defined(DEBUG) && (DEBUG > 1)
299                 { volatile uchar *q = p;
300                         printf ("\nTuple code %02x  length %d\n\tData:",
301                                 code, len);
302
303                         for (i = 0; i < len; ++i) {
304                                 printf (" %02x", *q);
305                                 q+= 2;
306                         }
307                 }
308 #endif  /* DEBUG */
309                 switch (code) {
310                 case CISTPL_VERS_1:
311                         ident = p + 4;
312                         break;
313                 case CISTPL_FUNCID:
314                         /* Fix for broken SanDisk which may have 0x80 bit set */
315                         func_id = *p & 0x7F;
316                         break;
317                 case CISTPL_FUNCE:
318                         if (n_features < MAX_FEATURES)
319                                 feature_p[n_features++] = p;
320                         break;
321                 case CISTPL_CONFIG:
322                         config_base = (*(p+6) << 8) + (*(p+4));
323                         debug ("\n## Config_base = %04x ###\n", config_base);
324                 default:
325                         break;
326                 }
327                 p += 2 * len;
328         }
329
330         found = identify (ident);
331
332         if (func_id != ((uchar)~0)) {
333                 print_funcid (func_id);
334
335                 if (func_id == CISTPL_FUNCID_FIXED)
336                         found = 1;
337                 else
338                         return (1);     /* no disk drive */
339         }
340
341         for (i=0; i<n_features; ++i) {
342                 print_fixed (feature_p[i]);
343         }
344
345         if (!found) {
346                 printf ("unknown card type\n");
347                 return (1);
348         }
349
350         /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
351         *((uchar *)(addr + config_base)) = 1;
352
353         return (0);
354 }
355 #endif  /* CONFIG_IDE_8xx_PCCARD */
356
357 /* ------------------------------------------------------------------------- */
358
359
360 /* ---------------------------------------------------------------------------- */
361 /* board specific stuff:                                                        */
362 /* voltage_set(), hardware_enable() and hardware_disable()                      */
363 /* ---------------------------------------------------------------------------- */
364
365 /* ---------------------------------------------------------------------------- */
366 /* RPX Boards from Embedded Planet                                              */
367 /* ---------------------------------------------------------------------------- */
368
369 #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
370
371 /* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
372  * SYPCR is write once only, therefore must the slowest memory be faster
373  * than the bus monitor or we will get a machine check due to the bus timeout.
374  */
375
376 #define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
377
378 #undef PCMCIA_BMT_LIMIT
379 #define PCMCIA_BMT_LIMIT (6*8)
380
381 static int voltage_set(int slot, int vcc, int vpp)
382 {
383         u_long reg = 0;
384
385         switch(vcc) {
386         case 0: break;
387         case 33: reg |= BCSR1_PCVCTL4; break;
388         case 50: reg |= BCSR1_PCVCTL5; break;
389         default: return 1;
390         }
391
392         switch(vpp) {
393         case 0: break;
394         case 33:
395         case 50:
396                 if(vcc == vpp)
397                         reg |= BCSR1_PCVCTL6;
398                 else
399                         return 1;
400                 break;
401         case 120:
402                 reg |= BCSR1_PCVCTL7;
403         default: return 1;
404         }
405
406         if(vcc == 120)
407            return 1;
408
409         /* first, turn off all power */
410
411         *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
412                                      | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
413
414         /* enable new powersettings */
415
416         *((uint *)RPX_CSR_ADDR) |= reg;
417
418         return 0;
419 }
420
421 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
422 static int hardware_enable (int slot)
423 {
424         return 0;       /* No hardware to enable */
425 }
426 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
427 static int hardware_disable(int slot)
428 {
429         return 0;       /* No hardware to disable */
430 }
431 #endif  /* CFG_CMD_PCMCIA */
432 #endif  /* CONFIG_RPXCLASSIC */
433
434 /* ---------------------------------------------------------------------------- */
435 /* (F)ADS Boards from Motorola                                                  */
436 /* ---------------------------------------------------------------------------- */
437
438 #if defined(CONFIG_ADS) || defined(CONFIG_FADS)
439
440 #ifdef CONFIG_ADS
441 #define PCMCIA_BOARD_MSG "ADS"
442 #define PCMCIA_GLITCHY_CD  /* My ADS board needs this */
443 #else
444 #define PCMCIA_BOARD_MSG "FADS"
445 #endif
446
447 static int voltage_set(int slot, int vcc, int vpp)
448 {
449         u_long reg = 0;
450
451         switch(vpp) {
452         case 0: reg = 0; break;
453         case 50: reg = 1; break;
454         case 120: reg = 2; break;
455         default: return 1;
456         }
457
458         switch(vcc) {
459         case 0: reg = 0; break;
460 #ifdef CONFIG_ADS
461         case 50: reg = BCSR1_PCCVCCON; break;
462 #endif
463 #ifdef CONFIG_FADS
464         case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
465         case 50: reg = BCSR1_PCCVCC1; break;
466 #endif
467         default: return 1;
468         }
469
470         /* first, turn off all power */
471
472 #ifdef CONFIG_ADS
473         *((uint *)BCSR1) |= BCSR1_PCCVCCON;
474 #endif
475 #ifdef CONFIG_FADS
476         *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
477 #endif
478         *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
479
480         /* enable new powersettings */
481
482 #ifdef CONFIG_ADS
483         *((uint *)BCSR1) &= ~reg;
484 #endif
485 #ifdef CONFIG_FADS
486         *((uint *)BCSR1) |= reg;
487 #endif
488
489         *((uint *)BCSR1) |= reg << 20;
490
491         return 0;
492 }
493
494 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
495
496 static int hardware_enable(int slot)
497 {
498         *((uint *)BCSR1) &= ~BCSR1_PCCEN;
499         return 0;
500 }
501
502 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
503 static int hardware_disable(int slot)
504 {
505         *((uint *)BCSR1) &= ~BCSR1_PCCEN;
506         return 0;
507 }
508 #endif  /* CFG_CMD_PCMCIA */
509
510 #endif  /* (F)ADS */
511
512 /* ---------------------------------------------------------------------------- */
513 /* TQM8xxL Boards by TQ Components                                              */
514 /* ---------------------------------------------------------------------------- */
515
516 #if defined(CONFIG_TQM8xxL)
517
518 #define PCMCIA_BOARD_MSG "TQM8xxL"
519
520
521 static int hardware_enable(int slot)
522 {
523         volatile immap_t        *immap;
524         volatile cpm8xx_t       *cp;
525         volatile pcmconf8xx_t   *pcmp;
526         volatile sysconf8xx_t   *sysp;
527         uint reg, mask;
528
529         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
530
531         udelay(10000);
532
533         immap = (immap_t *)CFG_IMMR;
534         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
535         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
536         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
537
538         /*
539          * Configure SIUMCR to enable PCMCIA port B
540          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
541          */
542         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
543
544         /* clear interrupt state, and disable interrupts */
545         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
546         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
547
548         /* disable interrupts & DMA */
549         PCMCIA_PGCRX(_slot_) = 0;
550
551         /*
552          * Disable PCMCIA buffers (isolate the interface)
553          * and assert RESET signal
554          */
555         debug ("Disable PCMCIA buffers and assert RESET\n");
556         reg  =  PCMCIA_PGCRX(_slot_);
557         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
558         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
559         PCMCIA_PGCRX(_slot_) = reg;
560         udelay(500);
561
562         /*
563          * Configure Port C pins for
564          * 5 Volts Enable and 3 Volts enable
565          */
566         immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
567         immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
568         /* remove all power */
569
570         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
571
572         /*
573          * Make sure there is a card in the slot, then configure the interface.
574          */
575         udelay(10000);
576         debug ("[%d] %s: PIPR(%p)=0x%x\n",
577                 __LINE__,__FUNCTION__,
578                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
579         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
580                 printf ("   No Card found\n");
581                 return (1);
582         }
583
584         /*
585          * Power On.
586          */
587         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
588         reg  = pcmp->pcmc_pipr;
589         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
590                 reg,
591                 (reg&PCMCIA_VS1(slot))?"n":"ff",
592                 (reg&PCMCIA_VS2(slot))?"n":"ff");
593         if ((reg & mask) == mask) {
594                 immap->im_ioport.iop_pcdat |= 0x0004;
595                 puts (" 5.0V card found: ");
596         } else {
597                 immap->im_ioport.iop_pcdat |= 0x0002;
598                 puts (" 3.3V card found: ");
599         }
600         immap->im_ioport.iop_pcdir |=  (0x0002 | 0x0004);
601 #if 0
602         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
603         cp->cp_pbdir &= ~(0x0020 | 0x0010);
604         cp->cp_pbpar &= ~(0x0020 | 0x0010);
605         udelay(500000);
606 #endif
607         udelay(1000);
608         debug ("Enable PCMCIA buffers and stop RESET\n");
609         reg  =  PCMCIA_PGCRX(_slot_);
610         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
611         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
612         PCMCIA_PGCRX(_slot_) = reg;
613
614         udelay(250000); /* some cards need >150 ms to come up :-( */
615
616         debug ("# hardware_enable done\n");
617
618         return (0);
619 }
620
621
622
623 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
624 static int hardware_disable(int slot)
625 {
626         volatile immap_t        *immap;
627         volatile pcmconf8xx_t   *pcmp;
628         u_long reg;
629
630         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
631
632         immap = (immap_t *)CFG_IMMR;
633         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
634
635         /* remove all power */
636         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
637
638         /* Configure PCMCIA General Control Register */
639         PCMCIA_PGCRX(_slot_) = 0;
640
641         debug ("Disable PCMCIA buffers and assert RESET\n");
642         reg  =  PCMCIA_PGCRX(_slot_);
643         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
644         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
645         PCMCIA_PGCRX(_slot_) = reg;
646
647         udelay(10000);
648
649         return (0);
650 }
651 #endif  /* CFG_CMD_PCMCIA */
652
653
654
655 static int voltage_set(int slot, int vcc, int vpp)
656 {
657         volatile immap_t        *immap;
658         volatile pcmconf8xx_t   *pcmp;
659         u_long reg;
660
661         debug ("voltage_set: "
662                 PCMCIA_BOARD_MSG
663                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
664                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
665
666         immap = (immap_t *)CFG_IMMR;
667         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
668         /*
669          * Disable PCMCIA buffers (isolate the interface)
670          * and assert RESET signal
671          */
672         debug ("Disable PCMCIA buffers and assert RESET\n");
673         reg  =  PCMCIA_PGCRX(_slot_);
674         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
675         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
676         PCMCIA_PGCRX(_slot_) = reg;
677         udelay(500);
678
679         /*
680          * Configure Port C pins for
681          * 5 Volts Enable and 3 Volts enable,
682          * Turn off all power
683          */
684         debug ("PCMCIA power OFF\n");
685         immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
686         immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
687         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
688
689         reg = 0;
690         switch(vcc) {
691         case  0:                break;
692         case 33: reg |= 0x0002; break;
693         case 50: reg |= 0x0004; break;
694         default:                goto done;
695         }
696
697         /* Checking supported voltages */
698
699         debug ("PIPR: 0x%x --> %s\n",
700                 pcmp->pcmc_pipr,
701                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
702
703         immap->im_ioport.iop_pcdat |= reg;
704         immap->im_ioport.iop_pcdir |=  (0x0002 | 0x0004);
705         if (reg) {
706                 debug ("PCMCIA powered at %sV\n",
707                         (reg&0x0004) ? "5.0" : "3.3");
708         } else {
709                 debug ("PCMCIA powered down\n");
710         }
711
712 done:
713         debug ("Enable PCMCIA buffers and stop RESET\n");
714         reg  =  PCMCIA_PGCRX(_slot_);
715         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
716         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
717         PCMCIA_PGCRX(_slot_) = reg;
718         udelay(500);
719
720         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
721                 slot+'A');
722         return (0);
723 }
724
725 #endif  /* TQM8xxL */
726
727
728 /* ---------------------------------------------------------------------------- */
729 /* LWMON Board                                                                  */
730 /* ---------------------------------------------------------------------------- */
731
732 #if defined(CONFIG_LWMON)
733
734 #define PCMCIA_BOARD_MSG "LWMON"
735
736 /* #define's for MAX1604 Power Switch */
737 #define MAX1604_OP_SUS          0x80
738 #define MAX1604_VCCBON          0x40
739 #define MAX1604_VCC_35          0x20
740 #define MAX1604_VCCBHIZ         0x10
741 #define MAX1604_VPPBON          0x08
742 #define MAX1604_VPPBPBPGM       0x04
743 #define MAX1604_VPPBHIZ         0x02
744 /* reserved                     0x01    */
745
746 static int hardware_enable(int slot)
747 {
748         volatile immap_t        *immap;
749         volatile cpm8xx_t       *cp;
750         volatile pcmconf8xx_t   *pcmp;
751         volatile sysconf8xx_t   *sysp;
752         uint reg, mask;
753         uchar val;
754
755
756         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
757
758         /* Switch on PCMCIA port in PIC register 0x60 */
759         reg = pic_read  (0x60);
760         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
761         reg &= ~0x10;
762         /* reg |=  0x08; Vpp not needed */
763         pic_write (0x60, reg);
764 #ifdef DEBUG
765         reg = pic_read  (0x60);
766         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
767 #endif
768         udelay(10000);
769
770         immap = (immap_t *)CFG_IMMR;
771         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
772         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
773         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
774
775         /*
776          * Configure SIUMCR to enable PCMCIA port B
777          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
778          */
779         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
780
781         /* clear interrupt state, and disable interrupts */
782         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
783         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
784
785         /* disable interrupts & DMA */
786         PCMCIA_PGCRX(_slot_) = 0;
787
788         /*
789          * Disable PCMCIA buffers (isolate the interface)
790          * and assert RESET signal
791          */
792         debug ("Disable PCMCIA buffers and assert RESET\n");
793         reg  =  PCMCIA_PGCRX(_slot_);
794         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
795         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
796         PCMCIA_PGCRX(_slot_) = reg;
797         udelay(500);
798
799         /*
800          * Make sure there is a card in the slot, then configure the interface.
801          */
802         udelay(10000);
803         debug ("[%d] %s: PIPR(%p)=0x%x\n",
804                 __LINE__,__FUNCTION__,
805                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
806         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
807                 printf ("   No Card found\n");
808                 return (1);
809         }
810
811         /*
812          * Power On.
813          */
814         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
815         reg  = pcmp->pcmc_pipr;
816         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
817                 reg,
818                 (reg&PCMCIA_VS1(slot))?"n":"ff",
819                 (reg&PCMCIA_VS2(slot))?"n":"ff");
820         if ((reg & mask) == mask) {
821                 val = 0;                /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
822                 puts (" 5.0V card found: ");
823         } else {
824                 val = MAX1604_VCC_35;   /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
825                 puts (" 3.3V card found: ");
826         }
827
828         /*  switch VCC on */
829         val |=  MAX1604_OP_SUS | MAX1604_VCCBON;
830         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
831         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
832
833         udelay(500000);
834
835         debug ("Enable PCMCIA buffers and stop RESET\n");
836         reg  =  PCMCIA_PGCRX(_slot_);
837         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
838         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
839         PCMCIA_PGCRX(_slot_) = reg;
840
841         udelay(250000); /* some cards need >150 ms to come up :-( */
842
843         debug ("# hardware_enable done\n");
844
845         return (0);
846 }
847
848
849
850 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
851 static int hardware_disable(int slot)
852 {
853         volatile immap_t        *immap;
854         volatile pcmconf8xx_t   *pcmp;
855         u_long reg;
856         uchar val;
857
858         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
859
860         immap = (immap_t *)CFG_IMMR;
861         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
862
863         /* remove all power, put output in high impedance state */
864         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
865         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
866         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
867
868         /* Configure PCMCIA General Control Register */
869         PCMCIA_PGCRX(_slot_) = 0;
870
871         debug ("Disable PCMCIA buffers and assert RESET\n");
872         reg  =  PCMCIA_PGCRX(_slot_);
873         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
874         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
875         PCMCIA_PGCRX(_slot_) = reg;
876
877         /* Switch off PCMCIA port in PIC register 0x60 */
878         reg = pic_read  (0x60);
879         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
880         reg |=  0x10;
881         reg &= ~0x08;
882         pic_write (0x60, reg);
883 #ifdef DEBUG
884         reg = pic_read  (0x60);
885         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
886 #endif
887         udelay(10000);
888
889         return (0);
890 }
891 #endif  /* CFG_CMD_PCMCIA */
892
893
894
895 static int voltage_set(int slot, int vcc, int vpp)
896 {
897         volatile immap_t        *immap;
898         volatile pcmconf8xx_t   *pcmp;
899         u_long reg;
900         uchar val;
901
902         debug ("voltage_set: "
903                 PCMCIA_BOARD_MSG
904                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
905                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
906
907         immap = (immap_t *)CFG_IMMR;
908         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
909         /*
910          * Disable PCMCIA buffers (isolate the interface)
911          * and assert RESET signal
912          */
913         debug ("Disable PCMCIA buffers and assert RESET\n");
914         reg  =  PCMCIA_PGCRX(_slot_);
915         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
916         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
917         PCMCIA_PGCRX(_slot_) = reg;
918         udelay(500);
919
920         /*
921          * Turn off all power (switch to high impedance)
922          */
923         debug ("PCMCIA power OFF\n");
924         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
925         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
926         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
927
928         val = 0;
929         switch(vcc) {
930         case  0:                        break;
931         case 33: val = MAX1604_VCC_35;  break;
932         case 50:                        break;
933         default:                        goto done;
934         }
935
936         /* Checking supported voltages */
937
938         debug ("PIPR: 0x%x --> %s\n",
939                 pcmp->pcmc_pipr,
940                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
941
942         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
943         if (val) {
944                 debug ("PCMCIA powered at %sV\n",
945                         (val & MAX1604_VCC_35) ? "3.3" : "5.0");
946         } else {
947                 debug ("PCMCIA powered down\n");
948         }
949
950 done:
951         debug ("Enable PCMCIA buffers and stop RESET\n");
952         reg  =  PCMCIA_PGCRX(_slot_);
953         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
954         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
955         PCMCIA_PGCRX(_slot_) = reg;
956         udelay(500);
957
958         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
959                 slot+'A');
960         return (0);
961 }
962
963 #endif  /* LWMON */
964
965 /* ---------------------------------------------------------------------------- */
966 /* GTH board by Corelatus AB                                                    */
967 /* ---------------------------------------------------------------------------- */
968 #if defined(CONFIG_GTH)
969
970 #define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
971
972 static int voltage_set(int slot, int vcc, int vpp)
973 {  /* Do nothing */
974   return 0;
975 }
976
977 static int hardware_enable (int slot)
978 {
979   volatile immap_t      *immap;
980   volatile cpm8xx_t     *cp;
981   volatile pcmconf8xx_t *pcmp;
982   volatile sysconf8xx_t *sysp;
983   uint reg, mask;
984
985   debug ("hardware_enable: GTH Slot %c\n", 'A'+slot);
986
987   immap = (immap_t *)CFG_IMMR;
988   sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
989   pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
990   cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
991
992   /* clear interrupt state, and disable interrupts */
993   pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
994   pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
995
996   /* disable interrupts & DMA */
997   PCMCIA_PGCRX(_slot_) = 0;
998
999   /*
1000    * Disable PCMCIA buffers (isolate the interface)
1001    * and assert RESET signal
1002    */
1003   debug ("Disable PCMCIA buffers and assert RESET\n");
1004   reg  =  PCMCIA_PGCRX(_slot_);
1005   reg |=  __MY_PCMCIA_GCRX_CXRESET;     /* active high */
1006   reg |=  __MY_PCMCIA_GCRX_CXOE;                /* active low  */
1007   PCMCIA_PGCRX(_slot_) = reg;
1008   udelay(500);
1009
1010   /*
1011    * Make sure there is a card in the slot, then configure the interface.
1012    */
1013   udelay(10000);
1014   debug ("[%d] %s: PIPR(%p)=0x%x\n",
1015                 __LINE__,__FUNCTION__,
1016                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1017   if (pcmp->pcmc_pipr & 0x98000000) {
1018     printf ("   No Card found\n");
1019     return (1);
1020   }
1021
1022   mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1023   reg  = pcmp->pcmc_pipr;
1024   debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1025                 reg,
1026                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1027                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1028
1029   debug ("Enable PCMCIA buffers and stop RESET\n");
1030   reg  =  PCMCIA_PGCRX(_slot_);
1031   reg &= ~__MY_PCMCIA_GCRX_CXRESET;     /* active high */
1032   reg &= ~__MY_PCMCIA_GCRX_CXOE;                /* active low  */
1033   PCMCIA_PGCRX(_slot_) = reg;
1034
1035   udelay(250000);       /* some cards need >150 ms to come up :-( */
1036
1037   debug ("# hardware_enable done\n");
1038
1039   return 0;
1040 }
1041 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1042 static int hardware_disable(int slot)
1043 {
1044         return 0;       /* No hardware to disable */
1045 }
1046 #endif  /* CFG_CMD_PCMCIA */
1047 #endif  /* CONFIG_GTH */
1048
1049 /* ---------------------------------------------------------------------------- */
1050 /* ICU862 Boards by Cambridge Broadband Ltd.                                    */
1051 /* ---------------------------------------------------------------------------- */
1052
1053 #if defined(CONFIG_ICU862)
1054
1055 #define PCMCIA_BOARD_MSG "ICU862"
1056
1057 static void cfg_port_B (void);
1058
1059 static int hardware_enable(int slot)
1060 {
1061         volatile immap_t        *immap;
1062         volatile cpm8xx_t       *cp;
1063         volatile pcmconf8xx_t   *pcmp;
1064         volatile sysconf8xx_t   *sysp;
1065         uint reg, pipr, mask;
1066         int i;
1067
1068         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1069
1070         udelay(10000);
1071
1072         immap = (immap_t *)CFG_IMMR;
1073         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1074         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1075         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1076
1077         /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1078         cfg_port_B ();
1079
1080         /*
1081          * Configure SIUMCR to enable PCMCIA port B
1082          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1083          */
1084         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1085
1086         /* clear interrupt state, and disable interrupts */
1087         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1088         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1089
1090         /* disable interrupts & DMA */
1091         PCMCIA_PGCRX(_slot_) = 0;
1092
1093         /*
1094          * Disable PCMCIA buffers (isolate the interface)
1095          * and assert RESET signal
1096          */
1097         debug ("Disable PCMCIA buffers and assert RESET\n");
1098         reg  =  PCMCIA_PGCRX(_slot_);
1099         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
1100         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
1101         PCMCIA_PGCRX(_slot_) = reg;
1102         udelay(500);
1103
1104         /*
1105          * Make sure there is a card in the slot, then configure the interface.
1106          */
1107         udelay(10000);
1108         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1109                 __LINE__,__FUNCTION__,
1110                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1111         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1112                 printf ("   No Card found\n");
1113                 return (1);
1114         }
1115
1116         /*
1117          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1118          */
1119         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1120         pipr = pcmp->pcmc_pipr;
1121         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1122                 pipr,
1123                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1124                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1125
1126         reg  = cp->cp_pbdat;
1127         if ((pipr & mask) == mask) {
1128                 reg |=  (TPS2205_VPP_PGM | TPS2205_VPP_VCC |    /* VAVPP => Hi-Z */
1129                          TPS2205_VCC3);                         /* 3V off       */
1130                 reg &= ~(TPS2205_VCC5);                         /* 5V on        */
1131                 puts (" 5.0V card found: ");
1132         } else {
1133                 reg |=  (TPS2205_VPP_PGM | TPS2205_VPP_VCC |    /* VAVPP => Hi-Z */
1134                          TPS2205_VCC5);                         /* 5V off       */
1135                 reg &= ~(TPS2205_VCC3);                         /* 3V on        */
1136                 puts (" 3.3V card found: ");
1137         }
1138
1139         debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1140                 reg,
1141                 (reg & TPS2205_VCC3)    ? "off" : "on",
1142                 (reg & TPS2205_VCC5)    ? "off" : "on",
1143                 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1144                 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1145
1146         cp->cp_pbdat = reg;
1147
1148         /*  Wait 500 ms; use this to check for over-current */
1149         for (i=0; i<5000; ++i) {
1150                 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1151                         printf ("   *** Overcurrent - Safety shutdown ***\n");
1152                         cp->cp_pbdat &= ~(TPS2205_SHDN);
1153                         return (1);
1154                 }
1155                 udelay (100);
1156         }
1157
1158         debug ("Enable PCMCIA buffers and stop RESET\n");
1159         reg  =  PCMCIA_PGCRX(_slot_);
1160         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1161         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1162         PCMCIA_PGCRX(_slot_) = reg;
1163
1164         udelay(250000); /* some cards need >150 ms to come up :-( */
1165
1166         debug ("# hardware_enable done\n");
1167
1168         return (0);
1169 }
1170
1171
1172
1173 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1174 static int hardware_disable(int slot)
1175 {
1176         volatile immap_t        *immap;
1177         volatile cpm8xx_t       *cp;
1178         volatile pcmconf8xx_t   *pcmp;
1179         u_long reg;
1180
1181         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1182
1183         immap = (immap_t *)CFG_IMMR;
1184         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1185         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1186
1187         /* Shut down */
1188         cp->cp_pbdat &= ~(TPS2205_SHDN);
1189
1190         /* Configure PCMCIA General Control Register */
1191         PCMCIA_PGCRX(_slot_) = 0;
1192
1193         debug ("Disable PCMCIA buffers and assert RESET\n");
1194         reg  =  PCMCIA_PGCRX(_slot_);
1195         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1196         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1197         PCMCIA_PGCRX(_slot_) = reg;
1198
1199         udelay(10000);
1200
1201         return (0);
1202 }
1203 #endif  /* CFG_CMD_PCMCIA */
1204
1205
1206
1207 static int voltage_set(int slot, int vcc, int vpp)
1208 {
1209         volatile immap_t        *immap;
1210         volatile cpm8xx_t       *cp;
1211         volatile pcmconf8xx_t   *pcmp;
1212         u_long reg;
1213
1214         debug ("voltage_set: "
1215                 PCMCIA_BOARD_MSG
1216                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1217                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1218
1219         immap = (immap_t *)CFG_IMMR;
1220         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1221         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1222         /*
1223          * Disable PCMCIA buffers (isolate the interface)
1224          * and assert RESET signal
1225          */
1226         debug ("Disable PCMCIA buffers and assert RESET\n");
1227         reg  =  PCMCIA_PGCRX(_slot_);
1228         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
1229         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
1230         PCMCIA_PGCRX(_slot_) = reg;
1231         udelay(500);
1232
1233         /*
1234          * Configure Port C pins for
1235          * 5 Volts Enable and 3 Volts enable,
1236          * Turn all power pins to Hi-Z
1237          */
1238         debug ("PCMCIA power OFF\n");
1239         cfg_port_B ();  /* Enables switch, but all in Hi-Z */
1240
1241         reg  = cp->cp_pbdat;
1242
1243         switch(vcc) {
1244         case  0:                        break;  /* Switch off           */
1245         case 33: reg &= ~TPS2205_VCC3;  break;  /* Switch on 3.3V       */
1246         case 50: reg &= ~TPS2205_VCC5;  break;  /* Switch on 5.0V       */
1247         default:                        goto done;
1248         }
1249
1250         /* Checking supported voltages */
1251
1252         debug ("PIPR: 0x%x --> %s\n",
1253                 pcmp->pcmc_pipr,
1254                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1255
1256         cp->cp_pbdat = reg;
1257
1258 #ifdef DEBUG
1259     {
1260         char *s;
1261
1262         if ((reg & TPS2205_VCC3) == 0) {
1263                 s = "at 3.3V";
1264         } else if ((reg & TPS2205_VCC5) == 0) {
1265                 s = "at 5.0V";
1266         } else {
1267                 s = "down";
1268         }
1269         printf ("PCMCIA powered %s\n", s);
1270     }
1271 #endif
1272
1273 done:
1274         debug ("Enable PCMCIA buffers and stop RESET\n");
1275         reg  =  PCMCIA_PGCRX(_slot_);
1276         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1277         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1278         PCMCIA_PGCRX(_slot_) = reg;
1279         udelay(500);
1280
1281         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1282                 slot+'A');
1283         return (0);
1284 }
1285
1286 static void cfg_port_B (void)
1287 {
1288         volatile immap_t        *immap;
1289         volatile cpm8xx_t       *cp;
1290         uint reg;
1291
1292         immap = (immap_t *)CFG_IMMR;
1293         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1294
1295         /*
1296          * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1297          *
1298          * Switch off all voltages, assert shutdown
1299          */
1300         reg  = cp->cp_pbdat;
1301         reg |=  (TPS2205_VPP_PGM | TPS2205_VPP_VCC |    /* VAVPP => Hi-Z */
1302                  TPS2205_VCC3    | TPS2205_VCC5    |    /* VAVCC => Hi-Z */
1303                  TPS2205_SHDN);                         /* enable switch */
1304         cp->cp_pbdat = reg;
1305
1306         cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1307
1308         reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1309         cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1310
1311         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1312                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1313 }
1314
1315 #endif  /* ICU862 */
1316
1317
1318 /* ---------------------------------------------------------------------------- */
1319 /* C2MON Boards by TTTech Computertechnik AG                                    */
1320 /* ---------------------------------------------------------------------------- */
1321
1322 #if defined(CONFIG_C2MON)
1323
1324 #define PCMCIA_BOARD_MSG "C2MON"
1325
1326 static void cfg_ports (void);
1327
1328 static int hardware_enable(int slot)
1329 {
1330         volatile immap_t        *immap;
1331         volatile cpm8xx_t       *cp;
1332         volatile pcmconf8xx_t   *pcmp;
1333         volatile sysconf8xx_t   *sysp;
1334         uint reg, pipr, mask;
1335         ushort sreg;
1336         int i;
1337
1338         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1339
1340         udelay(10000);
1341
1342         immap = (immap_t *)CFG_IMMR;
1343         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1344         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1345         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1346
1347         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1348         cfg_ports ();
1349
1350         /*
1351          * Configure SIUMCR to enable PCMCIA port B
1352          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1353          */
1354         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1355
1356         /* clear interrupt state, and disable interrupts */
1357         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1358         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1359
1360         /* disable interrupts & DMA */
1361         PCMCIA_PGCRX(_slot_) = 0;
1362
1363         /*
1364          * Disable PCMCIA buffers (isolate the interface)
1365          * and assert RESET signal
1366          */
1367         debug ("Disable PCMCIA buffers and assert RESET\n");
1368         reg  =  PCMCIA_PGCRX(_slot_);
1369         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
1370         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
1371         PCMCIA_PGCRX(_slot_) = reg;
1372         udelay(500);
1373
1374         /*
1375          * Make sure there is a card in the slot, then configure the interface.
1376          */
1377         udelay(10000);
1378         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1379                 __LINE__,__FUNCTION__,
1380                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1381         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1382                 printf ("   No Card found\n");
1383                 return (1);
1384         }
1385
1386         /*
1387          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1388          */
1389         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1390         pipr = pcmp->pcmc_pipr;
1391         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1392                 pipr,
1393                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1394                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1395
1396         sreg = immap->im_ioport.iop_pcdat;
1397         if ((pipr & mask) == mask) {
1398                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1399                           TPS2211_VCCD1);                       /* 5V on        */
1400                 sreg &= ~(TPS2211_VCCD0);                       /* 3V off       */
1401                 puts (" 5.0V card found: ");
1402         } else {
1403                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1404                           TPS2211_VCCD0);                       /* 3V on        */
1405                 sreg &= ~(TPS2211_VCCD1);                       /* 5V off       */
1406                 puts (" 3.3V card found: ");
1407         }
1408
1409         debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1410                 sreg,
1411                 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1412                 (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) ? "on" : "off"
1413         );
1414
1415         immap->im_ioport.iop_pcdat = sreg;
1416
1417         /*  Wait 500 ms; use this to check for over-current */
1418         for (i=0; i<5000; ++i) {
1419                 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1420                     printf ("   *** Overcurrent - Safety shutdown ***\n");
1421                     immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1422                     return (1);
1423                 }
1424                 udelay (100);
1425         }
1426
1427         debug ("Enable PCMCIA buffers and stop RESET\n");
1428         reg  =  PCMCIA_PGCRX(_slot_);
1429         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1430         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1431         PCMCIA_PGCRX(_slot_) = reg;
1432
1433         udelay(250000); /* some cards need >150 ms to come up :-( */
1434
1435         debug ("# hardware_enable done\n");
1436
1437         return (0);
1438 }
1439
1440
1441
1442 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1443 static int hardware_disable(int slot)
1444 {
1445         volatile immap_t        *immap;
1446         volatile cpm8xx_t       *cp;
1447         volatile pcmconf8xx_t   *pcmp;
1448         u_long reg;
1449
1450         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1451
1452         immap = (immap_t *)CFG_IMMR;
1453         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1454
1455         /* Configure PCMCIA General Control Register */
1456         PCMCIA_PGCRX(_slot_) = 0;
1457
1458         debug ("Disable PCMCIA buffers and assert RESET\n");
1459         reg  =  PCMCIA_PGCRX(_slot_);
1460         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1461         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1462         PCMCIA_PGCRX(_slot_) = reg;
1463
1464         /* ALl voltages off / Hi-Z */
1465         immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1466                                        TPS2211_VCCD0 | TPS2211_VCCD1 );
1467
1468         udelay(10000);
1469
1470         return (0);
1471 }
1472 #endif  /* CFG_CMD_PCMCIA */
1473
1474
1475
1476 static int voltage_set(int slot, int vcc, int vpp)
1477 {
1478         volatile immap_t        *immap;
1479         volatile cpm8xx_t       *cp;
1480         volatile pcmconf8xx_t   *pcmp;
1481         u_long reg;
1482         ushort sreg;
1483
1484         debug ("voltage_set: "
1485                 PCMCIA_BOARD_MSG
1486                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1487                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1488
1489         immap = (immap_t *)CFG_IMMR;
1490         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1491         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1492         /*
1493          * Disable PCMCIA buffers (isolate the interface)
1494          * and assert RESET signal
1495          */
1496         debug ("Disable PCMCIA buffers and assert RESET\n");
1497         reg  =  PCMCIA_PGCRX(_slot_);
1498         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
1499         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
1500         PCMCIA_PGCRX(_slot_) = reg;
1501         udelay(500);
1502
1503         /*
1504          * Configure Port C pins for
1505          * 5 Volts Enable and 3 Volts enable,
1506          * Turn all power pins to Hi-Z
1507          */
1508         debug ("PCMCIA power OFF\n");
1509         cfg_ports ();   /* Enables switch, but all in Hi-Z */
1510
1511         sreg  = immap->im_ioport.iop_pcdat;
1512         sreg |= TPS2211_VPPD0 | TPS2211_VPPD1;          /* VAVPP always Hi-Z */
1513
1514         switch(vcc) {
1515         case  0:                        break;  /* Switch off           */
1516         case 33: sreg |=  TPS2211_VCCD0;        /* Switch on 3.3V       */
1517                  sreg &= ~TPS2211_VCCD1;
1518                                         break;
1519         case 50: sreg &= ~TPS2211_VCCD0;        /* Switch on 5.0V       */
1520                  sreg |=  TPS2211_VCCD1;
1521                                         break;
1522         default:                        goto done;
1523         }
1524
1525         /* Checking supported voltages */
1526
1527         debug ("PIPR: 0x%x --> %s\n",
1528                 pcmp->pcmc_pipr,
1529                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1530
1531         immap->im_ioport.iop_pcdat = sreg;
1532
1533 #ifdef DEBUG
1534     {
1535         char *s;
1536
1537         if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1538                 s = "at 3.3V";
1539         } else if (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) {
1540                 s = "at 5.0V";
1541         } else {
1542                 s = "down";
1543         }
1544         printf ("PCMCIA powered %s\n", s);
1545     }
1546 #endif
1547
1548 done:
1549         debug ("Enable PCMCIA buffers and stop RESET\n");
1550         reg  =  PCMCIA_PGCRX(_slot_);
1551         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1552         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1553         PCMCIA_PGCRX(_slot_) = reg;
1554         udelay(500);
1555
1556         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1557                 slot+'A');
1558         return (0);
1559 }
1560
1561 static void cfg_ports (void)
1562 {
1563         volatile immap_t        *immap;
1564         volatile cpm8xx_t       *cp;
1565         ushort sreg;
1566
1567         immap = (immap_t *)CFG_IMMR;
1568         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1569
1570         /*
1571          * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1572          *
1573          * Switch off all voltages, assert shutdown
1574          */
1575         sreg = immap->im_ioport.iop_pcdat;
1576         sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1);       /* VAVPP => Hi-Z */
1577         sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1);       /* 3V and 5V off */
1578         immap->im_ioport.iop_pcdat = sreg;
1579
1580         immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1581         immap->im_ioport.iop_pcdir |=   TPS2211_OUTPUTS;
1582
1583         debug ("Set Port C: PAR:     %04x DIR:     %04x DAT:     %04x\n",
1584                 immap->im_ioport.iop_pcpar,
1585                 immap->im_ioport.iop_pcdir,
1586                 immap->im_ioport.iop_pcdat);
1587
1588         /*
1589          * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1590          *
1591          * Over-Current Input only
1592          */
1593         cp->cp_pbpar &= ~(TPS2211_INPUTS);
1594         cp->cp_pbdir &= ~(TPS2211_INPUTS);
1595
1596         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1597                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1598 }
1599
1600 #endif  /* C2MON */
1601
1602 /* ----------------------------------------------------------------------------
1603    MBX board from Morotola
1604    ---------------------------------------------------------------------------- */
1605
1606 #if defined( CONFIG_MBX )
1607 #include <../board/mbx8xx/csr.h>
1608
1609 /* A lot of this has been taken from the RPX code in this file it works from me.
1610    I have added the voltage selection for the MBX board. */
1611
1612 /* MBX voltage bit in control register #2 */
1613 #define CR2_VPP12       ((uchar)0x10)
1614 #define CR2_VPPVDD      ((uchar)0x20)
1615 #define CR2_VDD5        ((uchar)0x40)
1616 #define CR2_VDD3        ((uchar)0x80)
1617
1618 #define PCMCIA_BOARD_MSG "MBX860"
1619
1620 static int voltage_set (int slot, int vcc, int vpp)
1621 {
1622         uchar reg = 0;
1623
1624         debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1625                  'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1626
1627         switch (vcc) {
1628         case 0:
1629                 break;
1630         case 33:
1631                 reg |= CR2_VDD3;
1632                 break;
1633         case 50:
1634                 reg |= CR2_VDD5;
1635                 break;
1636         default:
1637                 return 1;
1638         }
1639
1640         switch (vpp) {
1641         case 0:
1642                 break;
1643         case 33:
1644         case 50:
1645                 if (vcc == vpp) {
1646                         reg |= CR2_VPPVDD;
1647                 } else {
1648                         return 1;
1649                 }
1650                 break;
1651         case 120:
1652                 reg |= CR2_VPP12;
1653                 break;
1654         default:
1655                 return 1;
1656         }
1657
1658         /* first, turn off all power */
1659         MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1660
1661         /* enable new powersettings */
1662         MBX_CSR2 |= reg;
1663         debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1664
1665         return (0);
1666 }
1667
1668 static int hardware_enable (int slot)
1669 {
1670         volatile immap_t *immap;
1671         volatile cpm8xx_t *cp;
1672         volatile pcmconf8xx_t *pcmp;
1673         volatile sysconf8xx_t *sysp;
1674         uint reg, mask;
1675
1676         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1677                                   'A' + slot);
1678
1679         udelay (10000);
1680
1681         immap = (immap_t *) CFG_IMMR;
1682         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1683         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1684         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1685
1686         /* clear interrupt state, and disable interrupts */
1687         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1688         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1689
1690         /* disable interrupts & DMA */
1691         PCMCIA_PGCRX (_slot_) = 0;
1692
1693         /*
1694          * Disable PCMCIA buffers (isolate the interface)
1695          * and assert RESET signal
1696          */
1697         debug ("Disable PCMCIA buffers and assert RESET\n");
1698         reg = PCMCIA_PGCRX (_slot_);
1699         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1700         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
1701         PCMCIA_PGCRX (_slot_) = reg;
1702         udelay (500);
1703
1704         /* remove all power */
1705         voltage_set (slot, 0, 0);
1706         /*
1707          * Make sure there is a card in the slot, then configure the interface.
1708          */
1709         udelay(10000);
1710         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1711                 __LINE__,__FUNCTION__,
1712                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1713         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1714                 printf ("   No Card found\n");
1715                 return (1);
1716         }
1717
1718         /*
1719          * Power On.
1720          */
1721         mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1722         reg = pcmp->pcmc_pipr;
1723         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1724                   (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1725                   (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1726
1727         if ((reg & mask) == mask) {
1728                 voltage_set (_slot_, 50, 0);
1729                 printf (" 5.0V card found: ");
1730         } else {
1731                 voltage_set (_slot_, 33, 0);
1732                 printf (" 3.3V card found: ");
1733         }
1734
1735         debug ("Enable PCMCIA buffers and stop RESET\n");
1736         reg = PCMCIA_PGCRX (_slot_);
1737         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1738         reg &= ~__MY_PCMCIA_GCRX_CXOE;  /* active low  */
1739         PCMCIA_PGCRX (_slot_) = reg;
1740
1741         udelay (250000);        /* some cards need >150 ms to come up :-( */
1742
1743         debug ("# hardware_enable done\n");
1744
1745         return (0);
1746 }
1747
1748 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1749 static int hardware_disable (int slot)
1750 {
1751         return 0;       /* No hardware to disable */
1752 }
1753 #endif /* CFG_CMD_PCMCIA */
1754 #endif /* CONFIG_MBX */
1755 /* ---------------------------------------------------------------------------- */
1756 /* R360MPI Board                                                                */
1757 /* ---------------------------------------------------------------------------- */
1758
1759 #if defined(CONFIG_R360MPI)
1760
1761 #define PCMCIA_BOARD_MSG "R360MPI"
1762
1763
1764 static int hardware_enable(int slot)
1765 {
1766         volatile immap_t        *immap;
1767         volatile cpm8xx_t       *cp;
1768         volatile pcmconf8xx_t   *pcmp;
1769         volatile sysconf8xx_t   *sysp;
1770         uint reg, mask;
1771
1772         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1773
1774         udelay(10000);
1775
1776         immap = (immap_t *)CFG_IMMR;
1777         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1778         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1779         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1780
1781         /*
1782          * Configure SIUMCR to enable PCMCIA port B
1783          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1784          */
1785         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1786
1787         /* clear interrupt state, and disable interrupts */
1788         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1789         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1790
1791         /* disable interrupts & DMA */
1792         PCMCIA_PGCRX(_slot_) = 0;
1793
1794         /*
1795          * Disable PCMCIA buffers (isolate the interface)
1796          * and assert RESET signal
1797          */
1798         debug ("Disable PCMCIA buffers and assert RESET\n");
1799         reg  =  PCMCIA_PGCRX(_slot_);
1800         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
1801         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
1802         PCMCIA_PGCRX(_slot_) = reg;
1803         udelay(500);
1804
1805         /*
1806          * Configure Ports A, B & C pins for
1807          * 5 Volts Enable and 3 Volts enable
1808          */
1809         immap->im_ioport.iop_pcpar &= ~(0x0400);
1810         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
1811         immap->im_ioport.iop_pcdir |= 0x0400;*/
1812
1813         immap->im_ioport.iop_papar &= ~(0x0200);/*
1814         immap->im_ioport.iop_padir |= 0x0200;*/
1815 #if 0
1816         immap->im_ioport.iop_pbpar &= ~(0xC000);
1817         immap->im_ioport.iop_pbdir &= ~(0xC000);
1818 #endif
1819         /* remove all power */
1820
1821         immap->im_ioport.iop_pcdat |= 0x0400;
1822         immap->im_ioport.iop_padat |= 0x0200;
1823
1824         /*
1825          * Make sure there is a card in the slot, then configure the interface.
1826          */
1827         udelay(10000);
1828         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1829                 __LINE__,__FUNCTION__,
1830                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1831         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1832                 printf ("   No Card found\n");
1833                 return (1);
1834         }
1835
1836         /*
1837          * Power On.
1838          */
1839         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1840         reg  = pcmp->pcmc_pipr;
1841         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1842                 reg,
1843                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1844                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1845         if ((reg & mask) == mask) {
1846                 immap->im_ioport.iop_pcdat &= ~(0x4000);
1847                 puts (" 5.0V card found: ");
1848         } else {
1849                 immap->im_ioport.iop_padat &= ~(0x0002);
1850                 puts (" 3.3V card found: ");
1851         }
1852         immap->im_ioport.iop_pcdir |= 0x0400;
1853         immap->im_ioport.iop_padir |= 0x0200;
1854 #if 0
1855         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
1856         cp->cp_pbdir &= ~(0x0020 | 0x0010);
1857         cp->cp_pbpar &= ~(0x0020 | 0x0010);
1858         udelay(500000);
1859 #endif
1860         debug ("Enable PCMCIA buffers and stop RESET\n");
1861         reg  =  PCMCIA_PGCRX(_slot_);
1862         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1863         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1864         PCMCIA_PGCRX(_slot_) = reg;
1865
1866         udelay(250000); /* some cards need >150 ms to come up :-( */
1867
1868         debug ("# hardware_enable done\n");
1869
1870         return (0);
1871 }
1872
1873
1874
1875 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1876 static int hardware_disable(int slot)
1877 {
1878         volatile immap_t        *immap;
1879         volatile pcmconf8xx_t   *pcmp;
1880         u_long reg;
1881
1882         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1883
1884         immap = (immap_t *)CFG_IMMR;
1885         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1886
1887         /* remove all power */
1888         immap->im_ioport.iop_pcdat |= 0x0400;
1889         immap->im_ioport.iop_padat |= 0x0200;
1890
1891         /* Configure PCMCIA General Control Register */
1892         PCMCIA_PGCRX(_slot_) = 0;
1893
1894         debug ("Disable PCMCIA buffers and assert RESET\n");
1895         reg  =  PCMCIA_PGCRX(_slot_);
1896         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1897         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1898         PCMCIA_PGCRX(_slot_) = reg;
1899
1900         udelay(10000);
1901
1902         return (0);
1903 }
1904 #endif  /* CFG_CMD_PCMCIA */
1905
1906
1907
1908 static int voltage_set(int slot, int vcc, int vpp)
1909 {
1910         volatile immap_t        *immap;
1911         volatile pcmconf8xx_t   *pcmp;
1912         u_long reg;
1913
1914         debug ("voltage_set: "
1915                 PCMCIA_BOARD_MSG
1916                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1917                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1918
1919         immap = (immap_t *)CFG_IMMR;
1920         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1921         /*
1922          * Disable PCMCIA buffers (isolate the interface)
1923          * and assert RESET signal
1924          */
1925         debug ("Disable PCMCIA buffers and assert RESET\n");
1926         reg  =  PCMCIA_PGCRX(_slot_);
1927         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
1928         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
1929         PCMCIA_PGCRX(_slot_) = reg;
1930         udelay(500);
1931
1932         /*
1933          * Configure Ports A & C pins for
1934          * 5 Volts Enable and 3 Volts enable,
1935          * Turn off all power
1936          */
1937         debug ("PCMCIA power OFF\n");
1938         immap->im_ioport.iop_pcpar &= ~(0x0400);
1939         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
1940         immap->im_ioport.iop_pcdir |= 0x0400;*/
1941
1942         immap->im_ioport.iop_papar &= ~(0x0200);/*
1943         immap->im_ioport.iop_padir |= 0x0200;*/
1944
1945         immap->im_ioport.iop_pcdat |= 0x0400;
1946         immap->im_ioport.iop_padat |= 0x0200;
1947
1948         reg = 0;
1949         switch(vcc) {
1950         case  0:                break;
1951         case 33: reg |= 0x0200; break;
1952         case 50: reg |= 0x0400; break;
1953         default:                goto done;
1954         }
1955
1956         /* Checking supported voltages */
1957
1958         debug ("PIPR: 0x%x --> %s\n",
1959                 pcmp->pcmc_pipr,
1960                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1961
1962         if (reg & 0x0200)
1963                 immap->im_ioport.iop_pcdat &= !reg;
1964         if (reg & 0x0400)
1965                 immap->im_ioport.iop_padat &= !reg;
1966         immap->im_ioport.iop_pcdir |=  0x0200;
1967         immap->im_ioport.iop_padir |=  0x0400;
1968         if (reg) {
1969                 debug ("PCMCIA powered at %sV\n",
1970                         (reg&0x0400) ? "5.0" : "3.3");
1971         } else {
1972                 debug ("PCMCIA powered down\n");
1973         }
1974
1975 done:
1976         debug ("Enable PCMCIA buffers and stop RESET\n");
1977         reg  =  PCMCIA_PGCRX(_slot_);
1978         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1979         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1980         PCMCIA_PGCRX(_slot_) = reg;
1981         udelay(500);
1982
1983         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1984                 slot+'A');
1985         return (0);
1986 }
1987
1988 #endif  /* R360MPI */
1989
1990 /* ---------------------------------------------------------------------------- */
1991 /* KUP4K Board                                          */
1992 /* ---------------------------------------------------------------------------- */
1993 #if defined(CONFIG_KUP4K)
1994
1995 #define PCMCIA_BOARD_MSG "KUP4K"
1996
1997 #define KUP4K_PCMCIA_B_3V3 (0x00020000)
1998
1999 static int hardware_enable(int slot)
2000 {
2001         volatile immap_t        *immap;
2002         volatile cpm8xx_t       *cp;
2003         volatile pcmconf8xx_t   *pcmp;
2004         volatile sysconf8xx_t   *sysp;
2005         uint reg, mask;
2006
2007         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2008
2009         udelay(10000);
2010
2011         immap = (immap_t *)CFG_IMMR;
2012         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2013         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2014         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2015
2016         /*
2017          * Configure SIUMCR to enable PCMCIA port B
2018          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2019          */
2020         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
2021
2022         /* clear interrupt state, and disable interrupts */
2023         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
2024         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
2025
2026         /* disable interrupts & DMA */
2027         PCMCIA_PGCRX(slot) = 0;
2028
2029         /*
2030          * Disable PCMCIA buffers (isolate the interface)
2031          * and assert RESET signal
2032          */
2033         debug ("Disable PCMCIA buffers and assert RESET\n");
2034         reg  =  PCMCIA_PGCRX(slot);
2035         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
2036         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
2037         PCMCIA_PGCRX(slot) = reg;
2038         udelay(2500);
2039
2040         /*
2041          * Configure Port B pins for
2042          * 3 Volts enable
2043          */
2044         if (slot) { /* Slot A is built-in */
2045                 cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2046                 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2047                 /* remove all power */
2048                 cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2049         }
2050         /*
2051          * Make sure there is a card in the slot, then configure the interface.
2052          */
2053         udelay(10000);
2054         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2055                 __LINE__,__FUNCTION__,
2056                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2057         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2058                 printf ("   No Card found\n");
2059                 return (1);
2060         }
2061
2062         /*
2063          * Power On.
2064          */
2065         printf("%s  Slot %c:", slot ? "" : "\n", 'A' + slot);
2066         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2067         reg  = pcmp->pcmc_pipr;
2068         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2069                 reg,
2070                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2071                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2072         if ((reg & mask) == mask) {
2073                 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2074         } else {
2075                 if(slot)
2076                         cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2077                 puts (" 3.3V card found: ");
2078         }
2079 #if 0
2080         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
2081         cp->cp_pbdir &= ~(0x0020 | 0x0010);
2082         cp->cp_pbpar &= ~(0x0020 | 0x0010);
2083         udelay(500000);
2084 #endif
2085         debug ("Enable PCMCIA buffers and stop RESET\n");
2086         reg  =  PCMCIA_PGCRX(slot);
2087         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2088         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2089         PCMCIA_PGCRX(slot) = reg;
2090
2091         udelay(250000); /* some cards need >150 ms to come up :-( */
2092
2093         debug ("# hardware_enable done\n");
2094
2095         return (0);
2096 }
2097
2098
2099
2100 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2101 static int hardware_disable(int slot)
2102 {
2103         volatile immap_t        *immap;
2104         volatile cpm8xx_t       *cp;
2105         volatile pcmconf8xx_t   *pcmp;
2106         u_long reg;
2107
2108         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2109
2110         immap = (immap_t *)CFG_IMMR;
2111         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2112         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2113         
2114         /* remove all power */
2115         if (slot)
2116                 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
2117
2118         /* Configure PCMCIA General Control Register */
2119         PCMCIA_PGCRX(slot) = 0;
2120
2121         debug ("Disable PCMCIA buffers and assert RESET\n");
2122         reg  =  PCMCIA_PGCRX(slot);
2123         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2124         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2125         PCMCIA_PGCRX(slot) = reg;
2126
2127         udelay(10000);
2128
2129         return (0);
2130 }
2131 #endif  /* CFG_CMD_PCMCIA */
2132
2133
2134
2135 static int voltage_set(int slot, int vcc, int vpp)
2136 {
2137         volatile immap_t        *immap;
2138         volatile cpm8xx_t       *cp;
2139         volatile pcmconf8xx_t   *pcmp;
2140         u_long reg;
2141
2142         debug ("voltage_set: "  \
2143                 PCMCIA_BOARD_MSG        \
2144                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2145                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2146
2147         if (!slot) /* Slot A is not configurable */
2148                 return 0;
2149
2150         immap = (immap_t *)CFG_IMMR;
2151         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2152         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2153
2154         /*
2155          * Disable PCMCIA buffers (isolate the interface)
2156          * and assert RESET signal
2157          */
2158         debug ("Disable PCMCIA buffers and assert RESET\n");
2159         reg  =  PCMCIA_PGCRX(slot);
2160         reg |=  __MY_PCMCIA_GCRX_CXRESET;       /* active high */
2161         reg |=  __MY_PCMCIA_GCRX_CXOE;          /* active low  */
2162         PCMCIA_PGCRX(slot) = reg;
2163         udelay(500);
2164
2165         debug ("PCMCIA power OFF\n");
2166         /*
2167          * Configure Port B pins for
2168          * 3 Volts enable
2169          */
2170         cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2171         cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2172         /* remove all power */
2173         cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2174
2175         switch(vcc) {
2176         case  0:                break;
2177         case 33:
2178                 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2179                 debug ("PCMCIA powered at 3.3V\n");
2180                 break;
2181         case 50:
2182                 debug ("PCMCIA: 5Volt vcc not supported\n");
2183                 break;
2184         default:
2185                 puts("PCMCIA: vcc not supported");
2186                 break;
2187         }
2188         udelay(10000);
2189         /* Checking supported voltages */
2190
2191         debug ("PIPR: 0x%x --> %s\n",
2192                 pcmp->pcmc_pipr,
2193                    (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
2194                         ? "only 5 V --> NOT SUPPORTED"
2195                         : "can do 3.3V");
2196
2197
2198         debug ("Enable PCMCIA buffers and stop RESET\n");
2199         reg  =  PCMCIA_PGCRX(slot);
2200         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2201         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2202         PCMCIA_PGCRX(slot) = reg;
2203         udelay(500);
2204
2205         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2206                 slot+'A');
2207         return (0);
2208 }
2209
2210 #endif  /* KUP4K */
2211
2212
2213
2214
2215
2216 /* ---------------------------------------------------------------------------- */
2217 /* End of Board Specific Stuff                                                  */
2218 /* ---------------------------------------------------------------------------- */
2219
2220
2221 /* ---------------------------------------------------------------------------- */
2222 /* MPC8xx Specific Stuff - should go to MPC8xx directory                        */
2223 /* ---------------------------------------------------------------------------- */
2224
2225 /*
2226  * Search this table to see if the windowsize is
2227  * supported...
2228  */
2229
2230 #define M8XX_SIZES_NO 32
2231
2232 static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2233 { 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2234   0x00000080, 0x00000040, 0x00000010, 0x00000020,
2235   0x00008000, 0x00004000, 0x00001000, 0x00002000,
2236   0x00000100, 0x00000200, 0x00000800, 0x00000400,
2237
2238   0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2239   0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2240   0x00010000, 0x00020000, 0x00080000, 0x00040000,
2241   0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2242
2243
2244 /* ---------------------------------------------------------------------------- */
2245
2246 static u_int m8xx_get_graycode(u_int size)
2247 {
2248         u_int k;
2249
2250         for (k = 0; k < M8XX_SIZES_NO; k++) {
2251                 if(m8xx_size_to_gray[k] == size)
2252                         break;
2253         }
2254
2255         if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2256                 k = -1;
2257
2258         return k;
2259 }
2260
2261 /* ------------------------------------------------------------------------- */
2262
2263 #if 0
2264 static u_int m8xx_get_speed(u_int ns, u_int is_io)
2265 {
2266         u_int reg, clocks, psst, psl, psht;
2267
2268         if(!ns) {
2269
2270                 /*
2271                  * We get called with IO maps setup to 0ns
2272                  * if not specified by the user.
2273                  * They should be 255ns.
2274                  */
2275
2276                 if(is_io)
2277                         ns = 255;
2278                 else
2279                         ns = 100;  /* fast memory if 0 */
2280         }
2281
2282         /*
2283          * In PSST, PSL, PSHT fields we tell the controller
2284          * timing parameters in CLKOUT clock cycles.
2285          * CLKOUT is the same as GCLK2_50.
2286          */
2287
2288 /* how we want to adjust the timing - in percent */
2289
2290 #define ADJ 180 /* 80 % longer accesstime - to be sure */
2291
2292         clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2293         clocks = (clocks * ADJ) / (100*1000);
2294
2295         if(clocks >= PCMCIA_BMT_LIMIT) {
2296                 DEBUG(0, "Max access time limit reached\n");
2297                 clocks = PCMCIA_BMT_LIMIT-1;
2298         }
2299
2300         psst = clocks / 7;          /* setup time */
2301         psht = clocks / 7;          /* hold time */
2302         psl  = (clocks * 5) / 7;    /* strobe length */
2303
2304         psst += clocks - (psst + psht + psl);
2305
2306         reg =  psst << 12;
2307         reg |= psl  << 7;
2308         reg |= psht << 16;
2309
2310         return reg;
2311 }
2312 #endif
2313
2314 /* ------------------------------------------------------------------------- */
2315
2316 #ifdef CONFIG_IDE_8xx_PCCARD
2317 static void print_funcid (int func)
2318 {
2319         puts (indent);
2320         switch (func) {
2321         case CISTPL_FUNCID_MULTI:
2322                 puts (" Multi-Function");
2323                 break;
2324         case CISTPL_FUNCID_MEMORY:
2325                 puts (" Memory");
2326                 break;
2327         case CISTPL_FUNCID_SERIAL:
2328                 puts (" Serial Port");
2329                 break;
2330         case CISTPL_FUNCID_PARALLEL:
2331                 puts (" Parallel Port");
2332                 break;
2333         case CISTPL_FUNCID_FIXED:
2334                 puts (" Fixed Disk");
2335                 break;
2336         case CISTPL_FUNCID_VIDEO:
2337                 puts (" Video Adapter");
2338                 break;
2339         case CISTPL_FUNCID_NETWORK:
2340                 puts (" Network Adapter");
2341                 break;
2342         case CISTPL_FUNCID_AIMS:
2343                 puts (" AIMS Card");
2344                 break;
2345         case CISTPL_FUNCID_SCSI:
2346                 puts (" SCSI Adapter");
2347                 break;
2348         default:
2349                 puts (" Unknown");
2350                 break;
2351         }
2352         puts (" Card\n");
2353 }
2354 #endif  /* CONFIG_IDE_8xx_PCCARD */
2355
2356 /* ------------------------------------------------------------------------- */
2357
2358 #ifdef CONFIG_IDE_8xx_PCCARD
2359 static void print_fixed (volatile uchar *p)
2360 {
2361         if (p == NULL)
2362                 return;
2363
2364         puts(indent);
2365
2366         switch (*p) {
2367         case CISTPL_FUNCE_IDE_IFACE:
2368             {   uchar iface = *(p+2);
2369
2370                 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2371                 puts (" interface ");
2372                 break;
2373             }
2374         case CISTPL_FUNCE_IDE_MASTER:
2375         case CISTPL_FUNCE_IDE_SLAVE:
2376             {   uchar f1 = *(p+2);
2377                 uchar f2 = *(p+4);
2378
2379                 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2380
2381                 if (f1 & CISTPL_IDE_UNIQUE)
2382                         puts (" [unique]");
2383
2384                 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2385
2386                 if (f2 & CISTPL_IDE_HAS_SLEEP)
2387                         puts (" [sleep]");
2388
2389                 if (f2 & CISTPL_IDE_HAS_STANDBY)
2390                         puts (" [standby]");
2391
2392                 if (f2 & CISTPL_IDE_HAS_IDLE)
2393                         puts (" [idle]");
2394
2395                 if (f2 & CISTPL_IDE_LOW_POWER)
2396                         puts (" [low power]");
2397
2398                 if (f2 & CISTPL_IDE_REG_INHIBIT)
2399                         puts (" [reg inhibit]");
2400
2401                 if (f2 & CISTPL_IDE_HAS_INDEX)
2402                         puts (" [index]");
2403
2404                 if (f2 & CISTPL_IDE_IOIS16)
2405                         puts (" [IOis16]");
2406
2407                 break;
2408             }
2409         }
2410         putc ('\n');
2411 }
2412 #endif  /* CONFIG_IDE_8xx_PCCARD */
2413
2414 /* ------------------------------------------------------------------------- */
2415
2416 #ifdef CONFIG_IDE_8xx_PCCARD
2417
2418 #define MAX_IDENT_CHARS         64
2419 #define MAX_IDENT_FIELDS        4
2420
2421 static uchar *known_cards[] = {
2422         "ARGOSY PnPIDE D5",
2423         NULL
2424 };
2425
2426 static int identify  (volatile uchar *p)
2427 {
2428         uchar id_str[MAX_IDENT_CHARS];
2429         uchar data;
2430         uchar *t;
2431         uchar **card;
2432         int i, done;
2433
2434         if (p == NULL)
2435                 return (0);     /* Don't know */
2436
2437         t = id_str;
2438         done =0;
2439
2440         for (i=0; i<=4 && !done; ++i, p+=2) {
2441                 while ((data = *p) != '\0') {
2442                         if (data == 0xFF) {
2443                                 done = 1;
2444                                 break;
2445                         }
2446                         *t++ = data;
2447                         if (t == &id_str[MAX_IDENT_CHARS-1]) {
2448                                 done = 1;
2449                                 break;
2450                         }
2451                         p += 2;
2452                 }
2453                 if (!done)
2454                         *t++ = ' ';
2455         }
2456         *t = '\0';
2457         while (--t > id_str) {
2458                 if (*t == ' ')
2459                         *t = '\0';
2460                 else
2461                         break;
2462         }
2463         puts (id_str);
2464         putc ('\n');
2465
2466         for (card=known_cards; *card; ++card) {
2467                 debug ("## Compare against \"%s\"\n", *card);
2468                 if (strcmp(*card, id_str) == 0) {       /* found! */
2469                         debug ("## CARD FOUND ##\n");
2470                         return (1);
2471                 }
2472         }
2473
2474         return (0);     /* don't know */
2475 }
2476 #endif  /* CONFIG_IDE_8xx_PCCARD */
2477
2478 /* ------------------------------------------------------------------------- */
2479
2480 #endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */