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