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