]> git.ipfire.org Git - people/ms/u-boot.git/blame - common/cmd_pcmcia.c
* Code cleanup, mostly for GCC-3.3.x
[people/ms/u-boot.git] / common / cmd_pcmcia.c
CommitLineData
c609719b 1/*
6e592385 2 * (C) Copyright 2000-2004
c609719b
WD
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>
b028f715 60#if defined(CONFIG_8xx)
c609719b
WD
61#include <mpc8xx.h>
62#endif
63#if defined(CONFIG_LWMON)
64#include <i2c.h>
65#endif
db01a2ea
WD
66#ifdef CONFIG_PXA_PCMCIA
67#include <asm/arch/pxa-regs.h>
68#endif
c609719b 69
e2ffd59b
WD
70#include <asm/io.h>
71
c609719b
WD
72#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
73 ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
74
75int pcmcia_on (void);
76
77#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
78static int pcmcia_off (void);
66fd3d1c
WD
79#endif
80
81#ifdef CONFIG_I82365
82
83extern int i82365_init (void);
84extern void i82365_exit (void);
85
86#else /* ! CONFIG_I82365 */
87
88#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
c609719b
WD
89static int hardware_disable(int slot);
90#endif
91static int hardware_enable (int slot);
92static int voltage_set(int slot, int vcc, int vpp);
c609719b 93
db01a2ea 94#if (! defined(CONFIG_I82365)) && (! defined(CONFIG_PXA_PCMCIA))
c609719b 95static u_int m8xx_get_graycode(u_int size);
6e592385 96#endif /* !CONFIG_I82365, !CONFIG_PXA_PCMCIA */
c609719b
WD
97#if 0
98static u_int m8xx_get_speed(u_int ns, u_int is_io);
99#endif
100
1f53a416 101/* -------------------------------------------------------------------- */
c609719b 102
db01a2ea
WD
103#ifndef CONFIG_PXA_PCMCIA
104
c609719b
WD
105/* look up table for pgcrx registers */
106
107static u_int *pcmcia_pgcrx[2] = {
108 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
109 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
110};
c609719b
WD
111#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
112
6e592385
WD
113#endif /* CONFIG_PXA_PCMCIA */
114
66fd3d1c
WD
115#endif /* CONFIG_I82365 */
116
db01a2ea 117#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
66fd3d1c
WD
118static void print_funcid (int func);
119static void print_fixed (volatile uchar *p);
120static int identify (volatile uchar *p);
121static int check_ide_device (int slot);
6e592385 122#endif /* CONFIG_IDE_8xx_PCCARD, CONFIG_PXA_PCMCIA */
db01a2ea 123
c609719b
WD
124const char *indent = "\t ";
125
1f53a416 126/* -------------------------------------------------------------------- */
c609719b
WD
127
128#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
129
130int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
131{
132 int rcode = 0;
133
134 if (argc != 2) {
135 printf ("Usage: pinit {on | off}\n");
136 return 1;
137 }
138 if (strcmp(argv[1],"on") == 0) {
139 rcode = pcmcia_on ();
140 } else if (strcmp(argv[1],"off") == 0) {
141 rcode = pcmcia_off ();
142 } else {
143 printf ("Usage: pinit {on | off}\n");
144 return 1;
145 }
146
147 return rcode;
148}
149#endif /* CFG_CMD_PCMCIA */
150
1f53a416 151/* -------------------------------------------------------------------- */
c609719b 152
66fd3d1c
WD
153#ifdef CONFIG_I82365
154int pcmcia_on (void)
155{
156 u_int rc;
157
158 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
159
160 rc = i82365_init();
161
db01a2ea 162 if (rc == 0) {
66fd3d1c
WD
163 rc = check_ide_device(0);
164 }
165
166 return (rc);
167}
168#else
169
db01a2ea
WD
170#ifndef CONFIG_PXA_PCMCIA
171
c40b2956
WD
172#ifdef CONFIG_HMI10
173# define HMI10_FRAM_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(2) | PCMCIA_SL(4))
a6cccaea 174#endif
e7df029f 175#if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
c609719b
WD
176# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
177#else
178# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
179#endif
180
181int pcmcia_on (void)
182{
183 int i;
184 u_long reg, base;
185 pcmcia_win_t *win;
ea909b76
WD
186 u_int slotbit;
187 u_int rc, slot;
c609719b
WD
188
189 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
190
191 /* intialize the fixed memory windows */
192 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
193 base = CFG_PCMCIA_MEM_ADDR;
194
195 if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
196 printf ("Cannot set window size to 0x%08x\n",
197 CFG_PCMCIA_MEM_SIZE);
198 return (1);
199 }
200
ea909b76 201 slotbit = PCMCIA_SLOT_x;
c609719b
WD
202 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
203 win->br = base;
204
ea909b76
WD
205#if (PCMCIA_SOCKETS_NO == 2)
206 if (i == 4) /* Another slot starting from win 4 */
207 slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
208#endif
c609719b
WD
209 switch (i) {
210#ifdef CONFIG_IDE_8xx_PCCARD
ea909b76 211 case 4:
c40b2956 212#ifdef CONFIG_HMI10
a6cccaea
WD
213 { /* map FRAM area */
214 win->or = ( PCMCIA_BSIZE_256K
215 | PCMCIA_PPS_8
216 | PCMCIA_PRS_ATTR
217 | slotbit
218 | PCMCIA_PV
c40b2956 219 | HMI10_FRAM_TIMING );
a6cccaea
WD
220 break;
221 }
222#endif
c609719b
WD
223 case 0: { /* map attribute memory */
224 win->or = ( PCMCIA_BSIZE_64M
225 | PCMCIA_PPS_8
226 | PCMCIA_PRS_ATTR
ea909b76 227 | slotbit
c609719b
WD
228 | PCMCIA_PV
229 | CFG_PCMCIA_TIMING );
230 break;
231 }
ea909b76 232 case 5:
c609719b
WD
233 case 1: { /* map I/O window for data reg */
234 win->or = ( PCMCIA_BSIZE_1K
235 | PCMCIA_PPS_16
236 | PCMCIA_PRS_IO
ea909b76 237 | slotbit
c609719b
WD
238 | PCMCIA_PV
239 | CFG_PCMCIA_TIMING );
240 break;
241 }
ea909b76 242 case 6:
1f53a416 243 case 2: { /* map I/O window for cmd/ctrl reg block */
c609719b
WD
244 win->or = ( PCMCIA_BSIZE_1K
245 | PCMCIA_PPS_8
246 | PCMCIA_PRS_IO
ea909b76 247 | slotbit
c609719b
WD
248 | PCMCIA_PV
249 | CFG_PCMCIA_TIMING );
250 break;
251 }
252#endif /* CONFIG_IDE_8xx_PCCARD */
c40b2956 253#ifdef CONFIG_HMI10
7cb22f97 254 case 3: { /* map I/O window for 4xUART data/ctrl */
a522fa0e 255 win->br += 0x40000;
7cb22f97
WD
256 win->or = ( PCMCIA_BSIZE_256K
257 | PCMCIA_PPS_8
258 | PCMCIA_PRS_IO
259 | slotbit
260 | PCMCIA_PV
261 | CFG_PCMCIA_TIMING );
262 break;
263 }
c40b2956 264#endif /* CONFIG_HMI10 */
c609719b
WD
265 default: /* set to not valid */
266 win->or = 0;
267 break;
268 }
269
270 debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
271 i, win->br, win->or);
272 base += CFG_PCMCIA_MEM_SIZE;
273 ++win;
274 }
275
1f53a416 276 for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
ea909b76
WD
277 /* turn off voltage */
278 if ((rc = voltage_set(slot, 0, 0)))
279 continue;
1f53a416 280
ea909b76
WD
281 /* Enable external hardware */
282 if ((rc = hardware_enable(slot)))
283 continue;
1f53a416 284
c609719b 285#ifdef CONFIG_IDE_8xx_PCCARD
ea909b76
WD
286 if ((rc = check_ide_device(i)))
287 continue;
c609719b 288#endif
ea909b76
WD
289 }
290 return (rc);
c609719b 291}
db01a2ea 292
c26e454d 293#endif /* CONFIG_PXA_PCMCIA */
db01a2ea 294
66fd3d1c 295#endif /* CONFIG_I82365 */
c609719b 296
db01a2ea
WD
297#ifdef CONFIG_PXA_PCMCIA
298
299static int hardware_enable (int slot)
300{
301 return 0; /* No hardware to enable */
302}
303
304static int hardware_disable(int slot)
305{
306 return 0; /* No hardware to disable */
307}
308
309static int voltage_set(int slot, int vcc, int vpp)
310{
311 return 0;
312}
313
314void msWait(unsigned msVal)
315{
316 udelay(msVal*1000);
317}
318
319int pcmcia_on (void)
320{
321 unsigned int reg_arr[] = {
322 0x48000028, CFG_MCMEM0_VAL,
323 0x4800002c, CFG_MCMEM1_VAL,
324 0x48000030, CFG_MCATT0_VAL,
325 0x48000034, CFG_MCATT1_VAL,
326 0x48000038, CFG_MCIO0_VAL,
327 0x4800003c, CFG_MCIO1_VAL,
328
329 0, 0
330 };
331 int i, rc;
332
333#ifdef CONFIG_EXADRON1
334 int cardDetect;
335 volatile unsigned int *v_pBCRReg =
336 (volatile unsigned int *) 0x08000000;
337#endif
338
339 debug ("%s\n", __FUNCTION__);
340
341 i = 0;
342 while (reg_arr[i])
343 *((volatile unsigned int *) reg_arr[i++]) |= reg_arr[i++];
344 udelay (1000);
345
346 debug ("%s: programmed mem controller \n", __FUNCTION__);
347
348#ifdef CONFIG_EXADRON1
349
350/*define useful BCR masks */
351#define BCR_CF_INIT_VAL 0x00007230
352#define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL 0x00007231
353#define BCR_CF_PWRON_BUSOFF_RESETON_VAL 0x00007233
354#define BCR_CF_PWRON_BUSON_RESETON_VAL 0x00007213
355#define BCR_CF_PWRON_BUSON_RESETOFF_VAL 0x00007211
356
357 /* we see from the GPIO bit if the card is present */
358 cardDetect = !(GPLR0 & GPIO_bit (14));
359
360 if (cardDetect) {
361 printf ("No PCMCIA card found!\n");
362 }
363
364 /* reset the card via the BCR line */
365 *v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
366 msWait (500);
367
368 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
369 msWait (500);
370
371 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
372 msWait (500);
373
374 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
375 msWait (500);
376
377 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
378 msWait (1500);
379
380 /* enable address bus */
381 GPCR1 = 0x01;
382 /* and the first CF slot */
383 MECR = 0x00000002;
384
385#endif /* EXADRON 1 */
386
387 rc = check_ide_device (0); /* use just slot 0 */
388
389 return rc;
390}
391
392#endif /* CONFIG_PXA_PCMCIA */
393
1f53a416 394/* -------------------------------------------------------------------- */
c609719b
WD
395
396#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
397
66fd3d1c
WD
398#ifdef CONFIG_I82365
399static int pcmcia_off (void)
400{
401 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
402
403 i82365_exit();
404
405 return 0;
406}
407#else
db01a2ea
WD
408
409#ifndef CONFIG_PXA_PCMCIA
410
c609719b
WD
411static int pcmcia_off (void)
412{
413 int i;
414 pcmcia_win_t *win;
415
416 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
417
418 /* clear interrupt state, and disable interrupts */
419 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
420 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
421
422 /* turn off interrupt and disable CxOE */
423 PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
424
425 /* turn off memory windows */
426 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
427
428 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
429 /* disable memory window */
430 win->or = 0;
431 ++win;
432 }
433
434 /* turn off voltage */
435 voltage_set(_slot_, 0, 0);
436
437 /* disable external hardware */
438 printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
439 hardware_disable(_slot_);
440 return 0;
441}
db01a2ea
WD
442
443#endif /* CONFIG_PXA_PCMCIA */
444
66fd3d1c 445#endif /* CONFIG_I82365 */
c609719b 446
db01a2ea
WD
447#ifdef CONFIG_PXA_PCMCIA
448static int pcmcia_off (void)
449{
450 return 0;
451}
452#endif
453
c609719b
WD
454#endif /* CFG_CMD_PCMCIA */
455
1f53a416 456/* -------------------------------------------------------------------- */
c609719b 457
db01a2ea 458#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
c609719b
WD
459
460#define MAX_TUPEL_SZ 512
461#define MAX_FEATURES 4
462
6069ff26 463int ide_devices_found;
ea909b76 464static int check_ide_device (int slot)
c609719b
WD
465{
466 volatile uchar *ident = NULL;
467 volatile uchar *feature_p[MAX_FEATURES];
ea909b76 468 volatile uchar *p, *start, *addr;
c609719b
WD
469 int n_features = 0;
470 uchar func_id = ~0;
471 uchar code, len;
472 ushort config_base = 0;
473 int found = 0;
474 int i;
475
1f53a416
WD
476 addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
477 CFG_PCMCIA_MEM_SIZE * (slot * 4));
d0fb80c3 478 debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
c609719b 479
ea909b76 480 start = p = (volatile uchar *) addr;
c609719b
WD
481
482 while ((p - start) < MAX_TUPEL_SZ) {
483
484 code = *p; p += 2;
485
486 if (code == 0xFF) { /* End of chain */
487 break;
488 }
489
490 len = *p; p += 2;
491#if defined(DEBUG) && (DEBUG > 1)
492 { volatile uchar *q = p;
493 printf ("\nTuple code %02x length %d\n\tData:",
494 code, len);
495
496 for (i = 0; i < len; ++i) {
497 printf (" %02x", *q);
498 q+= 2;
499 }
500 }
501#endif /* DEBUG */
502 switch (code) {
503 case CISTPL_VERS_1:
504 ident = p + 4;
505 break;
506 case CISTPL_FUNCID:
507 /* Fix for broken SanDisk which may have 0x80 bit set */
508 func_id = *p & 0x7F;
509 break;
510 case CISTPL_FUNCE:
511 if (n_features < MAX_FEATURES)
512 feature_p[n_features++] = p;
513 break;
514 case CISTPL_CONFIG:
515 config_base = (*(p+6) << 8) + (*(p+4));
516 debug ("\n## Config_base = %04x ###\n", config_base);
517 default:
518 break;
519 }
520 p += 2 * len;
521 }
522
523 found = identify (ident);
524
525 if (func_id != ((uchar)~0)) {
526 print_funcid (func_id);
527
528 if (func_id == CISTPL_FUNCID_FIXED)
529 found = 1;
530 else
531 return (1); /* no disk drive */
532 }
533
534 for (i=0; i<n_features; ++i) {
535 print_fixed (feature_p[i]);
536 }
537
538 if (!found) {
539 printf ("unknown card type\n");
540 return (1);
541 }
542
6069ff26
WD
543 ide_devices_found |= (1 << slot);
544
e2ffd59b
WD
545#if CONFIG_CPC45
546#else
c609719b 547 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
ea909b76 548 *((uchar *)(addr + config_base)) = 1;
e2ffd59b
WD
549#endif
550#if 0
551 printf("\n## Config_base = %04x ###\n", config_base);
552 printf("Configuration Option Register: %02x @ %x\n", readb(addr + config_base), addr + config_base);
553 printf("Card Configuration and Status Register: %02x\n", readb(addr + config_base + 2));
554 printf("Pin Replacement Register Register: %02x\n", readb(addr + config_base + 4));
555 printf("Socket and Copy Register: %02x\n", readb(addr + config_base + 6));
556#endif
c609719b
WD
557 return (0);
558}
559#endif /* CONFIG_IDE_8xx_PCCARD */
560
1f53a416 561/* -------------------------------------------------------------------- */
c609719b
WD
562
563
1f53a416
WD
564/* -------------------------------------------------------------------- */
565/* board specific stuff: */
566/* voltage_set(), hardware_enable() and hardware_disable() */
567/* -------------------------------------------------------------------- */
c609719b 568
1f53a416
WD
569/* -------------------------------------------------------------------- */
570/* RPX Boards from Embedded Planet */
571/* -------------------------------------------------------------------- */
c609719b
WD
572
573#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
574
575/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
576 * SYPCR is write once only, therefore must the slowest memory be faster
577 * than the bus monitor or we will get a machine check due to the bus timeout.
578 */
579
580#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
581
582#undef PCMCIA_BMT_LIMIT
583#define PCMCIA_BMT_LIMIT (6*8)
584
585static int voltage_set(int slot, int vcc, int vpp)
586{
587 u_long reg = 0;
588
589 switch(vcc) {
590 case 0: break;
591 case 33: reg |= BCSR1_PCVCTL4; break;
592 case 50: reg |= BCSR1_PCVCTL5; break;
593 default: return 1;
594 }
595
596 switch(vpp) {
597 case 0: break;
598 case 33:
599 case 50:
600 if(vcc == vpp)
601 reg |= BCSR1_PCVCTL6;
602 else
603 return 1;
604 break;
605 case 120:
606 reg |= BCSR1_PCVCTL7;
607 default: return 1;
608 }
609
610 if(vcc == 120)
611 return 1;
612
613 /* first, turn off all power */
614
615 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
616 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
617
618 /* enable new powersettings */
619
620 *((uint *)RPX_CSR_ADDR) |= reg;
621
622 return 0;
623}
624
625#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
626static int hardware_enable (int slot)
627{
628 return 0; /* No hardware to enable */
629}
630#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
631static int hardware_disable(int slot)
632{
633 return 0; /* No hardware to disable */
634}
635#endif /* CFG_CMD_PCMCIA */
636#endif /* CONFIG_RPXCLASSIC */
637
1f53a416
WD
638/* -------------------------------------------------------------------- */
639/* (F)ADS Boards from Motorola */
640/* -------------------------------------------------------------------- */
c609719b
WD
641
642#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
643
644#ifdef CONFIG_ADS
645#define PCMCIA_BOARD_MSG "ADS"
646#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
647#else
648#define PCMCIA_BOARD_MSG "FADS"
649#endif
650
651static int voltage_set(int slot, int vcc, int vpp)
652{
653 u_long reg = 0;
654
655 switch(vpp) {
656 case 0: reg = 0; break;
657 case 50: reg = 1; break;
658 case 120: reg = 2; break;
659 default: return 1;
660 }
661
662 switch(vcc) {
663 case 0: reg = 0; break;
664#ifdef CONFIG_ADS
665 case 50: reg = BCSR1_PCCVCCON; break;
666#endif
667#ifdef CONFIG_FADS
668 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
669 case 50: reg = BCSR1_PCCVCC1; break;
670#endif
671 default: return 1;
672 }
673
674 /* first, turn off all power */
675
676#ifdef CONFIG_ADS
677 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
678#endif
679#ifdef CONFIG_FADS
680 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
681#endif
682 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
683
684 /* enable new powersettings */
685
686#ifdef CONFIG_ADS
687 *((uint *)BCSR1) &= ~reg;
688#endif
689#ifdef CONFIG_FADS
690 *((uint *)BCSR1) |= reg;
691#endif
692
693 *((uint *)BCSR1) |= reg << 20;
694
695 return 0;
696}
697
698#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
699
700static int hardware_enable(int slot)
701{
702 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
703 return 0;
704}
705
706#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
707static int hardware_disable(int slot)
708{
709 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
710 return 0;
711}
712#endif /* CFG_CMD_PCMCIA */
713
714#endif /* (F)ADS */
715
1f53a416
WD
716/* -------------------------------------------------------------------- */
717/* TQM8xxL Boards by TQ Components */
dc7c9a1a 718/* SC8xx Boards by SinoVee Microsystems */
1f53a416 719/* -------------------------------------------------------------------- */
c609719b 720
dc7c9a1a 721#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
c609719b 722
dc7c9a1a 723#if defined(CONFIG_TQM8xxL)
c609719b 724#define PCMCIA_BOARD_MSG "TQM8xxL"
dc7c9a1a
WD
725#endif
726#if defined(CONFIG_SVM_SC8xx)
727#define PCMCIA_BOARD_MSG "SC8xx"
728#endif
c609719b
WD
729
730static int hardware_enable(int slot)
731{
732 volatile immap_t *immap;
733 volatile cpm8xx_t *cp;
734 volatile pcmconf8xx_t *pcmp;
735 volatile sysconf8xx_t *sysp;
736 uint reg, mask;
737
738 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
739
740 udelay(10000);
741
742 immap = (immap_t *)CFG_IMMR;
743 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
744 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
745 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
746
747 /*
748 * Configure SIUMCR to enable PCMCIA port B
749 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
750 */
751 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
752
753 /* clear interrupt state, and disable interrupts */
e7df029f 754 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
755 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
c609719b 756
c609719b 757 /*
1f53a416
WD
758 * Disable interrupts, DMA, and PCMCIA buffers
759 * (isolate the interface) and assert RESET signal
c609719b
WD
760 */
761 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
762 reg = 0;
763 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
e7df029f 764#ifndef NSCU_OE_INV
1f53a416 765 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
e7df029f 766#endif
767 PCMCIA_PGCRX(slot) = reg;
c609719b
WD
768 udelay(500);
769
c40b2956 770#ifndef CONFIG_HMI10
e7df029f 771#ifndef CONFIG_NSCU
c609719b
WD
772 /*
773 * Configure Port C pins for
774 * 5 Volts Enable and 3 Volts enable
775 */
776 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
777 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
778 /* remove all power */
779
780 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
e7df029f 781#endif
c40b2956 782#else /* CONFIG_HMI10 */
a522fa0e
WD
783 /*
784 * Configure Port B pins for
785 * 5 Volts Enable and 3 Volts enable
786 */
787 immap->im_cpm.cp_pbpar &= ~(0x00000300);
788
789 /* remove all power */
790 immap->im_cpm.cp_pbdat |= 0x00000300;
c40b2956 791#endif /* CONFIG_HMI10 */
c609719b
WD
792
793 /*
794 * Make sure there is a card in the slot, then configure the interface.
795 */
796 udelay(10000);
797 debug ("[%d] %s: PIPR(%p)=0x%x\n",
798 __LINE__,__FUNCTION__,
799 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
c40b2956 800#ifndef CONFIG_HMI10
ea909b76 801 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
a522fa0e
WD
802#else
803 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
c40b2956 804#endif /* CONFIG_HMI10 */
c609719b
WD
805 printf (" No Card found\n");
806 return (1);
807 }
808
809 /*
810 * Power On.
811 */
812 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
813 reg = pcmp->pcmc_pipr;
814 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
815 reg,
816 (reg&PCMCIA_VS1(slot))?"n":"ff",
817 (reg&PCMCIA_VS2(slot))?"n":"ff");
e7df029f 818#ifndef CONFIG_NSCU
c609719b 819 if ((reg & mask) == mask) {
c40b2956 820#ifndef CONFIG_HMI10
c609719b 821 immap->im_ioport.iop_pcdat |= 0x0004;
a522fa0e
WD
822#else
823 immap->im_cpm.cp_pbdat &= ~(0x0000100);
c40b2956 824#endif /* CONFIG_HMI10 */
c609719b
WD
825 puts (" 5.0V card found: ");
826 } else {
c40b2956 827#ifndef CONFIG_HMI10
c609719b 828 immap->im_ioport.iop_pcdat |= 0x0002;
a522fa0e
WD
829#else
830 immap->im_cpm.cp_pbdat &= ~(0x0000200);
c40b2956 831#endif /* CONFIG_HMI10 */
c609719b
WD
832 puts (" 3.3V card found: ");
833 }
c40b2956 834#ifndef CONFIG_HMI10
1f53a416 835 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
a522fa0e
WD
836#else
837 immap->im_cpm.cp_pbdir |= 0x00000300;
c40b2956 838#endif /* CONFIG_HMI10 */
e7df029f 839#else
840 if ((reg & mask) == mask) {
841 puts (" 5.0V card found: ");
842 } else {
843 puts (" 3.3V card found: ");
844 }
845#endif
c609719b
WD
846#if 0
847 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
848 cp->cp_pbdir &= ~(0x0020 | 0x0010);
849 cp->cp_pbpar &= ~(0x0020 | 0x0010);
850 udelay(500000);
851#endif
852 udelay(1000);
853 debug ("Enable PCMCIA buffers and stop RESET\n");
e7df029f 854 reg = PCMCIA_PGCRX(slot);
c609719b 855 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
e7df029f 856#ifndef NSCU_OE_INV
c609719b 857 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
e7df029f 858#else
859 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
860#endif
861 PCMCIA_PGCRX(slot) = reg;
c609719b
WD
862
863 udelay(250000); /* some cards need >150 ms to come up :-( */
864
865 debug ("# hardware_enable done\n");
866
867 return (0);
868}
869
870
c609719b
WD
871#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
872static int hardware_disable(int slot)
873{
874 volatile immap_t *immap;
875 volatile pcmconf8xx_t *pcmp;
876 u_long reg;
877
878 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
879
880 immap = (immap_t *)CFG_IMMR;
881 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
882
c40b2956 883#ifndef CONFIG_HMI10
e7df029f 884#ifndef CONFIG_NSCU
c609719b
WD
885 /* remove all power */
886 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
e7df029f 887#endif
c40b2956 888#else /* CONFIG_HMI10 */
a522fa0e 889 immap->im_cpm.cp_pbdat |= 0x00000300;
c40b2956 890#endif /* CONFIG_HMI10 */
c609719b 891
c609719b 892 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416 893 reg = 0;
c609719b 894 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
e7df029f 895#ifndef NSCU_OE_INV
c609719b 896 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
e7df029f 897#endif
898 PCMCIA_PGCRX(slot) = reg;
c609719b
WD
899
900 udelay(10000);
901
902 return (0);
903}
904#endif /* CFG_CMD_PCMCIA */
905
e7df029f 906#ifdef CONFIG_NSCU
907static int voltage_set(int slot, int vcc, int vpp)
908{
909 return 0;
910}
911#else
c609719b
WD
912static int voltage_set(int slot, int vcc, int vpp)
913{
914 volatile immap_t *immap;
915 volatile pcmconf8xx_t *pcmp;
916 u_long reg;
917
918 debug ("voltage_set: "
919 PCMCIA_BOARD_MSG
920 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
921 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
922
923 immap = (immap_t *)CFG_IMMR;
924 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
925 /*
926 * Disable PCMCIA buffers (isolate the interface)
927 * and assert RESET signal
928 */
929 debug ("Disable PCMCIA buffers and assert RESET\n");
e7df029f 930 reg = PCMCIA_PGCRX(slot);
1f53a416 931 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
e7df029f 932#ifndef NSCU_OE_INV
1f53a416 933 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
e7df029f 934#else
935 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
936#endif
937 PCMCIA_PGCRX(slot) = reg;
c609719b
WD
938 udelay(500);
939
c40b2956 940#ifndef CONFIG_HMI10
c609719b
WD
941 /*
942 * Configure Port C pins for
943 * 5 Volts Enable and 3 Volts enable,
944 * Turn off all power
945 */
946 debug ("PCMCIA power OFF\n");
947 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
948 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
949 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
950
951 reg = 0;
952 switch(vcc) {
953 case 0: break;
954 case 33: reg |= 0x0002; break;
955 case 50: reg |= 0x0004; break;
956 default: goto done;
957 }
c40b2956 958#else /* CONFIG_HMI10 */
a522fa0e
WD
959 /*
960 * Configure Port B pins for
961 * 5 Volts Enable and 3 Volts enable,
962 * Turn off all power
963 */
964 debug ("PCMCIA power OFF\n");
965 immap->im_cpm.cp_pbpar &= ~(0x00000300);
966 /* remove all power */
967
968 immap->im_cpm.cp_pbdat |= 0x00000300;
969
970 reg = 0;
971 switch(vcc) {
972 case 0: break;
973 case 33: reg |= 0x00000200; break;
974 case 50: reg |= 0x00000100; break;
975 default: goto done;
976}
c40b2956 977#endif /* CONFIG_HMI10 */
c609719b
WD
978
979 /* Checking supported voltages */
980
981 debug ("PIPR: 0x%x --> %s\n",
982 pcmp->pcmc_pipr,
983 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
984
c40b2956 985#ifndef CONFIG_HMI10
c609719b 986 immap->im_ioport.iop_pcdat |= reg;
1f53a416 987 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
a522fa0e
WD
988#else
989 immap->im_cpm.cp_pbdat &= !reg;
990 immap->im_cpm.cp_pbdir |= 0x00000300;
c40b2956 991#endif /* CONFIG_HMI10 */
c609719b 992 if (reg) {
c40b2956 993#ifndef CONFIG_HMI10
c609719b
WD
994 debug ("PCMCIA powered at %sV\n",
995 (reg&0x0004) ? "5.0" : "3.3");
a522fa0e
WD
996#else
997 debug ("PCMCIA powered at %sV\n",
998 (reg&0x00000200) ? "5.0" : "3.3");
c40b2956 999#endif /* CONFIG_HMI10 */
c609719b
WD
1000 } else {
1001 debug ("PCMCIA powered down\n");
1002 }
1003
1004done:
1005 debug ("Enable PCMCIA buffers and stop RESET\n");
e7df029f 1006 reg = PCMCIA_PGCRX(slot);
c609719b 1007 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
e7df029f 1008#ifndef NSCU_OE_INV
c609719b 1009 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
e7df029f 1010#else
1011 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1012#endif
1013 PCMCIA_PGCRX(slot) = reg;
c609719b
WD
1014 udelay(500);
1015
1016 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1017 slot+'A');
1018 return (0);
1019}
e7df029f 1020#endif
c609719b
WD
1021
1022#endif /* TQM8xxL */
1023
1024
1f53a416
WD
1025/* -------------------------------------------------------------------- */
1026/* LWMON Board */
1027/* -------------------------------------------------------------------- */
c609719b
WD
1028
1029#if defined(CONFIG_LWMON)
1030
1031#define PCMCIA_BOARD_MSG "LWMON"
1032
1033/* #define's for MAX1604 Power Switch */
1034#define MAX1604_OP_SUS 0x80
1035#define MAX1604_VCCBON 0x40
1036#define MAX1604_VCC_35 0x20
1037#define MAX1604_VCCBHIZ 0x10
1038#define MAX1604_VPPBON 0x08
1039#define MAX1604_VPPBPBPGM 0x04
1040#define MAX1604_VPPBHIZ 0x02
1041/* reserved 0x01 */
1042
1043static int hardware_enable(int slot)
1044{
1045 volatile immap_t *immap;
1046 volatile cpm8xx_t *cp;
1047 volatile pcmconf8xx_t *pcmp;
1048 volatile sysconf8xx_t *sysp;
1049 uint reg, mask;
1050 uchar val;
1051
1052
1053 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1054
1055 /* Switch on PCMCIA port in PIC register 0x60 */
1056 reg = pic_read (0x60);
1057 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1058 reg &= ~0x10;
1f53a416 1059 /* reg |= 0x08; Vpp not needed */
c609719b
WD
1060 pic_write (0x60, reg);
1061#ifdef DEBUG
1062 reg = pic_read (0x60);
1063 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1064#endif
1065 udelay(10000);
1066
1067 immap = (immap_t *)CFG_IMMR;
1068 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1069 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1070 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1071
1072 /*
1073 * Configure SIUMCR to enable PCMCIA port B
1074 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1075 */
1076 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1077
1078 /* clear interrupt state, and disable interrupts */
1079 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1080 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1081
c609719b 1082 /*
1f53a416
WD
1083 * Disable interrupts, DMA, and PCMCIA buffers
1084 * (isolate the interface) and assert RESET signal
c609719b
WD
1085 */
1086 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
1087 reg = 0;
1088 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1089 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
c609719b
WD
1090 PCMCIA_PGCRX(_slot_) = reg;
1091 udelay(500);
1092
1093 /*
1094 * Make sure there is a card in the slot, then configure the interface.
1095 */
1096 udelay(10000);
1097 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1098 __LINE__,__FUNCTION__,
1099 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
ea909b76 1100 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
c609719b
WD
1101 printf (" No Card found\n");
1102 return (1);
1103 }
1104
1105 /*
1106 * Power On.
1107 */
1108 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1109 reg = pcmp->pcmc_pipr;
1110 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1111 reg,
1112 (reg&PCMCIA_VS1(slot))?"n":"ff",
1113 (reg&PCMCIA_VS2(slot))?"n":"ff");
1114 if ((reg & mask) == mask) {
1115 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
1116 puts (" 5.0V card found: ");
1117 } else {
1118 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
1119 puts (" 3.3V card found: ");
1120 }
1121
1122 /* switch VCC on */
1f53a416 1123 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
c609719b
WD
1124 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1125 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1126
1127 udelay(500000);
1128
1129 debug ("Enable PCMCIA buffers and stop RESET\n");
1130 reg = PCMCIA_PGCRX(_slot_);
1131 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1132 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1133 PCMCIA_PGCRX(_slot_) = reg;
1134
1135 udelay(250000); /* some cards need >150 ms to come up :-( */
1136
1137 debug ("# hardware_enable done\n");
1138
1139 return (0);
1140}
1141
1142
c609719b
WD
1143#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1144static int hardware_disable(int slot)
1145{
1146 volatile immap_t *immap;
1147 volatile pcmconf8xx_t *pcmp;
1148 u_long reg;
1149 uchar val;
1150
1151 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1152
1153 immap = (immap_t *)CFG_IMMR;
1154 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1155
1156 /* remove all power, put output in high impedance state */
1157 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1158 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1159 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1160
1161 /* Configure PCMCIA General Control Register */
c609719b 1162 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416 1163 reg = 0;
c609719b
WD
1164 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1165 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1166 PCMCIA_PGCRX(_slot_) = reg;
1167
1168 /* Switch off PCMCIA port in PIC register 0x60 */
1169 reg = pic_read (0x60);
1170 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1171 reg |= 0x10;
1172 reg &= ~0x08;
1173 pic_write (0x60, reg);
1174#ifdef DEBUG
1175 reg = pic_read (0x60);
1176 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1177#endif
1178 udelay(10000);
1179
1180 return (0);
1181}
1182#endif /* CFG_CMD_PCMCIA */
1183
1184
c609719b
WD
1185static int voltage_set(int slot, int vcc, int vpp)
1186{
1187 volatile immap_t *immap;
1188 volatile pcmconf8xx_t *pcmp;
1189 u_long reg;
1190 uchar val;
1191
1192 debug ("voltage_set: "
1193 PCMCIA_BOARD_MSG
1194 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1195 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1196
1197 immap = (immap_t *)CFG_IMMR;
1198 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1199 /*
1200 * Disable PCMCIA buffers (isolate the interface)
1201 * and assert RESET signal
1202 */
1203 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
1204 reg = PCMCIA_PGCRX(_slot_);
1205 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1206 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
c609719b
WD
1207 PCMCIA_PGCRX(_slot_) = reg;
1208 udelay(500);
1209
1210 /*
1211 * Turn off all power (switch to high impedance)
1212 */
1213 debug ("PCMCIA power OFF\n");
1214 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1215 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1216 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1217
1218 val = 0;
1219 switch(vcc) {
1220 case 0: break;
1221 case 33: val = MAX1604_VCC_35; break;
1222 case 50: break;
1223 default: goto done;
1224 }
1225
1226 /* Checking supported voltages */
1227
1228 debug ("PIPR: 0x%x --> %s\n",
1229 pcmp->pcmc_pipr,
1230 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1231
1232 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1233 if (val) {
1234 debug ("PCMCIA powered at %sV\n",
1235 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1236 } else {
1237 debug ("PCMCIA powered down\n");
1238 }
1239
1240done:
1241 debug ("Enable PCMCIA buffers and stop RESET\n");
1242 reg = PCMCIA_PGCRX(_slot_);
1243 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1244 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1245 PCMCIA_PGCRX(_slot_) = reg;
1246 udelay(500);
1247
1248 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1249 slot+'A');
1250 return (0);
1251}
1252
1253#endif /* LWMON */
1254
1f53a416
WD
1255/* -------------------------------------------------------------------- */
1256/* GTH board by Corelatus AB */
1257/* -------------------------------------------------------------------- */
c609719b
WD
1258#if defined(CONFIG_GTH)
1259
1260#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1261
1f53a416
WD
1262static int voltage_set (int slot, int vcc, int vpp)
1263{ /* Do nothing */
1264 return 0;
c609719b
WD
1265}
1266
1267static int hardware_enable (int slot)
1268{
1f53a416
WD
1269 volatile immap_t *immap;
1270 volatile cpm8xx_t *cp;
1271 volatile pcmconf8xx_t *pcmp;
1272 volatile sysconf8xx_t *sysp;
1273 uint reg, mask;
c609719b 1274
1f53a416 1275 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
c609719b 1276
1f53a416
WD
1277 immap = (immap_t *) CFG_IMMR;
1278 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1279 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1280 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
c609719b 1281
1f53a416
WD
1282 /* clear interrupt state, and disable interrupts */
1283 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1284 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
c609719b 1285
1f53a416
WD
1286 /*
1287 * Disable interrupts, DMA, and PCMCIA buffers
1288 * (isolate the interface) and assert RESET signal
1289 */
1290 debug ("Disable PCMCIA buffers and assert RESET\n");
1291 reg = 0;
1292 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1293 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1294 PCMCIA_PGCRX (_slot_) = reg;
1295 udelay (500);
1296
1297 /*
1298 * Make sure there is a card in the slot,
1299 * then configure the interface.
1300 */
1301 udelay (10000);
1302 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1303 __LINE__, __FUNCTION__,
1304 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1305 if (pcmp->pcmc_pipr & 0x98000000) {
1306 printf (" No Card found\n");
1307 return (1);
1308 }
1309
1310 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1311 reg = pcmp->pcmc_pipr;
1312 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1313 reg,
1314 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1315 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1316
1317 debug ("Enable PCMCIA buffers and stop RESET\n");
1318 reg = PCMCIA_PGCRX (_slot_);
1319 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1320 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1321 PCMCIA_PGCRX (_slot_) = reg;
1322
1323 udelay (250000); /* some cards need >150 ms to come up :-( */
1324
1325 debug ("# hardware_enable done\n");
1326
1327 return 0;
c609719b
WD
1328}
1329#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1330static int hardware_disable(int slot)
1331{
1332 return 0; /* No hardware to disable */
1333}
1334#endif /* CFG_CMD_PCMCIA */
1335#endif /* CONFIG_GTH */
1336
1f53a416
WD
1337/* -------------------------------------------------------------------- */
1338/* ICU862 Boards by Cambridge Broadband Ltd. */
1339/* -------------------------------------------------------------------- */
c609719b
WD
1340
1341#if defined(CONFIG_ICU862)
1342
1343#define PCMCIA_BOARD_MSG "ICU862"
1344
1345static void cfg_port_B (void);
1346
1347static int hardware_enable(int slot)
1348{
1349 volatile immap_t *immap;
1350 volatile cpm8xx_t *cp;
1351 volatile pcmconf8xx_t *pcmp;
1352 volatile sysconf8xx_t *sysp;
1353 uint reg, pipr, mask;
1354 int i;
1355
1356 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1357
1358 udelay(10000);
1359
1360 immap = (immap_t *)CFG_IMMR;
1361 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1362 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1363 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1364
1365 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1366 cfg_port_B ();
1367
1368 /*
1369 * Configure SIUMCR to enable PCMCIA port B
1370 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1371 */
1372 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1373
1374 /* clear interrupt state, and disable interrupts */
1375 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1376 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1377
c609719b 1378 /*
1f53a416
WD
1379 * Disable interrupts, DMA, and PCMCIA buffers
1380 * (isolate the interface) and assert RESET signal
c609719b
WD
1381 */
1382 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
1383 reg = 0;
1384 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1385 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
c609719b
WD
1386 PCMCIA_PGCRX(_slot_) = reg;
1387 udelay(500);
1388
1389 /*
1390 * Make sure there is a card in the slot, then configure the interface.
1391 */
1392 udelay(10000);
1393 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1394 __LINE__,__FUNCTION__,
1395 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
ea909b76 1396 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
c609719b
WD
1397 printf (" No Card found\n");
1398 return (1);
1399 }
1400
1401 /*
1402 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1403 */
1404 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1405 pipr = pcmp->pcmc_pipr;
1406 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1407 pipr,
1408 (reg&PCMCIA_VS1(slot))?"n":"ff",
1409 (reg&PCMCIA_VS2(slot))?"n":"ff");
1410
1411 reg = cp->cp_pbdat;
1412 if ((pipr & mask) == mask) {
1f53a416
WD
1413 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1414 TPS2205_VCC3); /* 3V off */
c609719b
WD
1415 reg &= ~(TPS2205_VCC5); /* 5V on */
1416 puts (" 5.0V card found: ");
1417 } else {
1f53a416
WD
1418 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1419 TPS2205_VCC5); /* 5V off */
c609719b
WD
1420 reg &= ~(TPS2205_VCC3); /* 3V on */
1421 puts (" 3.3V card found: ");
1422 }
1423
1424 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1425 reg,
1426 (reg & TPS2205_VCC3) ? "off" : "on",
1427 (reg & TPS2205_VCC5) ? "off" : "on",
1428 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1429 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1430
1431 cp->cp_pbdat = reg;
1432
1433 /* Wait 500 ms; use this to check for over-current */
1434 for (i=0; i<5000; ++i) {
1435 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1436 printf (" *** Overcurrent - Safety shutdown ***\n");
1437 cp->cp_pbdat &= ~(TPS2205_SHDN);
1438 return (1);
1439 }
1440 udelay (100);
1441 }
1442
1443 debug ("Enable PCMCIA buffers and stop RESET\n");
1444 reg = PCMCIA_PGCRX(_slot_);
1445 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1446 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1447 PCMCIA_PGCRX(_slot_) = reg;
1448
1449 udelay(250000); /* some cards need >150 ms to come up :-( */
1450
1451 debug ("# hardware_enable done\n");
1452
1453 return (0);
1454}
1455
1456
c609719b
WD
1457#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1458static int hardware_disable(int slot)
1459{
1460 volatile immap_t *immap;
1461 volatile cpm8xx_t *cp;
1462 volatile pcmconf8xx_t *pcmp;
1463 u_long reg;
1464
1465 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1466
1467 immap = (immap_t *)CFG_IMMR;
1468 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1469 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1470
1471 /* Shut down */
1472 cp->cp_pbdat &= ~(TPS2205_SHDN);
1473
1474 /* Configure PCMCIA General Control Register */
c609719b 1475 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416 1476 reg = 0;
c609719b
WD
1477 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1478 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1479 PCMCIA_PGCRX(_slot_) = reg;
1480
1481 udelay(10000);
1482
1483 return (0);
1484}
1485#endif /* CFG_CMD_PCMCIA */
1486
1487
c609719b
WD
1488static int voltage_set(int slot, int vcc, int vpp)
1489{
1490 volatile immap_t *immap;
1491 volatile cpm8xx_t *cp;
1492 volatile pcmconf8xx_t *pcmp;
1493 u_long reg;
1494
1495 debug ("voltage_set: "
1496 PCMCIA_BOARD_MSG
1497 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1498 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1499
1500 immap = (immap_t *)CFG_IMMR;
1501 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1502 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1503 /*
1504 * Disable PCMCIA buffers (isolate the interface)
1505 * and assert RESET signal
1506 */
1507 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
1508 reg = PCMCIA_PGCRX(_slot_);
1509 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1510 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
c609719b
WD
1511 PCMCIA_PGCRX(_slot_) = reg;
1512 udelay(500);
1513
1514 /*
1515 * Configure Port C pins for
1516 * 5 Volts Enable and 3 Volts enable,
1517 * Turn all power pins to Hi-Z
1518 */
1519 debug ("PCMCIA power OFF\n");
1520 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1521
1522 reg = cp->cp_pbdat;
1523
1524 switch(vcc) {
1525 case 0: break; /* Switch off */
1526 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1527 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1528 default: goto done;
1529 }
1530
1531 /* Checking supported voltages */
1532
1533 debug ("PIPR: 0x%x --> %s\n",
1534 pcmp->pcmc_pipr,
1535 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1536
1537 cp->cp_pbdat = reg;
1538
1539#ifdef DEBUG
1540 {
1541 char *s;
1542
1543 if ((reg & TPS2205_VCC3) == 0) {
1544 s = "at 3.3V";
1545 } else if ((reg & TPS2205_VCC5) == 0) {
1546 s = "at 5.0V";
1547 } else {
1548 s = "down";
1549 }
1550 printf ("PCMCIA powered %s\n", s);
1551 }
1552#endif
1553
1554done:
1555 debug ("Enable PCMCIA buffers and stop RESET\n");
1556 reg = PCMCIA_PGCRX(_slot_);
1557 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1558 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1559 PCMCIA_PGCRX(_slot_) = reg;
1560 udelay(500);
1561
1562 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1563 slot+'A');
1564 return (0);
1565}
1566
1567static void cfg_port_B (void)
1568{
1569 volatile immap_t *immap;
1570 volatile cpm8xx_t *cp;
1571 uint reg;
1572
1573 immap = (immap_t *)CFG_IMMR;
1574 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1575
1576 /*
1577 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1578 *
1579 * Switch off all voltages, assert shutdown
1580 */
1581 reg = cp->cp_pbdat;
1f53a416
WD
1582 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1583 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1584 TPS2205_SHDN); /* enable switch */
c609719b
WD
1585 cp->cp_pbdat = reg;
1586
1587 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1588
1589 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1590 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1591
1592 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1593 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1594}
1595
1596#endif /* ICU862 */
1597
1598
1f53a416
WD
1599/* -------------------------------------------------------------------- */
1600/* C2MON Boards by TTTech Computertechnik AG */
1601/* -------------------------------------------------------------------- */
c609719b
WD
1602
1603#if defined(CONFIG_C2MON)
1604
1605#define PCMCIA_BOARD_MSG "C2MON"
1606
1607static void cfg_ports (void);
1608
1609static int hardware_enable(int slot)
1610{
1611 volatile immap_t *immap;
1612 volatile cpm8xx_t *cp;
1613 volatile pcmconf8xx_t *pcmp;
1614 volatile sysconf8xx_t *sysp;
1615 uint reg, pipr, mask;
1616 ushort sreg;
1617 int i;
1618
1619 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1620
1621 udelay(10000);
1622
1623 immap = (immap_t *)CFG_IMMR;
1624 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1625 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1626 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1627
1628 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1629 cfg_ports ();
1630
1631 /*
1632 * Configure SIUMCR to enable PCMCIA port B
1633 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1634 */
1635 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1636
1637 /* clear interrupt state, and disable interrupts */
1638 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1639 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1640
c609719b 1641 /*
1f53a416
WD
1642 * Disable interrupts, DMA, and PCMCIA buffers
1643 * (isolate the interface) and assert RESET signal
c609719b
WD
1644 */
1645 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
1646 reg = 0;
1647 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1648 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
c609719b
WD
1649 PCMCIA_PGCRX(_slot_) = reg;
1650 udelay(500);
1651
1652 /*
1653 * Make sure there is a card in the slot, then configure the interface.
1654 */
1655 udelay(10000);
1656 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1657 __LINE__,__FUNCTION__,
1658 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
ea909b76 1659 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
c609719b
WD
1660 printf (" No Card found\n");
1661 return (1);
1662 }
1663
1664 /*
1665 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1666 */
1667 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1668 pipr = pcmp->pcmc_pipr;
1669 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1670 pipr,
1671 (reg&PCMCIA_VS1(slot))?"n":"ff",
1672 (reg&PCMCIA_VS2(slot))?"n":"ff");
1673
1674 sreg = immap->im_ioport.iop_pcdat;
1675 if ((pipr & mask) == mask) {
1676 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1677 TPS2211_VCCD1); /* 5V on */
1678 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1679 puts (" 5.0V card found: ");
1680 } else {
1681 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1682 TPS2211_VCCD0); /* 3V on */
1683 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1684 puts (" 3.3V card found: ");
1685 }
1686
1687 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1688 sreg,
1689 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1690 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1691 );
1692
1693 immap->im_ioport.iop_pcdat = sreg;
1694
1695 /* Wait 500 ms; use this to check for over-current */
1696 for (i=0; i<5000; ++i) {
1697 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1698 printf (" *** Overcurrent - Safety shutdown ***\n");
1699 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1700 return (1);
1701 }
1702 udelay (100);
1703 }
1704
1705 debug ("Enable PCMCIA buffers and stop RESET\n");
1706 reg = PCMCIA_PGCRX(_slot_);
1707 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1708 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1709 PCMCIA_PGCRX(_slot_) = reg;
1710
1711 udelay(250000); /* some cards need >150 ms to come up :-( */
1712
1713 debug ("# hardware_enable done\n");
1714
1715 return (0);
1716}
1717
1718
c609719b
WD
1719#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1720static int hardware_disable(int slot)
1721{
1722 volatile immap_t *immap;
1723 volatile cpm8xx_t *cp;
1724 volatile pcmconf8xx_t *pcmp;
1725 u_long reg;
1726
1727 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1728
1729 immap = (immap_t *)CFG_IMMR;
1730 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1731
1732 /* Configure PCMCIA General Control Register */
c609719b 1733 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416 1734 reg = 0;
c609719b
WD
1735 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1736 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1737 PCMCIA_PGCRX(_slot_) = reg;
1738
1739 /* ALl voltages off / Hi-Z */
1740 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1741 TPS2211_VCCD0 | TPS2211_VCCD1 );
1742
1743 udelay(10000);
1744
1745 return (0);
1746}
1747#endif /* CFG_CMD_PCMCIA */
1748
1749
c609719b
WD
1750static int voltage_set(int slot, int vcc, int vpp)
1751{
1752 volatile immap_t *immap;
1753 volatile cpm8xx_t *cp;
1754 volatile pcmconf8xx_t *pcmp;
1755 u_long reg;
1756 ushort sreg;
1757
1758 debug ("voltage_set: "
1759 PCMCIA_BOARD_MSG
1760 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1761 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1762
1763 immap = (immap_t *)CFG_IMMR;
1764 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1765 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1766 /*
1767 * Disable PCMCIA buffers (isolate the interface)
1768 * and assert RESET signal
1769 */
1770 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
1771 reg = PCMCIA_PGCRX(_slot_);
1772 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1773 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
c609719b
WD
1774 PCMCIA_PGCRX(_slot_) = reg;
1775 udelay(500);
1776
1777 /*
1778 * Configure Port C pins for
1779 * 5 Volts Enable and 3 Volts enable,
1780 * Turn all power pins to Hi-Z
1781 */
1782 debug ("PCMCIA power OFF\n");
1783 cfg_ports (); /* Enables switch, but all in Hi-Z */
1784
1785 sreg = immap->im_ioport.iop_pcdat;
1786 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1787
1788 switch(vcc) {
1789 case 0: break; /* Switch off */
1790 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1791 sreg &= ~TPS2211_VCCD1;
1792 break;
1793 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1794 sreg |= TPS2211_VCCD1;
1795 break;
1796 default: goto done;
1797 }
1798
1799 /* Checking supported voltages */
1800
1801 debug ("PIPR: 0x%x --> %s\n",
1802 pcmp->pcmc_pipr,
1803 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1804
1805 immap->im_ioport.iop_pcdat = sreg;
1806
1807#ifdef DEBUG
1808 {
1809 char *s;
1810
1811 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1812 s = "at 3.3V";
1813 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1814 s = "at 5.0V";
1815 } else {
1816 s = "down";
1817 }
1818 printf ("PCMCIA powered %s\n", s);
1819 }
1820#endif
1821
1822done:
1823 debug ("Enable PCMCIA buffers and stop RESET\n");
1824 reg = PCMCIA_PGCRX(_slot_);
1825 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1826 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1827 PCMCIA_PGCRX(_slot_) = reg;
1828 udelay(500);
1829
1830 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1831 slot+'A');
1832 return (0);
1833}
1834
1835static void cfg_ports (void)
1836{
1837 volatile immap_t *immap;
1838 volatile cpm8xx_t *cp;
1839 ushort sreg;
1840
1841 immap = (immap_t *)CFG_IMMR;
1842 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1843
1844 /*
1845 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1846 *
1847 * Switch off all voltages, assert shutdown
1848 */
1849 sreg = immap->im_ioport.iop_pcdat;
1850 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1851 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1852 immap->im_ioport.iop_pcdat = sreg;
1853
1854 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1855 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1856
1857 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1858 immap->im_ioport.iop_pcpar,
1859 immap->im_ioport.iop_pcdir,
1860 immap->im_ioport.iop_pcdat);
1861
1862 /*
1863 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1864 *
1865 * Over-Current Input only
1866 */
1867 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1868 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1869
1870 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1871 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1872}
1873
1874#endif /* C2MON */
1875
1f53a416
WD
1876/* -------------------------------------------------------------------- */
1877/* MBX board from Morotola */
1878/* -------------------------------------------------------------------- */
c609719b
WD
1879
1880#if defined( CONFIG_MBX )
1881#include <../board/mbx8xx/csr.h>
1882
1883/* A lot of this has been taken from the RPX code in this file it works from me.
1884 I have added the voltage selection for the MBX board. */
1885
1886/* MBX voltage bit in control register #2 */
1887#define CR2_VPP12 ((uchar)0x10)
1888#define CR2_VPPVDD ((uchar)0x20)
1889#define CR2_VDD5 ((uchar)0x40)
1890#define CR2_VDD3 ((uchar)0x80)
1891
1892#define PCMCIA_BOARD_MSG "MBX860"
1893
1894static int voltage_set (int slot, int vcc, int vpp)
1895{
1896 uchar reg = 0;
1897
1898 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1899 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1900
1901 switch (vcc) {
1902 case 0:
1903 break;
1904 case 33:
1905 reg |= CR2_VDD3;
1906 break;
1907 case 50:
1908 reg |= CR2_VDD5;
1909 break;
1910 default:
1911 return 1;
1912 }
1913
1914 switch (vpp) {
1915 case 0:
1916 break;
1917 case 33:
1918 case 50:
1919 if (vcc == vpp) {
1920 reg |= CR2_VPPVDD;
1921 } else {
1922 return 1;
1923 }
1924 break;
1925 case 120:
1926 reg |= CR2_VPP12;
1927 break;
1928 default:
1929 return 1;
1930 }
1931
1932 /* first, turn off all power */
1933 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1934
1935 /* enable new powersettings */
1936 MBX_CSR2 |= reg;
1937 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1938
1939 return (0);
1940}
1941
1942static int hardware_enable (int slot)
1943{
1944 volatile immap_t *immap;
1945 volatile cpm8xx_t *cp;
1946 volatile pcmconf8xx_t *pcmp;
1947 volatile sysconf8xx_t *sysp;
1948 uint reg, mask;
1949
1950 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1951 'A' + slot);
1952
1953 udelay (10000);
1954
1955 immap = (immap_t *) CFG_IMMR;
1956 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1957 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1958 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1959
1960 /* clear interrupt state, and disable interrupts */
1961 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1962 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1963
c609719b 1964 /*
1f53a416
WD
1965 * Disable interrupts, DMA, and PCMCIA buffers
1966 * (isolate the interface) and assert RESET signal
c609719b
WD
1967 */
1968 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416 1969 reg = 0;
c609719b
WD
1970 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1971 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1972 PCMCIA_PGCRX (_slot_) = reg;
1973 udelay (500);
1974
1975 /* remove all power */
1976 voltage_set (slot, 0, 0);
1977 /*
1978 * Make sure there is a card in the slot, then configure the interface.
1979 */
ea909b76
WD
1980 udelay(10000);
1981 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1982 __LINE__,__FUNCTION__,
1983 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
c40b2956 1984#ifndef CONFIG_HMI10
ea909b76 1985 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
a522fa0e
WD
1986#else
1987 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
c40b2956 1988#endif /* CONFIG_HMI10 */
c609719b
WD
1989 printf (" No Card found\n");
1990 return (1);
1991 }
1992
1993 /*
1994 * Power On.
1995 */
1996 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1997 reg = pcmp->pcmc_pipr;
1998 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1999 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
2000 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
2001
2002 if ((reg & mask) == mask) {
2003 voltage_set (_slot_, 50, 0);
2004 printf (" 5.0V card found: ");
2005 } else {
2006 voltage_set (_slot_, 33, 0);
2007 printf (" 3.3V card found: ");
2008 }
2009
2010 debug ("Enable PCMCIA buffers and stop RESET\n");
2011 reg = PCMCIA_PGCRX (_slot_);
2012 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2013 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2014 PCMCIA_PGCRX (_slot_) = reg;
2015
2016 udelay (250000); /* some cards need >150 ms to come up :-( */
2017
2018 debug ("# hardware_enable done\n");
2019
2020 return (0);
2021}
2022
2023#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2024static int hardware_disable (int slot)
2025{
2026 return 0; /* No hardware to disable */
2027}
2028#endif /* CFG_CMD_PCMCIA */
2029#endif /* CONFIG_MBX */
1f53a416
WD
2030/* -------------------------------------------------------------------- */
2031/* R360MPI Board */
2032/* -------------------------------------------------------------------- */
c609719b
WD
2033
2034#if defined(CONFIG_R360MPI)
2035
2036#define PCMCIA_BOARD_MSG "R360MPI"
2037
2038
2039static int hardware_enable(int slot)
2040{
2041 volatile immap_t *immap;
2042 volatile cpm8xx_t *cp;
2043 volatile pcmconf8xx_t *pcmp;
2044 volatile sysconf8xx_t *sysp;
2045 uint reg, mask;
2046
2047 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2048
2049 udelay(10000);
2050
2051 immap = (immap_t *)CFG_IMMR;
2052 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2053 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2054 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2055
2056 /*
2057 * Configure SIUMCR to enable PCMCIA port B
2058 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2059 */
2060 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2061
2062 /* clear interrupt state, and disable interrupts */
2063 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2064 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2065
c609719b 2066 /*
1f53a416
WD
2067 * Disable interrupts, DMA, and PCMCIA buffers
2068 * (isolate the interface) and assert RESET signal
c609719b
WD
2069 */
2070 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
2071 reg = 0;
2072 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2073 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
c609719b
WD
2074 PCMCIA_PGCRX(_slot_) = reg;
2075 udelay(500);
2076
2077 /*
2078 * Configure Ports A, B & C pins for
2079 * 5 Volts Enable and 3 Volts enable
2080 */
2081 immap->im_ioport.iop_pcpar &= ~(0x0400);
2082 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2083 immap->im_ioport.iop_pcdir |= 0x0400;*/
2084
2085 immap->im_ioport.iop_papar &= ~(0x0200);/*
2086 immap->im_ioport.iop_padir |= 0x0200;*/
2087#if 0
2088 immap->im_ioport.iop_pbpar &= ~(0xC000);
2089 immap->im_ioport.iop_pbdir &= ~(0xC000);
2090#endif
2091 /* remove all power */
2092
2093 immap->im_ioport.iop_pcdat |= 0x0400;
2094 immap->im_ioport.iop_padat |= 0x0200;
2095
2096 /*
2097 * Make sure there is a card in the slot, then configure the interface.
2098 */
2099 udelay(10000);
2100 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2101 __LINE__,__FUNCTION__,
2102 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
ea909b76 2103 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
c609719b
WD
2104 printf (" No Card found\n");
2105 return (1);
2106 }
2107
2108 /*
2109 * Power On.
2110 */
2111 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2112 reg = pcmp->pcmc_pipr;
2113 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2114 reg,
2115 (reg&PCMCIA_VS1(slot))?"n":"ff",
2116 (reg&PCMCIA_VS2(slot))?"n":"ff");
2117 if ((reg & mask) == mask) {
2118 immap->im_ioport.iop_pcdat &= ~(0x4000);
2119 puts (" 5.0V card found: ");
2120 } else {
2121 immap->im_ioport.iop_padat &= ~(0x0002);
2122 puts (" 3.3V card found: ");
2123 }
2124 immap->im_ioport.iop_pcdir |= 0x0400;
2125 immap->im_ioport.iop_padir |= 0x0200;
2126#if 0
2127 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2128 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2129 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2130 udelay(500000);
2131#endif
2132 debug ("Enable PCMCIA buffers and stop RESET\n");
2133 reg = PCMCIA_PGCRX(_slot_);
2134 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2135 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2136 PCMCIA_PGCRX(_slot_) = reg;
2137
2138 udelay(250000); /* some cards need >150 ms to come up :-( */
2139
2140 debug ("# hardware_enable done\n");
2141
2142 return (0);
2143}
2144
2145
c609719b
WD
2146#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2147static int hardware_disable(int slot)
2148{
2149 volatile immap_t *immap;
2150 volatile pcmconf8xx_t *pcmp;
2151 u_long reg;
2152
2153 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2154
2155 immap = (immap_t *)CFG_IMMR;
2156 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2157
2158 /* remove all power */
2159 immap->im_ioport.iop_pcdat |= 0x0400;
2160 immap->im_ioport.iop_padat |= 0x0200;
2161
2162 /* Configure PCMCIA General Control Register */
c609719b 2163 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416 2164 reg = 0;
c609719b
WD
2165 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2166 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2167 PCMCIA_PGCRX(_slot_) = reg;
2168
2169 udelay(10000);
2170
2171 return (0);
2172}
2173#endif /* CFG_CMD_PCMCIA */
2174
2175
c609719b
WD
2176static int voltage_set(int slot, int vcc, int vpp)
2177{
2178 volatile immap_t *immap;
2179 volatile pcmconf8xx_t *pcmp;
2180 u_long reg;
2181
2182 debug ("voltage_set: "
2183 PCMCIA_BOARD_MSG
2184 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2185 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2186
2187 immap = (immap_t *)CFG_IMMR;
2188 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2189 /*
2190 * Disable PCMCIA buffers (isolate the interface)
2191 * and assert RESET signal
2192 */
2193 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
2194 reg = PCMCIA_PGCRX(_slot_);
2195 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2196 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
c609719b
WD
2197 PCMCIA_PGCRX(_slot_) = reg;
2198 udelay(500);
2199
2200 /*
2201 * Configure Ports A & C pins for
2202 * 5 Volts Enable and 3 Volts enable,
2203 * Turn off all power
2204 */
2205 debug ("PCMCIA power OFF\n");
2206 immap->im_ioport.iop_pcpar &= ~(0x0400);
2207 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2208 immap->im_ioport.iop_pcdir |= 0x0400;*/
2209
2210 immap->im_ioport.iop_papar &= ~(0x0200);/*
2211 immap->im_ioport.iop_padir |= 0x0200;*/
2212
2213 immap->im_ioport.iop_pcdat |= 0x0400;
2214 immap->im_ioport.iop_padat |= 0x0200;
2215
2216 reg = 0;
2217 switch(vcc) {
2218 case 0: break;
2219 case 33: reg |= 0x0200; break;
2220 case 50: reg |= 0x0400; break;
2221 default: goto done;
2222 }
2223
2224 /* Checking supported voltages */
2225
2226 debug ("PIPR: 0x%x --> %s\n",
2227 pcmp->pcmc_pipr,
2228 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2229
2230 if (reg & 0x0200)
2231 immap->im_ioport.iop_pcdat &= !reg;
2232 if (reg & 0x0400)
2233 immap->im_ioport.iop_padat &= !reg;
1f53a416
WD
2234 immap->im_ioport.iop_pcdir |= 0x0200;
2235 immap->im_ioport.iop_padir |= 0x0400;
c609719b
WD
2236 if (reg) {
2237 debug ("PCMCIA powered at %sV\n",
2238 (reg&0x0400) ? "5.0" : "3.3");
2239 } else {
2240 debug ("PCMCIA powered down\n");
2241 }
2242
2243done:
2244 debug ("Enable PCMCIA buffers and stop RESET\n");
2245 reg = PCMCIA_PGCRX(_slot_);
2246 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2247 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2248 PCMCIA_PGCRX(_slot_) = reg;
2249 udelay(500);
2250
2251 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2252 slot+'A');
2253 return (0);
2254}
2255
2256#endif /* R360MPI */
2257
1f53a416 2258/* -------------------------------------------------------------------- */
0608e04d 2259/* KUP4K and KUP4X Boards */
1f53a416 2260/* -------------------------------------------------------------------- */
0608e04d 2261#if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
56f94be3 2262
0608e04d 2263#define PCMCIA_BOARD_MSG "KUP"
56f94be3
WD
2264
2265#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2266
2267static int hardware_enable(int slot)
2268{
2269 volatile immap_t *immap;
2270 volatile cpm8xx_t *cp;
2271 volatile pcmconf8xx_t *pcmp;
2272 volatile sysconf8xx_t *sysp;
2273 uint reg, mask;
2274
2275 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2276
2277 udelay(10000);
2278
2279 immap = (immap_t *)CFG_IMMR;
2280 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2281 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2282 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2283
2284 /*
2285 * Configure SIUMCR to enable PCMCIA port B
2286 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2287 */
2288 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2289
2290 /* clear interrupt state, and disable interrupts */
ea909b76
WD
2291 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2292 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
56f94be3 2293
56f94be3 2294 /*
1f53a416
WD
2295 * Disable interrupts, DMA, and PCMCIA buffers
2296 * (isolate the interface) and assert RESET signal
56f94be3
WD
2297 */
2298 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
2299 reg = 0;
2300 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2301 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
ea909b76
WD
2302 PCMCIA_PGCRX(slot) = reg;
2303 udelay(2500);
56f94be3
WD
2304
2305 /*
2306 * Configure Port B pins for
2307 * 3 Volts enable
2308 */
ea909b76
WD
2309 if (slot) { /* Slot A is built-in */
2310 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2311 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2312 /* remove all power */
2313 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2314 }
56f94be3
WD
2315 /*
2316 * Make sure there is a card in the slot, then configure the interface.
2317 */
2318 udelay(10000);
2319 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2320 __LINE__,__FUNCTION__,
2321 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
ea909b76 2322 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
56f94be3
WD
2323 printf (" No Card found\n");
2324 return (1);
2325 }
2326
2327 /*
2328 * Power On.
2329 */
a6c7ad2f 2330 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
56f94be3
WD
2331 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2332 reg = pcmp->pcmc_pipr;
2333 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2334 reg,
2335 (reg&PCMCIA_VS1(slot))?"n":"ff",
2336 (reg&PCMCIA_VS2(slot))?"n":"ff");
2337 if ((reg & mask) == mask) {
2338 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2339 } else {
ea909b76
WD
2340 if(slot)
2341 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
56f94be3
WD
2342 puts (" 3.3V card found: ");
2343 }
2344#if 0
2345 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2346 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2347 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2348 udelay(500000);
2349#endif
2350 debug ("Enable PCMCIA buffers and stop RESET\n");
ea909b76 2351 reg = PCMCIA_PGCRX(slot);
56f94be3
WD
2352 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2353 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
ea909b76 2354 PCMCIA_PGCRX(slot) = reg;
56f94be3
WD
2355
2356 udelay(250000); /* some cards need >150 ms to come up :-( */
2357
2358 debug ("# hardware_enable done\n");
2359
2360 return (0);
2361}
2362
2363
56f94be3
WD
2364#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2365static int hardware_disable(int slot)
2366{
2367 volatile immap_t *immap;
2368 volatile cpm8xx_t *cp;
2369 volatile pcmconf8xx_t *pcmp;
2370 u_long reg;
2371
2372 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2373
2374 immap = (immap_t *)CFG_IMMR;
2375 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2376 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1f53a416 2377
56f94be3 2378 /* remove all power */
ea909b76
WD
2379 if (slot)
2380 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
56f94be3
WD
2381
2382 /* Configure PCMCIA General Control Register */
56f94be3 2383 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416 2384 reg = 0;
56f94be3
WD
2385 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2386 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
ea909b76 2387 PCMCIA_PGCRX(slot) = reg;
56f94be3
WD
2388
2389 udelay(10000);
2390
2391 return (0);
2392}
2393#endif /* CFG_CMD_PCMCIA */
2394
2395
56f94be3
WD
2396static int voltage_set(int slot, int vcc, int vpp)
2397{
2398 volatile immap_t *immap;
2399 volatile cpm8xx_t *cp;
2400 volatile pcmconf8xx_t *pcmp;
2401 u_long reg;
2402
2403 debug ("voltage_set: " \
2404 PCMCIA_BOARD_MSG \
2405 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2406 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2407
ea909b76
WD
2408 if (!slot) /* Slot A is not configurable */
2409 return 0;
2410
56f94be3
WD
2411 immap = (immap_t *)CFG_IMMR;
2412 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2413 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2414
2415 /*
2416 * Disable PCMCIA buffers (isolate the interface)
2417 * and assert RESET signal
2418 */
2419 debug ("Disable PCMCIA buffers and assert RESET\n");
1f53a416
WD
2420 reg = PCMCIA_PGCRX(slot);
2421 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2422 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
ea909b76 2423 PCMCIA_PGCRX(slot) = reg;
56f94be3
WD
2424 udelay(500);
2425
2426 debug ("PCMCIA power OFF\n");
2427 /*
2428 * Configure Port B pins for
2429 * 3 Volts enable
2430 */
2431 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2432 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2433 /* remove all power */
2434 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2435
2436 switch(vcc) {
2437 case 0: break;
2438 case 33:
2439 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2440 debug ("PCMCIA powered at 3.3V\n");
2441 break;
2442 case 50:
2443 debug ("PCMCIA: 5Volt vcc not supported\n");
2444 break;
2445 default:
2446 puts("PCMCIA: vcc not supported");
2447 break;
2448 }
ea909b76 2449 udelay(10000);
56f94be3
WD
2450 /* Checking supported voltages */
2451
2452 debug ("PIPR: 0x%x --> %s\n",
2453 pcmp->pcmc_pipr,
ea909b76 2454 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
56f94be3
WD
2455 ? "only 5 V --> NOT SUPPORTED"
2456 : "can do 3.3V");
2457
2458
2459 debug ("Enable PCMCIA buffers and stop RESET\n");
ea909b76 2460 reg = PCMCIA_PGCRX(slot);
56f94be3
WD
2461 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2462 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
ea909b76 2463 PCMCIA_PGCRX(slot) = reg;
56f94be3
WD
2464 udelay(500);
2465
2466 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2467 slot+'A');
2468 return (0);
2469}
2470
0608e04d 2471#endif /* KUP4K || KUP4X */
56f94be3
WD
2472
2473
1f53a416
WD
2474/* -------------------------------------------------------------------- */
2475/* End of Board Specific Stuff */
2476/* -------------------------------------------------------------------- */
c609719b
WD
2477
2478
1f53a416
WD
2479/* -------------------------------------------------------------------- */
2480/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2481/* -------------------------------------------------------------------- */
c609719b
WD
2482
2483/*
2484 * Search this table to see if the windowsize is
2485 * supported...
2486 */
2487
2488#define M8XX_SIZES_NO 32
2489
2490static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2491{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2492 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2493 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2494 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2495
2496 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2497 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2498 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2499 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2500
2501
1f53a416 2502/* -------------------------------------------------------------------- */
c609719b 2503
db01a2ea 2504#if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
7f70e853 2505
c609719b
WD
2506static u_int m8xx_get_graycode(u_int size)
2507{
2508 u_int k;
2509
2510 for (k = 0; k < M8XX_SIZES_NO; k++) {
2511 if(m8xx_size_to_gray[k] == size)
2512 break;
2513 }
2514
2515 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2516 k = -1;
2517
2518 return k;
2519}
2520
7f70e853
WD
2521#endif /* CONFIG_I82365 */
2522
1f53a416 2523/* -------------------------------------------------------------------- */
c609719b
WD
2524
2525#if 0
2526static u_int m8xx_get_speed(u_int ns, u_int is_io)
2527{
2528 u_int reg, clocks, psst, psl, psht;
2529
2530 if(!ns) {
2531
2532 /*
2533 * We get called with IO maps setup to 0ns
2534 * if not specified by the user.
2535 * They should be 255ns.
2536 */
2537
2538 if(is_io)
2539 ns = 255;
2540 else
2541 ns = 100; /* fast memory if 0 */
2542 }
2543
2544 /*
2545 * In PSST, PSL, PSHT fields we tell the controller
2546 * timing parameters in CLKOUT clock cycles.
2547 * CLKOUT is the same as GCLK2_50.
2548 */
2549
2550/* how we want to adjust the timing - in percent */
2551
2552#define ADJ 180 /* 80 % longer accesstime - to be sure */
2553
2554 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2555 clocks = (clocks * ADJ) / (100*1000);
2556
2557 if(clocks >= PCMCIA_BMT_LIMIT) {
2558 DEBUG(0, "Max access time limit reached\n");
2559 clocks = PCMCIA_BMT_LIMIT-1;
2560 }
2561
2562 psst = clocks / 7; /* setup time */
2563 psht = clocks / 7; /* hold time */
2564 psl = (clocks * 5) / 7; /* strobe length */
2565
2566 psst += clocks - (psst + psht + psl);
2567
2568 reg = psst << 12;
2569 reg |= psl << 7;
2570 reg |= psht << 16;
2571
2572 return reg;
2573}
2574#endif
2575
1f53a416 2576/* -------------------------------------------------------------------- */
c609719b 2577
db01a2ea 2578#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
c609719b
WD
2579static void print_funcid (int func)
2580{
2581 puts (indent);
2582 switch (func) {
2583 case CISTPL_FUNCID_MULTI:
2584 puts (" Multi-Function");
2585 break;
2586 case CISTPL_FUNCID_MEMORY:
2587 puts (" Memory");
2588 break;
2589 case CISTPL_FUNCID_SERIAL:
2590 puts (" Serial Port");
2591 break;
2592 case CISTPL_FUNCID_PARALLEL:
2593 puts (" Parallel Port");
2594 break;
2595 case CISTPL_FUNCID_FIXED:
2596 puts (" Fixed Disk");
2597 break;
2598 case CISTPL_FUNCID_VIDEO:
2599 puts (" Video Adapter");
2600 break;
2601 case CISTPL_FUNCID_NETWORK:
2602 puts (" Network Adapter");
2603 break;
2604 case CISTPL_FUNCID_AIMS:
2605 puts (" AIMS Card");
2606 break;
2607 case CISTPL_FUNCID_SCSI:
2608 puts (" SCSI Adapter");
2609 break;
2610 default:
2611 puts (" Unknown");
2612 break;
2613 }
2614 puts (" Card\n");
2615}
2616#endif /* CONFIG_IDE_8xx_PCCARD */
2617
1f53a416 2618/* -------------------------------------------------------------------- */
c609719b 2619
db01a2ea 2620#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
c609719b
WD
2621static void print_fixed (volatile uchar *p)
2622{
2623 if (p == NULL)
2624 return;
2625
2626 puts(indent);
2627
2628 switch (*p) {
2629 case CISTPL_FUNCE_IDE_IFACE:
2630 { uchar iface = *(p+2);
2631
2632 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2633 puts (" interface ");
2634 break;
2635 }
2636 case CISTPL_FUNCE_IDE_MASTER:
2637 case CISTPL_FUNCE_IDE_SLAVE:
2638 { uchar f1 = *(p+2);
2639 uchar f2 = *(p+4);
2640
2641 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2642
2643 if (f1 & CISTPL_IDE_UNIQUE)
2644 puts (" [unique]");
2645
2646 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2647
2648 if (f2 & CISTPL_IDE_HAS_SLEEP)
2649 puts (" [sleep]");
2650
2651 if (f2 & CISTPL_IDE_HAS_STANDBY)
2652 puts (" [standby]");
2653
2654 if (f2 & CISTPL_IDE_HAS_IDLE)
2655 puts (" [idle]");
2656
2657 if (f2 & CISTPL_IDE_LOW_POWER)
2658 puts (" [low power]");
2659
2660 if (f2 & CISTPL_IDE_REG_INHIBIT)
2661 puts (" [reg inhibit]");
2662
2663 if (f2 & CISTPL_IDE_HAS_INDEX)
2664 puts (" [index]");
2665
2666 if (f2 & CISTPL_IDE_IOIS16)
2667 puts (" [IOis16]");
2668
2669 break;
2670 }
2671 }
2672 putc ('\n');
2673}
2674#endif /* CONFIG_IDE_8xx_PCCARD */
2675
1f53a416 2676/* -------------------------------------------------------------------- */
c609719b 2677
db01a2ea 2678#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
c609719b
WD
2679
2680#define MAX_IDENT_CHARS 64
2681#define MAX_IDENT_FIELDS 4
2682
2683static uchar *known_cards[] = {
2684 "ARGOSY PnPIDE D5",
2685 NULL
2686};
2687
2688static int identify (volatile uchar *p)
2689{
2690 uchar id_str[MAX_IDENT_CHARS];
2691 uchar data;
2692 uchar *t;
2693 uchar **card;
2694 int i, done;
2695
2696 if (p == NULL)
2697 return (0); /* Don't know */
2698
2699 t = id_str;
2700 done =0;
2701
2702 for (i=0; i<=4 && !done; ++i, p+=2) {
2703 while ((data = *p) != '\0') {
2704 if (data == 0xFF) {
2705 done = 1;
2706 break;
2707 }
2708 *t++ = data;
2709 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2710 done = 1;
2711 break;
2712 }
2713 p += 2;
2714 }
2715 if (!done)
2716 *t++ = ' ';
2717 }
2718 *t = '\0';
2719 while (--t > id_str) {
2720 if (*t == ' ')
2721 *t = '\0';
2722 else
2723 break;
2724 }
2725 puts (id_str);
2726 putc ('\n');
2727
2728 for (card=known_cards; *card; ++card) {
2729 debug ("## Compare against \"%s\"\n", *card);
2730 if (strcmp(*card, id_str) == 0) { /* found! */
2731 debug ("## CARD FOUND ##\n");
2732 return (1);
2733 }
2734 }
2735
2736 return (0); /* don't know */
2737}
2738#endif /* CONFIG_IDE_8xx_PCCARD */
2739
04a85b3b
WD
2740/* -------------------------------------------------------------------- */
2741/* NETTA board by Intracom S.A. */
2742/* -------------------------------------------------------------------- */
2743
2744#if defined(CONFIG_NETTA)
2745
2746/* some sane bit macros */
2747#define _BD(_b) (1U << (31-(_b)))
2748#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2749
2750#define _BW(_b) (1U << (15-(_b)))
2751#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2752
2753#define _BB(_b) (1U << (7-(_b)))
2754#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2755
2756#define _B(_b) _BD(_b)
2757#define _BR(_l, _h) _BDR(_l, _h)
2758
2759#define PCMCIA_BOARD_MSG "NETTA"
2760
2761static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2762
2763static void cfg_vppd(int no)
2764{
2765 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2766 unsigned short mask;
2767
2768 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2769 return;
2770
2771 mask = vppd_masks[no];
2772
2773 immap->im_ioport.iop_papar &= ~mask;
2774 immap->im_ioport.iop_paodr &= ~mask;
2775 immap->im_ioport.iop_padir |= mask;
2776}
2777
2778static void set_vppd(int no, int what)
2779{
2780 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2781 unsigned short mask;
2782
2783 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2784 return;
2785
2786 mask = vppd_masks[no];
2787
2788 if (what)
2789 immap->im_ioport.iop_padat |= mask;
2790 else
2791 immap->im_ioport.iop_padat &= ~mask;
2792}
2793
2794static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2795
2796static void cfg_vccd(int no)
2797{
2798 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2799 unsigned short mask;
2800
2801 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2802 return;
2803
2804 mask = vccd_masks[no];
2805
2806 immap->im_ioport.iop_papar &= ~mask;
2807 immap->im_ioport.iop_paodr &= ~mask;
2808 immap->im_ioport.iop_padir |= mask;
2809}
2810
2811static void set_vccd(int no, int what)
2812{
2813 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2814 unsigned short mask;
2815
2816 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2817 return;
2818
2819 mask = vccd_masks[no];
2820
2821 if (what)
2822 immap->im_ioport.iop_padat |= mask;
2823 else
2824 immap->im_ioport.iop_padat &= ~mask;
2825}
2826
2827static const unsigned short oc_mask = _BW(8);
2828
2829static void cfg_oc(void)
2830{
2831 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2832 unsigned short mask = oc_mask;
2833
2834 immap->im_ioport.iop_pcdir &= ~mask;
2835 immap->im_ioport.iop_pcso &= ~mask;
2836 immap->im_ioport.iop_pcint &= ~mask;
2837 immap->im_ioport.iop_pcpar &= ~mask;
2838}
2839
2840static int get_oc(void)
2841{
2842 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2843 unsigned short mask = oc_mask;
2844 int what;
2845
2846 what = !!(immap->im_ioport.iop_pcdat & mask);;
2847 return what;
2848}
2849
2850static const unsigned short shdn_mask = _BW(12);
2851
2852static void cfg_shdn(void)
2853{
2854 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2855 unsigned short mask;
2856
2857 mask = shdn_mask;
2858
2859 immap->im_ioport.iop_papar &= ~mask;
2860 immap->im_ioport.iop_paodr &= ~mask;
2861 immap->im_ioport.iop_padir |= mask;
2862}
2863
2864static void set_shdn(int what)
2865{
2866 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2867 unsigned short mask;
2868
2869 mask = shdn_mask;
2870
2871 if (what)
2872 immap->im_ioport.iop_padat |= mask;
2873 else
2874 immap->im_ioport.iop_padat &= ~mask;
2875}
2876
2877static void cfg_ports (void);
2878
2879static int hardware_enable(int slot)
2880{
2881 volatile immap_t *immap;
2882 volatile cpm8xx_t *cp;
2883 volatile pcmconf8xx_t *pcmp;
2884 volatile sysconf8xx_t *sysp;
2885 uint reg, pipr, mask;
2886 int i;
2887
2888 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2889
2890 udelay(10000);
2891
2892 immap = (immap_t *)CFG_IMMR;
2893 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2894 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2895 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2896
2897 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
2898 cfg_ports ();
2899
2900 /* clear interrupt state, and disable interrupts */
2901 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2902 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2903
2904 /*
2905 * Disable interrupts, DMA, and PCMCIA buffers
2906 * (isolate the interface) and assert RESET signal
2907 */
2908 debug ("Disable PCMCIA buffers and assert RESET\n");
2909 reg = 0;
2910 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2911 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2912 PCMCIA_PGCRX(_slot_) = reg;
2913
2914 udelay(500);
2915
2916 /*
2917 * Make sure there is a card in the slot, then configure the interface.
2918 */
2919 udelay(10000);
2920 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2921 __LINE__,__FUNCTION__,
2922 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2923 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2924 printf (" No Card found\n");
2925 return (1);
2926 }
2927
2928 /*
2929 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
2930 */
2931 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2932 pipr = pcmp->pcmc_pipr;
2933 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2934 pipr,
2935 (reg&PCMCIA_VS1(slot))?"n":"ff",
2936 (reg&PCMCIA_VS2(slot))?"n":"ff");
2937
2938 if ((pipr & mask) == mask) {
2939 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
2940 set_vccd(0, 0); set_vccd(1, 1); /* 5V on, 3V off */
2941 puts (" 5.0V card found: ");
2942 } else {
2943 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
2944 set_vccd(0, 1); set_vccd(1, 0); /* 5V off, 3V on */
2945 puts (" 3.3V card found: ");
2946 }
2947
2948 /* Wait 500 ms; use this to check for over-current */
2949 for (i=0; i<5000; ++i) {
2950 if (!get_oc()) {
2951 printf (" *** Overcurrent - Safety shutdown ***\n");
2952 set_vccd(0, 0); set_vccd(1, 0); /* VAVPP => Hi-Z */
2953 return (1);
2954 }
2955 udelay (100);
2956 }
2957
2958 debug ("Enable PCMCIA buffers and stop RESET\n");
2959 reg = PCMCIA_PGCRX(_slot_);
2960 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2961 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2962 PCMCIA_PGCRX(_slot_) = reg;
2963
2964 udelay(250000); /* some cards need >150 ms to come up :-( */
2965
2966 debug ("# hardware_enable done\n");
2967
2968 return (0);
2969}
2970
2971
2972#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2973static int hardware_disable(int slot)
2974{
2975 volatile immap_t *immap;
2976 volatile pcmconf8xx_t *pcmp;
2977 u_long reg;
2978
2979 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2980
2981 immap = (immap_t *)CFG_IMMR;
2982 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2983
2984 /* Configure PCMCIA General Control Register */
2985 debug ("Disable PCMCIA buffers and assert RESET\n");
2986 reg = 0;
2987 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2988 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2989 PCMCIA_PGCRX(_slot_) = reg;
2990
2991 /* All voltages off / Hi-Z */
2992 set_vppd(0, 1); set_vppd(1, 1);
2993 set_vccd(0, 1); set_vccd(1, 1);
2994
2995 udelay(10000);
2996
2997 return (0);
2998}
2999#endif /* CFG_CMD_PCMCIA */
3000
3001
3002static int voltage_set(int slot, int vcc, int vpp)
3003{
3004 volatile immap_t *immap;
3005 volatile cpm8xx_t *cp;
3006 volatile pcmconf8xx_t *pcmp;
3007 u_long reg;
3008 ushort sreg;
3009
3010 debug ("voltage_set: "
3011 PCMCIA_BOARD_MSG
3012 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3013 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3014
3015 immap = (immap_t *)CFG_IMMR;
3016 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3017 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3018 /*
3019 * Disable PCMCIA buffers (isolate the interface)
3020 * and assert RESET signal
3021 */
3022 debug ("Disable PCMCIA buffers and assert RESET\n");
3023 reg = PCMCIA_PGCRX(_slot_);
3024 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3025 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
3026 PCMCIA_PGCRX(_slot_) = reg;
3027 udelay(500);
3028
3029 /*
3030 * Configure Port C pins for
3031 * 5 Volts Enable and 3 Volts enable,
3032 * Turn all power pins to Hi-Z
3033 */
3034 debug ("PCMCIA power OFF\n");
3035 cfg_ports (); /* Enables switch, but all in Hi-Z */
3036
3037 sreg = immap->im_ioport.iop_pcdat;
3038 set_vppd(0, 1); set_vppd(1, 1);
3039
3040 switch(vcc) {
3041 case 0:
3042 break; /* Switch off */
3043
3044 case 33:
3045 set_vccd(0, 1); set_vccd(1, 0);
3046 break;
3047
3048 case 50:
3049 set_vccd(0, 0); set_vccd(1, 1);
3050 break;
3051
3052 default:
3053 goto done;
3054 }
3055
3056 /* Checking supported voltages */
3057
3058 debug ("PIPR: 0x%x --> %s\n",
3059 pcmp->pcmc_pipr,
3060 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
3061
3062done:
3063 debug ("Enable PCMCIA buffers and stop RESET\n");
3064 reg = PCMCIA_PGCRX(_slot_);
3065 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3066 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3067 PCMCIA_PGCRX(_slot_) = reg;
3068 udelay(500);
3069
3070 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3071 slot+'A');
3072 return (0);
3073}
3074
3075static void cfg_ports (void)
3076{
3077 volatile immap_t *immap;
3078 volatile cpm8xx_t *cp;
3079
3080 immap = (immap_t *)CFG_IMMR;
3081 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3082
3083
3084 cfg_vppd(0); cfg_vppd(1); /* VPPD0,VPPD1 VAVPP => Hi-Z */
3085 cfg_vccd(0); cfg_vccd(1); /* 3V and 5V off */
3086 cfg_shdn();
3087 cfg_oc();
3088
3089 /*
3090 * Configure Port A for TPS2211 PC-Card Power-Interface Switch
3091 *
3092 * Switch off all voltages, assert shutdown
3093 */
3094 set_vppd(0, 1); set_vppd(1, 1);
3095 set_vccd(0, 0); set_vccd(1, 0);
3096 set_shdn(1);
3097
3098 udelay(100000);
3099}
3100
3101#endif /* NETTA */
3102
3103
f7d1572b
WD
3104/* -------------------------------------------------------------------- */
3105/* UC100 Boards */
3106/* -------------------------------------------------------------------- */
3107
3108#if defined(CONFIG_UC100)
3109
3110#define PCMCIA_BOARD_MSG "UC100"
3111
3112/*
3113 * Remark: don't turn off OE "__MY_PCMCIA_GCRX_CXOE" on UC100 board.
3114 * This leads to board-hangup! (sr, 8 Dez. 2004)
3115 */
3116
3117static void cfg_ports (void);
3118
3119static int hardware_enable(int slot)
3120{
3121 volatile immap_t *immap;
3122 volatile cpm8xx_t *cp;
3123 volatile pcmconf8xx_t *pcmp;
3124 volatile sysconf8xx_t *sysp;
3125 uint reg, mask;
3126
3127 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3128
3129 udelay(10000);
3130
3131 immap = (immap_t *)CFG_IMMR;
3132 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3133 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3134 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3135
3136 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3137 cfg_ports ();
3138
3139 /*
3140 * Configure SIUMCR to enable PCMCIA port B
3141 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
3142 */
3143 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
3144
3145 /* clear interrupt state, and disable interrupts */
3146 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
3147 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3148
3149 /*
3150 * Disable interrupts, DMA, and PCMCIA buffers
3151 * (isolate the interface) and assert RESET signal
3152 */
3153 debug ("Disable PCMCIA buffers and assert RESET\n");
3154 reg = 0;
3155 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3156 PCMCIA_PGCRX(_slot_) = reg;
3157 udelay(500);
3158
3159 /*
3160 * Make sure there is a card in the slot, then configure the interface.
3161 */
3162 udelay(10000);
3163 debug ("[%d] %s: PIPR(%p)=0x%x\n",
3164 __LINE__,__FUNCTION__,
3165 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3166 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3167 printf (" No Card found\n");
3168 return (1);
3169 }
3170
3171 /*
3172 * Power On.
3173 */
3174 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3175 reg = pcmp->pcmc_pipr;
3176 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3177 reg,
3178 (reg&PCMCIA_VS1(slot))?"n":"ff",
3179 (reg&PCMCIA_VS2(slot))?"n":"ff");
3180 if ((reg & mask) == mask) {
3181 puts (" 5.0V card found: ");
3182 } else {
3183 puts (" 3.3V card found: ");
3184 }
3185
3186 /* switch VCC on */
3187 immap->im_ioport.iop_padat |= 0x8000; /* power enable 3.3V */
3188
3189 udelay(10000);
3190
3191 debug ("Enable PCMCIA buffers and stop RESET\n");
3192 reg = PCMCIA_PGCRX(_slot_);
3193 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3194 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3195 PCMCIA_PGCRX(_slot_) = reg;
3196
3197 udelay(250000); /* some cards need >150 ms to come up :-( */
3198
3199 debug ("# hardware_enable done\n");
3200
3201 return (0);
3202}
3203
3204
3205#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3206static int hardware_disable(int slot)
3207{
3208 volatile immap_t *immap;
3209 volatile cpm8xx_t *cp;
3210 volatile pcmconf8xx_t *pcmp;
3211 u_long reg;
3212
3213 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3214
3215 immap = (immap_t *)CFG_IMMR;
3216 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3217
3218 /* switch VCC off */
3219 immap->im_ioport.iop_padat &= ~0x8000; /* power disable 3.3V */
3220
3221 /* Configure PCMCIA General Control Register */
3222 debug ("Disable PCMCIA buffers and assert RESET\n");
3223 reg = 0;
3224 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3225 PCMCIA_PGCRX(_slot_) = reg;
3226
3227 udelay(10000);
3228
3229 return (0);
3230}
3231#endif /* CFG_CMD_PCMCIA */
3232
3233
3234static int voltage_set(int slot, int vcc, int vpp)
3235{
3236 volatile immap_t *immap;
3237 volatile pcmconf8xx_t *pcmp;
3238 u_long reg;
3239
3240 debug ("voltage_set: "
3241 PCMCIA_BOARD_MSG
3242 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3243 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3244
3245 immap = (immap_t *)CFG_IMMR;
3246 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3247 /*
3248 * Disable PCMCIA buffers (isolate the interface)
3249 * and assert RESET signal
3250 */
3251 debug ("Disable PCMCIA buffers and assert RESET\n");
3252 reg = PCMCIA_PGCRX(_slot_);
3253 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3254 PCMCIA_PGCRX(_slot_) = reg;
3255 udelay(500);
3256
3257 /*
3258 * Configure Port C pins for
3259 * 5 Volts Enable and 3 Volts enable,
3260 * Turn all power pins to Hi-Z
3261 */
3262 debug ("PCMCIA power OFF\n");
3263 cfg_ports (); /* Enables switch, but all in Hi-Z */
3264
3265 debug ("Enable PCMCIA buffers and stop RESET\n");
3266 reg = PCMCIA_PGCRX(_slot_);
3267 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3268 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3269 PCMCIA_PGCRX(_slot_) = reg;
3270 udelay(500);
3271
3272 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3273 slot+'A');
3274 return (0);
3275}
3276
3277static void cfg_ports (void)
3278{
3279 volatile immap_t *immap;
3280
3281 immap = (immap_t *)CFG_IMMR;
3282
3283 /*
3284 * Configure Port A for MAX1602 PC-Card Power-Interface Switch
3285 */
3286 immap->im_ioport.iop_padat &= ~0x8000; /* set port x output to low */
3287 immap->im_ioport.iop_padir |= 0x8000; /* enable port x as output */
3288
3289 debug ("Set Port A: PAR: %08x DIR: %08x DAT: %08x\n",
3290 immap->im_ioport.iop_papar, immap->im_ioport.iop_padir,
3291 immap->im_ioport.iop_padat);
3292}
3293
3294#endif /* UC100 */
3295
3296
1f53a416 3297/* -------------------------------------------------------------------- */
c609719b
WD
3298
3299#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
8bde7f77
WD
3300
3301/**************************************************/
3302
3303#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
0d498393
WD
3304U_BOOT_CMD(
3305 pinit, 2, 1, do_pinit,
8bde7f77
WD
3306 "pinit - PCMCIA sub-system\n",
3307 "on - power on PCMCIA socket\n"
3308 "pinit off - power off PCMCIA socket\n"
3309);
3310#endif