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