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