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