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