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