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