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