]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_pcmcia.c
Add support for VirtLab2 board
[karo-tx-uboot.git] / common / cmd_pcmcia.c
1 /*
2  * (C) Copyright 2000-2006
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 #ifdef CONFIG_PXA_PCMCIA
67 #include <asm/arch/pxa-regs.h>
68 #endif
69
70 #include <asm/io.h>
71
72 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
73     ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
74
75 int pcmcia_on (void);
76
77 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
78 static int  pcmcia_off (void);
79 #endif
80
81 #ifdef CONFIG_I82365
82
83 extern int i82365_init (void);
84 extern void i82365_exit (void);
85
86 #else /* ! CONFIG_I82365 */
87
88 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
89 static int  hardware_disable(int slot);
90 #endif
91 static int  hardware_enable (int slot);
92 static int  voltage_set(int slot, int vcc, int vpp);
93
94 #if (! defined(CONFIG_I82365)) && (! defined(CONFIG_PXA_PCMCIA))
95 static u_int m8xx_get_graycode(u_int size);
96 #endif  /* !CONFIG_I82365, !CONFIG_PXA_PCMCIA */
97 #if 0
98 static u_int m8xx_get_speed(u_int ns, u_int is_io);
99 #endif
100
101 /* -------------------------------------------------------------------- */
102
103 #ifndef CONFIG_PXA_PCMCIA
104
105 /* look up table for pgcrx registers */
106
107 static u_int *pcmcia_pgcrx[2] = {
108         &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
109         &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
110 };
111 #define PCMCIA_PGCRX(slot)      (*pcmcia_pgcrx[slot])
112
113 #endif  /* CONFIG_PXA_PCMCIA */
114
115 #endif /* CONFIG_I82365 */
116
117 #if defined(CONFIG_IDE_8xx_PCCARD)  || defined(CONFIG_PXA_PCMCIA)
118 static void print_funcid (int func);
119 static void print_fixed  (volatile uchar *p);
120 static int  identify     (volatile uchar *p);
121 static int  check_ide_device (int slot);
122 #endif  /* CONFIG_IDE_8xx_PCCARD, CONFIG_PXA_PCMCIA */
123
124 const char *indent = "\t   ";
125
126 /* -------------------------------------------------------------------- */
127
128 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
129
130 int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
131 {
132         int rcode = 0;
133
134         if (argc != 2) {
135                 printf ("Usage: pinit {on | off}\n");
136                 return 1;
137         }
138         if (strcmp(argv[1],"on") == 0) {
139                 rcode = pcmcia_on ();
140         } else if (strcmp(argv[1],"off") == 0) {
141                 rcode = pcmcia_off ();
142         } else {
143                 printf ("Usage: pinit {on | off}\n");
144                 return 1;
145         }
146
147         return rcode;
148 }
149 #endif  /* CFG_CMD_PCMCIA */
150
151 /* -------------------------------------------------------------------- */
152
153 #ifdef CONFIG_I82365
154 int pcmcia_on (void)
155 {
156         u_int rc;
157
158         debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
159
160         rc = i82365_init();
161
162         if (rc == 0) {
163                 rc = check_ide_device(0);
164         }
165
166         return (rc);
167 }
168 #else
169
170 #ifndef CONFIG_PXA_PCMCIA
171
172 #ifdef CONFIG_HMI10
173 # define  HMI10_FRAM_TIMING     (PCMCIA_SHT(2) | PCMCIA_SST(2) | PCMCIA_SL(4))
174 #endif
175 #if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
176 # define  CFG_PCMCIA_TIMING     (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
177 #else
178 # define  CFG_PCMCIA_TIMING     (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
179 #endif
180
181 int pcmcia_on (void)
182 {
183         int i;
184         u_long reg, base;
185         pcmcia_win_t *win;
186         u_int slotbit;
187         u_int rc, slot;
188
189         debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
190
191         /* intialize the fixed memory windows */
192         win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
193         base = CFG_PCMCIA_MEM_ADDR;
194
195         if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
196                 printf ("Cannot set window size to 0x%08x\n",
197                         CFG_PCMCIA_MEM_SIZE);
198                 return (1);
199         }
200
201         slotbit = PCMCIA_SLOT_x;
202         for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
203                 win->br = base;
204
205 #if (PCMCIA_SOCKETS_NO == 2)
206                 if (i == 4) /* Another slot starting from win 4 */
207                         slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
208 #endif
209                 switch (i) {
210 #ifdef CONFIG_IDE_8xx_PCCARD
211                 case 4:
212 #ifdef CONFIG_HMI10
213                     {   /* map FRAM area */
214                         win->or = (     PCMCIA_BSIZE_256K
215                                 |       PCMCIA_PPS_8
216                                 |       PCMCIA_PRS_ATTR
217                                 |       slotbit
218                                 |       PCMCIA_PV
219                                 |       HMI10_FRAM_TIMING );
220                         break;
221                     }
222 #endif
223                 case 0: {       /* map attribute memory */
224                         win->or = (     PCMCIA_BSIZE_64M
225                                 |       PCMCIA_PPS_8
226                                 |       PCMCIA_PRS_ATTR
227                                 |       slotbit
228                                 |       PCMCIA_PV
229                                 |       CFG_PCMCIA_TIMING );
230                         break;
231                     }
232                 case 5:
233                 case 1: {       /* map I/O window for data reg */
234                         win->or = (     PCMCIA_BSIZE_1K
235                                 |       PCMCIA_PPS_16
236                                 |       PCMCIA_PRS_IO
237                                 |       slotbit
238                                 |       PCMCIA_PV
239                                 |       CFG_PCMCIA_TIMING );
240                         break;
241                     }
242                 case 6:
243                 case 2: {       /* map I/O window for cmd/ctrl reg block */
244                         win->or = (     PCMCIA_BSIZE_1K
245                                 |       PCMCIA_PPS_8
246                                 |       PCMCIA_PRS_IO
247                                 |       slotbit
248                                 |       PCMCIA_PV
249                                 |       CFG_PCMCIA_TIMING );
250                         break;
251                     }
252 #endif  /* CONFIG_IDE_8xx_PCCARD */
253 #ifdef CONFIG_HMI10
254                 case 3: {       /* map I/O window for 4xUART data/ctrl */
255                         win->br += 0x40000;
256                         win->or = (     PCMCIA_BSIZE_256K
257                                 |       PCMCIA_PPS_8
258                                 |       PCMCIA_PRS_IO
259                                 |       slotbit
260                                 |       PCMCIA_PV
261                                 |       CFG_PCMCIA_TIMING );
262                         break;
263                     }
264 #endif /* CONFIG_HMI10 */
265                 default:        /* set to not valid */
266                         win->or = 0;
267                         break;
268                 }
269
270                 debug ("MemWin %d: PBR 0x%08lX  POR %08lX\n",
271                         i, win->br, win->or);
272                 base += CFG_PCMCIA_MEM_SIZE;
273                 ++win;
274         }
275
276         for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
277                 /* turn off voltage */
278                 if ((rc = voltage_set(slot, 0, 0)))
279                         continue;
280
281                 /* Enable external hardware */
282                 if ((rc = hardware_enable(slot)))
283                         continue;
284
285 #ifdef CONFIG_IDE_8xx_PCCARD
286                 if ((rc = check_ide_device(i)))
287                         continue;
288 #endif
289         }
290         return (rc);
291 }
292
293 #endif /* CONFIG_PXA_PCMCIA */
294
295 #endif /* CONFIG_I82365 */
296
297 #ifdef CONFIG_PXA_PCMCIA
298
299 static int hardware_enable (int slot)
300 {
301         return 0;       /* No hardware to enable */
302 }
303
304 static int hardware_disable(int slot)
305 {
306         return 0;       /* No hardware to disable */
307 }
308
309 static int voltage_set(int slot, int vcc, int vpp)
310 {
311         return 0;
312 }
313
314 void msWait(unsigned msVal)
315 {
316         udelay(msVal*1000);
317 }
318
319 int pcmcia_on (void)
320 {
321         unsigned int reg_arr[] = {
322                 0x48000028, CFG_MCMEM0_VAL,
323                 0x4800002c, CFG_MCMEM1_VAL,
324                 0x48000030, CFG_MCATT0_VAL,
325                 0x48000034, CFG_MCATT1_VAL,
326                 0x48000038, CFG_MCIO0_VAL,
327                 0x4800003c, CFG_MCIO1_VAL,
328
329                 0, 0
330         };
331         int i, rc;
332
333 #ifdef CONFIG_EXADRON1
334         int cardDetect;
335         volatile unsigned int *v_pBCRReg =
336                 (volatile unsigned int *) 0x08000000;
337 #endif
338
339         debug ("%s\n", __FUNCTION__);
340
341         i = 0;
342         while (reg_arr[i])
343                 *((volatile unsigned int *) reg_arr[i++]) |= reg_arr[i++];
344         udelay (1000);
345
346         debug ("%s: programmed mem controller \n", __FUNCTION__);
347
348 #ifdef CONFIG_EXADRON1
349
350 /*define useful BCR masks */
351 #define BCR_CF_INIT_VAL                     0x00007230
352 #define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL    0x00007231
353 #define BCR_CF_PWRON_BUSOFF_RESETON_VAL     0x00007233
354 #define BCR_CF_PWRON_BUSON_RESETON_VAL      0x00007213
355 #define BCR_CF_PWRON_BUSON_RESETOFF_VAL     0x00007211
356
357         /* we see from the GPIO bit if the card is present */
358         cardDetect = !(GPLR0 & GPIO_bit (14));
359
360         if (cardDetect) {
361                 printf ("No PCMCIA card found!\n");
362         }
363
364         /* reset the card via the BCR line */
365         *v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
366         msWait (500);
367
368         *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
369         msWait (500);
370
371         *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
372         msWait (500);
373
374         *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
375         msWait (500);
376
377         *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
378         msWait (1500);
379
380         /* enable address bus */
381         GPCR1 = 0x01;
382         /* and the first CF slot */
383         MECR = 0x00000002;
384
385 #endif /* EXADRON 1 */
386
387         rc = check_ide_device (0);      /* use just slot 0 */
388
389         return rc;
390 }
391
392 #endif /* CONFIG_PXA_PCMCIA */
393
394 /* -------------------------------------------------------------------- */
395
396 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
397
398 #ifdef CONFIG_I82365
399 static int pcmcia_off (void)
400 {
401         printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
402
403         i82365_exit();
404
405         return 0;
406 }
407 #else
408
409 #ifndef CONFIG_PXA_PCMCIA
410
411 static int pcmcia_off (void)
412 {
413         int i;
414         pcmcia_win_t *win;
415
416         printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
417
418         /* clear interrupt state, and disable interrupts */
419         ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr =  PCMCIA_MASK(_slot_);
420         ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
421
422         /* turn off interrupt and disable CxOE */
423         PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
424
425         /* turn off memory windows */
426         win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
427
428         for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
429                 /* disable memory window */
430                 win->or = 0;
431                 ++win;
432         }
433
434         /* turn off voltage */
435         voltage_set(_slot_, 0, 0);
436
437         /* disable external hardware */
438         printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
439         hardware_disable(_slot_);
440         return 0;
441 }
442
443 #endif /* CONFIG_PXA_PCMCIA */
444
445 #endif /* CONFIG_I82365 */
446
447 #ifdef CONFIG_PXA_PCMCIA
448 static int pcmcia_off (void)
449 {
450         return 0;
451 }
452 #endif
453
454 #endif  /* CFG_CMD_PCMCIA */
455
456 /* -------------------------------------------------------------------- */
457
458 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
459
460 #define MAX_TUPEL_SZ    512
461 #define MAX_FEATURES    4
462
463 int ide_devices_found;
464 static int check_ide_device (int slot)
465 {
466         volatile uchar *ident = NULL;
467         volatile uchar *feature_p[MAX_FEATURES];
468         volatile uchar *p, *start, *addr;
469         int n_features = 0;
470         uchar func_id = ~0;
471         uchar code, len;
472         ushort config_base = 0;
473         int found = 0;
474         int i;
475
476         addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
477                                   CFG_PCMCIA_MEM_SIZE * (slot * 4));
478         debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
479
480         start = p = (volatile uchar *) addr;
481
482         while ((p - start) < MAX_TUPEL_SZ) {
483
484                 code = *p; p += 2;
485
486                 if (code == 0xFF) { /* End of chain */
487                         break;
488                 }
489
490                 len = *p; p += 2;
491 #if defined(DEBUG) && (DEBUG > 1)
492                 { volatile uchar *q = p;
493                         printf ("\nTuple code %02x  length %d\n\tData:",
494                                 code, len);
495
496                         for (i = 0; i < len; ++i) {
497                                 printf (" %02x", *q);
498                                 q+= 2;
499                         }
500                 }
501 #endif  /* DEBUG */
502                 switch (code) {
503                 case CISTPL_VERS_1:
504                         ident = p + 4;
505                         break;
506                 case CISTPL_FUNCID:
507                         /* Fix for broken SanDisk which may have 0x80 bit set */
508                         func_id = *p & 0x7F;
509                         break;
510                 case CISTPL_FUNCE:
511                         if (n_features < MAX_FEATURES)
512                                 feature_p[n_features++] = p;
513                         break;
514                 case CISTPL_CONFIG:
515                         config_base = (*(p+6) << 8) + (*(p+4));
516                         debug ("\n## Config_base = %04x ###\n", config_base);
517                 default:
518                         break;
519                 }
520                 p += 2 * len;
521         }
522
523         found = identify (ident);
524
525         if (func_id != ((uchar)~0)) {
526                 print_funcid (func_id);
527
528                 if (func_id == CISTPL_FUNCID_FIXED)
529                         found = 1;
530                 else
531                         return (1);     /* no disk drive */
532         }
533
534         for (i=0; i<n_features; ++i) {
535                 print_fixed (feature_p[i]);
536         }
537
538         if (!found) {
539                 printf ("unknown card type\n");
540                 return (1);
541         }
542
543         ide_devices_found |= (1 << slot);
544
545 #if CONFIG_CPC45
546 #else
547         /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
548         *((uchar *)(addr + config_base)) = 1;
549 #endif
550 #if 0
551         printf("\n## Config_base = %04x ###\n", config_base);
552         printf("Configuration Option Register: %02x @ %x\n", readb(addr + config_base), addr + config_base);
553         printf("Card Configuration and Status Register: %02x\n", readb(addr + config_base + 2));
554         printf("Pin Replacement Register Register: %02x\n", readb(addr + config_base + 4));
555         printf("Socket and Copy Register: %02x\n", readb(addr + config_base + 6));
556 #endif
557         return (0);
558 }
559 #endif  /* CONFIG_IDE_8xx_PCCARD */
560
561 /* -------------------------------------------------------------------- */
562
563
564 /* -------------------------------------------------------------------- */
565 /* board specific stuff:                                                */
566 /* voltage_set(), hardware_enable() and hardware_disable()              */
567 /* -------------------------------------------------------------------- */
568
569 /* -------------------------------------------------------------------- */
570 /* RPX Boards from Embedded Planet                                      */
571 /* -------------------------------------------------------------------- */
572
573 #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
574
575 /* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
576  * SYPCR is write once only, therefore must the slowest memory be faster
577  * than the bus monitor or we will get a machine check due to the bus timeout.
578  */
579
580 #define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
581
582 #undef PCMCIA_BMT_LIMIT
583 #define PCMCIA_BMT_LIMIT (6*8)
584
585 static int voltage_set(int slot, int vcc, int vpp)
586 {
587         u_long reg = 0;
588
589         switch(vcc) {
590         case 0: break;
591         case 33: reg |= BCSR1_PCVCTL4; break;
592         case 50: reg |= BCSR1_PCVCTL5; break;
593         default: return 1;
594         }
595
596         switch(vpp) {
597         case 0: break;
598         case 33:
599         case 50:
600                 if(vcc == vpp)
601                         reg |= BCSR1_PCVCTL6;
602                 else
603                         return 1;
604                 break;
605         case 120:
606                 reg |= BCSR1_PCVCTL7;
607         default: return 1;
608         }
609
610         if(vcc == 120)
611            return 1;
612
613         /* first, turn off all power */
614
615         *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
616                                      | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
617
618         /* enable new powersettings */
619
620         *((uint *)RPX_CSR_ADDR) |= reg;
621
622         return 0;
623 }
624
625 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
626 static int hardware_enable (int slot)
627 {
628         return 0;       /* No hardware to enable */
629 }
630 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
631 static int hardware_disable(int slot)
632 {
633         return 0;       /* No hardware to disable */
634 }
635 #endif  /* CFG_CMD_PCMCIA */
636 #endif  /* CONFIG_RPXCLASSIC */
637
638 /* -------------------------------------------------------------------- */
639 /* (F)ADS Boards from Motorola                                          */
640 /* -------------------------------------------------------------------- */
641
642 #if defined(CONFIG_ADS) || defined(CONFIG_FADS)
643
644 #ifdef CONFIG_ADS
645 #define PCMCIA_BOARD_MSG "ADS"
646 #define PCMCIA_GLITCHY_CD  /* My ADS board needs this */
647 #else
648 #define PCMCIA_BOARD_MSG "FADS"
649 #endif
650
651 static int voltage_set(int slot, int vcc, int vpp)
652 {
653         u_long reg = 0;
654
655         switch(vpp) {
656         case 0: reg = 0; break;
657         case 50: reg = 1; break;
658         case 120: reg = 2; break;
659         default: return 1;
660         }
661
662         switch(vcc) {
663         case 0: reg = 0; break;
664 #ifdef CONFIG_ADS
665         case 50: reg = BCSR1_PCCVCCON; break;
666 #endif
667 #ifdef CONFIG_FADS
668         case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
669         case 50: reg = BCSR1_PCCVCC1; break;
670 #endif
671         default: return 1;
672         }
673
674         /* first, turn off all power */
675
676 #ifdef CONFIG_ADS
677         *((uint *)BCSR1) |= BCSR1_PCCVCCON;
678 #endif
679 #ifdef CONFIG_FADS
680         *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
681 #endif
682         *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
683
684         /* enable new powersettings */
685
686 #ifdef CONFIG_ADS
687         *((uint *)BCSR1) &= ~reg;
688 #endif
689 #ifdef CONFIG_FADS
690         *((uint *)BCSR1) |= reg;
691 #endif
692
693         *((uint *)BCSR1) |= reg << 20;
694
695         return 0;
696 }
697
698 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
699
700 static int hardware_enable(int slot)
701 {
702         *((uint *)BCSR1) &= ~BCSR1_PCCEN;
703         return 0;
704 }
705
706 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
707 static int hardware_disable(int slot)
708 {
709         *((uint *)BCSR1) &= ~BCSR1_PCCEN;
710         return 0;
711 }
712 #endif  /* CFG_CMD_PCMCIA */
713
714 #endif  /* (F)ADS */
715
716 /* -------------------------------------------------------------------- */
717 /* TQM8xxL Boards by TQ Components                                      */
718 /* SC8xx   Boards by SinoVee Microsystems                               */
719 /* -------------------------------------------------------------------- */
720
721 #if (defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)) \
722         && !defined(CONFIG_VIRTLAB2)
723
724 #if defined(CONFIG_TQM8xxL)
725 #define PCMCIA_BOARD_MSG "TQM8xxL"
726 #endif
727 #if defined(CONFIG_SVM_SC8xx)
728 #define PCMCIA_BOARD_MSG "SC8xx"
729 #endif
730
731 static int hardware_enable(int slot)
732 {
733         volatile immap_t        *immap;
734         volatile cpm8xx_t       *cp;
735         volatile pcmconf8xx_t   *pcmp;
736         volatile sysconf8xx_t   *sysp;
737         uint reg, mask;
738
739         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
740
741         udelay(10000);
742
743         immap = (immap_t *)CFG_IMMR;
744         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
745         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
746         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
747
748         /*
749          * Configure SIUMCR to enable PCMCIA port B
750          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
751          */
752         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
753
754         /* clear interrupt state, and disable interrupts */
755         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
756         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
757
758         /*
759          * Disable interrupts, DMA, and PCMCIA buffers
760          * (isolate the interface) and assert RESET signal
761          */
762         debug ("Disable PCMCIA buffers and assert RESET\n");
763         reg  = 0;
764         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
765 #ifndef NSCU_OE_INV
766         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
767 #endif
768         PCMCIA_PGCRX(slot) = reg;
769         udelay(500);
770
771 #ifndef CONFIG_HMI10
772 #ifndef CONFIG_NSCU
773         /*
774          * Configure Port C pins for
775          * 5 Volts Enable and 3 Volts enable
776          */
777         immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
778         immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
779         /* remove all power */
780
781         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
782 #endif
783 #else   /* CONFIG_HMI10 */
784         /*
785          * Configure Port B  pins for
786          * 5 Volts Enable and 3 Volts enable
787          */
788         immap->im_cpm.cp_pbpar &= ~(0x00000300);
789
790         /* remove all power */
791         immap->im_cpm.cp_pbdat |= 0x00000300;
792 #endif  /* CONFIG_HMI10 */
793
794         /*
795          * Make sure there is a card in the slot, then configure the interface.
796          */
797         udelay(10000);
798         debug ("[%d] %s: PIPR(%p)=0x%x\n",
799                 __LINE__,__FUNCTION__,
800                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
801 #ifndef CONFIG_HMI10
802         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
803 #else
804         if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
805 #endif  /* CONFIG_HMI10 */
806                 printf ("   No Card found\n");
807                 return (1);
808         }
809
810         /*
811          * Power On.
812          */
813         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
814         reg  = pcmp->pcmc_pipr;
815         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
816                 reg,
817                 (reg&PCMCIA_VS1(slot))?"n":"ff",
818                 (reg&PCMCIA_VS2(slot))?"n":"ff");
819 #ifndef CONFIG_NSCU
820         if ((reg & mask) == mask) {
821 #ifndef CONFIG_HMI10
822                 immap->im_ioport.iop_pcdat |= 0x0004;
823 #else
824                 immap->im_cpm.cp_pbdat &= ~(0x0000100);
825 #endif  /* CONFIG_HMI10 */
826                 puts (" 5.0V card found: ");
827         } else {
828 #ifndef CONFIG_HMI10
829                 immap->im_ioport.iop_pcdat |= 0x0002;
830 #else
831                 immap->im_cpm.cp_pbdat &= ~(0x0000200);
832 #endif  /* CONFIG_HMI10 */
833                 puts (" 3.3V card found: ");
834         }
835 #ifndef CONFIG_HMI10
836         immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
837 #else
838         immap->im_cpm.cp_pbdir |= 0x00000300;
839 #endif  /* CONFIG_HMI10 */
840 #else
841         if ((reg & mask) == mask) {
842                 puts (" 5.0V card found: ");
843         } else {
844                 puts (" 3.3V card found: ");
845         }
846 #endif
847 #if 0
848         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
849         cp->cp_pbdir &= ~(0x0020 | 0x0010);
850         cp->cp_pbpar &= ~(0x0020 | 0x0010);
851         udelay(500000);
852 #endif
853         udelay(1000);
854         debug ("Enable PCMCIA buffers and stop RESET\n");
855         reg  =  PCMCIA_PGCRX(slot);
856         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
857 #ifndef NSCU_OE_INV
858         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
859 #else
860         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
861 #endif
862         PCMCIA_PGCRX(slot) = reg;
863
864         udelay(250000); /* some cards need >150 ms to come up :-( */
865
866         debug ("# hardware_enable done\n");
867
868         return (0);
869 }
870
871
872 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
873 static int hardware_disable(int slot)
874 {
875         volatile immap_t        *immap;
876         volatile pcmconf8xx_t   *pcmp;
877         u_long reg;
878
879         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
880
881         immap = (immap_t *)CFG_IMMR;
882         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
883
884 #ifndef CONFIG_HMI10
885 #ifndef CONFIG_NSCU
886         /* remove all power */
887         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
888 #endif
889 #else   /* CONFIG_HMI10 */
890         immap->im_cpm.cp_pbdat |= 0x00000300;
891 #endif  /* CONFIG_HMI10 */
892
893         debug ("Disable PCMCIA buffers and assert RESET\n");
894         reg  = 0;
895         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
896 #ifndef NSCU_OE_INV
897         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
898 #endif
899         PCMCIA_PGCRX(slot) = reg;
900
901         udelay(10000);
902
903         return (0);
904 }
905 #endif  /* CFG_CMD_PCMCIA */
906
907 #ifdef CONFIG_NSCU
908 static int voltage_set(int slot, int vcc, int vpp)
909 {
910         return 0;
911 }
912 #else
913 static int voltage_set(int slot, int vcc, int vpp)
914 {
915         volatile immap_t        *immap;
916         volatile pcmconf8xx_t   *pcmp;
917         u_long reg;
918
919         debug ("voltage_set: "
920                 PCMCIA_BOARD_MSG
921                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
922                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
923
924         immap = (immap_t *)CFG_IMMR;
925         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
926         /*
927          * Disable PCMCIA buffers (isolate the interface)
928          * and assert RESET signal
929          */
930         debug ("Disable PCMCIA buffers and assert RESET\n");
931         reg  = PCMCIA_PGCRX(slot);
932         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
933 #ifndef NSCU_OE_INV
934         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
935 #else
936         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
937 #endif
938         PCMCIA_PGCRX(slot) = reg;
939         udelay(500);
940
941 #ifndef CONFIG_HMI10
942         /*
943          * Configure Port C pins for
944          * 5 Volts Enable and 3 Volts enable,
945          * Turn off all power
946          */
947         debug ("PCMCIA power OFF\n");
948         immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
949         immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
950         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
951
952         reg = 0;
953         switch(vcc) {
954         case  0:                break;
955         case 33: reg |= 0x0002; break;
956         case 50: reg |= 0x0004; break;
957         default:                goto done;
958         }
959 #else   /* CONFIG_HMI10 */
960         /*
961          * Configure Port B pins for
962          * 5 Volts Enable and 3 Volts enable,
963          * Turn off all power
964          */
965         debug ("PCMCIA power OFF\n");
966         immap->im_cpm.cp_pbpar &= ~(0x00000300);
967         /* remove all power */
968
969         immap->im_cpm.cp_pbdat |= 0x00000300;
970
971         reg = 0;
972         switch(vcc) {
973                 case  0:                        break;
974                 case 33: reg |= 0x00000200;     break;
975                 case 50: reg |= 0x00000100;     break;
976                 default:                        goto done;
977 }
978 #endif  /* CONFIG_HMI10 */
979
980         /* Checking supported voltages */
981
982         debug ("PIPR: 0x%x --> %s\n",
983                 pcmp->pcmc_pipr,
984                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
985
986 #ifndef CONFIG_HMI10
987         immap->im_ioport.iop_pcdat |= reg;
988         immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
989 #else
990         immap->im_cpm.cp_pbdat &= !reg;
991         immap->im_cpm.cp_pbdir |= 0x00000300;
992 #endif  /* CONFIG_HMI10 */
993         if (reg) {
994 #ifndef CONFIG_HMI10
995                 debug ("PCMCIA powered at %sV\n",
996                         (reg&0x0004) ? "5.0" : "3.3");
997 #else
998                 debug ("PCMCIA powered at %sV\n",
999                         (reg&0x00000200) ? "5.0" : "3.3");
1000 #endif  /* CONFIG_HMI10 */
1001         } else {
1002                 debug ("PCMCIA powered down\n");
1003         }
1004
1005 done:
1006         debug ("Enable PCMCIA buffers and stop RESET\n");
1007         reg  =  PCMCIA_PGCRX(slot);
1008         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1009 #ifndef NSCU_OE_INV
1010         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1011 #else
1012         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1013 #endif
1014         PCMCIA_PGCRX(slot) = reg;
1015         udelay(500);
1016
1017         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1018                 slot+'A');
1019         return (0);
1020 }
1021 #endif
1022
1023 #endif  /* TQM8xxL */
1024
1025 /* -------------------------------------------------------------------- */
1026 /* Virtlab2 Board by TQ Components                                      */
1027 /* -------------------------------------------------------------------- */
1028
1029 #if defined(CONFIG_VIRTLAB2)
1030 #define PCMCIA_BOARD_MSG "Virtlab2"
1031
1032 static int hardware_enable(int slot)
1033 {
1034         volatile pcmconf8xx_t   *pcmp =
1035                 (pcmconf8xx_t *)&(((immap_t *)CFG_IMMR)->im_pcmcia);
1036         volatile unsigned char  *powerctl =
1037                 (volatile unsigned char *)PCMCIA_CTRL;
1038         unsigned int            reg, mask;
1039
1040         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1041
1042         udelay(10000);
1043
1044         /* clear interrupt state, and disable interrupts */
1045         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
1046         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
1047
1048         /*
1049          * Disable interrupts, DMA, and PCMCIA buffers
1050          * (isolate the interface) and assert RESET signal
1051          */
1052         debug ("Disable PCMCIA buffers and assert RESET\n");
1053         reg = __MY_PCMCIA_GCRX_CXRESET;         /* active high */
1054         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1055
1056         PCMCIA_PGCRX(slot) = reg;
1057         udelay(500);
1058
1059         /* remove all power */
1060         *powerctl = 0;
1061
1062         /*
1063          * Make sure there is a card in the slot, then configure the interface.
1064          */
1065         udelay(10000);
1066         debug ("[%d] %s: PIPR(%p)=0x%x\n", __LINE__,__FUNCTION__,
1067                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1068
1069         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1070                 printf ("   No Card found\n");
1071                 return (1);
1072         }
1073
1074         /*
1075          * Power On.
1076          */
1077         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1078         reg  = pcmp->pcmc_pipr;
1079         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1080                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1081                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1082
1083         if ((reg & mask) == mask) {
1084                 *powerctl = 2;  /* Enable 5V Vccout */
1085                 puts (" 5.0V card found: ");
1086         } else {
1087                 *powerctl = 1;  /* Enable 3.3 V Vccout */
1088                 puts (" 3.3V card found: ");
1089         }
1090
1091         udelay(1000);
1092         debug ("Enable PCMCIA buffers and stop RESET\n");
1093         reg  =  PCMCIA_PGCRX(slot);
1094         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1095         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1096
1097         PCMCIA_PGCRX(slot) = reg;
1098
1099         udelay(250000); /* some cards need >150 ms to come up :-( */
1100
1101         debug ("# hardware_enable done\n");
1102
1103         return (0);
1104 }
1105
1106 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1107 static int hardware_disable(int slot)
1108 {
1109         volatile unsigned char  *powerctl =
1110                 (volatile unsigned char *)PCMCIA_CTRL;
1111         unsigned long            reg;
1112
1113         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1114
1115         /* remove all power */
1116         *powerctl = 0;
1117
1118         debug ("Disable PCMCIA buffers and assert RESET\n");
1119         reg = __MY_PCMCIA_GCRX_CXRESET;         /* active high */
1120         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1121
1122         PCMCIA_PGCRX(slot) = reg;
1123
1124         udelay(10000);
1125
1126         return (0);
1127 }
1128 #endif
1129
1130 static int voltage_set(int slot, int vcc, int vpp)
1131 {
1132         volatile pcmconf8xx_t   *pcmp =
1133                 (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1134         volatile unsigned char  *powerctl =
1135                 (volatile unsigned char *)PCMCIA_CTRL;
1136         unsigned long           reg;
1137
1138         debug ("voltage_set: " PCMCIA_BOARD_MSG
1139                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1140                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1141
1142         /*
1143          * Disable PCMCIA buffers (isolate the interface)
1144          * and assert RESET signal
1145          */
1146         debug ("Disable PCMCIA buffers and assert RESET\n");
1147         reg  = PCMCIA_PGCRX(slot);
1148         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1149         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1150
1151         PCMCIA_PGCRX(slot) = reg;
1152         udelay(500);
1153
1154         /*
1155          * Configure pins for 5 Volts Enable and 3 Volts enable,
1156          * Turn off all power.
1157          */
1158         debug ("PCMCIA power OFF\n");
1159         reg = 0;
1160         switch(vcc) {
1161         case  0:                break;
1162         case 33: reg = 0x0001;  break;
1163         case 50: reg = 0x0002;  break;
1164         default:                goto done;
1165         }
1166
1167         /* Checking supported voltages */
1168
1169         debug ("PIPR: 0x%x --> %s\n", pcmp->pcmc_pipr,
1170                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1171
1172         *powerctl = reg;
1173
1174         if (reg) {
1175                 debug ("PCMCIA powered at %sV\n", (reg&0x0004) ? "5.0" : "3.3");
1176         } else {
1177                 debug ("PCMCIA powered down\n");
1178         }
1179
1180 done:
1181         debug ("Enable PCMCIA buffers and stop RESET\n");
1182         reg  =  PCMCIA_PGCRX(slot);
1183         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1184         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1185
1186         PCMCIA_PGCRX(slot) = reg;
1187         udelay(500);
1188
1189         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A');
1190         return (0);
1191 }
1192 #endif  /* CONFIG_VIRTLAB2 */
1193
1194 /* -------------------------------------------------------------------- */
1195 /* LWMON Board                                                          */
1196 /* -------------------------------------------------------------------- */
1197
1198 #if defined(CONFIG_LWMON)
1199
1200 #define PCMCIA_BOARD_MSG "LWMON"
1201
1202 /* #define's for MAX1604 Power Switch */
1203 #define MAX1604_OP_SUS          0x80
1204 #define MAX1604_VCCBON          0x40
1205 #define MAX1604_VCC_35          0x20
1206 #define MAX1604_VCCBHIZ         0x10
1207 #define MAX1604_VPPBON          0x08
1208 #define MAX1604_VPPBPBPGM       0x04
1209 #define MAX1604_VPPBHIZ         0x02
1210 /* reserved                     0x01    */
1211
1212 static int hardware_enable(int slot)
1213 {
1214         volatile immap_t        *immap;
1215         volatile cpm8xx_t       *cp;
1216         volatile pcmconf8xx_t   *pcmp;
1217         volatile sysconf8xx_t   *sysp;
1218         uint reg, mask;
1219         uchar val;
1220
1221
1222         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1223
1224         /* Switch on PCMCIA port in PIC register 0x60 */
1225         reg = pic_read  (0x60);
1226         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1227         reg &= ~0x10;
1228         /* reg |= 0x08; Vpp not needed */
1229         pic_write (0x60, reg);
1230 #ifdef DEBUG
1231         reg = pic_read  (0x60);
1232         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1233 #endif
1234         udelay(10000);
1235
1236         immap = (immap_t *)CFG_IMMR;
1237         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1238         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1239         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1240
1241         /*
1242          * Configure SIUMCR to enable PCMCIA port B
1243          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1244          */
1245         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1246
1247         /* clear interrupt state, and disable interrupts */
1248         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1249         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1250
1251         /*
1252          * Disable interrupts, DMA, and PCMCIA buffers
1253          * (isolate the interface) and assert RESET signal
1254          */
1255         debug ("Disable PCMCIA buffers and assert RESET\n");
1256         reg  = 0;
1257         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1258         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1259         PCMCIA_PGCRX(_slot_) = reg;
1260         udelay(500);
1261
1262         /*
1263          * Make sure there is a card in the slot, then configure the interface.
1264          */
1265         udelay(10000);
1266         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1267                 __LINE__,__FUNCTION__,
1268                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1269         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1270                 printf ("   No Card found\n");
1271                 return (1);
1272         }
1273
1274         /*
1275          * Power On.
1276          */
1277         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1278         reg  = pcmp->pcmc_pipr;
1279         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1280                 reg,
1281                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1282                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1283         if ((reg & mask) == mask) {
1284                 val = 0;                /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
1285                 puts (" 5.0V card found: ");
1286         } else {
1287                 val = MAX1604_VCC_35;   /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
1288                 puts (" 3.3V card found: ");
1289         }
1290
1291         /*  switch VCC on */
1292         val |= MAX1604_OP_SUS | MAX1604_VCCBON;
1293         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1294         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1295
1296         udelay(500000);
1297
1298         debug ("Enable PCMCIA buffers and stop RESET\n");
1299         reg  =  PCMCIA_PGCRX(_slot_);
1300         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1301         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1302         PCMCIA_PGCRX(_slot_) = reg;
1303
1304         udelay(250000); /* some cards need >150 ms to come up :-( */
1305
1306         debug ("# hardware_enable done\n");
1307
1308         return (0);
1309 }
1310
1311
1312 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1313 static int hardware_disable(int slot)
1314 {
1315         volatile immap_t        *immap;
1316         volatile pcmconf8xx_t   *pcmp;
1317         u_long reg;
1318         uchar val;
1319
1320         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1321
1322         immap = (immap_t *)CFG_IMMR;
1323         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1324
1325         /* remove all power, put output in high impedance state */
1326         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1327         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1328         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1329
1330         /* Configure PCMCIA General Control Register */
1331         debug ("Disable PCMCIA buffers and assert RESET\n");
1332         reg  = 0;
1333         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1334         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1335         PCMCIA_PGCRX(_slot_) = reg;
1336
1337         /* Switch off PCMCIA port in PIC register 0x60 */
1338         reg = pic_read  (0x60);
1339         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1340         reg |=  0x10;
1341         reg &= ~0x08;
1342         pic_write (0x60, reg);
1343 #ifdef DEBUG
1344         reg = pic_read  (0x60);
1345         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1346 #endif
1347         udelay(10000);
1348
1349         return (0);
1350 }
1351 #endif  /* CFG_CMD_PCMCIA */
1352
1353
1354 static int voltage_set(int slot, int vcc, int vpp)
1355 {
1356         volatile immap_t        *immap;
1357         volatile pcmconf8xx_t   *pcmp;
1358         u_long reg;
1359         uchar val;
1360
1361         debug ("voltage_set: "
1362                 PCMCIA_BOARD_MSG
1363                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1364                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1365
1366         immap = (immap_t *)CFG_IMMR;
1367         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1368         /*
1369          * Disable PCMCIA buffers (isolate the interface)
1370          * and assert RESET signal
1371          */
1372         debug ("Disable PCMCIA buffers and assert RESET\n");
1373         reg  = PCMCIA_PGCRX(_slot_);
1374         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1375         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1376         PCMCIA_PGCRX(_slot_) = reg;
1377         udelay(500);
1378
1379         /*
1380          * Turn off all power (switch to high impedance)
1381          */
1382         debug ("PCMCIA power OFF\n");
1383         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1384         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1385         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1386
1387         val = 0;
1388         switch(vcc) {
1389         case  0:                        break;
1390         case 33: val = MAX1604_VCC_35;  break;
1391         case 50:                        break;
1392         default:                        goto done;
1393         }
1394
1395         /* Checking supported voltages */
1396
1397         debug ("PIPR: 0x%x --> %s\n",
1398                 pcmp->pcmc_pipr,
1399                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1400
1401         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1402         if (val) {
1403                 debug ("PCMCIA powered at %sV\n",
1404                         (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1405         } else {
1406                 debug ("PCMCIA powered down\n");
1407         }
1408
1409 done:
1410         debug ("Enable PCMCIA buffers and stop RESET\n");
1411         reg  =  PCMCIA_PGCRX(_slot_);
1412         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1413         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1414         PCMCIA_PGCRX(_slot_) = reg;
1415         udelay(500);
1416
1417         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1418                 slot+'A');
1419         return (0);
1420 }
1421
1422 #endif  /* LWMON */
1423
1424 /* -------------------------------------------------------------------- */
1425 /* GTH board by Corelatus AB                                            */
1426 /* -------------------------------------------------------------------- */
1427 #if defined(CONFIG_GTH)
1428
1429 #define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1430
1431 static int voltage_set (int slot, int vcc, int vpp)
1432 {       /* Do nothing */
1433         return 0;
1434 }
1435
1436 static int hardware_enable (int slot)
1437 {
1438         volatile immap_t *immap;
1439         volatile cpm8xx_t *cp;
1440         volatile pcmconf8xx_t *pcmp;
1441         volatile sysconf8xx_t *sysp;
1442         uint reg, mask;
1443
1444         debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
1445
1446         immap = (immap_t *) CFG_IMMR;
1447         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1448         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1449         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1450
1451         /* clear interrupt state, and disable interrupts */
1452         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1453         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1454
1455         /*
1456          * Disable interrupts, DMA, and PCMCIA buffers
1457          * (isolate the interface) and assert RESET signal
1458          */
1459         debug ("Disable PCMCIA buffers and assert RESET\n");
1460         reg = 0;
1461         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1462         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
1463         PCMCIA_PGCRX (_slot_) = reg;
1464         udelay (500);
1465
1466         /*
1467          * Make sure there is a card in the slot,
1468          * then configure the interface.
1469          */
1470         udelay (10000);
1471         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1472                 __LINE__, __FUNCTION__,
1473                 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1474         if (pcmp->pcmc_pipr & 0x98000000) {
1475                 printf ("   No Card found\n");
1476                 return (1);
1477         }
1478
1479         mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1480         reg = pcmp->pcmc_pipr;
1481         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1482                    reg,
1483                    (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1484                    (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
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 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1499 static int hardware_disable(int slot)
1500 {
1501         return 0;       /* No hardware to disable */
1502 }
1503 #endif  /* CFG_CMD_PCMCIA */
1504 #endif  /* CONFIG_GTH */
1505
1506 /* -------------------------------------------------------------------- */
1507 /* ICU862 Boards by Cambridge Broadband Ltd.                            */
1508 /* -------------------------------------------------------------------- */
1509
1510 #if defined(CONFIG_ICU862)
1511
1512 #define PCMCIA_BOARD_MSG "ICU862"
1513
1514 static void cfg_port_B (void);
1515
1516 static int hardware_enable(int slot)
1517 {
1518         volatile immap_t        *immap;
1519         volatile cpm8xx_t       *cp;
1520         volatile pcmconf8xx_t   *pcmp;
1521         volatile sysconf8xx_t   *sysp;
1522         uint reg, pipr, mask;
1523         int i;
1524
1525         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1526
1527         udelay(10000);
1528
1529         immap = (immap_t *)CFG_IMMR;
1530         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1531         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1532         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1533
1534         /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1535         cfg_port_B ();
1536
1537         /*
1538          * Configure SIUMCR to enable PCMCIA port B
1539          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1540          */
1541         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1542
1543         /* clear interrupt state, and disable interrupts */
1544         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1545         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1546
1547         /*
1548          * Disable interrupts, DMA, and PCMCIA buffers
1549          * (isolate the interface) and assert RESET signal
1550          */
1551         debug ("Disable PCMCIA buffers and assert RESET\n");
1552         reg  = 0;
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          * Make sure there is a card in the slot, then configure the interface.
1560          */
1561         udelay(10000);
1562         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1563                 __LINE__,__FUNCTION__,
1564                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1565         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1566                 printf ("   No Card found\n");
1567                 return (1);
1568         }
1569
1570         /*
1571          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1572          */
1573         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1574         pipr = pcmp->pcmc_pipr;
1575         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1576                 pipr,
1577                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1578                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1579
1580         reg  = cp->cp_pbdat;
1581         if ((pipr & mask) == mask) {
1582                 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1583                         TPS2205_VCC3);                          /* 3V off       */
1584                 reg &= ~(TPS2205_VCC5);                         /* 5V on        */
1585                 puts (" 5.0V card found: ");
1586         } else {
1587                 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1588                         TPS2205_VCC5);                          /* 5V off       */
1589                 reg &= ~(TPS2205_VCC3);                         /* 3V on        */
1590                 puts (" 3.3V card found: ");
1591         }
1592
1593         debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1594                 reg,
1595                 (reg & TPS2205_VCC3)    ? "off" : "on",
1596                 (reg & TPS2205_VCC5)    ? "off" : "on",
1597                 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1598                 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1599
1600         cp->cp_pbdat = reg;
1601
1602         /*  Wait 500 ms; use this to check for over-current */
1603         for (i=0; i<5000; ++i) {
1604                 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1605                         printf ("   *** Overcurrent - Safety shutdown ***\n");
1606                         cp->cp_pbdat &= ~(TPS2205_SHDN);
1607                         return (1);
1608                 }
1609                 udelay (100);
1610         }
1611
1612         debug ("Enable PCMCIA buffers and stop RESET\n");
1613         reg  =  PCMCIA_PGCRX(_slot_);
1614         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1615         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1616         PCMCIA_PGCRX(_slot_) = reg;
1617
1618         udelay(250000); /* some cards need >150 ms to come up :-( */
1619
1620         debug ("# hardware_enable done\n");
1621
1622         return (0);
1623 }
1624
1625
1626 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1627 static int hardware_disable(int slot)
1628 {
1629         volatile immap_t        *immap;
1630         volatile cpm8xx_t       *cp;
1631         volatile pcmconf8xx_t   *pcmp;
1632         u_long reg;
1633
1634         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1635
1636         immap = (immap_t *)CFG_IMMR;
1637         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1638         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1639
1640         /* Shut down */
1641         cp->cp_pbdat &= ~(TPS2205_SHDN);
1642
1643         /* Configure PCMCIA General Control Register */
1644         debug ("Disable PCMCIA buffers and assert RESET\n");
1645         reg  = 0;
1646         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1647         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1648         PCMCIA_PGCRX(_slot_) = reg;
1649
1650         udelay(10000);
1651
1652         return (0);
1653 }
1654 #endif  /* CFG_CMD_PCMCIA */
1655
1656
1657 static int voltage_set(int slot, int vcc, int vpp)
1658 {
1659         volatile immap_t        *immap;
1660         volatile cpm8xx_t       *cp;
1661         volatile pcmconf8xx_t   *pcmp;
1662         u_long reg;
1663
1664         debug ("voltage_set: "
1665                 PCMCIA_BOARD_MSG
1666                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1667                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1668
1669         immap = (immap_t *)CFG_IMMR;
1670         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1671         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1672         /*
1673          * Disable PCMCIA buffers (isolate the interface)
1674          * and assert RESET signal
1675          */
1676         debug ("Disable PCMCIA buffers and assert RESET\n");
1677         reg  = PCMCIA_PGCRX(_slot_);
1678         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1679         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1680         PCMCIA_PGCRX(_slot_) = reg;
1681         udelay(500);
1682
1683         /*
1684          * Configure Port C pins for
1685          * 5 Volts Enable and 3 Volts enable,
1686          * Turn all power pins to Hi-Z
1687          */
1688         debug ("PCMCIA power OFF\n");
1689         cfg_port_B ();  /* Enables switch, but all in Hi-Z */
1690
1691         reg  = cp->cp_pbdat;
1692
1693         switch(vcc) {
1694         case  0:                        break;  /* Switch off           */
1695         case 33: reg &= ~TPS2205_VCC3;  break;  /* Switch on 3.3V       */
1696         case 50: reg &= ~TPS2205_VCC5;  break;  /* Switch on 5.0V       */
1697         default:                        goto done;
1698         }
1699
1700         /* Checking supported voltages */
1701
1702         debug ("PIPR: 0x%x --> %s\n",
1703                 pcmp->pcmc_pipr,
1704                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1705
1706         cp->cp_pbdat = reg;
1707
1708 #ifdef DEBUG
1709     {
1710         char *s;
1711
1712         if ((reg & TPS2205_VCC3) == 0) {
1713                 s = "at 3.3V";
1714         } else if ((reg & TPS2205_VCC5) == 0) {
1715                 s = "at 5.0V";
1716         } else {
1717                 s = "down";
1718         }
1719         printf ("PCMCIA powered %s\n", s);
1720     }
1721 #endif
1722
1723 done:
1724         debug ("Enable PCMCIA buffers and stop RESET\n");
1725         reg  =  PCMCIA_PGCRX(_slot_);
1726         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1727         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1728         PCMCIA_PGCRX(_slot_) = reg;
1729         udelay(500);
1730
1731         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1732                 slot+'A');
1733         return (0);
1734 }
1735
1736 static void cfg_port_B (void)
1737 {
1738         volatile immap_t        *immap;
1739         volatile cpm8xx_t       *cp;
1740         uint reg;
1741
1742         immap = (immap_t *)CFG_IMMR;
1743         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1744
1745         /*
1746          * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1747          *
1748          * Switch off all voltages, assert shutdown
1749          */
1750         reg  = cp->cp_pbdat;
1751         reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1752                 TPS2205_VCC3    | TPS2205_VCC5    |     /* VAVCC => Hi-Z */
1753                 TPS2205_SHDN);                          /* enable switch */
1754         cp->cp_pbdat = reg;
1755
1756         cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1757
1758         reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1759         cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1760
1761         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1762                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1763 }
1764
1765 #endif  /* ICU862 */
1766
1767
1768 /* -------------------------------------------------------------------- */
1769 /* C2MON Boards by TTTech Computertechnik AG                            */
1770 /* -------------------------------------------------------------------- */
1771
1772 #if defined(CONFIG_C2MON)
1773
1774 #define PCMCIA_BOARD_MSG "C2MON"
1775
1776 static void cfg_ports (void);
1777
1778 static int hardware_enable(int slot)
1779 {
1780         volatile immap_t        *immap;
1781         volatile cpm8xx_t       *cp;
1782         volatile pcmconf8xx_t   *pcmp;
1783         volatile sysconf8xx_t   *sysp;
1784         uint reg, pipr, mask;
1785         ushort sreg;
1786         int i;
1787
1788         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1789
1790         udelay(10000);
1791
1792         immap = (immap_t *)CFG_IMMR;
1793         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1794         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1795         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1796
1797         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1798         cfg_ports ();
1799
1800         /*
1801          * Configure SIUMCR to enable PCMCIA port B
1802          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1803          */
1804         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1805
1806         /* clear interrupt state, and disable interrupts */
1807         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1808         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1809
1810         /*
1811          * Disable interrupts, DMA, and PCMCIA buffers
1812          * (isolate the interface) and assert RESET signal
1813          */
1814         debug ("Disable PCMCIA buffers and assert RESET\n");
1815         reg  = 0;
1816         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1817         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1818         PCMCIA_PGCRX(_slot_) = reg;
1819         udelay(500);
1820
1821         /*
1822          * Make sure there is a card in the slot, then configure the interface.
1823          */
1824         udelay(10000);
1825         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1826                 __LINE__,__FUNCTION__,
1827                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1828         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1829                 printf ("   No Card found\n");
1830                 return (1);
1831         }
1832
1833         /*
1834          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1835          */
1836         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1837         pipr = pcmp->pcmc_pipr;
1838         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1839                 pipr,
1840                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1841                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1842
1843         sreg = immap->im_ioport.iop_pcdat;
1844         if ((pipr & mask) == mask) {
1845                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1846                           TPS2211_VCCD1);                       /* 5V on        */
1847                 sreg &= ~(TPS2211_VCCD0);                       /* 3V off       */
1848                 puts (" 5.0V card found: ");
1849         } else {
1850                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1851                           TPS2211_VCCD0);                       /* 3V on        */
1852                 sreg &= ~(TPS2211_VCCD1);                       /* 5V off       */
1853                 puts (" 3.3V card found: ");
1854         }
1855
1856         debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1857                 sreg,
1858                 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1859                 (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) ? "on" : "off"
1860         );
1861
1862         immap->im_ioport.iop_pcdat = sreg;
1863
1864         /*  Wait 500 ms; use this to check for over-current */
1865         for (i=0; i<5000; ++i) {
1866                 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1867                     printf ("   *** Overcurrent - Safety shutdown ***\n");
1868                     immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1869                     return (1);
1870                 }
1871                 udelay (100);
1872         }
1873
1874         debug ("Enable PCMCIA buffers and stop RESET\n");
1875         reg  =  PCMCIA_PGCRX(_slot_);
1876         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1877         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1878         PCMCIA_PGCRX(_slot_) = reg;
1879
1880         udelay(250000); /* some cards need >150 ms to come up :-( */
1881
1882         debug ("# hardware_enable done\n");
1883
1884         return (0);
1885 }
1886
1887
1888 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1889 static int hardware_disable(int slot)
1890 {
1891         volatile immap_t        *immap;
1892         volatile cpm8xx_t       *cp;
1893         volatile pcmconf8xx_t   *pcmp;
1894         u_long reg;
1895
1896         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1897
1898         immap = (immap_t *)CFG_IMMR;
1899         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1900
1901         /* Configure PCMCIA General Control Register */
1902         debug ("Disable PCMCIA buffers and assert RESET\n");
1903         reg  = 0;
1904         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1905         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1906         PCMCIA_PGCRX(_slot_) = reg;
1907
1908         /* ALl voltages off / Hi-Z */
1909         immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1910                                        TPS2211_VCCD0 | TPS2211_VCCD1 );
1911
1912         udelay(10000);
1913
1914         return (0);
1915 }
1916 #endif  /* CFG_CMD_PCMCIA */
1917
1918
1919 static int voltage_set(int slot, int vcc, int vpp)
1920 {
1921         volatile immap_t        *immap;
1922         volatile cpm8xx_t       *cp;
1923         volatile pcmconf8xx_t   *pcmp;
1924         u_long reg;
1925         ushort sreg;
1926
1927         debug ("voltage_set: "
1928                 PCMCIA_BOARD_MSG
1929                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1930                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1931
1932         immap = (immap_t *)CFG_IMMR;
1933         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1934         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1935         /*
1936          * Disable PCMCIA buffers (isolate the interface)
1937          * and assert RESET signal
1938          */
1939         debug ("Disable PCMCIA buffers and assert RESET\n");
1940         reg  = PCMCIA_PGCRX(_slot_);
1941         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1942         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1943         PCMCIA_PGCRX(_slot_) = reg;
1944         udelay(500);
1945
1946         /*
1947          * Configure Port C pins for
1948          * 5 Volts Enable and 3 Volts enable,
1949          * Turn all power pins to Hi-Z
1950          */
1951         debug ("PCMCIA power OFF\n");
1952         cfg_ports ();   /* Enables switch, but all in Hi-Z */
1953
1954         sreg  = immap->im_ioport.iop_pcdat;
1955         sreg |= TPS2211_VPPD0 | TPS2211_VPPD1;          /* VAVPP always Hi-Z */
1956
1957         switch(vcc) {
1958         case  0:                        break;  /* Switch off           */
1959         case 33: sreg |=  TPS2211_VCCD0;        /* Switch on 3.3V       */
1960                  sreg &= ~TPS2211_VCCD1;
1961                                         break;
1962         case 50: sreg &= ~TPS2211_VCCD0;        /* Switch on 5.0V       */
1963                  sreg |=  TPS2211_VCCD1;
1964                                         break;
1965         default:                        goto done;
1966         }
1967
1968         /* Checking supported voltages */
1969
1970         debug ("PIPR: 0x%x --> %s\n",
1971                 pcmp->pcmc_pipr,
1972                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1973
1974         immap->im_ioport.iop_pcdat = sreg;
1975
1976 #ifdef DEBUG
1977     {
1978         char *s;
1979
1980         if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1981                 s = "at 3.3V";
1982         } else if (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) {
1983                 s = "at 5.0V";
1984         } else {
1985                 s = "down";
1986         }
1987         printf ("PCMCIA powered %s\n", s);
1988     }
1989 #endif
1990
1991 done:
1992         debug ("Enable PCMCIA buffers and stop RESET\n");
1993         reg  =  PCMCIA_PGCRX(_slot_);
1994         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1995         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1996         PCMCIA_PGCRX(_slot_) = reg;
1997         udelay(500);
1998
1999         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2000                 slot+'A');
2001         return (0);
2002 }
2003
2004 static void cfg_ports (void)
2005 {
2006         volatile immap_t        *immap;
2007         volatile cpm8xx_t       *cp;
2008         ushort sreg;
2009
2010         immap = (immap_t *)CFG_IMMR;
2011         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2012
2013         /*
2014          * Configure Port C for TPS2211 PC-Card Power-Interface Switch
2015          *
2016          * Switch off all voltages, assert shutdown
2017          */
2018         sreg = immap->im_ioport.iop_pcdat;
2019         sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1);       /* VAVPP => Hi-Z */
2020         sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1);       /* 3V and 5V off */
2021         immap->im_ioport.iop_pcdat = sreg;
2022
2023         immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
2024         immap->im_ioport.iop_pcdir |=   TPS2211_OUTPUTS;
2025
2026         debug ("Set Port C: PAR:     %04x DIR:     %04x DAT:     %04x\n",
2027                 immap->im_ioport.iop_pcpar,
2028                 immap->im_ioport.iop_pcdir,
2029                 immap->im_ioport.iop_pcdat);
2030
2031         /*
2032          * Configure Port B for TPS2211 PC-Card Power-Interface Switch
2033          *
2034          * Over-Current Input only
2035          */
2036         cp->cp_pbpar &= ~(TPS2211_INPUTS);
2037         cp->cp_pbdir &= ~(TPS2211_INPUTS);
2038
2039         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
2040                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
2041 }
2042
2043 #endif  /* C2MON */
2044
2045 /* -------------------------------------------------------------------- */
2046 /* MBX board from Morotola                                              */
2047 /* -------------------------------------------------------------------- */
2048
2049 #if defined( CONFIG_MBX )
2050 #include <../board/mbx8xx/csr.h>
2051
2052 /* A lot of this has been taken from the RPX code in this file it works from me.
2053    I have added the voltage selection for the MBX board. */
2054
2055 /* MBX voltage bit in control register #2 */
2056 #define CR2_VPP12       ((uchar)0x10)
2057 #define CR2_VPPVDD      ((uchar)0x20)
2058 #define CR2_VDD5        ((uchar)0x40)
2059 #define CR2_VDD3        ((uchar)0x80)
2060
2061 #define PCMCIA_BOARD_MSG "MBX860"
2062
2063 static int voltage_set (int slot, int vcc, int vpp)
2064 {
2065         uchar reg = 0;
2066
2067         debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2068                  'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
2069
2070         switch (vcc) {
2071         case 0:
2072                 break;
2073         case 33:
2074                 reg |= CR2_VDD3;
2075                 break;
2076         case 50:
2077                 reg |= CR2_VDD5;
2078                 break;
2079         default:
2080                 return 1;
2081         }
2082
2083         switch (vpp) {
2084         case 0:
2085                 break;
2086         case 33:
2087         case 50:
2088                 if (vcc == vpp) {
2089                         reg |= CR2_VPPVDD;
2090                 } else {
2091                         return 1;
2092                 }
2093                 break;
2094         case 120:
2095                 reg |= CR2_VPP12;
2096                 break;
2097         default:
2098                 return 1;
2099         }
2100
2101         /* first, turn off all power */
2102         MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
2103
2104         /* enable new powersettings */
2105         MBX_CSR2 |= reg;
2106         debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
2107
2108         return (0);
2109 }
2110
2111 static int hardware_enable (int slot)
2112 {
2113         volatile immap_t *immap;
2114         volatile cpm8xx_t *cp;
2115         volatile pcmconf8xx_t *pcmp;
2116         volatile sysconf8xx_t *sysp;
2117         uint reg, mask;
2118
2119         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
2120                                   'A' + slot);
2121
2122         udelay (10000);
2123
2124         immap = (immap_t *) CFG_IMMR;
2125         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
2126         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
2127         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
2128
2129         /* clear interrupt state, and disable interrupts */
2130         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
2131         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
2132
2133         /*
2134          * Disable interrupts, DMA, and PCMCIA buffers
2135          * (isolate the interface) and assert RESET signal
2136          */
2137         debug ("Disable PCMCIA buffers and assert RESET\n");
2138         reg = 0;
2139         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2140         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
2141         PCMCIA_PGCRX (_slot_) = reg;
2142         udelay (500);
2143
2144         /* remove all power */
2145         voltage_set (slot, 0, 0);
2146         /*
2147          * Make sure there is a card in the slot, then configure the interface.
2148          */
2149         udelay(10000);
2150         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2151                 __LINE__,__FUNCTION__,
2152                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2153 #ifndef CONFIG_HMI10
2154         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2155 #else
2156         if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
2157 #endif  /* CONFIG_HMI10 */
2158                 printf ("   No Card found\n");
2159                 return (1);
2160         }
2161
2162         /*
2163          * Power On.
2164          */
2165         mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
2166         reg = pcmp->pcmc_pipr;
2167         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
2168                   (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
2169                   (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
2170
2171         if ((reg & mask) == mask) {
2172                 voltage_set (_slot_, 50, 0);
2173                 printf (" 5.0V card found: ");
2174         } else {
2175                 voltage_set (_slot_, 33, 0);
2176                 printf (" 3.3V card found: ");
2177         }
2178
2179         debug ("Enable PCMCIA buffers and stop RESET\n");
2180         reg = PCMCIA_PGCRX (_slot_);
2181         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2182         reg &= ~__MY_PCMCIA_GCRX_CXOE;  /* active low  */
2183         PCMCIA_PGCRX (_slot_) = reg;
2184
2185         udelay (250000);        /* some cards need >150 ms to come up :-( */
2186
2187         debug ("# hardware_enable done\n");
2188
2189         return (0);
2190 }
2191
2192 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2193 static int hardware_disable (int slot)
2194 {
2195         return 0;       /* No hardware to disable */
2196 }
2197 #endif /* CFG_CMD_PCMCIA */
2198 #endif /* CONFIG_MBX */
2199 /* -------------------------------------------------------------------- */
2200 /* R360MPI Board                                                        */
2201 /* -------------------------------------------------------------------- */
2202
2203 #if defined(CONFIG_R360MPI)
2204
2205 #define PCMCIA_BOARD_MSG "R360MPI"
2206
2207
2208 static int hardware_enable(int slot)
2209 {
2210         volatile immap_t        *immap;
2211         volatile cpm8xx_t       *cp;
2212         volatile pcmconf8xx_t   *pcmp;
2213         volatile sysconf8xx_t   *sysp;
2214         uint reg, mask;
2215
2216         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2217
2218         udelay(10000);
2219
2220         immap = (immap_t *)CFG_IMMR;
2221         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2222         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2223         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2224
2225         /*
2226          * Configure SIUMCR to enable PCMCIA port B
2227          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2228          */
2229         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
2230
2231         /* clear interrupt state, and disable interrupts */
2232         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
2233         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2234
2235         /*
2236          * Disable interrupts, DMA, and PCMCIA buffers
2237          * (isolate the interface) and assert RESET signal
2238          */
2239         debug ("Disable PCMCIA buffers and assert RESET\n");
2240         reg  = 0;
2241         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2242         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2243         PCMCIA_PGCRX(_slot_) = reg;
2244         udelay(500);
2245
2246         /*
2247          * Configure Ports A, B & C pins for
2248          * 5 Volts Enable and 3 Volts enable
2249          */
2250         immap->im_ioport.iop_pcpar &= ~(0x0400);
2251         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
2252         immap->im_ioport.iop_pcdir |= 0x0400;*/
2253
2254         immap->im_ioport.iop_papar &= ~(0x0200);/*
2255         immap->im_ioport.iop_padir |= 0x0200;*/
2256 #if 0
2257         immap->im_ioport.iop_pbpar &= ~(0xC000);
2258         immap->im_ioport.iop_pbdir &= ~(0xC000);
2259 #endif
2260         /* remove all power */
2261
2262         immap->im_ioport.iop_pcdat |= 0x0400;
2263         immap->im_ioport.iop_padat |= 0x0200;
2264
2265         /*
2266          * Make sure there is a card in the slot, then configure the interface.
2267          */
2268         udelay(10000);
2269         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2270                 __LINE__,__FUNCTION__,
2271                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2272         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2273                 printf ("   No Card found\n");
2274                 return (1);
2275         }
2276
2277         /*
2278          * Power On.
2279          */
2280         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2281         reg  = pcmp->pcmc_pipr;
2282         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2283                 reg,
2284                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2285                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2286         if ((reg & mask) == mask) {
2287                 immap->im_ioport.iop_pcdat &= ~(0x4000);
2288                 puts (" 5.0V card found: ");
2289         } else {
2290                 immap->im_ioport.iop_padat &= ~(0x0002);
2291                 puts (" 3.3V card found: ");
2292         }
2293         immap->im_ioport.iop_pcdir |= 0x0400;
2294         immap->im_ioport.iop_padir |= 0x0200;
2295 #if 0
2296         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
2297         cp->cp_pbdir &= ~(0x0020 | 0x0010);
2298         cp->cp_pbpar &= ~(0x0020 | 0x0010);
2299         udelay(500000);
2300 #endif
2301         debug ("Enable PCMCIA buffers and stop RESET\n");
2302         reg  =  PCMCIA_PGCRX(_slot_);
2303         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2304         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2305         PCMCIA_PGCRX(_slot_) = reg;
2306
2307         udelay(250000); /* some cards need >150 ms to come up :-( */
2308
2309         debug ("# hardware_enable done\n");
2310
2311         return (0);
2312 }
2313
2314
2315 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2316 static int hardware_disable(int slot)
2317 {
2318         volatile immap_t        *immap;
2319         volatile pcmconf8xx_t   *pcmp;
2320         u_long reg;
2321
2322         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2323
2324         immap = (immap_t *)CFG_IMMR;
2325         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2326
2327         /* remove all power */
2328         immap->im_ioport.iop_pcdat |= 0x0400;
2329         immap->im_ioport.iop_padat |= 0x0200;
2330
2331         /* Configure PCMCIA General Control Register */
2332         debug ("Disable PCMCIA buffers and assert RESET\n");
2333         reg  = 0;
2334         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2335         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2336         PCMCIA_PGCRX(_slot_) = reg;
2337
2338         udelay(10000);
2339
2340         return (0);
2341 }
2342 #endif  /* CFG_CMD_PCMCIA */
2343
2344
2345 static int voltage_set(int slot, int vcc, int vpp)
2346 {
2347         volatile immap_t        *immap;
2348         volatile pcmconf8xx_t   *pcmp;
2349         u_long reg;
2350
2351         debug ("voltage_set: "
2352                 PCMCIA_BOARD_MSG
2353                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2354                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2355
2356         immap = (immap_t *)CFG_IMMR;
2357         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2358         /*
2359          * Disable PCMCIA buffers (isolate the interface)
2360          * and assert RESET signal
2361          */
2362         debug ("Disable PCMCIA buffers and assert RESET\n");
2363         reg  = PCMCIA_PGCRX(_slot_);
2364         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2365         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2366         PCMCIA_PGCRX(_slot_) = reg;
2367         udelay(500);
2368
2369         /*
2370          * Configure Ports A & C pins for
2371          * 5 Volts Enable and 3 Volts enable,
2372          * Turn off all power
2373          */
2374         debug ("PCMCIA power OFF\n");
2375         immap->im_ioport.iop_pcpar &= ~(0x0400);
2376         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
2377         immap->im_ioport.iop_pcdir |= 0x0400;*/
2378
2379         immap->im_ioport.iop_papar &= ~(0x0200);/*
2380         immap->im_ioport.iop_padir |= 0x0200;*/
2381
2382         immap->im_ioport.iop_pcdat |= 0x0400;
2383         immap->im_ioport.iop_padat |= 0x0200;
2384
2385         reg = 0;
2386         switch(vcc) {
2387         case  0:                break;
2388         case 33: reg |= 0x0200; break;
2389         case 50: reg |= 0x0400; break;
2390         default:                goto done;
2391         }
2392
2393         /* Checking supported voltages */
2394
2395         debug ("PIPR: 0x%x --> %s\n",
2396                 pcmp->pcmc_pipr,
2397                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2398
2399         if (reg & 0x0200)
2400                 immap->im_ioport.iop_pcdat &= !reg;
2401         if (reg & 0x0400)
2402                 immap->im_ioport.iop_padat &= !reg;
2403         immap->im_ioport.iop_pcdir |= 0x0200;
2404         immap->im_ioport.iop_padir |= 0x0400;
2405         if (reg) {
2406                 debug ("PCMCIA powered at %sV\n",
2407                         (reg&0x0400) ? "5.0" : "3.3");
2408         } else {
2409                 debug ("PCMCIA powered down\n");
2410         }
2411
2412 done:
2413         debug ("Enable PCMCIA buffers and stop RESET\n");
2414         reg  =  PCMCIA_PGCRX(_slot_);
2415         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2416         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2417         PCMCIA_PGCRX(_slot_) = reg;
2418         udelay(500);
2419
2420         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2421                 slot+'A');
2422         return (0);
2423 }
2424
2425 #endif  /* R360MPI */
2426
2427 /* -------------------------------------------------------------------- */
2428 /* KUP4K and KUP4X Boards                                                               */
2429 /* -------------------------------------------------------------------- */
2430 #if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
2431
2432 #define PCMCIA_BOARD_MSG "KUP"
2433
2434 #define KUP4K_PCMCIA_B_3V3 (0x00020000)
2435
2436 static int hardware_enable(int slot)
2437 {
2438         volatile immap_t        *immap;
2439         volatile cpm8xx_t       *cp;
2440         volatile pcmconf8xx_t   *pcmp;
2441         volatile sysconf8xx_t   *sysp;
2442         uint reg, mask;
2443
2444         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2445
2446         udelay(10000);
2447
2448         immap = (immap_t *)CFG_IMMR;
2449         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2450         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2451         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2452
2453         /*
2454          * Configure SIUMCR to enable PCMCIA port B
2455          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2456          */
2457         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
2458
2459         /* clear interrupt state, and disable interrupts */
2460         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
2461         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
2462
2463         /*
2464          * Disable interrupts, DMA, and PCMCIA buffers
2465          * (isolate the interface) and assert RESET signal
2466          */
2467         debug ("Disable PCMCIA buffers and assert RESET\n");
2468         reg  = 0;
2469         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2470         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2471         PCMCIA_PGCRX(slot) = reg;
2472         udelay(2500);
2473
2474         /*
2475          * Configure Port B pins for
2476          * 3 Volts enable
2477          */
2478         if (slot) { /* Slot A is built-in */
2479                 cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2480                 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2481                 /* remove all power */
2482                 cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2483         }
2484         /*
2485          * Make sure there is a card in the slot, then configure the interface.
2486          */
2487         udelay(10000);
2488         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2489                 __LINE__,__FUNCTION__,
2490                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2491         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2492                 printf ("   No Card found\n");
2493                 return (1);
2494         }
2495
2496         /*
2497          * Power On.
2498          */
2499         printf("%s  Slot %c:", slot ? "" : "\n", 'A' + slot);
2500         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2501         reg  = pcmp->pcmc_pipr;
2502         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2503                 reg,
2504                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2505                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2506         if ((reg & mask) == mask) {
2507                 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2508         } else {
2509                 if(slot)
2510                         cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2511                 puts (" 3.3V card found: ");
2512         }
2513 #if 0
2514         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
2515         cp->cp_pbdir &= ~(0x0020 | 0x0010);
2516         cp->cp_pbpar &= ~(0x0020 | 0x0010);
2517         udelay(500000);
2518 #endif
2519         debug ("Enable PCMCIA buffers and stop RESET\n");
2520         reg  =  PCMCIA_PGCRX(slot);
2521         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2522         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2523         PCMCIA_PGCRX(slot) = reg;
2524
2525         udelay(250000); /* some cards need >150 ms to come up :-( */
2526
2527         debug ("# hardware_enable done\n");
2528
2529         return (0);
2530 }
2531
2532
2533 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2534 static int hardware_disable(int slot)
2535 {
2536         volatile immap_t        *immap;
2537         volatile cpm8xx_t       *cp;
2538         volatile pcmconf8xx_t   *pcmp;
2539         u_long reg;
2540
2541         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2542
2543         immap = (immap_t *)CFG_IMMR;
2544         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2545         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2546
2547         /* remove all power */
2548         if (slot)
2549                 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
2550
2551         /* Configure PCMCIA General Control Register */
2552         debug ("Disable PCMCIA buffers and assert RESET\n");
2553         reg  = 0;
2554         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2555         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2556         PCMCIA_PGCRX(slot) = reg;
2557
2558         udelay(10000);
2559
2560         return (0);
2561 }
2562 #endif  /* CFG_CMD_PCMCIA */
2563
2564
2565 static int voltage_set(int slot, int vcc, int vpp)
2566 {
2567         volatile immap_t        *immap;
2568         volatile cpm8xx_t       *cp;
2569         volatile pcmconf8xx_t   *pcmp;
2570         u_long reg;
2571
2572         debug ("voltage_set: "  \
2573                 PCMCIA_BOARD_MSG        \
2574                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2575                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2576
2577         if (!slot) /* Slot A is not configurable */
2578                 return 0;
2579
2580         immap = (immap_t *)CFG_IMMR;
2581         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2582         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2583
2584         /*
2585          * Disable PCMCIA buffers (isolate the interface)
2586          * and assert RESET signal
2587          */
2588         debug ("Disable PCMCIA buffers and assert RESET\n");
2589         reg  = PCMCIA_PGCRX(slot);
2590         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2591         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2592         PCMCIA_PGCRX(slot) = reg;
2593         udelay(500);
2594
2595         debug ("PCMCIA power OFF\n");
2596         /*
2597          * Configure Port B pins for
2598          * 3 Volts enable
2599          */
2600         cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2601         cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2602         /* remove all power */
2603         cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2604
2605         switch(vcc) {
2606         case  0:                break;
2607         case 33:
2608                 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2609                 debug ("PCMCIA powered at 3.3V\n");
2610                 break;
2611         case 50:
2612                 debug ("PCMCIA: 5Volt vcc not supported\n");
2613                 break;
2614         default:
2615                 puts("PCMCIA: vcc not supported");
2616                 break;
2617         }
2618         udelay(10000);
2619         /* Checking supported voltages */
2620
2621         debug ("PIPR: 0x%x --> %s\n",
2622                 pcmp->pcmc_pipr,
2623                    (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
2624                         ? "only 5 V --> NOT SUPPORTED"
2625                         : "can do 3.3V");
2626
2627
2628         debug ("Enable PCMCIA buffers and stop RESET\n");
2629         reg  =  PCMCIA_PGCRX(slot);
2630         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2631         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2632         PCMCIA_PGCRX(slot) = reg;
2633         udelay(500);
2634
2635         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2636                 slot+'A');
2637         return (0);
2638 }
2639
2640 #endif  /* KUP4K || KUP4X */
2641
2642
2643 /* -------------------------------------------------------------------- */
2644 /* End of Board Specific Stuff                                          */
2645 /* -------------------------------------------------------------------- */
2646
2647
2648 /* -------------------------------------------------------------------- */
2649 /* MPC8xx Specific Stuff - should go to MPC8xx directory                */
2650 /* -------------------------------------------------------------------- */
2651
2652 /*
2653  * Search this table to see if the windowsize is
2654  * supported...
2655  */
2656
2657 #define M8XX_SIZES_NO 32
2658
2659 static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2660 { 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2661   0x00000080, 0x00000040, 0x00000010, 0x00000020,
2662   0x00008000, 0x00004000, 0x00001000, 0x00002000,
2663   0x00000100, 0x00000200, 0x00000800, 0x00000400,
2664
2665   0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2666   0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2667   0x00010000, 0x00020000, 0x00080000, 0x00040000,
2668   0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2669
2670
2671 /* -------------------------------------------------------------------- */
2672
2673 #if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
2674
2675 static u_int m8xx_get_graycode(u_int size)
2676 {
2677         u_int k;
2678
2679         for (k = 0; k < M8XX_SIZES_NO; k++) {
2680                 if(m8xx_size_to_gray[k] == size)
2681                         break;
2682         }
2683
2684         if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2685                 k = -1;
2686
2687         return k;
2688 }
2689
2690 #endif  /* CONFIG_I82365 */
2691
2692 /* -------------------------------------------------------------------- */
2693
2694 #if 0
2695 static u_int m8xx_get_speed(u_int ns, u_int is_io)
2696 {
2697         u_int reg, clocks, psst, psl, psht;
2698
2699         if(!ns) {
2700
2701                 /*
2702                  * We get called with IO maps setup to 0ns
2703                  * if not specified by the user.
2704                  * They should be 255ns.
2705                  */
2706
2707                 if(is_io)
2708                         ns = 255;
2709                 else
2710                         ns = 100;  /* fast memory if 0 */
2711         }
2712
2713         /*
2714          * In PSST, PSL, PSHT fields we tell the controller
2715          * timing parameters in CLKOUT clock cycles.
2716          * CLKOUT is the same as GCLK2_50.
2717          */
2718
2719 /* how we want to adjust the timing - in percent */
2720
2721 #define ADJ 180 /* 80 % longer accesstime - to be sure */
2722
2723         clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2724         clocks = (clocks * ADJ) / (100*1000);
2725
2726         if(clocks >= PCMCIA_BMT_LIMIT) {
2727                 DEBUG(0, "Max access time limit reached\n");
2728                 clocks = PCMCIA_BMT_LIMIT-1;
2729         }
2730
2731         psst = clocks / 7;          /* setup time */
2732         psht = clocks / 7;          /* hold time */
2733         psl  = (clocks * 5) / 7;    /* strobe length */
2734
2735         psst += clocks - (psst + psht + psl);
2736
2737         reg =  psst << 12;
2738         reg |= psl  << 7;
2739         reg |= psht << 16;
2740
2741         return reg;
2742 }
2743 #endif
2744
2745 /* -------------------------------------------------------------------- */
2746
2747 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2748 static void print_funcid (int func)
2749 {
2750         puts (indent);
2751         switch (func) {
2752         case CISTPL_FUNCID_MULTI:
2753                 puts (" Multi-Function");
2754                 break;
2755         case CISTPL_FUNCID_MEMORY:
2756                 puts (" Memory");
2757                 break;
2758         case CISTPL_FUNCID_SERIAL:
2759                 puts (" Serial Port");
2760                 break;
2761         case CISTPL_FUNCID_PARALLEL:
2762                 puts (" Parallel Port");
2763                 break;
2764         case CISTPL_FUNCID_FIXED:
2765                 puts (" Fixed Disk");
2766                 break;
2767         case CISTPL_FUNCID_VIDEO:
2768                 puts (" Video Adapter");
2769                 break;
2770         case CISTPL_FUNCID_NETWORK:
2771                 puts (" Network Adapter");
2772                 break;
2773         case CISTPL_FUNCID_AIMS:
2774                 puts (" AIMS Card");
2775                 break;
2776         case CISTPL_FUNCID_SCSI:
2777                 puts (" SCSI Adapter");
2778                 break;
2779         default:
2780                 puts (" Unknown");
2781                 break;
2782         }
2783         puts (" Card\n");
2784 }
2785 #endif  /* CONFIG_IDE_8xx_PCCARD */
2786
2787 /* -------------------------------------------------------------------- */
2788
2789 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2790 static void print_fixed (volatile uchar *p)
2791 {
2792         if (p == NULL)
2793                 return;
2794
2795         puts(indent);
2796
2797         switch (*p) {
2798         case CISTPL_FUNCE_IDE_IFACE:
2799             {   uchar iface = *(p+2);
2800
2801                 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2802                 puts (" interface ");
2803                 break;
2804             }
2805         case CISTPL_FUNCE_IDE_MASTER:
2806         case CISTPL_FUNCE_IDE_SLAVE:
2807             {   uchar f1 = *(p+2);
2808                 uchar f2 = *(p+4);
2809
2810                 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2811
2812                 if (f1 & CISTPL_IDE_UNIQUE)
2813                         puts (" [unique]");
2814
2815                 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2816
2817                 if (f2 & CISTPL_IDE_HAS_SLEEP)
2818                         puts (" [sleep]");
2819
2820                 if (f2 & CISTPL_IDE_HAS_STANDBY)
2821                         puts (" [standby]");
2822
2823                 if (f2 & CISTPL_IDE_HAS_IDLE)
2824                         puts (" [idle]");
2825
2826                 if (f2 & CISTPL_IDE_LOW_POWER)
2827                         puts (" [low power]");
2828
2829                 if (f2 & CISTPL_IDE_REG_INHIBIT)
2830                         puts (" [reg inhibit]");
2831
2832                 if (f2 & CISTPL_IDE_HAS_INDEX)
2833                         puts (" [index]");
2834
2835                 if (f2 & CISTPL_IDE_IOIS16)
2836                         puts (" [IOis16]");
2837
2838                 break;
2839             }
2840         }
2841         putc ('\n');
2842 }
2843 #endif  /* CONFIG_IDE_8xx_PCCARD */
2844
2845 /* -------------------------------------------------------------------- */
2846
2847 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2848
2849 #define MAX_IDENT_CHARS         64
2850 #define MAX_IDENT_FIELDS        4
2851
2852 static uchar *known_cards[] = {
2853         (uchar *)"ARGOSY PnPIDE D5",
2854         NULL
2855 };
2856
2857 static int identify  (volatile uchar *p)
2858 {
2859         uchar id_str[MAX_IDENT_CHARS];
2860         uchar data;
2861         uchar *t;
2862         uchar **card;
2863         int i, done;
2864
2865         if (p == NULL)
2866                 return (0);     /* Don't know */
2867
2868         t = id_str;
2869         done =0;
2870
2871         for (i=0; i<=4 && !done; ++i, p+=2) {
2872                 while ((data = *p) != '\0') {
2873                         if (data == 0xFF) {
2874                                 done = 1;
2875                                 break;
2876                         }
2877                         *t++ = data;
2878                         if (t == &id_str[MAX_IDENT_CHARS-1]) {
2879                                 done = 1;
2880                                 break;
2881                         }
2882                         p += 2;
2883                 }
2884                 if (!done)
2885                         *t++ = ' ';
2886         }
2887         *t = '\0';
2888         while (--t > id_str) {
2889                 if (*t == ' ')
2890                         *t = '\0';
2891                 else
2892                         break;
2893         }
2894         puts ((char *)id_str);
2895         putc ('\n');
2896
2897         for (card=known_cards; *card; ++card) {
2898                 debug ("## Compare against \"%s\"\n", *card);
2899                 if (strcmp((char *)*card, (char *)id_str) == 0) {       /* found! */
2900                         debug ("## CARD FOUND ##\n");
2901                         return (1);
2902                 }
2903         }
2904
2905         return (0);     /* don't know */
2906 }
2907 #endif  /* CONFIG_IDE_8xx_PCCARD */
2908
2909 /* -------------------------------------------------------------------- */
2910 /* NETTA board by Intracom S.A.                                         */
2911 /* -------------------------------------------------------------------- */
2912
2913 #if defined(CONFIG_NETTA)
2914
2915 /* some sane bit macros */
2916 #define _BD(_b)                         (1U << (31-(_b)))
2917 #define _BDR(_l, _h)                    (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2918
2919 #define _BW(_b)                         (1U << (15-(_b)))
2920 #define _BWR(_l, _h)                    (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2921
2922 #define _BB(_b)                         (1U << (7-(_b)))
2923 #define _BBR(_l, _h)                    (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2924
2925 #define _B(_b)                          _BD(_b)
2926 #define _BR(_l, _h)                     _BDR(_l, _h)
2927
2928 #define PCMCIA_BOARD_MSG "NETTA"
2929
2930 static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2931
2932 static void cfg_vppd(int no)
2933 {
2934         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2935         unsigned short mask;
2936
2937         if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2938                 return;
2939
2940         mask = vppd_masks[no];
2941
2942         immap->im_ioport.iop_papar &= ~mask;
2943         immap->im_ioport.iop_paodr &= ~mask;
2944         immap->im_ioport.iop_padir |=  mask;
2945 }
2946
2947 static void set_vppd(int no, int what)
2948 {
2949         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2950         unsigned short mask;
2951
2952         if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2953                 return;
2954
2955         mask = vppd_masks[no];
2956
2957         if (what)
2958                 immap->im_ioport.iop_padat |= mask;
2959         else
2960                 immap->im_ioport.iop_padat &= ~mask;
2961 }
2962
2963 static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2964
2965 static void cfg_vccd(int no)
2966 {
2967         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2968         unsigned short mask;
2969
2970         if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2971                 return;
2972
2973         mask = vccd_masks[no];
2974
2975         immap->im_ioport.iop_papar &= ~mask;
2976         immap->im_ioport.iop_paodr &= ~mask;
2977         immap->im_ioport.iop_padir |=  mask;
2978 }
2979
2980 static void set_vccd(int no, int what)
2981 {
2982         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2983         unsigned short mask;
2984
2985         if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2986                 return;
2987
2988         mask = vccd_masks[no];
2989
2990         if (what)
2991                 immap->im_ioport.iop_padat |= mask;
2992         else
2993                 immap->im_ioport.iop_padat &= ~mask;
2994 }
2995
2996 static const unsigned short oc_mask = _BW(8);
2997
2998 static void cfg_oc(void)
2999 {
3000         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3001         unsigned short mask = oc_mask;
3002
3003         immap->im_ioport.iop_pcdir &= ~mask;
3004         immap->im_ioport.iop_pcso  &= ~mask;
3005         immap->im_ioport.iop_pcint &= ~mask;
3006         immap->im_ioport.iop_pcpar &= ~mask;
3007 }
3008
3009 static int get_oc(void)
3010 {
3011         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3012         unsigned short mask = oc_mask;
3013         int what;
3014
3015         what = !!(immap->im_ioport.iop_pcdat & mask);;
3016         return what;
3017 }
3018
3019 static const unsigned short shdn_mask = _BW(12);
3020
3021 static void cfg_shdn(void)
3022 {
3023         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3024         unsigned short mask;
3025
3026         mask = shdn_mask;
3027
3028         immap->im_ioport.iop_papar &= ~mask;
3029         immap->im_ioport.iop_paodr &= ~mask;
3030         immap->im_ioport.iop_padir |=  mask;
3031 }
3032
3033 static void set_shdn(int what)
3034 {
3035         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3036         unsigned short mask;
3037
3038         mask = shdn_mask;
3039
3040         if (what)
3041                 immap->im_ioport.iop_padat |= mask;
3042         else
3043                 immap->im_ioport.iop_padat &= ~mask;
3044 }
3045
3046 static void cfg_ports (void);
3047
3048 static int hardware_enable(int slot)
3049 {
3050         volatile immap_t        *immap;
3051         volatile cpm8xx_t       *cp;
3052         volatile pcmconf8xx_t   *pcmp;
3053         volatile sysconf8xx_t   *sysp;
3054         uint reg, pipr, mask;
3055         int i;
3056
3057         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3058
3059         udelay(10000);
3060
3061         immap = (immap_t *)CFG_IMMR;
3062         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3063         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3064         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3065
3066         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3067         cfg_ports ();
3068
3069         /* clear interrupt state, and disable interrupts */
3070         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
3071         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3072
3073         /*
3074          * Disable interrupts, DMA, and PCMCIA buffers
3075          * (isolate the interface) and assert RESET signal
3076          */
3077         debug ("Disable PCMCIA buffers and assert RESET\n");
3078         reg  = 0;
3079         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3080         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
3081         PCMCIA_PGCRX(_slot_) = reg;
3082
3083         udelay(500);
3084
3085         /*
3086          * Make sure there is a card in the slot, then configure the interface.
3087          */
3088         udelay(10000);
3089         debug ("[%d] %s: PIPR(%p)=0x%x\n",
3090                 __LINE__,__FUNCTION__,
3091                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3092         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3093                 printf ("   No Card found\n");
3094                 return (1);
3095         }
3096
3097         /*
3098          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
3099          */
3100         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3101         pipr = pcmp->pcmc_pipr;
3102         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3103                 pipr,
3104                 (reg&PCMCIA_VS1(slot))?"n":"ff",
3105                 (reg&PCMCIA_VS2(slot))?"n":"ff");
3106
3107         if ((pipr & mask) == mask) {
3108                 set_vppd(0, 1); set_vppd(1, 1);                 /* VAVPP => Hi-Z */
3109                 set_vccd(0, 0); set_vccd(1, 1);                 /* 5V on, 3V off */
3110                 puts (" 5.0V card found: ");
3111         } else {
3112                 set_vppd(0, 1); set_vppd(1, 1);                 /* VAVPP => Hi-Z */
3113                 set_vccd(0, 1); set_vccd(1, 0);                 /* 5V off, 3V on */
3114                 puts (" 3.3V card found: ");
3115         }
3116
3117         /*  Wait 500 ms; use this to check for over-current */
3118         for (i=0; i<5000; ++i) {
3119                 if (!get_oc()) {
3120                         printf ("   *** Overcurrent - Safety shutdown ***\n");
3121                         set_vccd(0, 0); set_vccd(1, 0);                 /* VAVPP => Hi-Z */
3122                         return (1);
3123                 }
3124                 udelay (100);
3125         }
3126
3127         debug ("Enable PCMCIA buffers and stop RESET\n");
3128         reg  =  PCMCIA_PGCRX(_slot_);
3129         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3130         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3131         PCMCIA_PGCRX(_slot_) = reg;
3132
3133         udelay(250000); /* some cards need >150 ms to come up :-( */
3134
3135         debug ("# hardware_enable done\n");
3136
3137         return (0);
3138 }
3139
3140
3141 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3142 static int hardware_disable(int slot)
3143 {
3144         volatile immap_t        *immap;
3145         volatile pcmconf8xx_t   *pcmp;
3146         u_long reg;
3147
3148         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3149
3150         immap = (immap_t *)CFG_IMMR;
3151         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3152
3153         /* Configure PCMCIA General Control Register */
3154         debug ("Disable PCMCIA buffers and assert RESET\n");
3155         reg  = 0;
3156         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3157         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
3158         PCMCIA_PGCRX(_slot_) = reg;
3159
3160         /* All voltages off / Hi-Z */
3161                         set_vppd(0, 1); set_vppd(1, 1);
3162         set_vccd(0, 1); set_vccd(1, 1);
3163
3164         udelay(10000);
3165
3166         return (0);
3167 }
3168 #endif  /* CFG_CMD_PCMCIA */
3169
3170
3171 static int voltage_set(int slot, int vcc, int vpp)
3172 {
3173         volatile immap_t        *immap;
3174         volatile cpm8xx_t       *cp;
3175         volatile pcmconf8xx_t   *pcmp;
3176         u_long reg;
3177         ushort sreg;
3178
3179         debug ("voltage_set: "
3180                 PCMCIA_BOARD_MSG
3181                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3182                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3183
3184         immap = (immap_t *)CFG_IMMR;
3185         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3186         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3187         /*
3188          * Disable PCMCIA buffers (isolate the interface)
3189          * and assert RESET signal
3190          */
3191         debug ("Disable PCMCIA buffers and assert RESET\n");
3192         reg  = PCMCIA_PGCRX(_slot_);
3193         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3194         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
3195         PCMCIA_PGCRX(_slot_) = reg;
3196         udelay(500);
3197
3198         /*
3199          * Configure Port C pins for
3200          * 5 Volts Enable and 3 Volts enable,
3201          * Turn all power pins to Hi-Z
3202          */
3203         debug ("PCMCIA power OFF\n");
3204         cfg_ports ();   /* Enables switch, but all in Hi-Z */
3205
3206         sreg  = immap->im_ioport.iop_pcdat;
3207         set_vppd(0, 1); set_vppd(1, 1);
3208
3209         switch(vcc) {
3210         case  0:
3211                 break;  /* Switch off           */
3212
3213         case 33:
3214                 set_vccd(0, 1); set_vccd(1, 0);
3215                 break;
3216
3217         case 50:
3218                 set_vccd(0, 0); set_vccd(1, 1);
3219                 break;
3220
3221         default:
3222                 goto done;
3223         }
3224
3225         /* Checking supported voltages */
3226
3227         debug ("PIPR: 0x%x --> %s\n",
3228                 pcmp->pcmc_pipr,
3229                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
3230
3231 done:
3232         debug ("Enable PCMCIA buffers and stop RESET\n");
3233         reg  =  PCMCIA_PGCRX(_slot_);
3234         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3235         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3236         PCMCIA_PGCRX(_slot_) = reg;
3237         udelay(500);
3238
3239         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3240                 slot+'A');
3241         return (0);
3242 }
3243
3244 static void cfg_ports (void)
3245 {
3246         volatile immap_t        *immap;
3247         volatile cpm8xx_t       *cp;
3248
3249         immap = (immap_t *)CFG_IMMR;
3250         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3251
3252
3253         cfg_vppd(0); cfg_vppd(1);       /* VPPD0,VPPD1 VAVPP => Hi-Z */
3254         cfg_vccd(0); cfg_vccd(1);       /* 3V and 5V off */
3255         cfg_shdn();
3256         cfg_oc();
3257
3258         /*
3259          * Configure Port A for TPS2211 PC-Card Power-Interface Switch
3260          *
3261          * Switch off all voltages, assert shutdown
3262          */
3263         set_vppd(0, 1); set_vppd(1, 1);
3264         set_vccd(0, 0); set_vccd(1, 0);
3265         set_shdn(1);
3266
3267         udelay(100000);
3268 }
3269
3270 #endif  /* NETTA */
3271
3272
3273 /* -------------------------------------------------------------------- */
3274 /* UC100 Boards                                                         */
3275 /* -------------------------------------------------------------------- */
3276
3277 #if defined(CONFIG_UC100)
3278
3279 #define PCMCIA_BOARD_MSG "UC100"
3280
3281 /*
3282  * Remark: don't turn off OE "__MY_PCMCIA_GCRX_CXOE" on UC100 board.
3283  *         This leads to board-hangup! (sr, 8 Dez. 2004)
3284  */
3285
3286 static void cfg_ports (void);
3287
3288 static int hardware_enable(int slot)
3289 {
3290         volatile immap_t        *immap;
3291         volatile cpm8xx_t       *cp;
3292         volatile pcmconf8xx_t   *pcmp;
3293         volatile sysconf8xx_t   *sysp;
3294         uint reg, mask;
3295
3296         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3297
3298         udelay(10000);
3299
3300         immap = (immap_t *)CFG_IMMR;
3301         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3302         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3303         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3304
3305         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3306         cfg_ports ();
3307
3308         /*
3309          * Configure SIUMCR to enable PCMCIA port B
3310          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
3311          */
3312         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
3313
3314         /* clear interrupt state, and disable interrupts */
3315         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
3316         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3317
3318         /*
3319          * Disable interrupts, DMA, and PCMCIA buffers
3320          * (isolate the interface) and assert RESET signal
3321          */
3322         debug ("Disable PCMCIA buffers and assert RESET\n");
3323         reg  = 0;
3324         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3325         PCMCIA_PGCRX(_slot_) = reg;
3326         udelay(500);
3327
3328         /*
3329          * Make sure there is a card in the slot, then configure the interface.
3330          */
3331         udelay(10000);
3332         debug ("[%d] %s: PIPR(%p)=0x%x\n",
3333                 __LINE__,__FUNCTION__,
3334                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3335         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3336                 printf ("   No Card found\n");
3337                 return (1);
3338         }
3339
3340         /*
3341          * Power On.
3342          */
3343         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3344         reg  = pcmp->pcmc_pipr;
3345         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3346                 reg,
3347                 (reg&PCMCIA_VS1(slot))?"n":"ff",
3348                 (reg&PCMCIA_VS2(slot))?"n":"ff");
3349         if ((reg & mask) == mask) {
3350                 puts (" 5.0V card found: ");
3351         } else {
3352                 puts (" 3.3V card found: ");
3353         }
3354
3355         /*  switch VCC on */
3356         immap->im_ioport.iop_padat |= 0x8000; /* power enable 3.3V */
3357
3358         udelay(10000);
3359
3360         debug ("Enable PCMCIA buffers and stop RESET\n");
3361         reg  =  PCMCIA_PGCRX(_slot_);
3362         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3363         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3364         PCMCIA_PGCRX(_slot_) = reg;
3365
3366         udelay(250000); /* some cards need >150 ms to come up :-( */
3367
3368         debug ("# hardware_enable done\n");
3369
3370         return (0);
3371 }
3372
3373
3374 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3375 static int hardware_disable(int slot)
3376 {
3377         volatile immap_t        *immap;
3378         volatile cpm8xx_t       *cp;
3379         volatile pcmconf8xx_t   *pcmp;
3380         u_long reg;
3381
3382         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3383
3384         immap = (immap_t *)CFG_IMMR;
3385         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3386
3387         /* switch VCC off */
3388         immap->im_ioport.iop_padat &= ~0x8000; /* power disable 3.3V */
3389
3390         /* Configure PCMCIA General Control Register */
3391         debug ("Disable PCMCIA buffers and assert RESET\n");
3392         reg  = 0;
3393         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3394         PCMCIA_PGCRX(_slot_) = reg;
3395
3396         udelay(10000);
3397
3398         return (0);
3399 }
3400 #endif  /* CFG_CMD_PCMCIA */
3401
3402
3403 static int voltage_set(int slot, int vcc, int vpp)
3404 {
3405         volatile immap_t        *immap;
3406         volatile pcmconf8xx_t   *pcmp;
3407         u_long reg;
3408
3409         debug ("voltage_set: "
3410                 PCMCIA_BOARD_MSG
3411                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3412                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3413
3414         immap = (immap_t *)CFG_IMMR;
3415         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3416         /*
3417          * Disable PCMCIA buffers (isolate the interface)
3418          * and assert RESET signal
3419          */
3420         debug ("Disable PCMCIA buffers and assert RESET\n");
3421         reg  = PCMCIA_PGCRX(_slot_);
3422         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3423         PCMCIA_PGCRX(_slot_) = reg;
3424         udelay(500);
3425
3426         /*
3427          * Configure Port C pins for
3428          * 5 Volts Enable and 3 Volts enable,
3429          * Turn all power pins to Hi-Z
3430          */
3431         debug ("PCMCIA power OFF\n");
3432         cfg_ports ();   /* Enables switch, but all in Hi-Z */
3433
3434         debug ("Enable PCMCIA buffers and stop RESET\n");
3435         reg  =  PCMCIA_PGCRX(_slot_);
3436         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3437         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3438         PCMCIA_PGCRX(_slot_) = reg;
3439         udelay(500);
3440
3441         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3442                 slot+'A');
3443         return (0);
3444 }
3445
3446 static void cfg_ports (void)
3447 {
3448         volatile immap_t        *immap;
3449
3450         immap = (immap_t *)CFG_IMMR;
3451
3452         /*
3453          * Configure Port A for MAX1602 PC-Card Power-Interface Switch
3454          */
3455         immap->im_ioport.iop_padat &= ~0x8000;  /* set port x output to low */
3456         immap->im_ioport.iop_padir |= 0x8000;   /* enable port x as output */
3457
3458         debug ("Set Port A: PAR: %08x DIR: %08x DAT: %08x\n",
3459                immap->im_ioport.iop_papar, immap->im_ioport.iop_padir,
3460                immap->im_ioport.iop_padat);
3461 }
3462
3463 #endif  /* UC100 */
3464
3465
3466 /* -------------------------------------------------------------------- */
3467
3468 #endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
3469
3470 /**************************************************/
3471
3472 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3473 U_BOOT_CMD(
3474         pinit,  2,      1,      do_pinit,
3475         "pinit   - PCMCIA sub-system\n",
3476         "on  - power on PCMCIA socket\n"
3477         "pinit off - power off PCMCIA socket\n"
3478 );
3479 #endif