blob: c009156af30adbcfbb84600a99c4f9935948d027 [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 */
wdenkdc7c9a12003-03-26 06:55:25 +0000517/* SC8xx Boards by SinoVee Microsystems */
wdenk1f53a412002-12-04 23:39:58 +0000518/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000519
wdenkdc7c9a12003-03-26 06:55:25 +0000520#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
521
wdenkc6097192002-11-03 00:24:07 +0000522#if defined(CONFIG_TQM8xxL)
wdenkc6097192002-11-03 00:24:07 +0000523#define PCMCIA_BOARD_MSG "TQM8xxL"
wdenkdc7c9a12003-03-26 06:55:25 +0000524#endif
525#if defined(CONFIG_SVM_SC8xx)
526#define PCMCIA_BOARD_MSG "SC8xx"
527#endif
wdenkc6097192002-11-03 00:24:07 +0000528
529static int hardware_enable(int slot)
530{
531 volatile immap_t *immap;
532 volatile cpm8xx_t *cp;
533 volatile pcmconf8xx_t *pcmp;
534 volatile sysconf8xx_t *sysp;
535 uint reg, mask;
536
537 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
538
539 udelay(10000);
540
541 immap = (immap_t *)CFG_IMMR;
542 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
543 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
544 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
545
546 /*
547 * Configure SIUMCR to enable PCMCIA port B
548 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
549 */
550 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
551
552 /* clear interrupt state, and disable interrupts */
553 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
554 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
555
wdenkc6097192002-11-03 00:24:07 +0000556 /*
wdenk1f53a412002-12-04 23:39:58 +0000557 * Disable interrupts, DMA, and PCMCIA buffers
558 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000559 */
560 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000561 reg = 0;
562 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
563 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000564 PCMCIA_PGCRX(_slot_) = reg;
565 udelay(500);
566
567 /*
568 * Configure Port C pins for
569 * 5 Volts Enable and 3 Volts enable
570 */
571 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
572 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
573 /* remove all power */
574
575 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
576
577 /*
578 * Make sure there is a card in the slot, then configure the interface.
579 */
580 udelay(10000);
581 debug ("[%d] %s: PIPR(%p)=0x%x\n",
582 __LINE__,__FUNCTION__,
583 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +0000584 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000585 printf (" No Card found\n");
586 return (1);
587 }
588
589 /*
590 * Power On.
591 */
592 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
593 reg = pcmp->pcmc_pipr;
594 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
595 reg,
596 (reg&PCMCIA_VS1(slot))?"n":"ff",
597 (reg&PCMCIA_VS2(slot))?"n":"ff");
598 if ((reg & mask) == mask) {
599 immap->im_ioport.iop_pcdat |= 0x0004;
600 puts (" 5.0V card found: ");
601 } else {
602 immap->im_ioport.iop_pcdat |= 0x0002;
603 puts (" 3.3V card found: ");
604 }
wdenk1f53a412002-12-04 23:39:58 +0000605 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000606#if 0
607 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
608 cp->cp_pbdir &= ~(0x0020 | 0x0010);
609 cp->cp_pbpar &= ~(0x0020 | 0x0010);
610 udelay(500000);
611#endif
612 udelay(1000);
613 debug ("Enable PCMCIA buffers and stop RESET\n");
614 reg = PCMCIA_PGCRX(_slot_);
615 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
616 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
617 PCMCIA_PGCRX(_slot_) = reg;
618
619 udelay(250000); /* some cards need >150 ms to come up :-( */
620
621 debug ("# hardware_enable done\n");
622
623 return (0);
624}
625
626
627
628#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
629static int hardware_disable(int slot)
630{
631 volatile immap_t *immap;
632 volatile pcmconf8xx_t *pcmp;
633 u_long reg;
634
635 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
636
637 immap = (immap_t *)CFG_IMMR;
638 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
639
640 /* remove all power */
641 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
642
wdenkc6097192002-11-03 00:24:07 +0000643 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000644 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000645 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
646 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
647 PCMCIA_PGCRX(_slot_) = reg;
648
649 udelay(10000);
650
651 return (0);
652}
653#endif /* CFG_CMD_PCMCIA */
654
655
656
657static int voltage_set(int slot, int vcc, int vpp)
658{
659 volatile immap_t *immap;
660 volatile pcmconf8xx_t *pcmp;
661 u_long reg;
662
663 debug ("voltage_set: "
664 PCMCIA_BOARD_MSG
665 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
666 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
667
668 immap = (immap_t *)CFG_IMMR;
669 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
670 /*
671 * Disable PCMCIA buffers (isolate the interface)
672 * and assert RESET signal
673 */
674 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000675 reg = PCMCIA_PGCRX(_slot_);
676 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
677 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000678 PCMCIA_PGCRX(_slot_) = reg;
679 udelay(500);
680
681 /*
682 * Configure Port C pins for
683 * 5 Volts Enable and 3 Volts enable,
684 * Turn off all power
685 */
686 debug ("PCMCIA power OFF\n");
687 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
688 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
689 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
690
691 reg = 0;
692 switch(vcc) {
693 case 0: break;
694 case 33: reg |= 0x0002; break;
695 case 50: reg |= 0x0004; break;
696 default: goto done;
697 }
698
699 /* Checking supported voltages */
700
701 debug ("PIPR: 0x%x --> %s\n",
702 pcmp->pcmc_pipr,
703 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
704
705 immap->im_ioport.iop_pcdat |= reg;
wdenk1f53a412002-12-04 23:39:58 +0000706 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000707 if (reg) {
708 debug ("PCMCIA powered at %sV\n",
709 (reg&0x0004) ? "5.0" : "3.3");
710 } else {
711 debug ("PCMCIA powered down\n");
712 }
713
714done:
715 debug ("Enable PCMCIA buffers and stop RESET\n");
716 reg = PCMCIA_PGCRX(_slot_);
717 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
718 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
719 PCMCIA_PGCRX(_slot_) = reg;
720 udelay(500);
721
722 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
723 slot+'A');
724 return (0);
725}
726
727#endif /* TQM8xxL */
728
729
wdenk1f53a412002-12-04 23:39:58 +0000730/* -------------------------------------------------------------------- */
731/* LWMON Board */
732/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000733
734#if defined(CONFIG_LWMON)
735
736#define PCMCIA_BOARD_MSG "LWMON"
737
738/* #define's for MAX1604 Power Switch */
739#define MAX1604_OP_SUS 0x80
740#define MAX1604_VCCBON 0x40
741#define MAX1604_VCC_35 0x20
742#define MAX1604_VCCBHIZ 0x10
743#define MAX1604_VPPBON 0x08
744#define MAX1604_VPPBPBPGM 0x04
745#define MAX1604_VPPBHIZ 0x02
746/* reserved 0x01 */
747
748static int hardware_enable(int slot)
749{
750 volatile immap_t *immap;
751 volatile cpm8xx_t *cp;
752 volatile pcmconf8xx_t *pcmp;
753 volatile sysconf8xx_t *sysp;
754 uint reg, mask;
755 uchar val;
756
757
758 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
759
760 /* Switch on PCMCIA port in PIC register 0x60 */
761 reg = pic_read (0x60);
762 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
763 reg &= ~0x10;
wdenk1f53a412002-12-04 23:39:58 +0000764 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +0000765 pic_write (0x60, reg);
766#ifdef DEBUG
767 reg = pic_read (0x60);
768 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
769#endif
770 udelay(10000);
771
772 immap = (immap_t *)CFG_IMMR;
773 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
774 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
775 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
776
777 /*
778 * Configure SIUMCR to enable PCMCIA port B
779 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
780 */
781 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
782
783 /* clear interrupt state, and disable interrupts */
784 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
785 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
786
wdenkc6097192002-11-03 00:24:07 +0000787 /*
wdenk1f53a412002-12-04 23:39:58 +0000788 * Disable interrupts, DMA, and PCMCIA buffers
789 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000790 */
791 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000792 reg = 0;
793 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
794 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000795 PCMCIA_PGCRX(_slot_) = reg;
796 udelay(500);
797
798 /*
799 * Make sure there is a card in the slot, then configure the interface.
800 */
801 udelay(10000);
802 debug ("[%d] %s: PIPR(%p)=0x%x\n",
803 __LINE__,__FUNCTION__,
804 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +0000805 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000806 printf (" No Card found\n");
807 return (1);
808 }
809
810 /*
811 * Power On.
812 */
813 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
814 reg = pcmp->pcmc_pipr;
815 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
816 reg,
817 (reg&PCMCIA_VS1(slot))?"n":"ff",
818 (reg&PCMCIA_VS2(slot))?"n":"ff");
819 if ((reg & mask) == mask) {
820 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
821 puts (" 5.0V card found: ");
822 } else {
823 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
824 puts (" 3.3V card found: ");
825 }
826
827 /* switch VCC on */
wdenk1f53a412002-12-04 23:39:58 +0000828 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +0000829 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
830 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
831
832 udelay(500000);
833
834 debug ("Enable PCMCIA buffers and stop RESET\n");
835 reg = PCMCIA_PGCRX(_slot_);
836 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
837 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
838 PCMCIA_PGCRX(_slot_) = reg;
839
840 udelay(250000); /* some cards need >150 ms to come up :-( */
841
842 debug ("# hardware_enable done\n");
843
844 return (0);
845}
846
847
848
849#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
850static int hardware_disable(int slot)
851{
852 volatile immap_t *immap;
853 volatile pcmconf8xx_t *pcmp;
854 u_long reg;
855 uchar val;
856
857 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
858
859 immap = (immap_t *)CFG_IMMR;
860 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
861
862 /* remove all power, put output in high impedance state */
863 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
864 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
865 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
866
867 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +0000868 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000869 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000870 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
871 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
872 PCMCIA_PGCRX(_slot_) = reg;
873
874 /* Switch off PCMCIA port in PIC register 0x60 */
875 reg = pic_read (0x60);
876 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
877 reg |= 0x10;
878 reg &= ~0x08;
879 pic_write (0x60, reg);
880#ifdef DEBUG
881 reg = pic_read (0x60);
882 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
883#endif
884 udelay(10000);
885
886 return (0);
887}
888#endif /* CFG_CMD_PCMCIA */
889
890
891
892static int voltage_set(int slot, int vcc, int vpp)
893{
894 volatile immap_t *immap;
895 volatile pcmconf8xx_t *pcmp;
896 u_long reg;
897 uchar val;
898
899 debug ("voltage_set: "
900 PCMCIA_BOARD_MSG
901 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
902 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
903
904 immap = (immap_t *)CFG_IMMR;
905 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
906 /*
907 * Disable PCMCIA buffers (isolate the interface)
908 * and assert RESET signal
909 */
910 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000911 reg = PCMCIA_PGCRX(_slot_);
912 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
913 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000914 PCMCIA_PGCRX(_slot_) = reg;
915 udelay(500);
916
917 /*
918 * Turn off all power (switch to high impedance)
919 */
920 debug ("PCMCIA power OFF\n");
921 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
922 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
923 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
924
925 val = 0;
926 switch(vcc) {
927 case 0: break;
928 case 33: val = MAX1604_VCC_35; break;
929 case 50: break;
930 default: goto done;
931 }
932
933 /* Checking supported voltages */
934
935 debug ("PIPR: 0x%x --> %s\n",
936 pcmp->pcmc_pipr,
937 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
938
939 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
940 if (val) {
941 debug ("PCMCIA powered at %sV\n",
942 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
943 } else {
944 debug ("PCMCIA powered down\n");
945 }
946
947done:
948 debug ("Enable PCMCIA buffers and stop RESET\n");
949 reg = PCMCIA_PGCRX(_slot_);
950 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
951 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
952 PCMCIA_PGCRX(_slot_) = reg;
953 udelay(500);
954
955 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
956 slot+'A');
957 return (0);
958}
959
960#endif /* LWMON */
961
wdenk1f53a412002-12-04 23:39:58 +0000962/* -------------------------------------------------------------------- */
963/* GTH board by Corelatus AB */
964/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000965#if defined(CONFIG_GTH)
966
967#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
968
wdenk1f53a412002-12-04 23:39:58 +0000969static int voltage_set (int slot, int vcc, int vpp)
970{ /* Do nothing */
971 return 0;
wdenkc6097192002-11-03 00:24:07 +0000972}
973
974static int hardware_enable (int slot)
975{
wdenk1f53a412002-12-04 23:39:58 +0000976 volatile immap_t *immap;
977 volatile cpm8xx_t *cp;
978 volatile pcmconf8xx_t *pcmp;
979 volatile sysconf8xx_t *sysp;
980 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +0000981
wdenk1f53a412002-12-04 23:39:58 +0000982 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +0000983
wdenk1f53a412002-12-04 23:39:58 +0000984 immap = (immap_t *) CFG_IMMR;
985 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
986 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
987 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +0000988
wdenk1f53a412002-12-04 23:39:58 +0000989 /* clear interrupt state, and disable interrupts */
990 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
991 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +0000992
wdenk1f53a412002-12-04 23:39:58 +0000993 /*
994 * Disable interrupts, DMA, and PCMCIA buffers
995 * (isolate the interface) and assert RESET signal
996 */
997 debug ("Disable PCMCIA buffers and assert RESET\n");
998 reg = 0;
999 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1000 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1001 PCMCIA_PGCRX (_slot_) = reg;
1002 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001003
wdenk1f53a412002-12-04 23:39:58 +00001004 /*
1005 * Make sure there is a card in the slot,
1006 * then configure the interface.
1007 */
1008 udelay (10000);
1009 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1010 __LINE__, __FUNCTION__,
1011 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1012 if (pcmp->pcmc_pipr & 0x98000000) {
1013 printf (" No Card found\n");
1014 return (1);
1015 }
wdenkc6097192002-11-03 00:24:07 +00001016
wdenk1f53a412002-12-04 23:39:58 +00001017 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1018 reg = pcmp->pcmc_pipr;
1019 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1020 reg,
1021 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1022 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001023
wdenk1f53a412002-12-04 23:39:58 +00001024 debug ("Enable PCMCIA buffers and stop RESET\n");
1025 reg = PCMCIA_PGCRX (_slot_);
1026 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1027 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1028 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001029
wdenk1f53a412002-12-04 23:39:58 +00001030 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001031
wdenk1f53a412002-12-04 23:39:58 +00001032 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001033
wdenk1f53a412002-12-04 23:39:58 +00001034 return 0;
wdenkc6097192002-11-03 00:24:07 +00001035}
1036#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1037static int hardware_disable(int slot)
1038{
1039 return 0; /* No hardware to disable */
1040}
1041#endif /* CFG_CMD_PCMCIA */
1042#endif /* CONFIG_GTH */
1043
wdenk1f53a412002-12-04 23:39:58 +00001044/* -------------------------------------------------------------------- */
1045/* ICU862 Boards by Cambridge Broadband Ltd. */
1046/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001047
1048#if defined(CONFIG_ICU862)
1049
1050#define PCMCIA_BOARD_MSG "ICU862"
1051
1052static void cfg_port_B (void);
1053
1054static int hardware_enable(int slot)
1055{
1056 volatile immap_t *immap;
1057 volatile cpm8xx_t *cp;
1058 volatile pcmconf8xx_t *pcmp;
1059 volatile sysconf8xx_t *sysp;
1060 uint reg, pipr, mask;
1061 int i;
1062
1063 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1064
1065 udelay(10000);
1066
1067 immap = (immap_t *)CFG_IMMR;
1068 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1069 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1070 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1071
1072 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1073 cfg_port_B ();
1074
1075 /*
1076 * Configure SIUMCR to enable PCMCIA port B
1077 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1078 */
1079 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1080
1081 /* clear interrupt state, and disable interrupts */
1082 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1083 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1084
wdenkc6097192002-11-03 00:24:07 +00001085 /*
wdenk1f53a412002-12-04 23:39:58 +00001086 * Disable interrupts, DMA, and PCMCIA buffers
1087 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001088 */
1089 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001090 reg = 0;
1091 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1092 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001093 PCMCIA_PGCRX(_slot_) = reg;
1094 udelay(500);
1095
1096 /*
1097 * Make sure there is a card in the slot, then configure the interface.
1098 */
1099 udelay(10000);
1100 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1101 __LINE__,__FUNCTION__,
1102 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001103 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001104 printf (" No Card found\n");
1105 return (1);
1106 }
1107
1108 /*
1109 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1110 */
1111 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1112 pipr = pcmp->pcmc_pipr;
1113 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1114 pipr,
1115 (reg&PCMCIA_VS1(slot))?"n":"ff",
1116 (reg&PCMCIA_VS2(slot))?"n":"ff");
1117
1118 reg = cp->cp_pbdat;
1119 if ((pipr & mask) == mask) {
wdenk1f53a412002-12-04 23:39:58 +00001120 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1121 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001122 reg &= ~(TPS2205_VCC5); /* 5V on */
1123 puts (" 5.0V card found: ");
1124 } else {
wdenk1f53a412002-12-04 23:39:58 +00001125 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1126 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001127 reg &= ~(TPS2205_VCC3); /* 3V on */
1128 puts (" 3.3V card found: ");
1129 }
1130
1131 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1132 reg,
1133 (reg & TPS2205_VCC3) ? "off" : "on",
1134 (reg & TPS2205_VCC5) ? "off" : "on",
1135 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1136 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1137
1138 cp->cp_pbdat = reg;
1139
1140 /* Wait 500 ms; use this to check for over-current */
1141 for (i=0; i<5000; ++i) {
1142 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1143 printf (" *** Overcurrent - Safety shutdown ***\n");
1144 cp->cp_pbdat &= ~(TPS2205_SHDN);
1145 return (1);
1146 }
1147 udelay (100);
1148 }
1149
1150 debug ("Enable PCMCIA buffers and stop RESET\n");
1151 reg = PCMCIA_PGCRX(_slot_);
1152 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1153 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1154 PCMCIA_PGCRX(_slot_) = reg;
1155
1156 udelay(250000); /* some cards need >150 ms to come up :-( */
1157
1158 debug ("# hardware_enable done\n");
1159
1160 return (0);
1161}
1162
1163
1164
1165#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1166static int hardware_disable(int slot)
1167{
1168 volatile immap_t *immap;
1169 volatile cpm8xx_t *cp;
1170 volatile pcmconf8xx_t *pcmp;
1171 u_long reg;
1172
1173 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1174
1175 immap = (immap_t *)CFG_IMMR;
1176 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1177 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1178
1179 /* Shut down */
1180 cp->cp_pbdat &= ~(TPS2205_SHDN);
1181
1182 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001183 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001184 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001185 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1186 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1187 PCMCIA_PGCRX(_slot_) = reg;
1188
1189 udelay(10000);
1190
1191 return (0);
1192}
1193#endif /* CFG_CMD_PCMCIA */
1194
1195
1196
1197static int voltage_set(int slot, int vcc, int vpp)
1198{
1199 volatile immap_t *immap;
1200 volatile cpm8xx_t *cp;
1201 volatile pcmconf8xx_t *pcmp;
1202 u_long reg;
1203
1204 debug ("voltage_set: "
1205 PCMCIA_BOARD_MSG
1206 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1207 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1208
1209 immap = (immap_t *)CFG_IMMR;
1210 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1211 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1212 /*
1213 * Disable PCMCIA buffers (isolate the interface)
1214 * and assert RESET signal
1215 */
1216 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001217 reg = PCMCIA_PGCRX(_slot_);
1218 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1219 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001220 PCMCIA_PGCRX(_slot_) = reg;
1221 udelay(500);
1222
1223 /*
1224 * Configure Port C pins for
1225 * 5 Volts Enable and 3 Volts enable,
1226 * Turn all power pins to Hi-Z
1227 */
1228 debug ("PCMCIA power OFF\n");
1229 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1230
1231 reg = cp->cp_pbdat;
1232
1233 switch(vcc) {
1234 case 0: break; /* Switch off */
1235 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1236 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1237 default: goto done;
1238 }
1239
1240 /* Checking supported voltages */
1241
1242 debug ("PIPR: 0x%x --> %s\n",
1243 pcmp->pcmc_pipr,
1244 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1245
1246 cp->cp_pbdat = reg;
1247
1248#ifdef DEBUG
1249 {
1250 char *s;
1251
1252 if ((reg & TPS2205_VCC3) == 0) {
1253 s = "at 3.3V";
1254 } else if ((reg & TPS2205_VCC5) == 0) {
1255 s = "at 5.0V";
1256 } else {
1257 s = "down";
1258 }
1259 printf ("PCMCIA powered %s\n", s);
1260 }
1261#endif
1262
1263done:
1264 debug ("Enable PCMCIA buffers and stop RESET\n");
1265 reg = PCMCIA_PGCRX(_slot_);
1266 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1267 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1268 PCMCIA_PGCRX(_slot_) = reg;
1269 udelay(500);
1270
1271 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1272 slot+'A');
1273 return (0);
1274}
1275
1276static void cfg_port_B (void)
1277{
1278 volatile immap_t *immap;
1279 volatile cpm8xx_t *cp;
1280 uint reg;
1281
1282 immap = (immap_t *)CFG_IMMR;
1283 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1284
1285 /*
1286 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1287 *
1288 * Switch off all voltages, assert shutdown
1289 */
1290 reg = cp->cp_pbdat;
wdenk1f53a412002-12-04 23:39:58 +00001291 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1292 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1293 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001294 cp->cp_pbdat = reg;
1295
1296 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1297
1298 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1299 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1300
1301 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1302 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1303}
1304
1305#endif /* ICU862 */
1306
1307
wdenk1f53a412002-12-04 23:39:58 +00001308/* -------------------------------------------------------------------- */
1309/* C2MON Boards by TTTech Computertechnik AG */
1310/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001311
1312#if defined(CONFIG_C2MON)
1313
1314#define PCMCIA_BOARD_MSG "C2MON"
1315
1316static void cfg_ports (void);
1317
1318static int hardware_enable(int slot)
1319{
1320 volatile immap_t *immap;
1321 volatile cpm8xx_t *cp;
1322 volatile pcmconf8xx_t *pcmp;
1323 volatile sysconf8xx_t *sysp;
1324 uint reg, pipr, mask;
1325 ushort sreg;
1326 int i;
1327
1328 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1329
1330 udelay(10000);
1331
1332 immap = (immap_t *)CFG_IMMR;
1333 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1334 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1335 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1336
1337 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1338 cfg_ports ();
1339
1340 /*
1341 * Configure SIUMCR to enable PCMCIA port B
1342 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1343 */
1344 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1345
1346 /* clear interrupt state, and disable interrupts */
1347 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1348 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1349
wdenkc6097192002-11-03 00:24:07 +00001350 /*
wdenk1f53a412002-12-04 23:39:58 +00001351 * Disable interrupts, DMA, and PCMCIA buffers
1352 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001353 */
1354 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001355 reg = 0;
1356 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1357 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001358 PCMCIA_PGCRX(_slot_) = reg;
1359 udelay(500);
1360
1361 /*
1362 * Make sure there is a card in the slot, then configure the interface.
1363 */
1364 udelay(10000);
1365 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1366 __LINE__,__FUNCTION__,
1367 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001368 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001369 printf (" No Card found\n");
1370 return (1);
1371 }
1372
1373 /*
1374 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1375 */
1376 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1377 pipr = pcmp->pcmc_pipr;
1378 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1379 pipr,
1380 (reg&PCMCIA_VS1(slot))?"n":"ff",
1381 (reg&PCMCIA_VS2(slot))?"n":"ff");
1382
1383 sreg = immap->im_ioport.iop_pcdat;
1384 if ((pipr & mask) == mask) {
1385 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1386 TPS2211_VCCD1); /* 5V on */
1387 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1388 puts (" 5.0V card found: ");
1389 } else {
1390 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1391 TPS2211_VCCD0); /* 3V on */
1392 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1393 puts (" 3.3V card found: ");
1394 }
1395
1396 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1397 sreg,
1398 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1399 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1400 );
1401
1402 immap->im_ioport.iop_pcdat = sreg;
1403
1404 /* Wait 500 ms; use this to check for over-current */
1405 for (i=0; i<5000; ++i) {
1406 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1407 printf (" *** Overcurrent - Safety shutdown ***\n");
1408 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1409 return (1);
1410 }
1411 udelay (100);
1412 }
1413
1414 debug ("Enable PCMCIA buffers and stop RESET\n");
1415 reg = PCMCIA_PGCRX(_slot_);
1416 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1417 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1418 PCMCIA_PGCRX(_slot_) = reg;
1419
1420 udelay(250000); /* some cards need >150 ms to come up :-( */
1421
1422 debug ("# hardware_enable done\n");
1423
1424 return (0);
1425}
1426
1427
1428
1429#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1430static int hardware_disable(int slot)
1431{
1432 volatile immap_t *immap;
1433 volatile cpm8xx_t *cp;
1434 volatile pcmconf8xx_t *pcmp;
1435 u_long reg;
1436
1437 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1438
1439 immap = (immap_t *)CFG_IMMR;
1440 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1441
1442 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001443 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001444 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001445 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1446 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1447 PCMCIA_PGCRX(_slot_) = reg;
1448
1449 /* ALl voltages off / Hi-Z */
1450 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1451 TPS2211_VCCD0 | TPS2211_VCCD1 );
1452
1453 udelay(10000);
1454
1455 return (0);
1456}
1457#endif /* CFG_CMD_PCMCIA */
1458
1459
1460
1461static int voltage_set(int slot, int vcc, int vpp)
1462{
1463 volatile immap_t *immap;
1464 volatile cpm8xx_t *cp;
1465 volatile pcmconf8xx_t *pcmp;
1466 u_long reg;
1467 ushort sreg;
1468
1469 debug ("voltage_set: "
1470 PCMCIA_BOARD_MSG
1471 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1472 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1473
1474 immap = (immap_t *)CFG_IMMR;
1475 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1476 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1477 /*
1478 * Disable PCMCIA buffers (isolate the interface)
1479 * and assert RESET signal
1480 */
1481 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001482 reg = PCMCIA_PGCRX(_slot_);
1483 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1484 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001485 PCMCIA_PGCRX(_slot_) = reg;
1486 udelay(500);
1487
1488 /*
1489 * Configure Port C pins for
1490 * 5 Volts Enable and 3 Volts enable,
1491 * Turn all power pins to Hi-Z
1492 */
1493 debug ("PCMCIA power OFF\n");
1494 cfg_ports (); /* Enables switch, but all in Hi-Z */
1495
1496 sreg = immap->im_ioport.iop_pcdat;
1497 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1498
1499 switch(vcc) {
1500 case 0: break; /* Switch off */
1501 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1502 sreg &= ~TPS2211_VCCD1;
1503 break;
1504 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1505 sreg |= TPS2211_VCCD1;
1506 break;
1507 default: goto done;
1508 }
1509
1510 /* Checking supported voltages */
1511
1512 debug ("PIPR: 0x%x --> %s\n",
1513 pcmp->pcmc_pipr,
1514 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1515
1516 immap->im_ioport.iop_pcdat = sreg;
1517
1518#ifdef DEBUG
1519 {
1520 char *s;
1521
1522 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1523 s = "at 3.3V";
1524 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1525 s = "at 5.0V";
1526 } else {
1527 s = "down";
1528 }
1529 printf ("PCMCIA powered %s\n", s);
1530 }
1531#endif
1532
1533done:
1534 debug ("Enable PCMCIA buffers and stop RESET\n");
1535 reg = PCMCIA_PGCRX(_slot_);
1536 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1537 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1538 PCMCIA_PGCRX(_slot_) = reg;
1539 udelay(500);
1540
1541 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1542 slot+'A');
1543 return (0);
1544}
1545
1546static void cfg_ports (void)
1547{
1548 volatile immap_t *immap;
1549 volatile cpm8xx_t *cp;
1550 ushort sreg;
1551
1552 immap = (immap_t *)CFG_IMMR;
1553 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1554
1555 /*
1556 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1557 *
1558 * Switch off all voltages, assert shutdown
1559 */
1560 sreg = immap->im_ioport.iop_pcdat;
1561 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1562 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1563 immap->im_ioport.iop_pcdat = sreg;
1564
1565 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1566 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1567
1568 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1569 immap->im_ioport.iop_pcpar,
1570 immap->im_ioport.iop_pcdir,
1571 immap->im_ioport.iop_pcdat);
1572
1573 /*
1574 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1575 *
1576 * Over-Current Input only
1577 */
1578 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1579 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1580
1581 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1582 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1583}
1584
1585#endif /* C2MON */
1586
wdenk1f53a412002-12-04 23:39:58 +00001587/* -------------------------------------------------------------------- */
1588/* MBX board from Morotola */
1589/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001590
1591#if defined( CONFIG_MBX )
1592#include <../board/mbx8xx/csr.h>
1593
1594/* A lot of this has been taken from the RPX code in this file it works from me.
1595 I have added the voltage selection for the MBX board. */
1596
1597/* MBX voltage bit in control register #2 */
1598#define CR2_VPP12 ((uchar)0x10)
1599#define CR2_VPPVDD ((uchar)0x20)
1600#define CR2_VDD5 ((uchar)0x40)
1601#define CR2_VDD3 ((uchar)0x80)
1602
1603#define PCMCIA_BOARD_MSG "MBX860"
1604
1605static int voltage_set (int slot, int vcc, int vpp)
1606{
1607 uchar reg = 0;
1608
1609 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1610 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1611
1612 switch (vcc) {
1613 case 0:
1614 break;
1615 case 33:
1616 reg |= CR2_VDD3;
1617 break;
1618 case 50:
1619 reg |= CR2_VDD5;
1620 break;
1621 default:
1622 return 1;
1623 }
1624
1625 switch (vpp) {
1626 case 0:
1627 break;
1628 case 33:
1629 case 50:
1630 if (vcc == vpp) {
1631 reg |= CR2_VPPVDD;
1632 } else {
1633 return 1;
1634 }
1635 break;
1636 case 120:
1637 reg |= CR2_VPP12;
1638 break;
1639 default:
1640 return 1;
1641 }
1642
1643 /* first, turn off all power */
1644 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1645
1646 /* enable new powersettings */
1647 MBX_CSR2 |= reg;
1648 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1649
1650 return (0);
1651}
1652
1653static int hardware_enable (int slot)
1654{
1655 volatile immap_t *immap;
1656 volatile cpm8xx_t *cp;
1657 volatile pcmconf8xx_t *pcmp;
1658 volatile sysconf8xx_t *sysp;
1659 uint reg, mask;
1660
1661 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1662 'A' + slot);
1663
1664 udelay (10000);
1665
1666 immap = (immap_t *) CFG_IMMR;
1667 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1668 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1669 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1670
1671 /* clear interrupt state, and disable interrupts */
1672 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1673 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1674
wdenkc6097192002-11-03 00:24:07 +00001675 /*
wdenk1f53a412002-12-04 23:39:58 +00001676 * Disable interrupts, DMA, and PCMCIA buffers
1677 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001678 */
1679 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001680 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001681 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1682 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1683 PCMCIA_PGCRX (_slot_) = reg;
1684 udelay (500);
1685
1686 /* remove all power */
1687 voltage_set (slot, 0, 0);
1688 /*
1689 * Make sure there is a card in the slot, then configure the interface.
1690 */
wdenkea909b72002-11-21 23:11:29 +00001691 udelay(10000);
1692 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1693 __LINE__,__FUNCTION__,
1694 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1695 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001696 printf (" No Card found\n");
1697 return (1);
1698 }
1699
1700 /*
1701 * Power On.
1702 */
1703 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1704 reg = pcmp->pcmc_pipr;
1705 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1706 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1707 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1708
1709 if ((reg & mask) == mask) {
1710 voltage_set (_slot_, 50, 0);
1711 printf (" 5.0V card found: ");
1712 } else {
1713 voltage_set (_slot_, 33, 0);
1714 printf (" 3.3V card found: ");
1715 }
1716
1717 debug ("Enable PCMCIA buffers and stop RESET\n");
1718 reg = PCMCIA_PGCRX (_slot_);
1719 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1720 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1721 PCMCIA_PGCRX (_slot_) = reg;
1722
1723 udelay (250000); /* some cards need >150 ms to come up :-( */
1724
1725 debug ("# hardware_enable done\n");
1726
1727 return (0);
1728}
1729
1730#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1731static int hardware_disable (int slot)
1732{
1733 return 0; /* No hardware to disable */
1734}
1735#endif /* CFG_CMD_PCMCIA */
1736#endif /* CONFIG_MBX */
wdenk1f53a412002-12-04 23:39:58 +00001737/* -------------------------------------------------------------------- */
1738/* R360MPI Board */
1739/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001740
1741#if defined(CONFIG_R360MPI)
1742
1743#define PCMCIA_BOARD_MSG "R360MPI"
1744
1745
1746static int hardware_enable(int slot)
1747{
1748 volatile immap_t *immap;
1749 volatile cpm8xx_t *cp;
1750 volatile pcmconf8xx_t *pcmp;
1751 volatile sysconf8xx_t *sysp;
1752 uint reg, mask;
1753
1754 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1755
1756 udelay(10000);
1757
1758 immap = (immap_t *)CFG_IMMR;
1759 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1760 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1761 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1762
1763 /*
1764 * Configure SIUMCR to enable PCMCIA port B
1765 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1766 */
1767 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1768
1769 /* clear interrupt state, and disable interrupts */
1770 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1771 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1772
wdenkc6097192002-11-03 00:24:07 +00001773 /*
wdenk1f53a412002-12-04 23:39:58 +00001774 * Disable interrupts, DMA, and PCMCIA buffers
1775 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001776 */
1777 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001778 reg = 0;
1779 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1780 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001781 PCMCIA_PGCRX(_slot_) = reg;
1782 udelay(500);
1783
1784 /*
1785 * Configure Ports A, B & C pins for
1786 * 5 Volts Enable and 3 Volts enable
1787 */
1788 immap->im_ioport.iop_pcpar &= ~(0x0400);
1789 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1790 immap->im_ioport.iop_pcdir |= 0x0400;*/
1791
1792 immap->im_ioport.iop_papar &= ~(0x0200);/*
1793 immap->im_ioport.iop_padir |= 0x0200;*/
1794#if 0
1795 immap->im_ioport.iop_pbpar &= ~(0xC000);
1796 immap->im_ioport.iop_pbdir &= ~(0xC000);
1797#endif
1798 /* remove all power */
1799
1800 immap->im_ioport.iop_pcdat |= 0x0400;
1801 immap->im_ioport.iop_padat |= 0x0200;
1802
1803 /*
1804 * Make sure there is a card in the slot, then configure the interface.
1805 */
1806 udelay(10000);
1807 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1808 __LINE__,__FUNCTION__,
1809 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001810 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001811 printf (" No Card found\n");
1812 return (1);
1813 }
1814
1815 /*
1816 * Power On.
1817 */
1818 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1819 reg = pcmp->pcmc_pipr;
1820 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1821 reg,
1822 (reg&PCMCIA_VS1(slot))?"n":"ff",
1823 (reg&PCMCIA_VS2(slot))?"n":"ff");
1824 if ((reg & mask) == mask) {
1825 immap->im_ioport.iop_pcdat &= ~(0x4000);
1826 puts (" 5.0V card found: ");
1827 } else {
1828 immap->im_ioport.iop_padat &= ~(0x0002);
1829 puts (" 3.3V card found: ");
1830 }
1831 immap->im_ioport.iop_pcdir |= 0x0400;
1832 immap->im_ioport.iop_padir |= 0x0200;
1833#if 0
1834 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
1835 cp->cp_pbdir &= ~(0x0020 | 0x0010);
1836 cp->cp_pbpar &= ~(0x0020 | 0x0010);
1837 udelay(500000);
1838#endif
1839 debug ("Enable PCMCIA buffers and stop RESET\n");
1840 reg = PCMCIA_PGCRX(_slot_);
1841 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1842 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1843 PCMCIA_PGCRX(_slot_) = reg;
1844
1845 udelay(250000); /* some cards need >150 ms to come up :-( */
1846
1847 debug ("# hardware_enable done\n");
1848
1849 return (0);
1850}
1851
1852
1853
1854#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1855static int hardware_disable(int slot)
1856{
1857 volatile immap_t *immap;
1858 volatile pcmconf8xx_t *pcmp;
1859 u_long reg;
1860
1861 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1862
1863 immap = (immap_t *)CFG_IMMR;
1864 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1865
1866 /* remove all power */
1867 immap->im_ioport.iop_pcdat |= 0x0400;
1868 immap->im_ioport.iop_padat |= 0x0200;
1869
1870 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001871 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001872 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001873 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1874 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1875 PCMCIA_PGCRX(_slot_) = reg;
1876
1877 udelay(10000);
1878
1879 return (0);
1880}
1881#endif /* CFG_CMD_PCMCIA */
1882
1883
1884
1885static int voltage_set(int slot, int vcc, int vpp)
1886{
1887 volatile immap_t *immap;
1888 volatile pcmconf8xx_t *pcmp;
1889 u_long reg;
1890
1891 debug ("voltage_set: "
1892 PCMCIA_BOARD_MSG
1893 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1894 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1895
1896 immap = (immap_t *)CFG_IMMR;
1897 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1898 /*
1899 * Disable PCMCIA buffers (isolate the interface)
1900 * and assert RESET signal
1901 */
1902 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001903 reg = PCMCIA_PGCRX(_slot_);
1904 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1905 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001906 PCMCIA_PGCRX(_slot_) = reg;
1907 udelay(500);
1908
1909 /*
1910 * Configure Ports A & C pins for
1911 * 5 Volts Enable and 3 Volts enable,
1912 * Turn off all power
1913 */
1914 debug ("PCMCIA power OFF\n");
1915 immap->im_ioport.iop_pcpar &= ~(0x0400);
1916 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1917 immap->im_ioport.iop_pcdir |= 0x0400;*/
1918
1919 immap->im_ioport.iop_papar &= ~(0x0200);/*
1920 immap->im_ioport.iop_padir |= 0x0200;*/
1921
1922 immap->im_ioport.iop_pcdat |= 0x0400;
1923 immap->im_ioport.iop_padat |= 0x0200;
1924
1925 reg = 0;
1926 switch(vcc) {
1927 case 0: break;
1928 case 33: reg |= 0x0200; break;
1929 case 50: reg |= 0x0400; break;
1930 default: goto done;
1931 }
1932
1933 /* Checking supported voltages */
1934
1935 debug ("PIPR: 0x%x --> %s\n",
1936 pcmp->pcmc_pipr,
1937 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1938
1939 if (reg & 0x0200)
1940 immap->im_ioport.iop_pcdat &= !reg;
1941 if (reg & 0x0400)
1942 immap->im_ioport.iop_padat &= !reg;
wdenk1f53a412002-12-04 23:39:58 +00001943 immap->im_ioport.iop_pcdir |= 0x0200;
1944 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00001945 if (reg) {
1946 debug ("PCMCIA powered at %sV\n",
1947 (reg&0x0400) ? "5.0" : "3.3");
1948 } else {
1949 debug ("PCMCIA powered down\n");
1950 }
1951
1952done:
1953 debug ("Enable PCMCIA buffers and stop RESET\n");
1954 reg = PCMCIA_PGCRX(_slot_);
1955 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1956 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1957 PCMCIA_PGCRX(_slot_) = reg;
1958 udelay(500);
1959
1960 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1961 slot+'A');
1962 return (0);
1963}
1964
1965#endif /* R360MPI */
1966
wdenk1f53a412002-12-04 23:39:58 +00001967/* -------------------------------------------------------------------- */
1968/* KUP4K Board */
1969/* -------------------------------------------------------------------- */
wdenk56f94be2002-11-05 16:35:14 +00001970#if defined(CONFIG_KUP4K)
1971
1972#define PCMCIA_BOARD_MSG "KUP4K"
1973
1974#define KUP4K_PCMCIA_B_3V3 (0x00020000)
1975
1976static int hardware_enable(int slot)
1977{
1978 volatile immap_t *immap;
1979 volatile cpm8xx_t *cp;
1980 volatile pcmconf8xx_t *pcmp;
1981 volatile sysconf8xx_t *sysp;
1982 uint reg, mask;
1983
1984 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1985
1986 udelay(10000);
1987
1988 immap = (immap_t *)CFG_IMMR;
1989 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1990 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1991 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1992
1993 /*
1994 * Configure SIUMCR to enable PCMCIA port B
1995 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1996 */
1997 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1998
1999 /* clear interrupt state, and disable interrupts */
wdenkea909b72002-11-21 23:11:29 +00002000 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2001 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002002
wdenk56f94be2002-11-05 16:35:14 +00002003 /*
wdenk1f53a412002-12-04 23:39:58 +00002004 * Disable interrupts, DMA, and PCMCIA buffers
2005 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002006 */
2007 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002008 reg = 0;
2009 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2010 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002011 PCMCIA_PGCRX(slot) = reg;
2012 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002013
2014 /*
2015 * Configure Port B pins for
2016 * 3 Volts enable
2017 */
wdenkea909b72002-11-21 23:11:29 +00002018 if (slot) { /* Slot A is built-in */
2019 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2020 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2021 /* remove all power */
2022 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2023 }
wdenk56f94be2002-11-05 16:35:14 +00002024 /*
2025 * Make sure there is a card in the slot, then configure the interface.
2026 */
2027 udelay(10000);
2028 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2029 __LINE__,__FUNCTION__,
2030 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002031 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002032 printf (" No Card found\n");
2033 return (1);
2034 }
2035
2036 /*
2037 * Power On.
2038 */
wdenka6c7ad22002-12-03 21:28:10 +00002039 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002040 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2041 reg = pcmp->pcmc_pipr;
2042 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2043 reg,
2044 (reg&PCMCIA_VS1(slot))?"n":"ff",
2045 (reg&PCMCIA_VS2(slot))?"n":"ff");
2046 if ((reg & mask) == mask) {
2047 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2048 } else {
wdenkea909b72002-11-21 23:11:29 +00002049 if(slot)
2050 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002051 puts (" 3.3V card found: ");
2052 }
2053#if 0
2054 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2055 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2056 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2057 udelay(500000);
2058#endif
2059 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002060 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002061 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2062 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002063 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002064
2065 udelay(250000); /* some cards need >150 ms to come up :-( */
2066
2067 debug ("# hardware_enable done\n");
2068
2069 return (0);
2070}
2071
2072
2073
2074#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2075static int hardware_disable(int slot)
2076{
2077 volatile immap_t *immap;
2078 volatile cpm8xx_t *cp;
2079 volatile pcmconf8xx_t *pcmp;
2080 u_long reg;
2081
2082 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2083
2084 immap = (immap_t *)CFG_IMMR;
2085 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2086 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk1f53a412002-12-04 23:39:58 +00002087
wdenk56f94be2002-11-05 16:35:14 +00002088 /* remove all power */
wdenkea909b72002-11-21 23:11:29 +00002089 if (slot)
2090 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002091
2092 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002093 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002094 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002095 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2096 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002097 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002098
2099 udelay(10000);
2100
2101 return (0);
2102}
2103#endif /* CFG_CMD_PCMCIA */
2104
2105
2106
2107static int voltage_set(int slot, int vcc, int vpp)
2108{
2109 volatile immap_t *immap;
2110 volatile cpm8xx_t *cp;
2111 volatile pcmconf8xx_t *pcmp;
2112 u_long reg;
2113
2114 debug ("voltage_set: " \
2115 PCMCIA_BOARD_MSG \
2116 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2117 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2118
wdenkea909b72002-11-21 23:11:29 +00002119 if (!slot) /* Slot A is not configurable */
2120 return 0;
2121
wdenk56f94be2002-11-05 16:35:14 +00002122 immap = (immap_t *)CFG_IMMR;
2123 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2124 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2125
2126 /*
2127 * Disable PCMCIA buffers (isolate the interface)
2128 * and assert RESET signal
2129 */
2130 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002131 reg = PCMCIA_PGCRX(slot);
2132 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2133 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002134 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002135 udelay(500);
2136
2137 debug ("PCMCIA power OFF\n");
2138 /*
2139 * Configure Port B pins for
2140 * 3 Volts enable
2141 */
2142 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2143 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2144 /* remove all power */
2145 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2146
2147 switch(vcc) {
2148 case 0: break;
2149 case 33:
2150 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2151 debug ("PCMCIA powered at 3.3V\n");
2152 break;
2153 case 50:
2154 debug ("PCMCIA: 5Volt vcc not supported\n");
2155 break;
2156 default:
2157 puts("PCMCIA: vcc not supported");
2158 break;
2159 }
wdenkea909b72002-11-21 23:11:29 +00002160 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002161 /* Checking supported voltages */
2162
2163 debug ("PIPR: 0x%x --> %s\n",
2164 pcmp->pcmc_pipr,
wdenkea909b72002-11-21 23:11:29 +00002165 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002166 ? "only 5 V --> NOT SUPPORTED"
2167 : "can do 3.3V");
2168
2169
2170 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002171 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002172 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2173 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002174 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002175 udelay(500);
2176
2177 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2178 slot+'A');
2179 return (0);
2180}
2181
2182#endif /* KUP4K */
2183
2184
2185
2186
wdenkc6097192002-11-03 00:24:07 +00002187
wdenk1f53a412002-12-04 23:39:58 +00002188/* -------------------------------------------------------------------- */
2189/* End of Board Specific Stuff */
2190/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002191
2192
wdenk1f53a412002-12-04 23:39:58 +00002193/* -------------------------------------------------------------------- */
2194/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2195/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002196
2197/*
2198 * Search this table to see if the windowsize is
2199 * supported...
2200 */
2201
2202#define M8XX_SIZES_NO 32
2203
2204static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2205{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2206 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2207 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2208 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2209
2210 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2211 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2212 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2213 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2214
2215
wdenk1f53a412002-12-04 23:39:58 +00002216/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002217
2218static u_int m8xx_get_graycode(u_int size)
2219{
2220 u_int k;
2221
2222 for (k = 0; k < M8XX_SIZES_NO; k++) {
2223 if(m8xx_size_to_gray[k] == size)
2224 break;
2225 }
2226
2227 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2228 k = -1;
2229
2230 return k;
2231}
2232
wdenk1f53a412002-12-04 23:39:58 +00002233/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002234
2235#if 0
2236static u_int m8xx_get_speed(u_int ns, u_int is_io)
2237{
2238 u_int reg, clocks, psst, psl, psht;
2239
2240 if(!ns) {
2241
2242 /*
2243 * We get called with IO maps setup to 0ns
2244 * if not specified by the user.
2245 * They should be 255ns.
2246 */
2247
2248 if(is_io)
2249 ns = 255;
2250 else
2251 ns = 100; /* fast memory if 0 */
2252 }
2253
2254 /*
2255 * In PSST, PSL, PSHT fields we tell the controller
2256 * timing parameters in CLKOUT clock cycles.
2257 * CLKOUT is the same as GCLK2_50.
2258 */
2259
2260/* how we want to adjust the timing - in percent */
2261
2262#define ADJ 180 /* 80 % longer accesstime - to be sure */
2263
2264 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2265 clocks = (clocks * ADJ) / (100*1000);
2266
2267 if(clocks >= PCMCIA_BMT_LIMIT) {
2268 DEBUG(0, "Max access time limit reached\n");
2269 clocks = PCMCIA_BMT_LIMIT-1;
2270 }
2271
2272 psst = clocks / 7; /* setup time */
2273 psht = clocks / 7; /* hold time */
2274 psl = (clocks * 5) / 7; /* strobe length */
2275
2276 psst += clocks - (psst + psht + psl);
2277
2278 reg = psst << 12;
2279 reg |= psl << 7;
2280 reg |= psht << 16;
2281
2282 return reg;
2283}
2284#endif
2285
wdenk1f53a412002-12-04 23:39:58 +00002286/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002287
2288#ifdef CONFIG_IDE_8xx_PCCARD
2289static void print_funcid (int func)
2290{
2291 puts (indent);
2292 switch (func) {
2293 case CISTPL_FUNCID_MULTI:
2294 puts (" Multi-Function");
2295 break;
2296 case CISTPL_FUNCID_MEMORY:
2297 puts (" Memory");
2298 break;
2299 case CISTPL_FUNCID_SERIAL:
2300 puts (" Serial Port");
2301 break;
2302 case CISTPL_FUNCID_PARALLEL:
2303 puts (" Parallel Port");
2304 break;
2305 case CISTPL_FUNCID_FIXED:
2306 puts (" Fixed Disk");
2307 break;
2308 case CISTPL_FUNCID_VIDEO:
2309 puts (" Video Adapter");
2310 break;
2311 case CISTPL_FUNCID_NETWORK:
2312 puts (" Network Adapter");
2313 break;
2314 case CISTPL_FUNCID_AIMS:
2315 puts (" AIMS Card");
2316 break;
2317 case CISTPL_FUNCID_SCSI:
2318 puts (" SCSI Adapter");
2319 break;
2320 default:
2321 puts (" Unknown");
2322 break;
2323 }
2324 puts (" Card\n");
2325}
2326#endif /* CONFIG_IDE_8xx_PCCARD */
2327
wdenk1f53a412002-12-04 23:39:58 +00002328/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002329
2330#ifdef CONFIG_IDE_8xx_PCCARD
2331static void print_fixed (volatile uchar *p)
2332{
2333 if (p == NULL)
2334 return;
2335
2336 puts(indent);
2337
2338 switch (*p) {
2339 case CISTPL_FUNCE_IDE_IFACE:
2340 { uchar iface = *(p+2);
2341
2342 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2343 puts (" interface ");
2344 break;
2345 }
2346 case CISTPL_FUNCE_IDE_MASTER:
2347 case CISTPL_FUNCE_IDE_SLAVE:
2348 { uchar f1 = *(p+2);
2349 uchar f2 = *(p+4);
2350
2351 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2352
2353 if (f1 & CISTPL_IDE_UNIQUE)
2354 puts (" [unique]");
2355
2356 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2357
2358 if (f2 & CISTPL_IDE_HAS_SLEEP)
2359 puts (" [sleep]");
2360
2361 if (f2 & CISTPL_IDE_HAS_STANDBY)
2362 puts (" [standby]");
2363
2364 if (f2 & CISTPL_IDE_HAS_IDLE)
2365 puts (" [idle]");
2366
2367 if (f2 & CISTPL_IDE_LOW_POWER)
2368 puts (" [low power]");
2369
2370 if (f2 & CISTPL_IDE_REG_INHIBIT)
2371 puts (" [reg inhibit]");
2372
2373 if (f2 & CISTPL_IDE_HAS_INDEX)
2374 puts (" [index]");
2375
2376 if (f2 & CISTPL_IDE_IOIS16)
2377 puts (" [IOis16]");
2378
2379 break;
2380 }
2381 }
2382 putc ('\n');
2383}
2384#endif /* CONFIG_IDE_8xx_PCCARD */
2385
wdenk1f53a412002-12-04 23:39:58 +00002386/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002387
2388#ifdef CONFIG_IDE_8xx_PCCARD
2389
2390#define MAX_IDENT_CHARS 64
2391#define MAX_IDENT_FIELDS 4
2392
2393static uchar *known_cards[] = {
2394 "ARGOSY PnPIDE D5",
2395 NULL
2396};
2397
2398static int identify (volatile uchar *p)
2399{
2400 uchar id_str[MAX_IDENT_CHARS];
2401 uchar data;
2402 uchar *t;
2403 uchar **card;
2404 int i, done;
2405
2406 if (p == NULL)
2407 return (0); /* Don't know */
2408
2409 t = id_str;
2410 done =0;
2411
2412 for (i=0; i<=4 && !done; ++i, p+=2) {
2413 while ((data = *p) != '\0') {
2414 if (data == 0xFF) {
2415 done = 1;
2416 break;
2417 }
2418 *t++ = data;
2419 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2420 done = 1;
2421 break;
2422 }
2423 p += 2;
2424 }
2425 if (!done)
2426 *t++ = ' ';
2427 }
2428 *t = '\0';
2429 while (--t > id_str) {
2430 if (*t == ' ')
2431 *t = '\0';
2432 else
2433 break;
2434 }
2435 puts (id_str);
2436 putc ('\n');
2437
2438 for (card=known_cards; *card; ++card) {
2439 debug ("## Compare against \"%s\"\n", *card);
2440 if (strcmp(*card, id_str) == 0) { /* found! */
2441 debug ("## CARD FOUND ##\n");
2442 return (1);
2443 }
2444 }
2445
2446 return (0); /* don't know */
2447}
2448#endif /* CONFIG_IDE_8xx_PCCARD */
2449
wdenk1f53a412002-12-04 23:39:58 +00002450/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002451
2452#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */