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