]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_pcmcia.c
Cleanup compile warning.
[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 #ifdef DEBUG
1133         volatile pcmconf8xx_t   *pcmp =
1134                 (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1135 #endif
1136         volatile unsigned char  *powerctl =
1137                 (volatile unsigned char *)PCMCIA_CTRL;
1138         unsigned long           reg;
1139
1140         debug ("voltage_set: " PCMCIA_BOARD_MSG
1141                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1142                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1143
1144         /*
1145          * Disable PCMCIA buffers (isolate the interface)
1146          * and assert RESET signal
1147          */
1148         debug ("Disable PCMCIA buffers and assert RESET\n");
1149         reg  = PCMCIA_PGCRX(slot);
1150         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1151         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1152
1153         PCMCIA_PGCRX(slot) = reg;
1154         udelay(500);
1155
1156         /*
1157          * Configure pins for 5 Volts Enable and 3 Volts enable,
1158          * Turn off all power.
1159          */
1160         debug ("PCMCIA power OFF\n");
1161         reg = 0;
1162         switch(vcc) {
1163         case  0:                break;
1164         case 33: reg = 0x0001;  break;
1165         case 50: reg = 0x0002;  break;
1166         default:                goto done;
1167         }
1168
1169         /* Checking supported voltages */
1170
1171         debug ("PIPR: 0x%x --> %s\n", pcmp->pcmc_pipr,
1172                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1173
1174         *powerctl = reg;
1175
1176         if (reg) {
1177                 debug ("PCMCIA powered at %sV\n", (reg&0x0004) ? "5.0" : "3.3");
1178         } else {
1179                 debug ("PCMCIA powered down\n");
1180         }
1181
1182 done:
1183         debug ("Enable PCMCIA buffers and stop RESET\n");
1184         reg  =  PCMCIA_PGCRX(slot);
1185         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1186         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1187
1188         PCMCIA_PGCRX(slot) = reg;
1189         udelay(500);
1190
1191         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A');
1192         return (0);
1193 }
1194 #endif  /* CONFIG_VIRTLAB2 */
1195
1196 /* -------------------------------------------------------------------- */
1197 /* LWMON Board                                                          */
1198 /* -------------------------------------------------------------------- */
1199
1200 #if defined(CONFIG_LWMON)
1201
1202 #define PCMCIA_BOARD_MSG "LWMON"
1203
1204 /* #define's for MAX1604 Power Switch */
1205 #define MAX1604_OP_SUS          0x80
1206 #define MAX1604_VCCBON          0x40
1207 #define MAX1604_VCC_35          0x20
1208 #define MAX1604_VCCBHIZ         0x10
1209 #define MAX1604_VPPBON          0x08
1210 #define MAX1604_VPPBPBPGM       0x04
1211 #define MAX1604_VPPBHIZ         0x02
1212 /* reserved                     0x01    */
1213
1214 static int hardware_enable(int slot)
1215 {
1216         volatile immap_t        *immap;
1217         volatile cpm8xx_t       *cp;
1218         volatile pcmconf8xx_t   *pcmp;
1219         volatile sysconf8xx_t   *sysp;
1220         uint reg, mask;
1221         uchar val;
1222
1223
1224         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1225
1226         /* Switch on PCMCIA port in PIC register 0x60 */
1227         reg = pic_read  (0x60);
1228         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1229         reg &= ~0x10;
1230         /* reg |= 0x08; Vpp not needed */
1231         pic_write (0x60, reg);
1232 #ifdef DEBUG
1233         reg = pic_read  (0x60);
1234         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1235 #endif
1236         udelay(10000);
1237
1238         immap = (immap_t *)CFG_IMMR;
1239         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1240         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1241         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1242
1243         /*
1244          * Configure SIUMCR to enable PCMCIA port B
1245          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1246          */
1247         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1248
1249         /* clear interrupt state, and disable interrupts */
1250         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1251         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1252
1253         /*
1254          * Disable interrupts, DMA, and PCMCIA buffers
1255          * (isolate the interface) and assert RESET signal
1256          */
1257         debug ("Disable PCMCIA buffers and assert RESET\n");
1258         reg  = 0;
1259         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1260         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1261         PCMCIA_PGCRX(_slot_) = reg;
1262         udelay(500);
1263
1264         /*
1265          * Make sure there is a card in the slot, then configure the interface.
1266          */
1267         udelay(10000);
1268         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1269                 __LINE__,__FUNCTION__,
1270                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1271         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1272                 printf ("   No Card found\n");
1273                 return (1);
1274         }
1275
1276         /*
1277          * Power On.
1278          */
1279         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1280         reg  = pcmp->pcmc_pipr;
1281         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1282                 reg,
1283                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1284                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1285         if ((reg & mask) == mask) {
1286                 val = 0;                /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
1287                 puts (" 5.0V card found: ");
1288         } else {
1289                 val = MAX1604_VCC_35;   /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
1290                 puts (" 3.3V card found: ");
1291         }
1292
1293         /*  switch VCC on */
1294         val |= MAX1604_OP_SUS | MAX1604_VCCBON;
1295         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1296         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1297
1298         udelay(500000);
1299
1300         debug ("Enable PCMCIA buffers and stop RESET\n");
1301         reg  =  PCMCIA_PGCRX(_slot_);
1302         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1303         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1304         PCMCIA_PGCRX(_slot_) = reg;
1305
1306         udelay(250000); /* some cards need >150 ms to come up :-( */
1307
1308         debug ("# hardware_enable done\n");
1309
1310         return (0);
1311 }
1312
1313
1314 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1315 static int hardware_disable(int slot)
1316 {
1317         volatile immap_t        *immap;
1318         volatile pcmconf8xx_t   *pcmp;
1319         u_long reg;
1320         uchar val;
1321
1322         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1323
1324         immap = (immap_t *)CFG_IMMR;
1325         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1326
1327         /* remove all power, put output in high impedance state */
1328         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1329         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1330         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1331
1332         /* Configure PCMCIA General Control Register */
1333         debug ("Disable PCMCIA buffers and assert RESET\n");
1334         reg  = 0;
1335         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1336         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1337         PCMCIA_PGCRX(_slot_) = reg;
1338
1339         /* Switch off PCMCIA port in PIC register 0x60 */
1340         reg = pic_read  (0x60);
1341         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1342         reg |=  0x10;
1343         reg &= ~0x08;
1344         pic_write (0x60, reg);
1345 #ifdef DEBUG
1346         reg = pic_read  (0x60);
1347         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1348 #endif
1349         udelay(10000);
1350
1351         return (0);
1352 }
1353 #endif  /* CFG_CMD_PCMCIA */
1354
1355
1356 static int voltage_set(int slot, int vcc, int vpp)
1357 {
1358         volatile immap_t        *immap;
1359         volatile pcmconf8xx_t   *pcmp;
1360         u_long reg;
1361         uchar val;
1362
1363         debug ("voltage_set: "
1364                 PCMCIA_BOARD_MSG
1365                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1366                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1367
1368         immap = (immap_t *)CFG_IMMR;
1369         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1370         /*
1371          * Disable PCMCIA buffers (isolate the interface)
1372          * and assert RESET signal
1373          */
1374         debug ("Disable PCMCIA buffers and assert RESET\n");
1375         reg  = PCMCIA_PGCRX(_slot_);
1376         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1377         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1378         PCMCIA_PGCRX(_slot_) = reg;
1379         udelay(500);
1380
1381         /*
1382          * Turn off all power (switch to high impedance)
1383          */
1384         debug ("PCMCIA power OFF\n");
1385         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1386         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1387         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1388
1389         val = 0;
1390         switch(vcc) {
1391         case  0:                        break;
1392         case 33: val = MAX1604_VCC_35;  break;
1393         case 50:                        break;
1394         default:                        goto done;
1395         }
1396
1397         /* Checking supported voltages */
1398
1399         debug ("PIPR: 0x%x --> %s\n",
1400                 pcmp->pcmc_pipr,
1401                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1402
1403         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1404         if (val) {
1405                 debug ("PCMCIA powered at %sV\n",
1406                         (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1407         } else {
1408                 debug ("PCMCIA powered down\n");
1409         }
1410
1411 done:
1412         debug ("Enable PCMCIA buffers and stop RESET\n");
1413         reg  =  PCMCIA_PGCRX(_slot_);
1414         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1415         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1416         PCMCIA_PGCRX(_slot_) = reg;
1417         udelay(500);
1418
1419         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1420                 slot+'A');
1421         return (0);
1422 }
1423
1424 #endif  /* LWMON */
1425
1426 /* -------------------------------------------------------------------- */
1427 /* GTH board by Corelatus AB                                            */
1428 /* -------------------------------------------------------------------- */
1429 #if defined(CONFIG_GTH)
1430
1431 #define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1432
1433 static int voltage_set (int slot, int vcc, int vpp)
1434 {       /* Do nothing */
1435         return 0;
1436 }
1437
1438 static int hardware_enable (int slot)
1439 {
1440         volatile immap_t *immap;
1441         volatile cpm8xx_t *cp;
1442         volatile pcmconf8xx_t *pcmp;
1443         volatile sysconf8xx_t *sysp;
1444         uint reg, mask;
1445
1446         debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
1447
1448         immap = (immap_t *) CFG_IMMR;
1449         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1450         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1451         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1452
1453         /* clear interrupt state, and disable interrupts */
1454         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1455         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1456
1457         /*
1458          * Disable interrupts, DMA, and PCMCIA buffers
1459          * (isolate the interface) and assert RESET signal
1460          */
1461         debug ("Disable PCMCIA buffers and assert RESET\n");
1462         reg = 0;
1463         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1464         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
1465         PCMCIA_PGCRX (_slot_) = reg;
1466         udelay (500);
1467
1468         /*
1469          * Make sure there is a card in the slot,
1470          * then configure the interface.
1471          */
1472         udelay (10000);
1473         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1474                 __LINE__, __FUNCTION__,
1475                 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1476         if (pcmp->pcmc_pipr & 0x98000000) {
1477                 printf ("   No Card found\n");
1478                 return (1);
1479         }
1480
1481         mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1482         reg = pcmp->pcmc_pipr;
1483         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1484                    reg,
1485                    (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1486                    (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1487
1488         debug ("Enable PCMCIA buffers and stop RESET\n");
1489         reg  =  PCMCIA_PGCRX (_slot_);
1490         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1491         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1492         PCMCIA_PGCRX (_slot_) = reg;
1493
1494         udelay (250000);        /* some cards need >150 ms to come up :-( */
1495
1496         debug ("# hardware_enable done\n");
1497
1498         return 0;
1499 }
1500 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1501 static int hardware_disable(int slot)
1502 {
1503         return 0;       /* No hardware to disable */
1504 }
1505 #endif  /* CFG_CMD_PCMCIA */
1506 #endif  /* CONFIG_GTH */
1507
1508 /* -------------------------------------------------------------------- */
1509 /* ICU862 Boards by Cambridge Broadband Ltd.                            */
1510 /* -------------------------------------------------------------------- */
1511
1512 #if defined(CONFIG_ICU862)
1513
1514 #define PCMCIA_BOARD_MSG "ICU862"
1515
1516 static void cfg_port_B (void);
1517
1518 static int hardware_enable(int slot)
1519 {
1520         volatile immap_t        *immap;
1521         volatile cpm8xx_t       *cp;
1522         volatile pcmconf8xx_t   *pcmp;
1523         volatile sysconf8xx_t   *sysp;
1524         uint reg, pipr, mask;
1525         int i;
1526
1527         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1528
1529         udelay(10000);
1530
1531         immap = (immap_t *)CFG_IMMR;
1532         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1533         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1534         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1535
1536         /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1537         cfg_port_B ();
1538
1539         /*
1540          * Configure SIUMCR to enable PCMCIA port B
1541          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1542          */
1543         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1544
1545         /* clear interrupt state, and disable interrupts */
1546         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1547         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1548
1549         /*
1550          * Disable interrupts, DMA, and PCMCIA buffers
1551          * (isolate the interface) and assert RESET signal
1552          */
1553         debug ("Disable PCMCIA buffers and assert RESET\n");
1554         reg  = 0;
1555         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1556         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1557         PCMCIA_PGCRX(_slot_) = reg;
1558         udelay(500);
1559
1560         /*
1561          * Make sure there is a card in the slot, then configure the interface.
1562          */
1563         udelay(10000);
1564         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1565                 __LINE__,__FUNCTION__,
1566                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1567         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1568                 printf ("   No Card found\n");
1569                 return (1);
1570         }
1571
1572         /*
1573          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1574          */
1575         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1576         pipr = pcmp->pcmc_pipr;
1577         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1578                 pipr,
1579                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1580                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1581
1582         reg  = cp->cp_pbdat;
1583         if ((pipr & mask) == mask) {
1584                 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1585                         TPS2205_VCC3);                          /* 3V off       */
1586                 reg &= ~(TPS2205_VCC5);                         /* 5V on        */
1587                 puts (" 5.0V card found: ");
1588         } else {
1589                 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1590                         TPS2205_VCC5);                          /* 5V off       */
1591                 reg &= ~(TPS2205_VCC3);                         /* 3V on        */
1592                 puts (" 3.3V card found: ");
1593         }
1594
1595         debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1596                 reg,
1597                 (reg & TPS2205_VCC3)    ? "off" : "on",
1598                 (reg & TPS2205_VCC5)    ? "off" : "on",
1599                 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1600                 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1601
1602         cp->cp_pbdat = reg;
1603
1604         /*  Wait 500 ms; use this to check for over-current */
1605         for (i=0; i<5000; ++i) {
1606                 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1607                         printf ("   *** Overcurrent - Safety shutdown ***\n");
1608                         cp->cp_pbdat &= ~(TPS2205_SHDN);
1609                         return (1);
1610                 }
1611                 udelay (100);
1612         }
1613
1614         debug ("Enable PCMCIA buffers and stop RESET\n");
1615         reg  =  PCMCIA_PGCRX(_slot_);
1616         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1617         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1618         PCMCIA_PGCRX(_slot_) = reg;
1619
1620         udelay(250000); /* some cards need >150 ms to come up :-( */
1621
1622         debug ("# hardware_enable done\n");
1623
1624         return (0);
1625 }
1626
1627
1628 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1629 static int hardware_disable(int slot)
1630 {
1631         volatile immap_t        *immap;
1632         volatile cpm8xx_t       *cp;
1633         volatile pcmconf8xx_t   *pcmp;
1634         u_long reg;
1635
1636         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1637
1638         immap = (immap_t *)CFG_IMMR;
1639         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1640         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1641
1642         /* Shut down */
1643         cp->cp_pbdat &= ~(TPS2205_SHDN);
1644
1645         /* Configure PCMCIA General Control Register */
1646         debug ("Disable PCMCIA buffers and assert RESET\n");
1647         reg  = 0;
1648         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1649         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1650         PCMCIA_PGCRX(_slot_) = reg;
1651
1652         udelay(10000);
1653
1654         return (0);
1655 }
1656 #endif  /* CFG_CMD_PCMCIA */
1657
1658
1659 static int voltage_set(int slot, int vcc, int vpp)
1660 {
1661         volatile immap_t        *immap;
1662         volatile cpm8xx_t       *cp;
1663         volatile pcmconf8xx_t   *pcmp;
1664         u_long reg;
1665
1666         debug ("voltage_set: "
1667                 PCMCIA_BOARD_MSG
1668                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1669                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1670
1671         immap = (immap_t *)CFG_IMMR;
1672         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1673         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1674         /*
1675          * Disable PCMCIA buffers (isolate the interface)
1676          * and assert RESET signal
1677          */
1678         debug ("Disable PCMCIA buffers and assert RESET\n");
1679         reg  = PCMCIA_PGCRX(_slot_);
1680         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1681         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1682         PCMCIA_PGCRX(_slot_) = reg;
1683         udelay(500);
1684
1685         /*
1686          * Configure Port C pins for
1687          * 5 Volts Enable and 3 Volts enable,
1688          * Turn all power pins to Hi-Z
1689          */
1690         debug ("PCMCIA power OFF\n");
1691         cfg_port_B ();  /* Enables switch, but all in Hi-Z */
1692
1693         reg  = cp->cp_pbdat;
1694
1695         switch(vcc) {
1696         case  0:                        break;  /* Switch off           */
1697         case 33: reg &= ~TPS2205_VCC3;  break;  /* Switch on 3.3V       */
1698         case 50: reg &= ~TPS2205_VCC5;  break;  /* Switch on 5.0V       */
1699         default:                        goto done;
1700         }
1701
1702         /* Checking supported voltages */
1703
1704         debug ("PIPR: 0x%x --> %s\n",
1705                 pcmp->pcmc_pipr,
1706                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1707
1708         cp->cp_pbdat = reg;
1709
1710 #ifdef DEBUG
1711     {
1712         char *s;
1713
1714         if ((reg & TPS2205_VCC3) == 0) {
1715                 s = "at 3.3V";
1716         } else if ((reg & TPS2205_VCC5) == 0) {
1717                 s = "at 5.0V";
1718         } else {
1719                 s = "down";
1720         }
1721         printf ("PCMCIA powered %s\n", s);
1722     }
1723 #endif
1724
1725 done:
1726         debug ("Enable PCMCIA buffers and stop RESET\n");
1727         reg  =  PCMCIA_PGCRX(_slot_);
1728         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1729         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1730         PCMCIA_PGCRX(_slot_) = reg;
1731         udelay(500);
1732
1733         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1734                 slot+'A');
1735         return (0);
1736 }
1737
1738 static void cfg_port_B (void)
1739 {
1740         volatile immap_t        *immap;
1741         volatile cpm8xx_t       *cp;
1742         uint reg;
1743
1744         immap = (immap_t *)CFG_IMMR;
1745         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1746
1747         /*
1748          * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1749          *
1750          * Switch off all voltages, assert shutdown
1751          */
1752         reg  = cp->cp_pbdat;
1753         reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1754                 TPS2205_VCC3    | TPS2205_VCC5    |     /* VAVCC => Hi-Z */
1755                 TPS2205_SHDN);                          /* enable switch */
1756         cp->cp_pbdat = reg;
1757
1758         cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1759
1760         reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1761         cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1762
1763         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1764                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1765 }
1766
1767 #endif  /* ICU862 */
1768
1769
1770 /* -------------------------------------------------------------------- */
1771 /* C2MON Boards by TTTech Computertechnik AG                            */
1772 /* -------------------------------------------------------------------- */
1773
1774 #if defined(CONFIG_C2MON)
1775
1776 #define PCMCIA_BOARD_MSG "C2MON"
1777
1778 static void cfg_ports (void);
1779
1780 static int hardware_enable(int slot)
1781 {
1782         volatile immap_t        *immap;
1783         volatile cpm8xx_t       *cp;
1784         volatile pcmconf8xx_t   *pcmp;
1785         volatile sysconf8xx_t   *sysp;
1786         uint reg, pipr, mask;
1787         ushort sreg;
1788         int i;
1789
1790         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1791
1792         udelay(10000);
1793
1794         immap = (immap_t *)CFG_IMMR;
1795         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1796         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1797         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1798
1799         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1800         cfg_ports ();
1801
1802         /*
1803          * Configure SIUMCR to enable PCMCIA port B
1804          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1805          */
1806         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1807
1808         /* clear interrupt state, and disable interrupts */
1809         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1810         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1811
1812         /*
1813          * Disable interrupts, DMA, and PCMCIA buffers
1814          * (isolate the interface) and assert RESET signal
1815          */
1816         debug ("Disable PCMCIA buffers and assert RESET\n");
1817         reg  = 0;
1818         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1819         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1820         PCMCIA_PGCRX(_slot_) = reg;
1821         udelay(500);
1822
1823         /*
1824          * Make sure there is a card in the slot, then configure the interface.
1825          */
1826         udelay(10000);
1827         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1828                 __LINE__,__FUNCTION__,
1829                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1830         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1831                 printf ("   No Card found\n");
1832                 return (1);
1833         }
1834
1835         /*
1836          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1837          */
1838         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1839         pipr = pcmp->pcmc_pipr;
1840         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1841                 pipr,
1842                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1843                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1844
1845         sreg = immap->im_ioport.iop_pcdat;
1846         if ((pipr & mask) == mask) {
1847                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1848                           TPS2211_VCCD1);                       /* 5V on        */
1849                 sreg &= ~(TPS2211_VCCD0);                       /* 3V off       */
1850                 puts (" 5.0V card found: ");
1851         } else {
1852                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1853                           TPS2211_VCCD0);                       /* 3V on        */
1854                 sreg &= ~(TPS2211_VCCD1);                       /* 5V off       */
1855                 puts (" 3.3V card found: ");
1856         }
1857
1858         debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1859                 sreg,
1860                 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1861                 (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) ? "on" : "off"
1862         );
1863
1864         immap->im_ioport.iop_pcdat = sreg;
1865
1866         /*  Wait 500 ms; use this to check for over-current */
1867         for (i=0; i<5000; ++i) {
1868                 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1869                     printf ("   *** Overcurrent - Safety shutdown ***\n");
1870                     immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1871                     return (1);
1872                 }
1873                 udelay (100);
1874         }
1875
1876         debug ("Enable PCMCIA buffers and stop RESET\n");
1877         reg  =  PCMCIA_PGCRX(_slot_);
1878         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1879         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1880         PCMCIA_PGCRX(_slot_) = reg;
1881
1882         udelay(250000); /* some cards need >150 ms to come up :-( */
1883
1884         debug ("# hardware_enable done\n");
1885
1886         return (0);
1887 }
1888
1889
1890 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1891 static int hardware_disable(int slot)
1892 {
1893         volatile immap_t        *immap;
1894         volatile cpm8xx_t       *cp;
1895         volatile pcmconf8xx_t   *pcmp;
1896         u_long reg;
1897
1898         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1899
1900         immap = (immap_t *)CFG_IMMR;
1901         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1902
1903         /* Configure PCMCIA General Control Register */
1904         debug ("Disable PCMCIA buffers and assert RESET\n");
1905         reg  = 0;
1906         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1907         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1908         PCMCIA_PGCRX(_slot_) = reg;
1909
1910         /* ALl voltages off / Hi-Z */
1911         immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1912                                        TPS2211_VCCD0 | TPS2211_VCCD1 );
1913
1914         udelay(10000);
1915
1916         return (0);
1917 }
1918 #endif  /* CFG_CMD_PCMCIA */
1919
1920
1921 static int voltage_set(int slot, int vcc, int vpp)
1922 {
1923         volatile immap_t        *immap;
1924         volatile cpm8xx_t       *cp;
1925         volatile pcmconf8xx_t   *pcmp;
1926         u_long reg;
1927         ushort sreg;
1928
1929         debug ("voltage_set: "
1930                 PCMCIA_BOARD_MSG
1931                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1932                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1933
1934         immap = (immap_t *)CFG_IMMR;
1935         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1936         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1937         /*
1938          * Disable PCMCIA buffers (isolate the interface)
1939          * and assert RESET signal
1940          */
1941         debug ("Disable PCMCIA buffers and assert RESET\n");
1942         reg  = PCMCIA_PGCRX(_slot_);
1943         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1944         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1945         PCMCIA_PGCRX(_slot_) = reg;
1946         udelay(500);
1947
1948         /*
1949          * Configure Port C pins for
1950          * 5 Volts Enable and 3 Volts enable,
1951          * Turn all power pins to Hi-Z
1952          */
1953         debug ("PCMCIA power OFF\n");
1954         cfg_ports ();   /* Enables switch, but all in Hi-Z */
1955
1956         sreg  = immap->im_ioport.iop_pcdat;
1957         sreg |= TPS2211_VPPD0 | TPS2211_VPPD1;          /* VAVPP always Hi-Z */
1958
1959         switch(vcc) {
1960         case  0:                        break;  /* Switch off           */
1961         case 33: sreg |=  TPS2211_VCCD0;        /* Switch on 3.3V       */
1962                  sreg &= ~TPS2211_VCCD1;
1963                                         break;
1964         case 50: sreg &= ~TPS2211_VCCD0;        /* Switch on 5.0V       */
1965                  sreg |=  TPS2211_VCCD1;
1966                                         break;
1967         default:                        goto done;
1968         }
1969
1970         /* Checking supported voltages */
1971
1972         debug ("PIPR: 0x%x --> %s\n",
1973                 pcmp->pcmc_pipr,
1974                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1975
1976         immap->im_ioport.iop_pcdat = sreg;
1977
1978 #ifdef DEBUG
1979     {
1980         char *s;
1981
1982         if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1983                 s = "at 3.3V";
1984         } else if (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) {
1985                 s = "at 5.0V";
1986         } else {
1987                 s = "down";
1988         }
1989         printf ("PCMCIA powered %s\n", s);
1990     }
1991 #endif
1992
1993 done:
1994         debug ("Enable PCMCIA buffers and stop RESET\n");
1995         reg  =  PCMCIA_PGCRX(_slot_);
1996         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1997         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1998         PCMCIA_PGCRX(_slot_) = reg;
1999         udelay(500);
2000
2001         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2002                 slot+'A');
2003         return (0);
2004 }
2005
2006 static void cfg_ports (void)
2007 {
2008         volatile immap_t        *immap;
2009         volatile cpm8xx_t       *cp;
2010         ushort sreg;
2011
2012         immap = (immap_t *)CFG_IMMR;
2013         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2014
2015         /*
2016          * Configure Port C for TPS2211 PC-Card Power-Interface Switch
2017          *
2018          * Switch off all voltages, assert shutdown
2019          */
2020         sreg = immap->im_ioport.iop_pcdat;
2021         sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1);       /* VAVPP => Hi-Z */
2022         sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1);       /* 3V and 5V off */
2023         immap->im_ioport.iop_pcdat = sreg;
2024
2025         immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
2026         immap->im_ioport.iop_pcdir |=   TPS2211_OUTPUTS;
2027
2028         debug ("Set Port C: PAR:     %04x DIR:     %04x DAT:     %04x\n",
2029                 immap->im_ioport.iop_pcpar,
2030                 immap->im_ioport.iop_pcdir,
2031                 immap->im_ioport.iop_pcdat);
2032
2033         /*
2034          * Configure Port B for TPS2211 PC-Card Power-Interface Switch
2035          *
2036          * Over-Current Input only
2037          */
2038         cp->cp_pbpar &= ~(TPS2211_INPUTS);
2039         cp->cp_pbdir &= ~(TPS2211_INPUTS);
2040
2041         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
2042                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
2043 }
2044
2045 #endif  /* C2MON */
2046
2047 /* -------------------------------------------------------------------- */
2048 /* MBX board from Morotola                                              */
2049 /* -------------------------------------------------------------------- */
2050
2051 #if defined( CONFIG_MBX )
2052 #include <../board/mbx8xx/csr.h>
2053
2054 /* A lot of this has been taken from the RPX code in this file it works from me.
2055    I have added the voltage selection for the MBX board. */
2056
2057 /* MBX voltage bit in control register #2 */
2058 #define CR2_VPP12       ((uchar)0x10)
2059 #define CR2_VPPVDD      ((uchar)0x20)
2060 #define CR2_VDD5        ((uchar)0x40)
2061 #define CR2_VDD3        ((uchar)0x80)
2062
2063 #define PCMCIA_BOARD_MSG "MBX860"
2064
2065 static int voltage_set (int slot, int vcc, int vpp)
2066 {
2067         uchar reg = 0;
2068
2069         debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2070                  'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
2071
2072         switch (vcc) {
2073         case 0:
2074                 break;
2075         case 33:
2076                 reg |= CR2_VDD3;
2077                 break;
2078         case 50:
2079                 reg |= CR2_VDD5;
2080                 break;
2081         default:
2082                 return 1;
2083         }
2084
2085         switch (vpp) {
2086         case 0:
2087                 break;
2088         case 33:
2089         case 50:
2090                 if (vcc == vpp) {
2091                         reg |= CR2_VPPVDD;
2092                 } else {
2093                         return 1;
2094                 }
2095                 break;
2096         case 120:
2097                 reg |= CR2_VPP12;
2098                 break;
2099         default:
2100                 return 1;
2101         }
2102
2103         /* first, turn off all power */
2104         MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
2105
2106         /* enable new powersettings */
2107         MBX_CSR2 |= reg;
2108         debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
2109
2110         return (0);
2111 }
2112
2113 static int hardware_enable (int slot)
2114 {
2115         volatile immap_t *immap;
2116         volatile cpm8xx_t *cp;
2117         volatile pcmconf8xx_t *pcmp;
2118         volatile sysconf8xx_t *sysp;
2119         uint reg, mask;
2120
2121         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
2122                                   'A' + slot);
2123
2124         udelay (10000);
2125
2126         immap = (immap_t *) CFG_IMMR;
2127         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
2128         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
2129         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
2130
2131         /* clear interrupt state, and disable interrupts */
2132         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
2133         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
2134
2135         /*
2136          * Disable interrupts, DMA, and PCMCIA buffers
2137          * (isolate the interface) and assert RESET signal
2138          */
2139         debug ("Disable PCMCIA buffers and assert RESET\n");
2140         reg = 0;
2141         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2142         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
2143         PCMCIA_PGCRX (_slot_) = reg;
2144         udelay (500);
2145
2146         /* remove all power */
2147         voltage_set (slot, 0, 0);
2148         /*
2149          * Make sure there is a card in the slot, then configure the interface.
2150          */
2151         udelay(10000);
2152         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2153                 __LINE__,__FUNCTION__,
2154                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2155 #ifndef CONFIG_HMI10
2156         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2157 #else
2158         if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
2159 #endif  /* CONFIG_HMI10 */
2160                 printf ("   No Card found\n");
2161                 return (1);
2162         }
2163
2164         /*
2165          * Power On.
2166          */
2167         mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
2168         reg = pcmp->pcmc_pipr;
2169         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
2170                   (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
2171                   (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
2172
2173         if ((reg & mask) == mask) {
2174                 voltage_set (_slot_, 50, 0);
2175                 printf (" 5.0V card found: ");
2176         } else {
2177                 voltage_set (_slot_, 33, 0);
2178                 printf (" 3.3V card found: ");
2179         }
2180
2181         debug ("Enable PCMCIA buffers and stop RESET\n");
2182         reg = PCMCIA_PGCRX (_slot_);
2183         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2184         reg &= ~__MY_PCMCIA_GCRX_CXOE;  /* active low  */
2185         PCMCIA_PGCRX (_slot_) = reg;
2186
2187         udelay (250000);        /* some cards need >150 ms to come up :-( */
2188
2189         debug ("# hardware_enable done\n");
2190
2191         return (0);
2192 }
2193
2194 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2195 static int hardware_disable (int slot)
2196 {
2197         return 0;       /* No hardware to disable */
2198 }
2199 #endif /* CFG_CMD_PCMCIA */
2200 #endif /* CONFIG_MBX */
2201 /* -------------------------------------------------------------------- */
2202 /* R360MPI Board                                                        */
2203 /* -------------------------------------------------------------------- */
2204
2205 #if defined(CONFIG_R360MPI)
2206
2207 #define PCMCIA_BOARD_MSG "R360MPI"
2208
2209
2210 static int hardware_enable(int slot)
2211 {
2212         volatile immap_t        *immap;
2213         volatile cpm8xx_t       *cp;
2214         volatile pcmconf8xx_t   *pcmp;
2215         volatile sysconf8xx_t   *sysp;
2216         uint reg, mask;
2217
2218         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2219
2220         udelay(10000);
2221
2222         immap = (immap_t *)CFG_IMMR;
2223         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2224         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2225         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2226
2227         /*
2228          * Configure SIUMCR to enable PCMCIA port B
2229          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2230          */
2231         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
2232
2233         /* clear interrupt state, and disable interrupts */
2234         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
2235         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2236
2237         /*
2238          * Disable interrupts, DMA, and PCMCIA buffers
2239          * (isolate the interface) and assert RESET signal
2240          */
2241         debug ("Disable PCMCIA buffers and assert RESET\n");
2242         reg  = 0;
2243         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2244         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2245         PCMCIA_PGCRX(_slot_) = reg;
2246         udelay(500);
2247
2248         /*
2249          * Configure Ports A, B & C pins for
2250          * 5 Volts Enable and 3 Volts enable
2251          */
2252         immap->im_ioport.iop_pcpar &= ~(0x0400);
2253         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
2254         immap->im_ioport.iop_pcdir |= 0x0400;*/
2255
2256         immap->im_ioport.iop_papar &= ~(0x0200);/*
2257         immap->im_ioport.iop_padir |= 0x0200;*/
2258 #if 0
2259         immap->im_ioport.iop_pbpar &= ~(0xC000);
2260         immap->im_ioport.iop_pbdir &= ~(0xC000);
2261 #endif
2262         /* remove all power */
2263
2264         immap->im_ioport.iop_pcdat |= 0x0400;
2265         immap->im_ioport.iop_padat |= 0x0200;
2266
2267         /*
2268          * Make sure there is a card in the slot, then configure the interface.
2269          */
2270         udelay(10000);
2271         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2272                 __LINE__,__FUNCTION__,
2273                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2274         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2275                 printf ("   No Card found\n");
2276                 return (1);
2277         }
2278
2279         /*
2280          * Power On.
2281          */
2282         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2283         reg  = pcmp->pcmc_pipr;
2284         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2285                 reg,
2286                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2287                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2288         if ((reg & mask) == mask) {
2289                 immap->im_ioport.iop_pcdat &= ~(0x4000);
2290                 puts (" 5.0V card found: ");
2291         } else {
2292                 immap->im_ioport.iop_padat &= ~(0x0002);
2293                 puts (" 3.3V card found: ");
2294         }
2295         immap->im_ioport.iop_pcdir |= 0x0400;
2296         immap->im_ioport.iop_padir |= 0x0200;
2297 #if 0
2298         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
2299         cp->cp_pbdir &= ~(0x0020 | 0x0010);
2300         cp->cp_pbpar &= ~(0x0020 | 0x0010);
2301         udelay(500000);
2302 #endif
2303         debug ("Enable PCMCIA buffers and stop RESET\n");
2304         reg  =  PCMCIA_PGCRX(_slot_);
2305         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2306         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2307         PCMCIA_PGCRX(_slot_) = reg;
2308
2309         udelay(250000); /* some cards need >150 ms to come up :-( */
2310
2311         debug ("# hardware_enable done\n");
2312
2313         return (0);
2314 }
2315
2316
2317 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2318 static int hardware_disable(int slot)
2319 {
2320         volatile immap_t        *immap;
2321         volatile pcmconf8xx_t   *pcmp;
2322         u_long reg;
2323
2324         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2325
2326         immap = (immap_t *)CFG_IMMR;
2327         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2328
2329         /* remove all power */
2330         immap->im_ioport.iop_pcdat |= 0x0400;
2331         immap->im_ioport.iop_padat |= 0x0200;
2332
2333         /* Configure PCMCIA General Control Register */
2334         debug ("Disable PCMCIA buffers and assert RESET\n");
2335         reg  = 0;
2336         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2337         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2338         PCMCIA_PGCRX(_slot_) = reg;
2339
2340         udelay(10000);
2341
2342         return (0);
2343 }
2344 #endif  /* CFG_CMD_PCMCIA */
2345
2346
2347 static int voltage_set(int slot, int vcc, int vpp)
2348 {
2349         volatile immap_t        *immap;
2350         volatile pcmconf8xx_t   *pcmp;
2351         u_long reg;
2352
2353         debug ("voltage_set: "
2354                 PCMCIA_BOARD_MSG
2355                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2356                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2357
2358         immap = (immap_t *)CFG_IMMR;
2359         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2360         /*
2361          * Disable PCMCIA buffers (isolate the interface)
2362          * and assert RESET signal
2363          */
2364         debug ("Disable PCMCIA buffers and assert RESET\n");
2365         reg  = PCMCIA_PGCRX(_slot_);
2366         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2367         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2368         PCMCIA_PGCRX(_slot_) = reg;
2369         udelay(500);
2370
2371         /*
2372          * Configure Ports A & C pins for
2373          * 5 Volts Enable and 3 Volts enable,
2374          * Turn off all power
2375          */
2376         debug ("PCMCIA power OFF\n");
2377         immap->im_ioport.iop_pcpar &= ~(0x0400);
2378         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
2379         immap->im_ioport.iop_pcdir |= 0x0400;*/
2380
2381         immap->im_ioport.iop_papar &= ~(0x0200);/*
2382         immap->im_ioport.iop_padir |= 0x0200;*/
2383
2384         immap->im_ioport.iop_pcdat |= 0x0400;
2385         immap->im_ioport.iop_padat |= 0x0200;
2386
2387         reg = 0;
2388         switch(vcc) {
2389         case  0:                break;
2390         case 33: reg |= 0x0200; break;
2391         case 50: reg |= 0x0400; break;
2392         default:                goto done;
2393         }
2394
2395         /* Checking supported voltages */
2396
2397         debug ("PIPR: 0x%x --> %s\n",
2398                 pcmp->pcmc_pipr,
2399                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2400
2401         if (reg & 0x0200)
2402                 immap->im_ioport.iop_pcdat &= !reg;
2403         if (reg & 0x0400)
2404                 immap->im_ioport.iop_padat &= !reg;
2405         immap->im_ioport.iop_pcdir |= 0x0200;
2406         immap->im_ioport.iop_padir |= 0x0400;
2407         if (reg) {
2408                 debug ("PCMCIA powered at %sV\n",
2409                         (reg&0x0400) ? "5.0" : "3.3");
2410         } else {
2411                 debug ("PCMCIA powered down\n");
2412         }
2413
2414 done:
2415         debug ("Enable PCMCIA buffers and stop RESET\n");
2416         reg  =  PCMCIA_PGCRX(_slot_);
2417         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2418         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2419         PCMCIA_PGCRX(_slot_) = reg;
2420         udelay(500);
2421
2422         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2423                 slot+'A');
2424         return (0);
2425 }
2426
2427 #endif  /* R360MPI */
2428
2429 /* -------------------------------------------------------------------- */
2430 /* KUP4K and KUP4X Boards                                                               */
2431 /* -------------------------------------------------------------------- */
2432 #if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
2433
2434 #define PCMCIA_BOARD_MSG "KUP"
2435
2436 #define KUP4K_PCMCIA_B_3V3 (0x00020000)
2437
2438 static int hardware_enable(int slot)
2439 {
2440         volatile immap_t        *immap;
2441         volatile cpm8xx_t       *cp;
2442         volatile pcmconf8xx_t   *pcmp;
2443         volatile sysconf8xx_t   *sysp;
2444         uint reg, mask;
2445
2446         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2447
2448         udelay(10000);
2449
2450         immap = (immap_t *)CFG_IMMR;
2451         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2452         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2453         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2454
2455         /*
2456          * Configure SIUMCR to enable PCMCIA port B
2457          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2458          */
2459         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
2460
2461         /* clear interrupt state, and disable interrupts */
2462         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
2463         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
2464
2465         /*
2466          * Disable interrupts, DMA, and PCMCIA buffers
2467          * (isolate the interface) and assert RESET signal
2468          */
2469         debug ("Disable PCMCIA buffers and assert RESET\n");
2470         reg  = 0;
2471         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2472         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2473         PCMCIA_PGCRX(slot) = reg;
2474         udelay(2500);
2475
2476         /*
2477          * Configure Port B pins for
2478          * 3 Volts enable
2479          */
2480         if (slot) { /* Slot A is built-in */
2481                 cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2482                 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2483                 /* remove all power */
2484                 cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2485         }
2486         /*
2487          * Make sure there is a card in the slot, then configure the interface.
2488          */
2489         udelay(10000);
2490         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2491                 __LINE__,__FUNCTION__,
2492                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2493         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2494                 printf ("   No Card found\n");
2495                 return (1);
2496         }
2497
2498         /*
2499          * Power On.
2500          */
2501         printf("%s  Slot %c:", slot ? "" : "\n", 'A' + slot);
2502         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2503         reg  = pcmp->pcmc_pipr;
2504         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2505                 reg,
2506                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2507                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2508         if ((reg & mask) == mask) {
2509                 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2510         } else {
2511                 if(slot)
2512                         cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2513                 puts (" 3.3V card found: ");
2514         }
2515 #if 0
2516         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
2517         cp->cp_pbdir &= ~(0x0020 | 0x0010);
2518         cp->cp_pbpar &= ~(0x0020 | 0x0010);
2519         udelay(500000);
2520 #endif
2521         debug ("Enable PCMCIA buffers and stop RESET\n");
2522         reg  =  PCMCIA_PGCRX(slot);
2523         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2524         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2525         PCMCIA_PGCRX(slot) = reg;
2526
2527         udelay(250000); /* some cards need >150 ms to come up :-( */
2528
2529         debug ("# hardware_enable done\n");
2530
2531         return (0);
2532 }
2533
2534
2535 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2536 static int hardware_disable(int slot)
2537 {
2538         volatile immap_t        *immap;
2539         volatile cpm8xx_t       *cp;
2540         volatile pcmconf8xx_t   *pcmp;
2541         u_long reg;
2542
2543         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2544
2545         immap = (immap_t *)CFG_IMMR;
2546         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2547         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2548
2549         /* remove all power */
2550         if (slot)
2551                 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
2552
2553         /* Configure PCMCIA General Control Register */
2554         debug ("Disable PCMCIA buffers and assert RESET\n");
2555         reg  = 0;
2556         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2557         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2558         PCMCIA_PGCRX(slot) = reg;
2559
2560         udelay(10000);
2561
2562         return (0);
2563 }
2564 #endif  /* CFG_CMD_PCMCIA */
2565
2566
2567 static int voltage_set(int slot, int vcc, int vpp)
2568 {
2569         volatile immap_t        *immap;
2570         volatile cpm8xx_t       *cp;
2571         volatile pcmconf8xx_t   *pcmp;
2572         u_long reg;
2573
2574         debug ("voltage_set: "  \
2575                 PCMCIA_BOARD_MSG        \
2576                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2577                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2578
2579         if (!slot) /* Slot A is not configurable */
2580                 return 0;
2581
2582         immap = (immap_t *)CFG_IMMR;
2583         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2584         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2585
2586         /*
2587          * Disable PCMCIA buffers (isolate the interface)
2588          * and assert RESET signal
2589          */
2590         debug ("Disable PCMCIA buffers and assert RESET\n");
2591         reg  = PCMCIA_PGCRX(slot);
2592         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2593         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2594         PCMCIA_PGCRX(slot) = reg;
2595         udelay(500);
2596
2597         debug ("PCMCIA power OFF\n");
2598         /*
2599          * Configure Port B pins for
2600          * 3 Volts enable
2601          */
2602         cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2603         cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2604         /* remove all power */
2605         cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2606
2607         switch(vcc) {
2608         case  0:                break;
2609         case 33:
2610                 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2611                 debug ("PCMCIA powered at 3.3V\n");
2612                 break;
2613         case 50:
2614                 debug ("PCMCIA: 5Volt vcc not supported\n");
2615                 break;
2616         default:
2617                 puts("PCMCIA: vcc not supported");
2618                 break;
2619         }
2620         udelay(10000);
2621         /* Checking supported voltages */
2622
2623         debug ("PIPR: 0x%x --> %s\n",
2624                 pcmp->pcmc_pipr,
2625                    (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
2626                         ? "only 5 V --> NOT SUPPORTED"
2627                         : "can do 3.3V");
2628
2629
2630         debug ("Enable PCMCIA buffers and stop RESET\n");
2631         reg  =  PCMCIA_PGCRX(slot);
2632         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2633         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2634         PCMCIA_PGCRX(slot) = reg;
2635         udelay(500);
2636
2637         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2638                 slot+'A');
2639         return (0);
2640 }
2641
2642 #endif  /* KUP4K || KUP4X */
2643
2644
2645 /* -------------------------------------------------------------------- */
2646 /* End of Board Specific Stuff                                          */
2647 /* -------------------------------------------------------------------- */
2648
2649
2650 /* -------------------------------------------------------------------- */
2651 /* MPC8xx Specific Stuff - should go to MPC8xx directory                */
2652 /* -------------------------------------------------------------------- */
2653
2654 /*
2655  * Search this table to see if the windowsize is
2656  * supported...
2657  */
2658
2659 #define M8XX_SIZES_NO 32
2660
2661 static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2662 { 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2663   0x00000080, 0x00000040, 0x00000010, 0x00000020,
2664   0x00008000, 0x00004000, 0x00001000, 0x00002000,
2665   0x00000100, 0x00000200, 0x00000800, 0x00000400,
2666
2667   0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2668   0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2669   0x00010000, 0x00020000, 0x00080000, 0x00040000,
2670   0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2671
2672
2673 /* -------------------------------------------------------------------- */
2674
2675 #if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
2676
2677 static u_int m8xx_get_graycode(u_int size)
2678 {
2679         u_int k;
2680
2681         for (k = 0; k < M8XX_SIZES_NO; k++) {
2682                 if(m8xx_size_to_gray[k] == size)
2683                         break;
2684         }
2685
2686         if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2687                 k = -1;
2688
2689         return k;
2690 }
2691
2692 #endif  /* CONFIG_I82365 */
2693
2694 /* -------------------------------------------------------------------- */
2695
2696 #if 0
2697 static u_int m8xx_get_speed(u_int ns, u_int is_io)
2698 {
2699         u_int reg, clocks, psst, psl, psht;
2700
2701         if(!ns) {
2702
2703                 /*
2704                  * We get called with IO maps setup to 0ns
2705                  * if not specified by the user.
2706                  * They should be 255ns.
2707                  */
2708
2709                 if(is_io)
2710                         ns = 255;
2711                 else
2712                         ns = 100;  /* fast memory if 0 */
2713         }
2714
2715         /*
2716          * In PSST, PSL, PSHT fields we tell the controller
2717          * timing parameters in CLKOUT clock cycles.
2718          * CLKOUT is the same as GCLK2_50.
2719          */
2720
2721 /* how we want to adjust the timing - in percent */
2722
2723 #define ADJ 180 /* 80 % longer accesstime - to be sure */
2724
2725         clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2726         clocks = (clocks * ADJ) / (100*1000);
2727
2728         if(clocks >= PCMCIA_BMT_LIMIT) {
2729                 DEBUG(0, "Max access time limit reached\n");
2730                 clocks = PCMCIA_BMT_LIMIT-1;
2731         }
2732
2733         psst = clocks / 7;          /* setup time */
2734         psht = clocks / 7;          /* hold time */
2735         psl  = (clocks * 5) / 7;    /* strobe length */
2736
2737         psst += clocks - (psst + psht + psl);
2738
2739         reg =  psst << 12;
2740         reg |= psl  << 7;
2741         reg |= psht << 16;
2742
2743         return reg;
2744 }
2745 #endif
2746
2747 /* -------------------------------------------------------------------- */
2748
2749 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2750 static void print_funcid (int func)
2751 {
2752         puts (indent);
2753         switch (func) {
2754         case CISTPL_FUNCID_MULTI:
2755                 puts (" Multi-Function");
2756                 break;
2757         case CISTPL_FUNCID_MEMORY:
2758                 puts (" Memory");
2759                 break;
2760         case CISTPL_FUNCID_SERIAL:
2761                 puts (" Serial Port");
2762                 break;
2763         case CISTPL_FUNCID_PARALLEL:
2764                 puts (" Parallel Port");
2765                 break;
2766         case CISTPL_FUNCID_FIXED:
2767                 puts (" Fixed Disk");
2768                 break;
2769         case CISTPL_FUNCID_VIDEO:
2770                 puts (" Video Adapter");
2771                 break;
2772         case CISTPL_FUNCID_NETWORK:
2773                 puts (" Network Adapter");
2774                 break;
2775         case CISTPL_FUNCID_AIMS:
2776                 puts (" AIMS Card");
2777                 break;
2778         case CISTPL_FUNCID_SCSI:
2779                 puts (" SCSI Adapter");
2780                 break;
2781         default:
2782                 puts (" Unknown");
2783                 break;
2784         }
2785         puts (" Card\n");
2786 }
2787 #endif  /* CONFIG_IDE_8xx_PCCARD */
2788
2789 /* -------------------------------------------------------------------- */
2790
2791 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2792 static void print_fixed (volatile uchar *p)
2793 {
2794         if (p == NULL)
2795                 return;
2796
2797         puts(indent);
2798
2799         switch (*p) {
2800         case CISTPL_FUNCE_IDE_IFACE:
2801             {   uchar iface = *(p+2);
2802
2803                 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2804                 puts (" interface ");
2805                 break;
2806             }
2807         case CISTPL_FUNCE_IDE_MASTER:
2808         case CISTPL_FUNCE_IDE_SLAVE:
2809             {   uchar f1 = *(p+2);
2810                 uchar f2 = *(p+4);
2811
2812                 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2813
2814                 if (f1 & CISTPL_IDE_UNIQUE)
2815                         puts (" [unique]");
2816
2817                 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2818
2819                 if (f2 & CISTPL_IDE_HAS_SLEEP)
2820                         puts (" [sleep]");
2821
2822                 if (f2 & CISTPL_IDE_HAS_STANDBY)
2823                         puts (" [standby]");
2824
2825                 if (f2 & CISTPL_IDE_HAS_IDLE)
2826                         puts (" [idle]");
2827
2828                 if (f2 & CISTPL_IDE_LOW_POWER)
2829                         puts (" [low power]");
2830
2831                 if (f2 & CISTPL_IDE_REG_INHIBIT)
2832                         puts (" [reg inhibit]");
2833
2834                 if (f2 & CISTPL_IDE_HAS_INDEX)
2835                         puts (" [index]");
2836
2837                 if (f2 & CISTPL_IDE_IOIS16)
2838                         puts (" [IOis16]");
2839
2840                 break;
2841             }
2842         }
2843         putc ('\n');
2844 }
2845 #endif  /* CONFIG_IDE_8xx_PCCARD */
2846
2847 /* -------------------------------------------------------------------- */
2848
2849 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2850
2851 #define MAX_IDENT_CHARS         64
2852 #define MAX_IDENT_FIELDS        4
2853
2854 static uchar *known_cards[] = {
2855         (uchar *)"ARGOSY PnPIDE D5",
2856         NULL
2857 };
2858
2859 static int identify  (volatile uchar *p)
2860 {
2861         uchar id_str[MAX_IDENT_CHARS];
2862         uchar data;
2863         uchar *t;
2864         uchar **card;
2865         int i, done;
2866
2867         if (p == NULL)
2868                 return (0);     /* Don't know */
2869
2870         t = id_str;
2871         done =0;
2872
2873         for (i=0; i<=4 && !done; ++i, p+=2) {
2874                 while ((data = *p) != '\0') {
2875                         if (data == 0xFF) {
2876                                 done = 1;
2877                                 break;
2878                         }
2879                         *t++ = data;
2880                         if (t == &id_str[MAX_IDENT_CHARS-1]) {
2881                                 done = 1;
2882                                 break;
2883                         }
2884                         p += 2;
2885                 }
2886                 if (!done)
2887                         *t++ = ' ';
2888         }
2889         *t = '\0';
2890         while (--t > id_str) {
2891                 if (*t == ' ')
2892                         *t = '\0';
2893                 else
2894                         break;
2895         }
2896         puts ((char *)id_str);
2897         putc ('\n');
2898
2899         for (card=known_cards; *card; ++card) {
2900                 debug ("## Compare against \"%s\"\n", *card);
2901                 if (strcmp((char *)*card, (char *)id_str) == 0) {       /* found! */
2902                         debug ("## CARD FOUND ##\n");
2903                         return (1);
2904                 }
2905         }
2906
2907         return (0);     /* don't know */
2908 }
2909 #endif  /* CONFIG_IDE_8xx_PCCARD */
2910
2911 /* -------------------------------------------------------------------- */
2912 /* NETTA board by Intracom S.A.                                         */
2913 /* -------------------------------------------------------------------- */
2914
2915 #if defined(CONFIG_NETTA)
2916
2917 /* some sane bit macros */
2918 #define _BD(_b)                         (1U << (31-(_b)))
2919 #define _BDR(_l, _h)                    (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2920
2921 #define _BW(_b)                         (1U << (15-(_b)))
2922 #define _BWR(_l, _h)                    (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2923
2924 #define _BB(_b)                         (1U << (7-(_b)))
2925 #define _BBR(_l, _h)                    (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2926
2927 #define _B(_b)                          _BD(_b)
2928 #define _BR(_l, _h)                     _BDR(_l, _h)
2929
2930 #define PCMCIA_BOARD_MSG "NETTA"
2931
2932 static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2933
2934 static void cfg_vppd(int no)
2935 {
2936         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2937         unsigned short mask;
2938
2939         if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2940                 return;
2941
2942         mask = vppd_masks[no];
2943
2944         immap->im_ioport.iop_papar &= ~mask;
2945         immap->im_ioport.iop_paodr &= ~mask;
2946         immap->im_ioport.iop_padir |=  mask;
2947 }
2948
2949 static void set_vppd(int no, int what)
2950 {
2951         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2952         unsigned short mask;
2953
2954         if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2955                 return;
2956
2957         mask = vppd_masks[no];
2958
2959         if (what)
2960                 immap->im_ioport.iop_padat |= mask;
2961         else
2962                 immap->im_ioport.iop_padat &= ~mask;
2963 }
2964
2965 static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2966
2967 static void cfg_vccd(int no)
2968 {
2969         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2970         unsigned short mask;
2971
2972         if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2973                 return;
2974
2975         mask = vccd_masks[no];
2976
2977         immap->im_ioport.iop_papar &= ~mask;
2978         immap->im_ioport.iop_paodr &= ~mask;
2979         immap->im_ioport.iop_padir |=  mask;
2980 }
2981
2982 static void set_vccd(int no, int what)
2983 {
2984         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2985         unsigned short mask;
2986
2987         if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2988                 return;
2989
2990         mask = vccd_masks[no];
2991
2992         if (what)
2993                 immap->im_ioport.iop_padat |= mask;
2994         else
2995                 immap->im_ioport.iop_padat &= ~mask;
2996 }
2997
2998 static const unsigned short oc_mask = _BW(8);
2999
3000 static void cfg_oc(void)
3001 {
3002         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3003         unsigned short mask = oc_mask;
3004
3005         immap->im_ioport.iop_pcdir &= ~mask;
3006         immap->im_ioport.iop_pcso  &= ~mask;
3007         immap->im_ioport.iop_pcint &= ~mask;
3008         immap->im_ioport.iop_pcpar &= ~mask;
3009 }
3010
3011 static int get_oc(void)
3012 {
3013         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3014         unsigned short mask = oc_mask;
3015         int what;
3016
3017         what = !!(immap->im_ioport.iop_pcdat & mask);;
3018         return what;
3019 }
3020
3021 static const unsigned short shdn_mask = _BW(12);
3022
3023 static void cfg_shdn(void)
3024 {
3025         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3026         unsigned short mask;
3027
3028         mask = shdn_mask;
3029
3030         immap->im_ioport.iop_papar &= ~mask;
3031         immap->im_ioport.iop_paodr &= ~mask;
3032         immap->im_ioport.iop_padir |=  mask;
3033 }
3034
3035 static void set_shdn(int what)
3036 {
3037         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3038         unsigned short mask;
3039
3040         mask = shdn_mask;
3041
3042         if (what)
3043                 immap->im_ioport.iop_padat |= mask;
3044         else
3045                 immap->im_ioport.iop_padat &= ~mask;
3046 }
3047
3048 static void cfg_ports (void);
3049
3050 static int hardware_enable(int slot)
3051 {
3052         volatile immap_t        *immap;
3053         volatile cpm8xx_t       *cp;
3054         volatile pcmconf8xx_t   *pcmp;
3055         volatile sysconf8xx_t   *sysp;
3056         uint reg, pipr, mask;
3057         int i;
3058
3059         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3060
3061         udelay(10000);
3062
3063         immap = (immap_t *)CFG_IMMR;
3064         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3065         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3066         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3067
3068         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3069         cfg_ports ();
3070
3071         /* clear interrupt state, and disable interrupts */
3072         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
3073         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3074
3075         /*
3076          * Disable interrupts, DMA, and PCMCIA buffers
3077          * (isolate the interface) and assert RESET signal
3078          */
3079         debug ("Disable PCMCIA buffers and assert RESET\n");
3080         reg  = 0;
3081         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3082         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
3083         PCMCIA_PGCRX(_slot_) = reg;
3084
3085         udelay(500);
3086
3087         /*
3088          * Make sure there is a card in the slot, then configure the interface.
3089          */
3090         udelay(10000);
3091         debug ("[%d] %s: PIPR(%p)=0x%x\n",
3092                 __LINE__,__FUNCTION__,
3093                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3094         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3095                 printf ("   No Card found\n");
3096                 return (1);
3097         }
3098
3099         /*
3100          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
3101          */
3102         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3103         pipr = pcmp->pcmc_pipr;
3104         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3105                 pipr,
3106                 (reg&PCMCIA_VS1(slot))?"n":"ff",
3107                 (reg&PCMCIA_VS2(slot))?"n":"ff");
3108
3109         if ((pipr & mask) == mask) {
3110                 set_vppd(0, 1); set_vppd(1, 1);                 /* VAVPP => Hi-Z */
3111                 set_vccd(0, 0); set_vccd(1, 1);                 /* 5V on, 3V off */
3112                 puts (" 5.0V card found: ");
3113         } else {
3114                 set_vppd(0, 1); set_vppd(1, 1);                 /* VAVPP => Hi-Z */
3115                 set_vccd(0, 1); set_vccd(1, 0);                 /* 5V off, 3V on */
3116                 puts (" 3.3V card found: ");
3117         }
3118
3119         /*  Wait 500 ms; use this to check for over-current */
3120         for (i=0; i<5000; ++i) {
3121                 if (!get_oc()) {
3122                         printf ("   *** Overcurrent - Safety shutdown ***\n");
3123                         set_vccd(0, 0); set_vccd(1, 0);                 /* VAVPP => Hi-Z */
3124                         return (1);
3125                 }
3126                 udelay (100);
3127         }
3128
3129         debug ("Enable PCMCIA buffers and stop RESET\n");
3130         reg  =  PCMCIA_PGCRX(_slot_);
3131         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3132         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3133         PCMCIA_PGCRX(_slot_) = reg;
3134
3135         udelay(250000); /* some cards need >150 ms to come up :-( */
3136
3137         debug ("# hardware_enable done\n");
3138
3139         return (0);
3140 }
3141
3142
3143 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3144 static int hardware_disable(int slot)
3145 {
3146         volatile immap_t        *immap;
3147         volatile pcmconf8xx_t   *pcmp;
3148         u_long reg;
3149
3150         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3151
3152         immap = (immap_t *)CFG_IMMR;
3153         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3154
3155         /* Configure PCMCIA General Control Register */
3156         debug ("Disable PCMCIA buffers and assert RESET\n");
3157         reg  = 0;
3158         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3159         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
3160         PCMCIA_PGCRX(_slot_) = reg;
3161
3162         /* All voltages off / Hi-Z */
3163                         set_vppd(0, 1); set_vppd(1, 1);
3164         set_vccd(0, 1); set_vccd(1, 1);
3165
3166         udelay(10000);
3167
3168         return (0);
3169 }
3170 #endif  /* CFG_CMD_PCMCIA */
3171
3172
3173 static int voltage_set(int slot, int vcc, int vpp)
3174 {
3175         volatile immap_t        *immap;
3176         volatile cpm8xx_t       *cp;
3177         volatile pcmconf8xx_t   *pcmp;
3178         u_long reg;
3179         ushort sreg;
3180
3181         debug ("voltage_set: "
3182                 PCMCIA_BOARD_MSG
3183                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3184                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3185
3186         immap = (immap_t *)CFG_IMMR;
3187         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3188         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3189         /*
3190          * Disable PCMCIA buffers (isolate the interface)
3191          * and assert RESET signal
3192          */
3193         debug ("Disable PCMCIA buffers and assert RESET\n");
3194         reg  = PCMCIA_PGCRX(_slot_);
3195         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3196         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
3197         PCMCIA_PGCRX(_slot_) = reg;
3198         udelay(500);
3199
3200         /*
3201          * Configure Port C pins for
3202          * 5 Volts Enable and 3 Volts enable,
3203          * Turn all power pins to Hi-Z
3204          */
3205         debug ("PCMCIA power OFF\n");
3206         cfg_ports ();   /* Enables switch, but all in Hi-Z */
3207
3208         sreg  = immap->im_ioport.iop_pcdat;
3209         set_vppd(0, 1); set_vppd(1, 1);
3210
3211         switch(vcc) {
3212         case  0:
3213                 break;  /* Switch off           */
3214
3215         case 33:
3216                 set_vccd(0, 1); set_vccd(1, 0);
3217                 break;
3218
3219         case 50:
3220                 set_vccd(0, 0); set_vccd(1, 1);
3221                 break;
3222
3223         default:
3224                 goto done;
3225         }
3226
3227         /* Checking supported voltages */
3228
3229         debug ("PIPR: 0x%x --> %s\n",
3230                 pcmp->pcmc_pipr,
3231                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
3232
3233 done:
3234         debug ("Enable PCMCIA buffers and stop RESET\n");
3235         reg  =  PCMCIA_PGCRX(_slot_);
3236         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3237         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3238         PCMCIA_PGCRX(_slot_) = reg;
3239         udelay(500);
3240
3241         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3242                 slot+'A');
3243         return (0);
3244 }
3245
3246 static void cfg_ports (void)
3247 {
3248         volatile immap_t        *immap;
3249         volatile cpm8xx_t       *cp;
3250
3251         immap = (immap_t *)CFG_IMMR;
3252         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3253
3254
3255         cfg_vppd(0); cfg_vppd(1);       /* VPPD0,VPPD1 VAVPP => Hi-Z */
3256         cfg_vccd(0); cfg_vccd(1);       /* 3V and 5V off */
3257         cfg_shdn();
3258         cfg_oc();
3259
3260         /*
3261          * Configure Port A for TPS2211 PC-Card Power-Interface Switch
3262          *
3263          * Switch off all voltages, assert shutdown
3264          */
3265         set_vppd(0, 1); set_vppd(1, 1);
3266         set_vccd(0, 0); set_vccd(1, 0);
3267         set_shdn(1);
3268
3269         udelay(100000);
3270 }
3271
3272 #endif  /* NETTA */
3273
3274
3275 /* -------------------------------------------------------------------- */
3276 /* UC100 Boards                                                         */
3277 /* -------------------------------------------------------------------- */
3278
3279 #if defined(CONFIG_UC100)
3280
3281 #define PCMCIA_BOARD_MSG "UC100"
3282
3283 /*
3284  * Remark: don't turn off OE "__MY_PCMCIA_GCRX_CXOE" on UC100 board.
3285  *         This leads to board-hangup! (sr, 8 Dez. 2004)
3286  */
3287
3288 static void cfg_ports (void);
3289
3290 static int hardware_enable(int slot)
3291 {
3292         volatile immap_t        *immap;
3293         volatile cpm8xx_t       *cp;
3294         volatile pcmconf8xx_t   *pcmp;
3295         volatile sysconf8xx_t   *sysp;
3296         uint reg, mask;
3297
3298         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3299
3300         udelay(10000);
3301
3302         immap = (immap_t *)CFG_IMMR;
3303         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3304         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3305         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3306
3307         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3308         cfg_ports ();
3309
3310         /*
3311          * Configure SIUMCR to enable PCMCIA port B
3312          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
3313          */
3314         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
3315
3316         /* clear interrupt state, and disable interrupts */
3317         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
3318         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3319
3320         /*
3321          * Disable interrupts, DMA, and PCMCIA buffers
3322          * (isolate the interface) and assert RESET signal
3323          */
3324         debug ("Disable PCMCIA buffers and assert RESET\n");
3325         reg  = 0;
3326         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3327         PCMCIA_PGCRX(_slot_) = reg;
3328         udelay(500);
3329
3330         /*
3331          * Make sure there is a card in the slot, then configure the interface.
3332          */
3333         udelay(10000);
3334         debug ("[%d] %s: PIPR(%p)=0x%x\n",
3335                 __LINE__,__FUNCTION__,
3336                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3337         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3338                 printf ("   No Card found\n");
3339                 return (1);
3340         }
3341
3342         /*
3343          * Power On.
3344          */
3345         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3346         reg  = pcmp->pcmc_pipr;
3347         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3348                 reg,
3349                 (reg&PCMCIA_VS1(slot))?"n":"ff",
3350                 (reg&PCMCIA_VS2(slot))?"n":"ff");
3351         if ((reg & mask) == mask) {
3352                 puts (" 5.0V card found: ");
3353         } else {
3354                 puts (" 3.3V card found: ");
3355         }
3356
3357         /*  switch VCC on */
3358         immap->im_ioport.iop_padat |= 0x8000; /* power enable 3.3V */
3359
3360         udelay(10000);
3361
3362         debug ("Enable PCMCIA buffers and stop RESET\n");
3363         reg  =  PCMCIA_PGCRX(_slot_);
3364         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3365         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3366         PCMCIA_PGCRX(_slot_) = reg;
3367
3368         udelay(250000); /* some cards need >150 ms to come up :-( */
3369
3370         debug ("# hardware_enable done\n");
3371
3372         return (0);
3373 }
3374
3375
3376 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3377 static int hardware_disable(int slot)
3378 {
3379         volatile immap_t        *immap;
3380         volatile cpm8xx_t       *cp;
3381         volatile pcmconf8xx_t   *pcmp;
3382         u_long reg;
3383
3384         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3385
3386         immap = (immap_t *)CFG_IMMR;
3387         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3388
3389         /* switch VCC off */
3390         immap->im_ioport.iop_padat &= ~0x8000; /* power disable 3.3V */
3391
3392         /* Configure PCMCIA General Control Register */
3393         debug ("Disable PCMCIA buffers and assert RESET\n");
3394         reg  = 0;
3395         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3396         PCMCIA_PGCRX(_slot_) = reg;
3397
3398         udelay(10000);
3399
3400         return (0);
3401 }
3402 #endif  /* CFG_CMD_PCMCIA */
3403
3404
3405 static int voltage_set(int slot, int vcc, int vpp)
3406 {
3407         volatile immap_t        *immap;
3408         volatile pcmconf8xx_t   *pcmp;
3409         u_long reg;
3410
3411         debug ("voltage_set: "
3412                 PCMCIA_BOARD_MSG
3413                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3414                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3415
3416         immap = (immap_t *)CFG_IMMR;
3417         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3418         /*
3419          * Disable PCMCIA buffers (isolate the interface)
3420          * and assert RESET signal
3421          */
3422         debug ("Disable PCMCIA buffers and assert RESET\n");
3423         reg  = PCMCIA_PGCRX(_slot_);
3424         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3425         PCMCIA_PGCRX(_slot_) = reg;
3426         udelay(500);
3427
3428         /*
3429          * Configure Port C pins for
3430          * 5 Volts Enable and 3 Volts enable,
3431          * Turn all power pins to Hi-Z
3432          */
3433         debug ("PCMCIA power OFF\n");
3434         cfg_ports ();   /* Enables switch, but all in Hi-Z */
3435
3436         debug ("Enable PCMCIA buffers and stop RESET\n");
3437         reg  =  PCMCIA_PGCRX(_slot_);
3438         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3439         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3440         PCMCIA_PGCRX(_slot_) = reg;
3441         udelay(500);
3442
3443         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3444                 slot+'A');
3445         return (0);
3446 }
3447
3448 static void cfg_ports (void)
3449 {
3450         volatile immap_t        *immap;
3451
3452         immap = (immap_t *)CFG_IMMR;
3453
3454         /*
3455          * Configure Port A for MAX1602 PC-Card Power-Interface Switch
3456          */
3457         immap->im_ioport.iop_padat &= ~0x8000;  /* set port x output to low */
3458         immap->im_ioport.iop_padir |= 0x8000;   /* enable port x as output */
3459
3460         debug ("Set Port A: PAR: %08x DIR: %08x DAT: %08x\n",
3461                immap->im_ioport.iop_papar, immap->im_ioport.iop_padir,
3462                immap->im_ioport.iop_padat);
3463 }
3464
3465 #endif  /* UC100 */
3466
3467
3468 /* -------------------------------------------------------------------- */
3469
3470 #endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
3471
3472 /**************************************************/
3473
3474 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3475 U_BOOT_CMD(
3476         pinit,  2,      1,      do_pinit,
3477         "pinit   - PCMCIA sub-system\n",
3478         "on  - power on PCMCIA socket\n"
3479         "pinit off - power off PCMCIA socket\n"
3480 );
3481 #endif