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