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