blob: f9bd0ba89b647b2f59172409a71b78631bddbaef [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
wdenkea909b72002-11-21 23:11:29 +0000271static int check_ide_device (int slot)
wdenkc6097192002-11-03 00:24:07 +0000272{
273 volatile uchar *ident = NULL;
274 volatile uchar *feature_p[MAX_FEATURES];
wdenkea909b72002-11-21 23:11:29 +0000275 volatile uchar *p, *start, *addr;
wdenkc6097192002-11-03 00:24:07 +0000276 int n_features = 0;
277 uchar func_id = ~0;
278 uchar code, len;
279 ushort config_base = 0;
280 int found = 0;
281 int i;
282
wdenk1f53a412002-12-04 23:39:58 +0000283 addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
284 CFG_PCMCIA_MEM_SIZE * (slot * 4));
wdenkd0fb80c2003-01-11 09:48:40 +0000285 debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
wdenkc6097192002-11-03 00:24:07 +0000286
wdenkea909b72002-11-21 23:11:29 +0000287 start = p = (volatile uchar *) addr;
wdenkc6097192002-11-03 00:24:07 +0000288
289 while ((p - start) < MAX_TUPEL_SZ) {
290
291 code = *p; p += 2;
292
293 if (code == 0xFF) { /* End of chain */
294 break;
295 }
296
297 len = *p; p += 2;
298#if defined(DEBUG) && (DEBUG > 1)
299 { volatile uchar *q = p;
300 printf ("\nTuple code %02x length %d\n\tData:",
301 code, len);
302
303 for (i = 0; i < len; ++i) {
304 printf (" %02x", *q);
305 q+= 2;
306 }
307 }
308#endif /* DEBUG */
309 switch (code) {
310 case CISTPL_VERS_1:
311 ident = p + 4;
312 break;
313 case CISTPL_FUNCID:
314 /* Fix for broken SanDisk which may have 0x80 bit set */
315 func_id = *p & 0x7F;
316 break;
317 case CISTPL_FUNCE:
318 if (n_features < MAX_FEATURES)
319 feature_p[n_features++] = p;
320 break;
321 case CISTPL_CONFIG:
322 config_base = (*(p+6) << 8) + (*(p+4));
323 debug ("\n## Config_base = %04x ###\n", config_base);
324 default:
325 break;
326 }
327 p += 2 * len;
328 }
329
330 found = identify (ident);
331
332 if (func_id != ((uchar)~0)) {
333 print_funcid (func_id);
334
335 if (func_id == CISTPL_FUNCID_FIXED)
336 found = 1;
337 else
338 return (1); /* no disk drive */
339 }
340
341 for (i=0; i<n_features; ++i) {
342 print_fixed (feature_p[i]);
343 }
344
345 if (!found) {
346 printf ("unknown card type\n");
347 return (1);
348 }
349
350 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
wdenkea909b72002-11-21 23:11:29 +0000351 *((uchar *)(addr + config_base)) = 1;
wdenkc6097192002-11-03 00:24:07 +0000352
353 return (0);
354}
355#endif /* CONFIG_IDE_8xx_PCCARD */
356
wdenk1f53a412002-12-04 23:39:58 +0000357/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000358
359
wdenk1f53a412002-12-04 23:39:58 +0000360/* -------------------------------------------------------------------- */
361/* board specific stuff: */
362/* voltage_set(), hardware_enable() and hardware_disable() */
363/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000364
wdenk1f53a412002-12-04 23:39:58 +0000365/* -------------------------------------------------------------------- */
366/* RPX Boards from Embedded Planet */
367/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000368
369#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
370
371/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
372 * SYPCR is write once only, therefore must the slowest memory be faster
373 * than the bus monitor or we will get a machine check due to the bus timeout.
374 */
375
376#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
377
378#undef PCMCIA_BMT_LIMIT
379#define PCMCIA_BMT_LIMIT (6*8)
380
381static int voltage_set(int slot, int vcc, int vpp)
382{
383 u_long reg = 0;
384
385 switch(vcc) {
386 case 0: break;
387 case 33: reg |= BCSR1_PCVCTL4; break;
388 case 50: reg |= BCSR1_PCVCTL5; break;
389 default: return 1;
390 }
391
392 switch(vpp) {
393 case 0: break;
394 case 33:
395 case 50:
396 if(vcc == vpp)
397 reg |= BCSR1_PCVCTL6;
398 else
399 return 1;
400 break;
401 case 120:
402 reg |= BCSR1_PCVCTL7;
403 default: return 1;
404 }
405
406 if(vcc == 120)
407 return 1;
408
409 /* first, turn off all power */
410
411 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
412 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
413
414 /* enable new powersettings */
415
416 *((uint *)RPX_CSR_ADDR) |= reg;
417
418 return 0;
419}
420
421#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
422static int hardware_enable (int slot)
423{
424 return 0; /* No hardware to enable */
425}
426#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
427static int hardware_disable(int slot)
428{
429 return 0; /* No hardware to disable */
430}
431#endif /* CFG_CMD_PCMCIA */
432#endif /* CONFIG_RPXCLASSIC */
433
wdenk1f53a412002-12-04 23:39:58 +0000434/* -------------------------------------------------------------------- */
435/* (F)ADS Boards from Motorola */
436/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000437
438#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
439
440#ifdef CONFIG_ADS
441#define PCMCIA_BOARD_MSG "ADS"
442#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
443#else
444#define PCMCIA_BOARD_MSG "FADS"
445#endif
446
447static int voltage_set(int slot, int vcc, int vpp)
448{
449 u_long reg = 0;
450
451 switch(vpp) {
452 case 0: reg = 0; break;
453 case 50: reg = 1; break;
454 case 120: reg = 2; break;
455 default: return 1;
456 }
457
458 switch(vcc) {
459 case 0: reg = 0; break;
460#ifdef CONFIG_ADS
461 case 50: reg = BCSR1_PCCVCCON; break;
462#endif
463#ifdef CONFIG_FADS
464 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
465 case 50: reg = BCSR1_PCCVCC1; break;
466#endif
467 default: return 1;
468 }
469
470 /* first, turn off all power */
471
472#ifdef CONFIG_ADS
473 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
474#endif
475#ifdef CONFIG_FADS
476 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
477#endif
478 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
479
480 /* enable new powersettings */
481
482#ifdef CONFIG_ADS
483 *((uint *)BCSR1) &= ~reg;
484#endif
485#ifdef CONFIG_FADS
486 *((uint *)BCSR1) |= reg;
487#endif
488
489 *((uint *)BCSR1) |= reg << 20;
490
491 return 0;
492}
493
494#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
495
496static int hardware_enable(int slot)
497{
498 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
499 return 0;
500}
501
502#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
503static int hardware_disable(int slot)
504{
505 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
506 return 0;
507}
508#endif /* CFG_CMD_PCMCIA */
509
510#endif /* (F)ADS */
511
wdenk1f53a412002-12-04 23:39:58 +0000512/* -------------------------------------------------------------------- */
513/* TQM8xxL Boards by TQ Components */
514/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000515
516#if defined(CONFIG_TQM8xxL)
517
518#define PCMCIA_BOARD_MSG "TQM8xxL"
519
520
521static int hardware_enable(int slot)
522{
523 volatile immap_t *immap;
524 volatile cpm8xx_t *cp;
525 volatile pcmconf8xx_t *pcmp;
526 volatile sysconf8xx_t *sysp;
527 uint reg, mask;
528
529 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
530
531 udelay(10000);
532
533 immap = (immap_t *)CFG_IMMR;
534 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
535 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
536 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
537
538 /*
539 * Configure SIUMCR to enable PCMCIA port B
540 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
541 */
542 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
543
544 /* clear interrupt state, and disable interrupts */
545 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
546 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
547
wdenkc6097192002-11-03 00:24:07 +0000548 /*
wdenk1f53a412002-12-04 23:39:58 +0000549 * Disable interrupts, DMA, and PCMCIA buffers
550 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000551 */
552 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000553 reg = 0;
554 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
555 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000556 PCMCIA_PGCRX(_slot_) = reg;
557 udelay(500);
558
559 /*
560 * Configure Port C pins for
561 * 5 Volts Enable and 3 Volts enable
562 */
563 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
564 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
565 /* remove all power */
566
567 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
568
569 /*
570 * Make sure there is a card in the slot, then configure the interface.
571 */
572 udelay(10000);
573 debug ("[%d] %s: PIPR(%p)=0x%x\n",
574 __LINE__,__FUNCTION__,
575 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +0000576 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000577 printf (" No Card found\n");
578 return (1);
579 }
580
581 /*
582 * Power On.
583 */
584 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
585 reg = pcmp->pcmc_pipr;
586 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
587 reg,
588 (reg&PCMCIA_VS1(slot))?"n":"ff",
589 (reg&PCMCIA_VS2(slot))?"n":"ff");
590 if ((reg & mask) == mask) {
591 immap->im_ioport.iop_pcdat |= 0x0004;
592 puts (" 5.0V card found: ");
593 } else {
594 immap->im_ioport.iop_pcdat |= 0x0002;
595 puts (" 3.3V card found: ");
596 }
wdenk1f53a412002-12-04 23:39:58 +0000597 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000598#if 0
599 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
600 cp->cp_pbdir &= ~(0x0020 | 0x0010);
601 cp->cp_pbpar &= ~(0x0020 | 0x0010);
602 udelay(500000);
603#endif
604 udelay(1000);
605 debug ("Enable PCMCIA buffers and stop RESET\n");
606 reg = PCMCIA_PGCRX(_slot_);
607 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
608 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
609 PCMCIA_PGCRX(_slot_) = reg;
610
611 udelay(250000); /* some cards need >150 ms to come up :-( */
612
613 debug ("# hardware_enable done\n");
614
615 return (0);
616}
617
618
619
620#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
621static int hardware_disable(int slot)
622{
623 volatile immap_t *immap;
624 volatile pcmconf8xx_t *pcmp;
625 u_long reg;
626
627 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
628
629 immap = (immap_t *)CFG_IMMR;
630 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
631
632 /* remove all power */
633 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
634
wdenkc6097192002-11-03 00:24:07 +0000635 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000636 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000637 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
638 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
639 PCMCIA_PGCRX(_slot_) = reg;
640
641 udelay(10000);
642
643 return (0);
644}
645#endif /* CFG_CMD_PCMCIA */
646
647
648
649static int voltage_set(int slot, int vcc, int vpp)
650{
651 volatile immap_t *immap;
652 volatile pcmconf8xx_t *pcmp;
653 u_long reg;
654
655 debug ("voltage_set: "
656 PCMCIA_BOARD_MSG
657 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
658 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
659
660 immap = (immap_t *)CFG_IMMR;
661 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
662 /*
663 * Disable PCMCIA buffers (isolate the interface)
664 * and assert RESET signal
665 */
666 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000667 reg = PCMCIA_PGCRX(_slot_);
668 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
669 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000670 PCMCIA_PGCRX(_slot_) = reg;
671 udelay(500);
672
673 /*
674 * Configure Port C pins for
675 * 5 Volts Enable and 3 Volts enable,
676 * Turn off all power
677 */
678 debug ("PCMCIA power OFF\n");
679 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
680 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
681 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
682
683 reg = 0;
684 switch(vcc) {
685 case 0: break;
686 case 33: reg |= 0x0002; break;
687 case 50: reg |= 0x0004; break;
688 default: goto done;
689 }
690
691 /* Checking supported voltages */
692
693 debug ("PIPR: 0x%x --> %s\n",
694 pcmp->pcmc_pipr,
695 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
696
697 immap->im_ioport.iop_pcdat |= reg;
wdenk1f53a412002-12-04 23:39:58 +0000698 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000699 if (reg) {
700 debug ("PCMCIA powered at %sV\n",
701 (reg&0x0004) ? "5.0" : "3.3");
702 } else {
703 debug ("PCMCIA powered down\n");
704 }
705
706done:
707 debug ("Enable PCMCIA buffers and stop RESET\n");
708 reg = PCMCIA_PGCRX(_slot_);
709 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
710 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
711 PCMCIA_PGCRX(_slot_) = reg;
712 udelay(500);
713
714 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
715 slot+'A');
716 return (0);
717}
718
719#endif /* TQM8xxL */
720
721
wdenk1f53a412002-12-04 23:39:58 +0000722/* -------------------------------------------------------------------- */
723/* LWMON Board */
724/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000725
726#if defined(CONFIG_LWMON)
727
728#define PCMCIA_BOARD_MSG "LWMON"
729
730/* #define's for MAX1604 Power Switch */
731#define MAX1604_OP_SUS 0x80
732#define MAX1604_VCCBON 0x40
733#define MAX1604_VCC_35 0x20
734#define MAX1604_VCCBHIZ 0x10
735#define MAX1604_VPPBON 0x08
736#define MAX1604_VPPBPBPGM 0x04
737#define MAX1604_VPPBHIZ 0x02
738/* reserved 0x01 */
739
740static int hardware_enable(int slot)
741{
742 volatile immap_t *immap;
743 volatile cpm8xx_t *cp;
744 volatile pcmconf8xx_t *pcmp;
745 volatile sysconf8xx_t *sysp;
746 uint reg, mask;
747 uchar val;
748
749
750 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
751
752 /* Switch on PCMCIA port in PIC register 0x60 */
753 reg = pic_read (0x60);
754 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
755 reg &= ~0x10;
wdenk1f53a412002-12-04 23:39:58 +0000756 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +0000757 pic_write (0x60, reg);
758#ifdef DEBUG
759 reg = pic_read (0x60);
760 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
761#endif
762 udelay(10000);
763
764 immap = (immap_t *)CFG_IMMR;
765 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
766 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
767 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
768
769 /*
770 * Configure SIUMCR to enable PCMCIA port B
771 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
772 */
773 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
774
775 /* clear interrupt state, and disable interrupts */
776 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
777 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
778
wdenkc6097192002-11-03 00:24:07 +0000779 /*
wdenk1f53a412002-12-04 23:39:58 +0000780 * Disable interrupts, DMA, and PCMCIA buffers
781 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000782 */
783 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000784 reg = 0;
785 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
786 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000787 PCMCIA_PGCRX(_slot_) = reg;
788 udelay(500);
789
790 /*
791 * Make sure there is a card in the slot, then configure the interface.
792 */
793 udelay(10000);
794 debug ("[%d] %s: PIPR(%p)=0x%x\n",
795 __LINE__,__FUNCTION__,
796 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +0000797 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000798 printf (" No Card found\n");
799 return (1);
800 }
801
802 /*
803 * Power On.
804 */
805 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
806 reg = pcmp->pcmc_pipr;
807 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
808 reg,
809 (reg&PCMCIA_VS1(slot))?"n":"ff",
810 (reg&PCMCIA_VS2(slot))?"n":"ff");
811 if ((reg & mask) == mask) {
812 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
813 puts (" 5.0V card found: ");
814 } else {
815 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
816 puts (" 3.3V card found: ");
817 }
818
819 /* switch VCC on */
wdenk1f53a412002-12-04 23:39:58 +0000820 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +0000821 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
822 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
823
824 udelay(500000);
825
826 debug ("Enable PCMCIA buffers and stop RESET\n");
827 reg = PCMCIA_PGCRX(_slot_);
828 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
829 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
830 PCMCIA_PGCRX(_slot_) = reg;
831
832 udelay(250000); /* some cards need >150 ms to come up :-( */
833
834 debug ("# hardware_enable done\n");
835
836 return (0);
837}
838
839
840
841#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
842static int hardware_disable(int slot)
843{
844 volatile immap_t *immap;
845 volatile pcmconf8xx_t *pcmp;
846 u_long reg;
847 uchar val;
848
849 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
850
851 immap = (immap_t *)CFG_IMMR;
852 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
853
854 /* remove all power, put output in high impedance state */
855 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
856 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
857 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
858
859 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +0000860 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000861 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000862 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
863 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
864 PCMCIA_PGCRX(_slot_) = reg;
865
866 /* Switch off PCMCIA port in PIC register 0x60 */
867 reg = pic_read (0x60);
868 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
869 reg |= 0x10;
870 reg &= ~0x08;
871 pic_write (0x60, reg);
872#ifdef DEBUG
873 reg = pic_read (0x60);
874 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
875#endif
876 udelay(10000);
877
878 return (0);
879}
880#endif /* CFG_CMD_PCMCIA */
881
882
883
884static int voltage_set(int slot, int vcc, int vpp)
885{
886 volatile immap_t *immap;
887 volatile pcmconf8xx_t *pcmp;
888 u_long reg;
889 uchar val;
890
891 debug ("voltage_set: "
892 PCMCIA_BOARD_MSG
893 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
894 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
895
896 immap = (immap_t *)CFG_IMMR;
897 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
898 /*
899 * Disable PCMCIA buffers (isolate the interface)
900 * and assert RESET signal
901 */
902 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000903 reg = PCMCIA_PGCRX(_slot_);
904 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
905 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000906 PCMCIA_PGCRX(_slot_) = reg;
907 udelay(500);
908
909 /*
910 * Turn off all power (switch to high impedance)
911 */
912 debug ("PCMCIA power OFF\n");
913 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
914 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
915 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
916
917 val = 0;
918 switch(vcc) {
919 case 0: break;
920 case 33: val = MAX1604_VCC_35; break;
921 case 50: break;
922 default: goto done;
923 }
924
925 /* Checking supported voltages */
926
927 debug ("PIPR: 0x%x --> %s\n",
928 pcmp->pcmc_pipr,
929 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
930
931 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
932 if (val) {
933 debug ("PCMCIA powered at %sV\n",
934 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
935 } else {
936 debug ("PCMCIA powered down\n");
937 }
938
939done:
940 debug ("Enable PCMCIA buffers and stop RESET\n");
941 reg = PCMCIA_PGCRX(_slot_);
942 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
943 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
944 PCMCIA_PGCRX(_slot_) = reg;
945 udelay(500);
946
947 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
948 slot+'A');
949 return (0);
950}
951
952#endif /* LWMON */
953
wdenk1f53a412002-12-04 23:39:58 +0000954/* -------------------------------------------------------------------- */
955/* GTH board by Corelatus AB */
956/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000957#if defined(CONFIG_GTH)
958
959#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
960
wdenk1f53a412002-12-04 23:39:58 +0000961static int voltage_set (int slot, int vcc, int vpp)
962{ /* Do nothing */
963 return 0;
wdenkc6097192002-11-03 00:24:07 +0000964}
965
966static int hardware_enable (int slot)
967{
wdenk1f53a412002-12-04 23:39:58 +0000968 volatile immap_t *immap;
969 volatile cpm8xx_t *cp;
970 volatile pcmconf8xx_t *pcmp;
971 volatile sysconf8xx_t *sysp;
972 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +0000973
wdenk1f53a412002-12-04 23:39:58 +0000974 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +0000975
wdenk1f53a412002-12-04 23:39:58 +0000976 immap = (immap_t *) CFG_IMMR;
977 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
978 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
979 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +0000980
wdenk1f53a412002-12-04 23:39:58 +0000981 /* clear interrupt state, and disable interrupts */
982 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
983 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +0000984
wdenk1f53a412002-12-04 23:39:58 +0000985 /*
986 * Disable interrupts, DMA, and PCMCIA buffers
987 * (isolate the interface) and assert RESET signal
988 */
989 debug ("Disable PCMCIA buffers and assert RESET\n");
990 reg = 0;
991 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
992 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
993 PCMCIA_PGCRX (_slot_) = reg;
994 udelay (500);
wdenkc6097192002-11-03 00:24:07 +0000995
wdenk1f53a412002-12-04 23:39:58 +0000996 /*
997 * Make sure there is a card in the slot,
998 * then configure the interface.
999 */
1000 udelay (10000);
1001 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1002 __LINE__, __FUNCTION__,
1003 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1004 if (pcmp->pcmc_pipr & 0x98000000) {
1005 printf (" No Card found\n");
1006 return (1);
1007 }
wdenkc6097192002-11-03 00:24:07 +00001008
wdenk1f53a412002-12-04 23:39:58 +00001009 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1010 reg = pcmp->pcmc_pipr;
1011 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1012 reg,
1013 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1014 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001015
wdenk1f53a412002-12-04 23:39:58 +00001016 debug ("Enable PCMCIA buffers and stop RESET\n");
1017 reg = PCMCIA_PGCRX (_slot_);
1018 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1019 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1020 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001021
wdenk1f53a412002-12-04 23:39:58 +00001022 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001023
wdenk1f53a412002-12-04 23:39:58 +00001024 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001025
wdenk1f53a412002-12-04 23:39:58 +00001026 return 0;
wdenkc6097192002-11-03 00:24:07 +00001027}
1028#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1029static int hardware_disable(int slot)
1030{
1031 return 0; /* No hardware to disable */
1032}
1033#endif /* CFG_CMD_PCMCIA */
1034#endif /* CONFIG_GTH */
1035
wdenk1f53a412002-12-04 23:39:58 +00001036/* -------------------------------------------------------------------- */
1037/* ICU862 Boards by Cambridge Broadband Ltd. */
1038/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001039
1040#if defined(CONFIG_ICU862)
1041
1042#define PCMCIA_BOARD_MSG "ICU862"
1043
1044static void cfg_port_B (void);
1045
1046static int hardware_enable(int slot)
1047{
1048 volatile immap_t *immap;
1049 volatile cpm8xx_t *cp;
1050 volatile pcmconf8xx_t *pcmp;
1051 volatile sysconf8xx_t *sysp;
1052 uint reg, pipr, mask;
1053 int i;
1054
1055 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1056
1057 udelay(10000);
1058
1059 immap = (immap_t *)CFG_IMMR;
1060 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1061 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1062 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1063
1064 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1065 cfg_port_B ();
1066
1067 /*
1068 * Configure SIUMCR to enable PCMCIA port B
1069 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1070 */
1071 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1072
1073 /* clear interrupt state, and disable interrupts */
1074 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1075 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1076
wdenkc6097192002-11-03 00:24:07 +00001077 /*
wdenk1f53a412002-12-04 23:39:58 +00001078 * Disable interrupts, DMA, and PCMCIA buffers
1079 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001080 */
1081 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001082 reg = 0;
1083 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1084 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001085 PCMCIA_PGCRX(_slot_) = reg;
1086 udelay(500);
1087
1088 /*
1089 * Make sure there is a card in the slot, then configure the interface.
1090 */
1091 udelay(10000);
1092 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1093 __LINE__,__FUNCTION__,
1094 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001095 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001096 printf (" No Card found\n");
1097 return (1);
1098 }
1099
1100 /*
1101 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1102 */
1103 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1104 pipr = pcmp->pcmc_pipr;
1105 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1106 pipr,
1107 (reg&PCMCIA_VS1(slot))?"n":"ff",
1108 (reg&PCMCIA_VS2(slot))?"n":"ff");
1109
1110 reg = cp->cp_pbdat;
1111 if ((pipr & mask) == mask) {
wdenk1f53a412002-12-04 23:39:58 +00001112 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1113 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001114 reg &= ~(TPS2205_VCC5); /* 5V on */
1115 puts (" 5.0V card found: ");
1116 } else {
wdenk1f53a412002-12-04 23:39:58 +00001117 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1118 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001119 reg &= ~(TPS2205_VCC3); /* 3V on */
1120 puts (" 3.3V card found: ");
1121 }
1122
1123 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1124 reg,
1125 (reg & TPS2205_VCC3) ? "off" : "on",
1126 (reg & TPS2205_VCC5) ? "off" : "on",
1127 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1128 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1129
1130 cp->cp_pbdat = reg;
1131
1132 /* Wait 500 ms; use this to check for over-current */
1133 for (i=0; i<5000; ++i) {
1134 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1135 printf (" *** Overcurrent - Safety shutdown ***\n");
1136 cp->cp_pbdat &= ~(TPS2205_SHDN);
1137 return (1);
1138 }
1139 udelay (100);
1140 }
1141
1142 debug ("Enable PCMCIA buffers and stop RESET\n");
1143 reg = PCMCIA_PGCRX(_slot_);
1144 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1145 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1146 PCMCIA_PGCRX(_slot_) = reg;
1147
1148 udelay(250000); /* some cards need >150 ms to come up :-( */
1149
1150 debug ("# hardware_enable done\n");
1151
1152 return (0);
1153}
1154
1155
1156
1157#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1158static int hardware_disable(int slot)
1159{
1160 volatile immap_t *immap;
1161 volatile cpm8xx_t *cp;
1162 volatile pcmconf8xx_t *pcmp;
1163 u_long reg;
1164
1165 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1166
1167 immap = (immap_t *)CFG_IMMR;
1168 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1169 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1170
1171 /* Shut down */
1172 cp->cp_pbdat &= ~(TPS2205_SHDN);
1173
1174 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001175 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001176 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001177 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1178 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1179 PCMCIA_PGCRX(_slot_) = reg;
1180
1181 udelay(10000);
1182
1183 return (0);
1184}
1185#endif /* CFG_CMD_PCMCIA */
1186
1187
1188
1189static int voltage_set(int slot, int vcc, int vpp)
1190{
1191 volatile immap_t *immap;
1192 volatile cpm8xx_t *cp;
1193 volatile pcmconf8xx_t *pcmp;
1194 u_long reg;
1195
1196 debug ("voltage_set: "
1197 PCMCIA_BOARD_MSG
1198 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1199 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1200
1201 immap = (immap_t *)CFG_IMMR;
1202 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1203 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1204 /*
1205 * Disable PCMCIA buffers (isolate the interface)
1206 * and assert RESET signal
1207 */
1208 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001209 reg = PCMCIA_PGCRX(_slot_);
1210 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1211 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001212 PCMCIA_PGCRX(_slot_) = reg;
1213 udelay(500);
1214
1215 /*
1216 * Configure Port C pins for
1217 * 5 Volts Enable and 3 Volts enable,
1218 * Turn all power pins to Hi-Z
1219 */
1220 debug ("PCMCIA power OFF\n");
1221 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1222
1223 reg = cp->cp_pbdat;
1224
1225 switch(vcc) {
1226 case 0: break; /* Switch off */
1227 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1228 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1229 default: goto done;
1230 }
1231
1232 /* Checking supported voltages */
1233
1234 debug ("PIPR: 0x%x --> %s\n",
1235 pcmp->pcmc_pipr,
1236 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1237
1238 cp->cp_pbdat = reg;
1239
1240#ifdef DEBUG
1241 {
1242 char *s;
1243
1244 if ((reg & TPS2205_VCC3) == 0) {
1245 s = "at 3.3V";
1246 } else if ((reg & TPS2205_VCC5) == 0) {
1247 s = "at 5.0V";
1248 } else {
1249 s = "down";
1250 }
1251 printf ("PCMCIA powered %s\n", s);
1252 }
1253#endif
1254
1255done:
1256 debug ("Enable PCMCIA buffers and stop RESET\n");
1257 reg = PCMCIA_PGCRX(_slot_);
1258 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1259 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1260 PCMCIA_PGCRX(_slot_) = reg;
1261 udelay(500);
1262
1263 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1264 slot+'A');
1265 return (0);
1266}
1267
1268static void cfg_port_B (void)
1269{
1270 volatile immap_t *immap;
1271 volatile cpm8xx_t *cp;
1272 uint reg;
1273
1274 immap = (immap_t *)CFG_IMMR;
1275 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1276
1277 /*
1278 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1279 *
1280 * Switch off all voltages, assert shutdown
1281 */
1282 reg = cp->cp_pbdat;
wdenk1f53a412002-12-04 23:39:58 +00001283 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1284 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1285 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001286 cp->cp_pbdat = reg;
1287
1288 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1289
1290 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1291 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1292
1293 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1294 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1295}
1296
1297#endif /* ICU862 */
1298
1299
wdenk1f53a412002-12-04 23:39:58 +00001300/* -------------------------------------------------------------------- */
1301/* C2MON Boards by TTTech Computertechnik AG */
1302/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001303
1304#if defined(CONFIG_C2MON)
1305
1306#define PCMCIA_BOARD_MSG "C2MON"
1307
1308static void cfg_ports (void);
1309
1310static int hardware_enable(int slot)
1311{
1312 volatile immap_t *immap;
1313 volatile cpm8xx_t *cp;
1314 volatile pcmconf8xx_t *pcmp;
1315 volatile sysconf8xx_t *sysp;
1316 uint reg, pipr, mask;
1317 ushort sreg;
1318 int i;
1319
1320 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1321
1322 udelay(10000);
1323
1324 immap = (immap_t *)CFG_IMMR;
1325 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1326 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1327 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1328
1329 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1330 cfg_ports ();
1331
1332 /*
1333 * Configure SIUMCR to enable PCMCIA port B
1334 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1335 */
1336 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1337
1338 /* clear interrupt state, and disable interrupts */
1339 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1340 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1341
wdenkc6097192002-11-03 00:24:07 +00001342 /*
wdenk1f53a412002-12-04 23:39:58 +00001343 * Disable interrupts, DMA, and PCMCIA buffers
1344 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001345 */
1346 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001347 reg = 0;
1348 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1349 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001350 PCMCIA_PGCRX(_slot_) = reg;
1351 udelay(500);
1352
1353 /*
1354 * Make sure there is a card in the slot, then configure the interface.
1355 */
1356 udelay(10000);
1357 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1358 __LINE__,__FUNCTION__,
1359 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001360 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001361 printf (" No Card found\n");
1362 return (1);
1363 }
1364
1365 /*
1366 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1367 */
1368 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1369 pipr = pcmp->pcmc_pipr;
1370 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1371 pipr,
1372 (reg&PCMCIA_VS1(slot))?"n":"ff",
1373 (reg&PCMCIA_VS2(slot))?"n":"ff");
1374
1375 sreg = immap->im_ioport.iop_pcdat;
1376 if ((pipr & mask) == mask) {
1377 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1378 TPS2211_VCCD1); /* 5V on */
1379 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1380 puts (" 5.0V card found: ");
1381 } else {
1382 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1383 TPS2211_VCCD0); /* 3V on */
1384 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1385 puts (" 3.3V card found: ");
1386 }
1387
1388 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1389 sreg,
1390 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1391 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1392 );
1393
1394 immap->im_ioport.iop_pcdat = sreg;
1395
1396 /* Wait 500 ms; use this to check for over-current */
1397 for (i=0; i<5000; ++i) {
1398 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1399 printf (" *** Overcurrent - Safety shutdown ***\n");
1400 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1401 return (1);
1402 }
1403 udelay (100);
1404 }
1405
1406 debug ("Enable PCMCIA buffers and stop RESET\n");
1407 reg = PCMCIA_PGCRX(_slot_);
1408 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1409 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1410 PCMCIA_PGCRX(_slot_) = reg;
1411
1412 udelay(250000); /* some cards need >150 ms to come up :-( */
1413
1414 debug ("# hardware_enable done\n");
1415
1416 return (0);
1417}
1418
1419
1420
1421#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1422static int hardware_disable(int slot)
1423{
1424 volatile immap_t *immap;
1425 volatile cpm8xx_t *cp;
1426 volatile pcmconf8xx_t *pcmp;
1427 u_long reg;
1428
1429 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1430
1431 immap = (immap_t *)CFG_IMMR;
1432 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1433
1434 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001435 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001436 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001437 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1438 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1439 PCMCIA_PGCRX(_slot_) = reg;
1440
1441 /* ALl voltages off / Hi-Z */
1442 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1443 TPS2211_VCCD0 | TPS2211_VCCD1 );
1444
1445 udelay(10000);
1446
1447 return (0);
1448}
1449#endif /* CFG_CMD_PCMCIA */
1450
1451
1452
1453static int voltage_set(int slot, int vcc, int vpp)
1454{
1455 volatile immap_t *immap;
1456 volatile cpm8xx_t *cp;
1457 volatile pcmconf8xx_t *pcmp;
1458 u_long reg;
1459 ushort sreg;
1460
1461 debug ("voltage_set: "
1462 PCMCIA_BOARD_MSG
1463 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1464 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1465
1466 immap = (immap_t *)CFG_IMMR;
1467 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1468 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1469 /*
1470 * Disable PCMCIA buffers (isolate the interface)
1471 * and assert RESET signal
1472 */
1473 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001474 reg = PCMCIA_PGCRX(_slot_);
1475 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1476 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001477 PCMCIA_PGCRX(_slot_) = reg;
1478 udelay(500);
1479
1480 /*
1481 * Configure Port C pins for
1482 * 5 Volts Enable and 3 Volts enable,
1483 * Turn all power pins to Hi-Z
1484 */
1485 debug ("PCMCIA power OFF\n");
1486 cfg_ports (); /* Enables switch, but all in Hi-Z */
1487
1488 sreg = immap->im_ioport.iop_pcdat;
1489 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1490
1491 switch(vcc) {
1492 case 0: break; /* Switch off */
1493 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1494 sreg &= ~TPS2211_VCCD1;
1495 break;
1496 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1497 sreg |= TPS2211_VCCD1;
1498 break;
1499 default: goto done;
1500 }
1501
1502 /* Checking supported voltages */
1503
1504 debug ("PIPR: 0x%x --> %s\n",
1505 pcmp->pcmc_pipr,
1506 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1507
1508 immap->im_ioport.iop_pcdat = sreg;
1509
1510#ifdef DEBUG
1511 {
1512 char *s;
1513
1514 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1515 s = "at 3.3V";
1516 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1517 s = "at 5.0V";
1518 } else {
1519 s = "down";
1520 }
1521 printf ("PCMCIA powered %s\n", s);
1522 }
1523#endif
1524
1525done:
1526 debug ("Enable PCMCIA buffers and stop RESET\n");
1527 reg = PCMCIA_PGCRX(_slot_);
1528 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1529 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1530 PCMCIA_PGCRX(_slot_) = reg;
1531 udelay(500);
1532
1533 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1534 slot+'A');
1535 return (0);
1536}
1537
1538static void cfg_ports (void)
1539{
1540 volatile immap_t *immap;
1541 volatile cpm8xx_t *cp;
1542 ushort sreg;
1543
1544 immap = (immap_t *)CFG_IMMR;
1545 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1546
1547 /*
1548 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1549 *
1550 * Switch off all voltages, assert shutdown
1551 */
1552 sreg = immap->im_ioport.iop_pcdat;
1553 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1554 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1555 immap->im_ioport.iop_pcdat = sreg;
1556
1557 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1558 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1559
1560 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1561 immap->im_ioport.iop_pcpar,
1562 immap->im_ioport.iop_pcdir,
1563 immap->im_ioport.iop_pcdat);
1564
1565 /*
1566 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1567 *
1568 * Over-Current Input only
1569 */
1570 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1571 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1572
1573 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1574 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1575}
1576
1577#endif /* C2MON */
1578
wdenk1f53a412002-12-04 23:39:58 +00001579/* -------------------------------------------------------------------- */
1580/* MBX board from Morotola */
1581/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001582
1583#if defined( CONFIG_MBX )
1584#include <../board/mbx8xx/csr.h>
1585
1586/* A lot of this has been taken from the RPX code in this file it works from me.
1587 I have added the voltage selection for the MBX board. */
1588
1589/* MBX voltage bit in control register #2 */
1590#define CR2_VPP12 ((uchar)0x10)
1591#define CR2_VPPVDD ((uchar)0x20)
1592#define CR2_VDD5 ((uchar)0x40)
1593#define CR2_VDD3 ((uchar)0x80)
1594
1595#define PCMCIA_BOARD_MSG "MBX860"
1596
1597static int voltage_set (int slot, int vcc, int vpp)
1598{
1599 uchar reg = 0;
1600
1601 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1602 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1603
1604 switch (vcc) {
1605 case 0:
1606 break;
1607 case 33:
1608 reg |= CR2_VDD3;
1609 break;
1610 case 50:
1611 reg |= CR2_VDD5;
1612 break;
1613 default:
1614 return 1;
1615 }
1616
1617 switch (vpp) {
1618 case 0:
1619 break;
1620 case 33:
1621 case 50:
1622 if (vcc == vpp) {
1623 reg |= CR2_VPPVDD;
1624 } else {
1625 return 1;
1626 }
1627 break;
1628 case 120:
1629 reg |= CR2_VPP12;
1630 break;
1631 default:
1632 return 1;
1633 }
1634
1635 /* first, turn off all power */
1636 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1637
1638 /* enable new powersettings */
1639 MBX_CSR2 |= reg;
1640 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1641
1642 return (0);
1643}
1644
1645static int hardware_enable (int slot)
1646{
1647 volatile immap_t *immap;
1648 volatile cpm8xx_t *cp;
1649 volatile pcmconf8xx_t *pcmp;
1650 volatile sysconf8xx_t *sysp;
1651 uint reg, mask;
1652
1653 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1654 'A' + slot);
1655
1656 udelay (10000);
1657
1658 immap = (immap_t *) CFG_IMMR;
1659 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1660 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1661 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1662
1663 /* clear interrupt state, and disable interrupts */
1664 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1665 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1666
wdenkc6097192002-11-03 00:24:07 +00001667 /*
wdenk1f53a412002-12-04 23:39:58 +00001668 * Disable interrupts, DMA, and PCMCIA buffers
1669 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001670 */
1671 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001672 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001673 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1674 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1675 PCMCIA_PGCRX (_slot_) = reg;
1676 udelay (500);
1677
1678 /* remove all power */
1679 voltage_set (slot, 0, 0);
1680 /*
1681 * Make sure there is a card in the slot, then configure the interface.
1682 */
wdenkea909b72002-11-21 23:11:29 +00001683 udelay(10000);
1684 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1685 __LINE__,__FUNCTION__,
1686 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1687 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001688 printf (" No Card found\n");
1689 return (1);
1690 }
1691
1692 /*
1693 * Power On.
1694 */
1695 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1696 reg = pcmp->pcmc_pipr;
1697 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1698 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1699 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1700
1701 if ((reg & mask) == mask) {
1702 voltage_set (_slot_, 50, 0);
1703 printf (" 5.0V card found: ");
1704 } else {
1705 voltage_set (_slot_, 33, 0);
1706 printf (" 3.3V card found: ");
1707 }
1708
1709 debug ("Enable PCMCIA buffers and stop RESET\n");
1710 reg = PCMCIA_PGCRX (_slot_);
1711 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1712 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1713 PCMCIA_PGCRX (_slot_) = reg;
1714
1715 udelay (250000); /* some cards need >150 ms to come up :-( */
1716
1717 debug ("# hardware_enable done\n");
1718
1719 return (0);
1720}
1721
1722#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1723static int hardware_disable (int slot)
1724{
1725 return 0; /* No hardware to disable */
1726}
1727#endif /* CFG_CMD_PCMCIA */
1728#endif /* CONFIG_MBX */
wdenk1f53a412002-12-04 23:39:58 +00001729/* -------------------------------------------------------------------- */
1730/* R360MPI Board */
1731/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001732
1733#if defined(CONFIG_R360MPI)
1734
1735#define PCMCIA_BOARD_MSG "R360MPI"
1736
1737
1738static int hardware_enable(int slot)
1739{
1740 volatile immap_t *immap;
1741 volatile cpm8xx_t *cp;
1742 volatile pcmconf8xx_t *pcmp;
1743 volatile sysconf8xx_t *sysp;
1744 uint reg, mask;
1745
1746 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1747
1748 udelay(10000);
1749
1750 immap = (immap_t *)CFG_IMMR;
1751 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1752 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1753 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1754
1755 /*
1756 * Configure SIUMCR to enable PCMCIA port B
1757 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1758 */
1759 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1760
1761 /* clear interrupt state, and disable interrupts */
1762 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1763 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1764
wdenkc6097192002-11-03 00:24:07 +00001765 /*
wdenk1f53a412002-12-04 23:39:58 +00001766 * Disable interrupts, DMA, and PCMCIA buffers
1767 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001768 */
1769 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001770 reg = 0;
1771 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1772 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001773 PCMCIA_PGCRX(_slot_) = reg;
1774 udelay(500);
1775
1776 /*
1777 * Configure Ports A, B & C pins for
1778 * 5 Volts Enable and 3 Volts enable
1779 */
1780 immap->im_ioport.iop_pcpar &= ~(0x0400);
1781 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1782 immap->im_ioport.iop_pcdir |= 0x0400;*/
1783
1784 immap->im_ioport.iop_papar &= ~(0x0200);/*
1785 immap->im_ioport.iop_padir |= 0x0200;*/
1786#if 0
1787 immap->im_ioport.iop_pbpar &= ~(0xC000);
1788 immap->im_ioport.iop_pbdir &= ~(0xC000);
1789#endif
1790 /* remove all power */
1791
1792 immap->im_ioport.iop_pcdat |= 0x0400;
1793 immap->im_ioport.iop_padat |= 0x0200;
1794
1795 /*
1796 * Make sure there is a card in the slot, then configure the interface.
1797 */
1798 udelay(10000);
1799 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1800 __LINE__,__FUNCTION__,
1801 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001802 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001803 printf (" No Card found\n");
1804 return (1);
1805 }
1806
1807 /*
1808 * Power On.
1809 */
1810 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1811 reg = pcmp->pcmc_pipr;
1812 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1813 reg,
1814 (reg&PCMCIA_VS1(slot))?"n":"ff",
1815 (reg&PCMCIA_VS2(slot))?"n":"ff");
1816 if ((reg & mask) == mask) {
1817 immap->im_ioport.iop_pcdat &= ~(0x4000);
1818 puts (" 5.0V card found: ");
1819 } else {
1820 immap->im_ioport.iop_padat &= ~(0x0002);
1821 puts (" 3.3V card found: ");
1822 }
1823 immap->im_ioport.iop_pcdir |= 0x0400;
1824 immap->im_ioport.iop_padir |= 0x0200;
1825#if 0
1826 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
1827 cp->cp_pbdir &= ~(0x0020 | 0x0010);
1828 cp->cp_pbpar &= ~(0x0020 | 0x0010);
1829 udelay(500000);
1830#endif
1831 debug ("Enable PCMCIA buffers and stop RESET\n");
1832 reg = PCMCIA_PGCRX(_slot_);
1833 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1834 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1835 PCMCIA_PGCRX(_slot_) = reg;
1836
1837 udelay(250000); /* some cards need >150 ms to come up :-( */
1838
1839 debug ("# hardware_enable done\n");
1840
1841 return (0);
1842}
1843
1844
1845
1846#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1847static int hardware_disable(int slot)
1848{
1849 volatile immap_t *immap;
1850 volatile pcmconf8xx_t *pcmp;
1851 u_long reg;
1852
1853 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1854
1855 immap = (immap_t *)CFG_IMMR;
1856 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1857
1858 /* remove all power */
1859 immap->im_ioport.iop_pcdat |= 0x0400;
1860 immap->im_ioport.iop_padat |= 0x0200;
1861
1862 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001863 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001864 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001865 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1866 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1867 PCMCIA_PGCRX(_slot_) = reg;
1868
1869 udelay(10000);
1870
1871 return (0);
1872}
1873#endif /* CFG_CMD_PCMCIA */
1874
1875
1876
1877static int voltage_set(int slot, int vcc, int vpp)
1878{
1879 volatile immap_t *immap;
1880 volatile pcmconf8xx_t *pcmp;
1881 u_long reg;
1882
1883 debug ("voltage_set: "
1884 PCMCIA_BOARD_MSG
1885 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1886 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1887
1888 immap = (immap_t *)CFG_IMMR;
1889 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1890 /*
1891 * Disable PCMCIA buffers (isolate the interface)
1892 * and assert RESET signal
1893 */
1894 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001895 reg = PCMCIA_PGCRX(_slot_);
1896 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1897 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001898 PCMCIA_PGCRX(_slot_) = reg;
1899 udelay(500);
1900
1901 /*
1902 * Configure Ports A & C pins for
1903 * 5 Volts Enable and 3 Volts enable,
1904 * Turn off all power
1905 */
1906 debug ("PCMCIA power OFF\n");
1907 immap->im_ioport.iop_pcpar &= ~(0x0400);
1908 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1909 immap->im_ioport.iop_pcdir |= 0x0400;*/
1910
1911 immap->im_ioport.iop_papar &= ~(0x0200);/*
1912 immap->im_ioport.iop_padir |= 0x0200;*/
1913
1914 immap->im_ioport.iop_pcdat |= 0x0400;
1915 immap->im_ioport.iop_padat |= 0x0200;
1916
1917 reg = 0;
1918 switch(vcc) {
1919 case 0: break;
1920 case 33: reg |= 0x0200; break;
1921 case 50: reg |= 0x0400; break;
1922 default: goto done;
1923 }
1924
1925 /* Checking supported voltages */
1926
1927 debug ("PIPR: 0x%x --> %s\n",
1928 pcmp->pcmc_pipr,
1929 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1930
1931 if (reg & 0x0200)
1932 immap->im_ioport.iop_pcdat &= !reg;
1933 if (reg & 0x0400)
1934 immap->im_ioport.iop_padat &= !reg;
wdenk1f53a412002-12-04 23:39:58 +00001935 immap->im_ioport.iop_pcdir |= 0x0200;
1936 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00001937 if (reg) {
1938 debug ("PCMCIA powered at %sV\n",
1939 (reg&0x0400) ? "5.0" : "3.3");
1940 } else {
1941 debug ("PCMCIA powered down\n");
1942 }
1943
1944done:
1945 debug ("Enable PCMCIA buffers and stop RESET\n");
1946 reg = PCMCIA_PGCRX(_slot_);
1947 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1948 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1949 PCMCIA_PGCRX(_slot_) = reg;
1950 udelay(500);
1951
1952 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1953 slot+'A');
1954 return (0);
1955}
1956
1957#endif /* R360MPI */
1958
wdenk1f53a412002-12-04 23:39:58 +00001959/* -------------------------------------------------------------------- */
1960/* KUP4K Board */
1961/* -------------------------------------------------------------------- */
wdenk56f94be2002-11-05 16:35:14 +00001962#if defined(CONFIG_KUP4K)
1963
1964#define PCMCIA_BOARD_MSG "KUP4K"
1965
1966#define KUP4K_PCMCIA_B_3V3 (0x00020000)
1967
1968static int hardware_enable(int slot)
1969{
1970 volatile immap_t *immap;
1971 volatile cpm8xx_t *cp;
1972 volatile pcmconf8xx_t *pcmp;
1973 volatile sysconf8xx_t *sysp;
1974 uint reg, mask;
1975
1976 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1977
1978 udelay(10000);
1979
1980 immap = (immap_t *)CFG_IMMR;
1981 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1982 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1983 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1984
1985 /*
1986 * Configure SIUMCR to enable PCMCIA port B
1987 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1988 */
1989 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1990
1991 /* clear interrupt state, and disable interrupts */
wdenkea909b72002-11-21 23:11:29 +00001992 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
1993 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00001994
wdenk56f94be2002-11-05 16:35:14 +00001995 /*
wdenk1f53a412002-12-04 23:39:58 +00001996 * Disable interrupts, DMA, and PCMCIA buffers
1997 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00001998 */
1999 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002000 reg = 0;
2001 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2002 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002003 PCMCIA_PGCRX(slot) = reg;
2004 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002005
2006 /*
2007 * Configure Port B pins for
2008 * 3 Volts enable
2009 */
wdenkea909b72002-11-21 23:11:29 +00002010 if (slot) { /* Slot A is built-in */
2011 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2012 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2013 /* remove all power */
2014 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2015 }
wdenk56f94be2002-11-05 16:35:14 +00002016 /*
2017 * Make sure there is a card in the slot, then configure the interface.
2018 */
2019 udelay(10000);
2020 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2021 __LINE__,__FUNCTION__,
2022 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002023 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002024 printf (" No Card found\n");
2025 return (1);
2026 }
2027
2028 /*
2029 * Power On.
2030 */
wdenka6c7ad22002-12-03 21:28:10 +00002031 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002032 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2033 reg = pcmp->pcmc_pipr;
2034 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2035 reg,
2036 (reg&PCMCIA_VS1(slot))?"n":"ff",
2037 (reg&PCMCIA_VS2(slot))?"n":"ff");
2038 if ((reg & mask) == mask) {
2039 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2040 } else {
wdenkea909b72002-11-21 23:11:29 +00002041 if(slot)
2042 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002043 puts (" 3.3V card found: ");
2044 }
2045#if 0
2046 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2047 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2048 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2049 udelay(500000);
2050#endif
2051 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002052 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002053 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2054 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002055 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002056
2057 udelay(250000); /* some cards need >150 ms to come up :-( */
2058
2059 debug ("# hardware_enable done\n");
2060
2061 return (0);
2062}
2063
2064
2065
2066#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2067static int hardware_disable(int slot)
2068{
2069 volatile immap_t *immap;
2070 volatile cpm8xx_t *cp;
2071 volatile pcmconf8xx_t *pcmp;
2072 u_long reg;
2073
2074 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2075
2076 immap = (immap_t *)CFG_IMMR;
2077 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2078 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk1f53a412002-12-04 23:39:58 +00002079
wdenk56f94be2002-11-05 16:35:14 +00002080 /* remove all power */
wdenkea909b72002-11-21 23:11:29 +00002081 if (slot)
2082 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002083
2084 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002085 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002086 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002087 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2088 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002089 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002090
2091 udelay(10000);
2092
2093 return (0);
2094}
2095#endif /* CFG_CMD_PCMCIA */
2096
2097
2098
2099static int voltage_set(int slot, int vcc, int vpp)
2100{
2101 volatile immap_t *immap;
2102 volatile cpm8xx_t *cp;
2103 volatile pcmconf8xx_t *pcmp;
2104 u_long reg;
2105
2106 debug ("voltage_set: " \
2107 PCMCIA_BOARD_MSG \
2108 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2109 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2110
wdenkea909b72002-11-21 23:11:29 +00002111 if (!slot) /* Slot A is not configurable */
2112 return 0;
2113
wdenk56f94be2002-11-05 16:35:14 +00002114 immap = (immap_t *)CFG_IMMR;
2115 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2116 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2117
2118 /*
2119 * Disable PCMCIA buffers (isolate the interface)
2120 * and assert RESET signal
2121 */
2122 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002123 reg = PCMCIA_PGCRX(slot);
2124 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2125 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002126 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002127 udelay(500);
2128
2129 debug ("PCMCIA power OFF\n");
2130 /*
2131 * Configure Port B pins for
2132 * 3 Volts enable
2133 */
2134 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2135 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2136 /* remove all power */
2137 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2138
2139 switch(vcc) {
2140 case 0: break;
2141 case 33:
2142 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2143 debug ("PCMCIA powered at 3.3V\n");
2144 break;
2145 case 50:
2146 debug ("PCMCIA: 5Volt vcc not supported\n");
2147 break;
2148 default:
2149 puts("PCMCIA: vcc not supported");
2150 break;
2151 }
wdenkea909b72002-11-21 23:11:29 +00002152 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002153 /* Checking supported voltages */
2154
2155 debug ("PIPR: 0x%x --> %s\n",
2156 pcmp->pcmc_pipr,
wdenkea909b72002-11-21 23:11:29 +00002157 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002158 ? "only 5 V --> NOT SUPPORTED"
2159 : "can do 3.3V");
2160
2161
2162 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002163 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002164 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2165 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002166 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002167 udelay(500);
2168
2169 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2170 slot+'A');
2171 return (0);
2172}
2173
2174#endif /* KUP4K */
2175
2176
2177
2178
wdenkc6097192002-11-03 00:24:07 +00002179
wdenk1f53a412002-12-04 23:39:58 +00002180/* -------------------------------------------------------------------- */
2181/* End of Board Specific Stuff */
2182/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002183
2184
wdenk1f53a412002-12-04 23:39:58 +00002185/* -------------------------------------------------------------------- */
2186/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2187/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002188
2189/*
2190 * Search this table to see if the windowsize is
2191 * supported...
2192 */
2193
2194#define M8XX_SIZES_NO 32
2195
2196static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2197{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2198 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2199 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2200 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2201
2202 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2203 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2204 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2205 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2206
2207
wdenk1f53a412002-12-04 23:39:58 +00002208/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002209
2210static u_int m8xx_get_graycode(u_int size)
2211{
2212 u_int k;
2213
2214 for (k = 0; k < M8XX_SIZES_NO; k++) {
2215 if(m8xx_size_to_gray[k] == size)
2216 break;
2217 }
2218
2219 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2220 k = -1;
2221
2222 return k;
2223}
2224
wdenk1f53a412002-12-04 23:39:58 +00002225/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002226
2227#if 0
2228static u_int m8xx_get_speed(u_int ns, u_int is_io)
2229{
2230 u_int reg, clocks, psst, psl, psht;
2231
2232 if(!ns) {
2233
2234 /*
2235 * We get called with IO maps setup to 0ns
2236 * if not specified by the user.
2237 * They should be 255ns.
2238 */
2239
2240 if(is_io)
2241 ns = 255;
2242 else
2243 ns = 100; /* fast memory if 0 */
2244 }
2245
2246 /*
2247 * In PSST, PSL, PSHT fields we tell the controller
2248 * timing parameters in CLKOUT clock cycles.
2249 * CLKOUT is the same as GCLK2_50.
2250 */
2251
2252/* how we want to adjust the timing - in percent */
2253
2254#define ADJ 180 /* 80 % longer accesstime - to be sure */
2255
2256 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2257 clocks = (clocks * ADJ) / (100*1000);
2258
2259 if(clocks >= PCMCIA_BMT_LIMIT) {
2260 DEBUG(0, "Max access time limit reached\n");
2261 clocks = PCMCIA_BMT_LIMIT-1;
2262 }
2263
2264 psst = clocks / 7; /* setup time */
2265 psht = clocks / 7; /* hold time */
2266 psl = (clocks * 5) / 7; /* strobe length */
2267
2268 psst += clocks - (psst + psht + psl);
2269
2270 reg = psst << 12;
2271 reg |= psl << 7;
2272 reg |= psht << 16;
2273
2274 return reg;
2275}
2276#endif
2277
wdenk1f53a412002-12-04 23:39:58 +00002278/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002279
2280#ifdef CONFIG_IDE_8xx_PCCARD
2281static void print_funcid (int func)
2282{
2283 puts (indent);
2284 switch (func) {
2285 case CISTPL_FUNCID_MULTI:
2286 puts (" Multi-Function");
2287 break;
2288 case CISTPL_FUNCID_MEMORY:
2289 puts (" Memory");
2290 break;
2291 case CISTPL_FUNCID_SERIAL:
2292 puts (" Serial Port");
2293 break;
2294 case CISTPL_FUNCID_PARALLEL:
2295 puts (" Parallel Port");
2296 break;
2297 case CISTPL_FUNCID_FIXED:
2298 puts (" Fixed Disk");
2299 break;
2300 case CISTPL_FUNCID_VIDEO:
2301 puts (" Video Adapter");
2302 break;
2303 case CISTPL_FUNCID_NETWORK:
2304 puts (" Network Adapter");
2305 break;
2306 case CISTPL_FUNCID_AIMS:
2307 puts (" AIMS Card");
2308 break;
2309 case CISTPL_FUNCID_SCSI:
2310 puts (" SCSI Adapter");
2311 break;
2312 default:
2313 puts (" Unknown");
2314 break;
2315 }
2316 puts (" Card\n");
2317}
2318#endif /* CONFIG_IDE_8xx_PCCARD */
2319
wdenk1f53a412002-12-04 23:39:58 +00002320/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002321
2322#ifdef CONFIG_IDE_8xx_PCCARD
2323static void print_fixed (volatile uchar *p)
2324{
2325 if (p == NULL)
2326 return;
2327
2328 puts(indent);
2329
2330 switch (*p) {
2331 case CISTPL_FUNCE_IDE_IFACE:
2332 { uchar iface = *(p+2);
2333
2334 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2335 puts (" interface ");
2336 break;
2337 }
2338 case CISTPL_FUNCE_IDE_MASTER:
2339 case CISTPL_FUNCE_IDE_SLAVE:
2340 { uchar f1 = *(p+2);
2341 uchar f2 = *(p+4);
2342
2343 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2344
2345 if (f1 & CISTPL_IDE_UNIQUE)
2346 puts (" [unique]");
2347
2348 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2349
2350 if (f2 & CISTPL_IDE_HAS_SLEEP)
2351 puts (" [sleep]");
2352
2353 if (f2 & CISTPL_IDE_HAS_STANDBY)
2354 puts (" [standby]");
2355
2356 if (f2 & CISTPL_IDE_HAS_IDLE)
2357 puts (" [idle]");
2358
2359 if (f2 & CISTPL_IDE_LOW_POWER)
2360 puts (" [low power]");
2361
2362 if (f2 & CISTPL_IDE_REG_INHIBIT)
2363 puts (" [reg inhibit]");
2364
2365 if (f2 & CISTPL_IDE_HAS_INDEX)
2366 puts (" [index]");
2367
2368 if (f2 & CISTPL_IDE_IOIS16)
2369 puts (" [IOis16]");
2370
2371 break;
2372 }
2373 }
2374 putc ('\n');
2375}
2376#endif /* CONFIG_IDE_8xx_PCCARD */
2377
wdenk1f53a412002-12-04 23:39:58 +00002378/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002379
2380#ifdef CONFIG_IDE_8xx_PCCARD
2381
2382#define MAX_IDENT_CHARS 64
2383#define MAX_IDENT_FIELDS 4
2384
2385static uchar *known_cards[] = {
2386 "ARGOSY PnPIDE D5",
2387 NULL
2388};
2389
2390static int identify (volatile uchar *p)
2391{
2392 uchar id_str[MAX_IDENT_CHARS];
2393 uchar data;
2394 uchar *t;
2395 uchar **card;
2396 int i, done;
2397
2398 if (p == NULL)
2399 return (0); /* Don't know */
2400
2401 t = id_str;
2402 done =0;
2403
2404 for (i=0; i<=4 && !done; ++i, p+=2) {
2405 while ((data = *p) != '\0') {
2406 if (data == 0xFF) {
2407 done = 1;
2408 break;
2409 }
2410 *t++ = data;
2411 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2412 done = 1;
2413 break;
2414 }
2415 p += 2;
2416 }
2417 if (!done)
2418 *t++ = ' ';
2419 }
2420 *t = '\0';
2421 while (--t > id_str) {
2422 if (*t == ' ')
2423 *t = '\0';
2424 else
2425 break;
2426 }
2427 puts (id_str);
2428 putc ('\n');
2429
2430 for (card=known_cards; *card; ++card) {
2431 debug ("## Compare against \"%s\"\n", *card);
2432 if (strcmp(*card, id_str) == 0) { /* found! */
2433 debug ("## CARD FOUND ##\n");
2434 return (1);
2435 }
2436 }
2437
2438 return (0); /* don't know */
2439}
2440#endif /* CONFIG_IDE_8xx_PCCARD */
2441
wdenk1f53a412002-12-04 23:39:58 +00002442/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002443
2444#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */