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