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