blob: b7e57bfaf946080e4658656042898beff42e573b [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>
wdenkb028f712003-12-07 21:39:28 +000060#if defined(CONFIG_8xx)
wdenkc6097192002-11-03 00:24:07 +000061#include <mpc8xx.h>
62#endif
63#if defined(CONFIG_LWMON)
64#include <i2c.h>
65#endif
66
67#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
68 ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
69
70int pcmcia_on (void);
71
72#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
73static int pcmcia_off (void);
wdenk66fd3d12003-05-18 11:30:09 +000074#endif
75
76#ifdef CONFIG_I82365
77
78extern int i82365_init (void);
79extern void i82365_exit (void);
80
81#else /* ! CONFIG_I82365 */
82
83#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +000084static int hardware_disable(int slot);
85#endif
86static int hardware_enable (int slot);
87static int voltage_set(int slot, int vcc, int vpp);
wdenkc6097192002-11-03 00:24:07 +000088
wdenk7f70e852003-05-20 14:25:27 +000089#ifndef CONFIG_I82365
wdenkc6097192002-11-03 00:24:07 +000090static u_int m8xx_get_graycode(u_int size);
wdenk7f70e852003-05-20 14:25:27 +000091#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +000092#if 0
93static u_int m8xx_get_speed(u_int ns, u_int is_io);
94#endif
95
wdenk1f53a412002-12-04 23:39:58 +000096/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +000097
98/* look up table for pgcrx registers */
99
100static u_int *pcmcia_pgcrx[2] = {
101 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
102 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
103};
104
105#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
106
wdenk66fd3d12003-05-18 11:30:09 +0000107#endif /* CONFIG_I82365 */
108
109#ifdef CONFIG_IDE_8xx_PCCARD
110static void print_funcid (int func);
111static void print_fixed (volatile uchar *p);
112static int identify (volatile uchar *p);
113static int check_ide_device (int slot);
114#endif /* CONFIG_IDE_8xx_PCCARD */
115
wdenkc6097192002-11-03 00:24:07 +0000116const char *indent = "\t ";
117
wdenk1f53a412002-12-04 23:39:58 +0000118/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000119
120#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
121
122int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
123{
124 int rcode = 0;
125
126 if (argc != 2) {
127 printf ("Usage: pinit {on | off}\n");
128 return 1;
129 }
130 if (strcmp(argv[1],"on") == 0) {
131 rcode = pcmcia_on ();
132 } else if (strcmp(argv[1],"off") == 0) {
133 rcode = pcmcia_off ();
134 } else {
135 printf ("Usage: pinit {on | off}\n");
136 return 1;
137 }
138
139 return rcode;
140}
141#endif /* CFG_CMD_PCMCIA */
142
wdenk1f53a412002-12-04 23:39:58 +0000143/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000144
wdenk66fd3d12003-05-18 11:30:09 +0000145#ifdef CONFIG_I82365
146int pcmcia_on (void)
147{
148 u_int rc;
149
150 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
151
152 rc = i82365_init();
153
154 if (rc == 0)
155 {
156 rc = check_ide_device(0);
157 }
158
159 return (rc);
160}
161#else
162
wdenkc40b2952004-03-13 23:29:43 +0000163#ifdef CONFIG_HMI10
164# define HMI10_FRAM_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(2) | PCMCIA_SL(4))
wdenka6cccae2004-02-06 21:48:22 +0000165#endif
dzue7df0292003-10-19 21:43:26 +0000166#if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
wdenkc6097192002-11-03 00:24:07 +0000167# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
168#else
169# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
170#endif
171
172int pcmcia_on (void)
173{
174 int i;
175 u_long reg, base;
176 pcmcia_win_t *win;
wdenkea909b72002-11-21 23:11:29 +0000177 u_int slotbit;
178 u_int rc, slot;
wdenkc6097192002-11-03 00:24:07 +0000179
180 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
181
182 /* intialize the fixed memory windows */
183 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
184 base = CFG_PCMCIA_MEM_ADDR;
185
186 if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
187 printf ("Cannot set window size to 0x%08x\n",
188 CFG_PCMCIA_MEM_SIZE);
189 return (1);
190 }
191
wdenkea909b72002-11-21 23:11:29 +0000192 slotbit = PCMCIA_SLOT_x;
wdenkc6097192002-11-03 00:24:07 +0000193 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
194 win->br = base;
195
wdenkea909b72002-11-21 23:11:29 +0000196#if (PCMCIA_SOCKETS_NO == 2)
197 if (i == 4) /* Another slot starting from win 4 */
198 slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
199#endif
wdenkc6097192002-11-03 00:24:07 +0000200 switch (i) {
201#ifdef CONFIG_IDE_8xx_PCCARD
wdenkea909b72002-11-21 23:11:29 +0000202 case 4:
wdenkc40b2952004-03-13 23:29:43 +0000203#ifdef CONFIG_HMI10
wdenka6cccae2004-02-06 21:48:22 +0000204 { /* map FRAM area */
205 win->or = ( PCMCIA_BSIZE_256K
206 | PCMCIA_PPS_8
207 | PCMCIA_PRS_ATTR
208 | slotbit
209 | PCMCIA_PV
wdenkc40b2952004-03-13 23:29:43 +0000210 | HMI10_FRAM_TIMING );
wdenka6cccae2004-02-06 21:48:22 +0000211 break;
212 }
213#endif
wdenkc6097192002-11-03 00:24:07 +0000214 case 0: { /* map attribute memory */
215 win->or = ( PCMCIA_BSIZE_64M
216 | PCMCIA_PPS_8
217 | PCMCIA_PRS_ATTR
wdenkea909b72002-11-21 23:11:29 +0000218 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000219 | PCMCIA_PV
220 | CFG_PCMCIA_TIMING );
221 break;
222 }
wdenkea909b72002-11-21 23:11:29 +0000223 case 5:
wdenkc6097192002-11-03 00:24:07 +0000224 case 1: { /* map I/O window for data reg */
225 win->or = ( PCMCIA_BSIZE_1K
226 | PCMCIA_PPS_16
227 | PCMCIA_PRS_IO
wdenkea909b72002-11-21 23:11:29 +0000228 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000229 | PCMCIA_PV
230 | CFG_PCMCIA_TIMING );
231 break;
232 }
wdenkea909b72002-11-21 23:11:29 +0000233 case 6:
wdenk1f53a412002-12-04 23:39:58 +0000234 case 2: { /* map I/O window for cmd/ctrl reg block */
wdenkc6097192002-11-03 00:24:07 +0000235 win->or = ( PCMCIA_BSIZE_1K
236 | PCMCIA_PPS_8
237 | PCMCIA_PRS_IO
wdenkea909b72002-11-21 23:11:29 +0000238 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000239 | PCMCIA_PV
240 | CFG_PCMCIA_TIMING );
241 break;
242 }
243#endif /* CONFIG_IDE_8xx_PCCARD */
wdenkc40b2952004-03-13 23:29:43 +0000244#ifdef CONFIG_HMI10
wdenk7cb22f92003-12-27 19:24:54 +0000245 case 3: { /* map I/O window for 4xUART data/ctrl */
wdenka522fa02004-01-04 22:51:12 +0000246 win->br += 0x40000;
wdenk7cb22f92003-12-27 19:24:54 +0000247 win->or = ( PCMCIA_BSIZE_256K
248 | PCMCIA_PPS_8
249 | PCMCIA_PRS_IO
250 | slotbit
251 | PCMCIA_PV
252 | CFG_PCMCIA_TIMING );
253 break;
254 }
wdenkc40b2952004-03-13 23:29:43 +0000255#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000256 default: /* set to not valid */
257 win->or = 0;
258 break;
259 }
260
261 debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
262 i, win->br, win->or);
263 base += CFG_PCMCIA_MEM_SIZE;
264 ++win;
265 }
266
wdenk1f53a412002-12-04 23:39:58 +0000267 for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
wdenkea909b72002-11-21 23:11:29 +0000268 /* turn off voltage */
269 if ((rc = voltage_set(slot, 0, 0)))
270 continue;
wdenk1f53a412002-12-04 23:39:58 +0000271
wdenkea909b72002-11-21 23:11:29 +0000272 /* Enable external hardware */
273 if ((rc = hardware_enable(slot)))
274 continue;
wdenk1f53a412002-12-04 23:39:58 +0000275
wdenkc6097192002-11-03 00:24:07 +0000276#ifdef CONFIG_IDE_8xx_PCCARD
wdenkea909b72002-11-21 23:11:29 +0000277 if ((rc = check_ide_device(i)))
278 continue;
wdenkc6097192002-11-03 00:24:07 +0000279#endif
wdenkea909b72002-11-21 23:11:29 +0000280 }
281 return (rc);
wdenkc6097192002-11-03 00:24:07 +0000282}
wdenk66fd3d12003-05-18 11:30:09 +0000283#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000284
wdenk1f53a412002-12-04 23:39:58 +0000285/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000286
287#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
288
wdenk66fd3d12003-05-18 11:30:09 +0000289#ifdef CONFIG_I82365
290static int pcmcia_off (void)
291{
292 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
293
294 i82365_exit();
295
296 return 0;
297}
298#else
wdenkc6097192002-11-03 00:24:07 +0000299static int pcmcia_off (void)
300{
301 int i;
302 pcmcia_win_t *win;
303
304 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
305
306 /* clear interrupt state, and disable interrupts */
307 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
308 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
309
310 /* turn off interrupt and disable CxOE */
311 PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
312
313 /* turn off memory windows */
314 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
315
316 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
317 /* disable memory window */
318 win->or = 0;
319 ++win;
320 }
321
322 /* turn off voltage */
323 voltage_set(_slot_, 0, 0);
324
325 /* disable external hardware */
326 printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
327 hardware_disable(_slot_);
328 return 0;
329}
wdenk66fd3d12003-05-18 11:30:09 +0000330#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000331
332#endif /* CFG_CMD_PCMCIA */
333
wdenk1f53a412002-12-04 23:39:58 +0000334/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000335
336#ifdef CONFIG_IDE_8xx_PCCARD
337
338#define MAX_TUPEL_SZ 512
339#define MAX_FEATURES 4
340
wdenk6069ff22003-02-28 00:49:47 +0000341int ide_devices_found;
wdenkea909b72002-11-21 23:11:29 +0000342static int check_ide_device (int slot)
wdenkc6097192002-11-03 00:24:07 +0000343{
344 volatile uchar *ident = NULL;
345 volatile uchar *feature_p[MAX_FEATURES];
wdenkea909b72002-11-21 23:11:29 +0000346 volatile uchar *p, *start, *addr;
wdenkc6097192002-11-03 00:24:07 +0000347 int n_features = 0;
348 uchar func_id = ~0;
349 uchar code, len;
350 ushort config_base = 0;
351 int found = 0;
352 int i;
353
wdenk1f53a412002-12-04 23:39:58 +0000354 addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
355 CFG_PCMCIA_MEM_SIZE * (slot * 4));
wdenkd0fb80c2003-01-11 09:48:40 +0000356 debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
wdenkc6097192002-11-03 00:24:07 +0000357
wdenkea909b72002-11-21 23:11:29 +0000358 start = p = (volatile uchar *) addr;
wdenkc6097192002-11-03 00:24:07 +0000359
360 while ((p - start) < MAX_TUPEL_SZ) {
361
362 code = *p; p += 2;
363
364 if (code == 0xFF) { /* End of chain */
365 break;
366 }
367
368 len = *p; p += 2;
369#if defined(DEBUG) && (DEBUG > 1)
370 { volatile uchar *q = p;
371 printf ("\nTuple code %02x length %d\n\tData:",
372 code, len);
373
374 for (i = 0; i < len; ++i) {
375 printf (" %02x", *q);
376 q+= 2;
377 }
378 }
379#endif /* DEBUG */
380 switch (code) {
381 case CISTPL_VERS_1:
382 ident = p + 4;
383 break;
384 case CISTPL_FUNCID:
385 /* Fix for broken SanDisk which may have 0x80 bit set */
386 func_id = *p & 0x7F;
387 break;
388 case CISTPL_FUNCE:
389 if (n_features < MAX_FEATURES)
390 feature_p[n_features++] = p;
391 break;
392 case CISTPL_CONFIG:
393 config_base = (*(p+6) << 8) + (*(p+4));
394 debug ("\n## Config_base = %04x ###\n", config_base);
395 default:
396 break;
397 }
398 p += 2 * len;
399 }
400
401 found = identify (ident);
402
403 if (func_id != ((uchar)~0)) {
404 print_funcid (func_id);
405
406 if (func_id == CISTPL_FUNCID_FIXED)
407 found = 1;
408 else
409 return (1); /* no disk drive */
410 }
411
412 for (i=0; i<n_features; ++i) {
413 print_fixed (feature_p[i]);
414 }
415
416 if (!found) {
417 printf ("unknown card type\n");
418 return (1);
419 }
420
wdenk6069ff22003-02-28 00:49:47 +0000421 ide_devices_found |= (1 << slot);
422
wdenkc6097192002-11-03 00:24:07 +0000423 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
wdenkea909b72002-11-21 23:11:29 +0000424 *((uchar *)(addr + config_base)) = 1;
wdenkc6097192002-11-03 00:24:07 +0000425
426 return (0);
427}
428#endif /* CONFIG_IDE_8xx_PCCARD */
429
wdenk1f53a412002-12-04 23:39:58 +0000430/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000431
432
wdenk1f53a412002-12-04 23:39:58 +0000433/* -------------------------------------------------------------------- */
434/* board specific stuff: */
435/* voltage_set(), hardware_enable() and hardware_disable() */
436/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000437
wdenk1f53a412002-12-04 23:39:58 +0000438/* -------------------------------------------------------------------- */
439/* RPX Boards from Embedded Planet */
440/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000441
442#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
443
444/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
445 * SYPCR is write once only, therefore must the slowest memory be faster
446 * than the bus monitor or we will get a machine check due to the bus timeout.
447 */
448
449#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
450
451#undef PCMCIA_BMT_LIMIT
452#define PCMCIA_BMT_LIMIT (6*8)
453
454static int voltage_set(int slot, int vcc, int vpp)
455{
456 u_long reg = 0;
457
458 switch(vcc) {
459 case 0: break;
460 case 33: reg |= BCSR1_PCVCTL4; break;
461 case 50: reg |= BCSR1_PCVCTL5; break;
462 default: return 1;
463 }
464
465 switch(vpp) {
466 case 0: break;
467 case 33:
468 case 50:
469 if(vcc == vpp)
470 reg |= BCSR1_PCVCTL6;
471 else
472 return 1;
473 break;
474 case 120:
475 reg |= BCSR1_PCVCTL7;
476 default: return 1;
477 }
478
479 if(vcc == 120)
480 return 1;
481
482 /* first, turn off all power */
483
484 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
485 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
486
487 /* enable new powersettings */
488
489 *((uint *)RPX_CSR_ADDR) |= reg;
490
491 return 0;
492}
493
494#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
495static int hardware_enable (int slot)
496{
497 return 0; /* No hardware to enable */
498}
499#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
500static int hardware_disable(int slot)
501{
502 return 0; /* No hardware to disable */
503}
504#endif /* CFG_CMD_PCMCIA */
505#endif /* CONFIG_RPXCLASSIC */
506
wdenk1f53a412002-12-04 23:39:58 +0000507/* -------------------------------------------------------------------- */
508/* (F)ADS Boards from Motorola */
509/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000510
511#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
512
513#ifdef CONFIG_ADS
514#define PCMCIA_BOARD_MSG "ADS"
515#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
516#else
517#define PCMCIA_BOARD_MSG "FADS"
518#endif
519
520static int voltage_set(int slot, int vcc, int vpp)
521{
522 u_long reg = 0;
523
524 switch(vpp) {
525 case 0: reg = 0; break;
526 case 50: reg = 1; break;
527 case 120: reg = 2; break;
528 default: return 1;
529 }
530
531 switch(vcc) {
532 case 0: reg = 0; break;
533#ifdef CONFIG_ADS
534 case 50: reg = BCSR1_PCCVCCON; break;
535#endif
536#ifdef CONFIG_FADS
537 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
538 case 50: reg = BCSR1_PCCVCC1; break;
539#endif
540 default: return 1;
541 }
542
543 /* first, turn off all power */
544
545#ifdef CONFIG_ADS
546 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
547#endif
548#ifdef CONFIG_FADS
549 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
550#endif
551 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
552
553 /* enable new powersettings */
554
555#ifdef CONFIG_ADS
556 *((uint *)BCSR1) &= ~reg;
557#endif
558#ifdef CONFIG_FADS
559 *((uint *)BCSR1) |= reg;
560#endif
561
562 *((uint *)BCSR1) |= reg << 20;
563
564 return 0;
565}
566
567#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
568
569static int hardware_enable(int slot)
570{
571 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
572 return 0;
573}
574
575#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
576static int hardware_disable(int slot)
577{
578 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
579 return 0;
580}
581#endif /* CFG_CMD_PCMCIA */
582
583#endif /* (F)ADS */
584
wdenk1f53a412002-12-04 23:39:58 +0000585/* -------------------------------------------------------------------- */
586/* TQM8xxL Boards by TQ Components */
wdenkdc7c9a12003-03-26 06:55:25 +0000587/* SC8xx Boards by SinoVee Microsystems */
wdenk1f53a412002-12-04 23:39:58 +0000588/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000589
wdenkdc7c9a12003-03-26 06:55:25 +0000590#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
591
wdenkc6097192002-11-03 00:24:07 +0000592#if defined(CONFIG_TQM8xxL)
wdenkc6097192002-11-03 00:24:07 +0000593#define PCMCIA_BOARD_MSG "TQM8xxL"
wdenkdc7c9a12003-03-26 06:55:25 +0000594#endif
595#if defined(CONFIG_SVM_SC8xx)
596#define PCMCIA_BOARD_MSG "SC8xx"
597#endif
wdenkc6097192002-11-03 00:24:07 +0000598
599static int hardware_enable(int slot)
600{
601 volatile immap_t *immap;
602 volatile cpm8xx_t *cp;
603 volatile pcmconf8xx_t *pcmp;
604 volatile sysconf8xx_t *sysp;
605 uint reg, mask;
606
607 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
608
609 udelay(10000);
610
611 immap = (immap_t *)CFG_IMMR;
612 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
613 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
614 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
615
616 /*
617 * Configure SIUMCR to enable PCMCIA port B
618 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
619 */
620 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
621
622 /* clear interrupt state, and disable interrupts */
dzue7df0292003-10-19 21:43:26 +0000623 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
624 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenkc6097192002-11-03 00:24:07 +0000625
wdenkc6097192002-11-03 00:24:07 +0000626 /*
wdenk1f53a412002-12-04 23:39:58 +0000627 * Disable interrupts, DMA, and PCMCIA buffers
628 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000629 */
630 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000631 reg = 0;
632 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000633#ifndef NSCU_OE_INV
wdenk1f53a412002-12-04 23:39:58 +0000634 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000635#endif
636 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000637 udelay(500);
638
wdenkc40b2952004-03-13 23:29:43 +0000639#ifndef CONFIG_HMI10
dzue7df0292003-10-19 21:43:26 +0000640#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000641 /*
642 * Configure Port C pins for
643 * 5 Volts Enable and 3 Volts enable
644 */
645 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
646 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
647 /* remove all power */
648
649 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000650#endif
wdenkc40b2952004-03-13 23:29:43 +0000651#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000652 /*
653 * Configure Port B pins for
654 * 5 Volts Enable and 3 Volts enable
655 */
656 immap->im_cpm.cp_pbpar &= ~(0x00000300);
657
658 /* remove all power */
659 immap->im_cpm.cp_pbdat |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000660#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000661
662 /*
663 * Make sure there is a card in the slot, then configure the interface.
664 */
665 udelay(10000);
666 debug ("[%d] %s: PIPR(%p)=0x%x\n",
667 __LINE__,__FUNCTION__,
668 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkc40b2952004-03-13 23:29:43 +0000669#ifndef CONFIG_HMI10
wdenkea909b72002-11-21 23:11:29 +0000670 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenka522fa02004-01-04 22:51:12 +0000671#else
672 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkc40b2952004-03-13 23:29:43 +0000673#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000674 printf (" No Card found\n");
675 return (1);
676 }
677
678 /*
679 * Power On.
680 */
681 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
682 reg = pcmp->pcmc_pipr;
683 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
684 reg,
685 (reg&PCMCIA_VS1(slot))?"n":"ff",
686 (reg&PCMCIA_VS2(slot))?"n":"ff");
dzue7df0292003-10-19 21:43:26 +0000687#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000688 if ((reg & mask) == mask) {
wdenkc40b2952004-03-13 23:29:43 +0000689#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000690 immap->im_ioport.iop_pcdat |= 0x0004;
wdenka522fa02004-01-04 22:51:12 +0000691#else
692 immap->im_cpm.cp_pbdat &= ~(0x0000100);
wdenkc40b2952004-03-13 23:29:43 +0000693#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000694 puts (" 5.0V card found: ");
695 } else {
wdenkc40b2952004-03-13 23:29:43 +0000696#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000697 immap->im_ioport.iop_pcdat |= 0x0002;
wdenka522fa02004-01-04 22:51:12 +0000698#else
699 immap->im_cpm.cp_pbdat &= ~(0x0000200);
wdenkc40b2952004-03-13 23:29:43 +0000700#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000701 puts (" 3.3V card found: ");
702 }
wdenkc40b2952004-03-13 23:29:43 +0000703#ifndef CONFIG_HMI10
wdenk1f53a412002-12-04 23:39:58 +0000704 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000705#else
wdenka522fa02004-01-04 22:51:12 +0000706 immap->im_cpm.cp_pbdir |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000707#endif /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000708#else
dzue7df0292003-10-19 21:43:26 +0000709 if ((reg & mask) == mask) {
710 puts (" 5.0V card found: ");
711 } else {
712 puts (" 3.3V card found: ");
713 }
714#endif
wdenkc6097192002-11-03 00:24:07 +0000715#if 0
716 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
717 cp->cp_pbdir &= ~(0x0020 | 0x0010);
718 cp->cp_pbpar &= ~(0x0020 | 0x0010);
719 udelay(500000);
720#endif
721 udelay(1000);
722 debug ("Enable PCMCIA buffers and stop RESET\n");
dzue7df0292003-10-19 21:43:26 +0000723 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +0000724 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000725#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000726 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000727#else
728 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
729#endif
730 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000731
732 udelay(250000); /* some cards need >150 ms to come up :-( */
733
734 debug ("# hardware_enable done\n");
735
736 return (0);
737}
738
739
wdenkc6097192002-11-03 00:24:07 +0000740#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
741static int hardware_disable(int slot)
742{
743 volatile immap_t *immap;
744 volatile pcmconf8xx_t *pcmp;
745 u_long reg;
746
747 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
748
749 immap = (immap_t *)CFG_IMMR;
750 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
751
wdenkc40b2952004-03-13 23:29:43 +0000752#ifndef CONFIG_HMI10
dzue7df0292003-10-19 21:43:26 +0000753#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000754 /* remove all power */
755 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000756#endif
wdenkc40b2952004-03-13 23:29:43 +0000757#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000758 immap->im_cpm.cp_pbdat |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000759#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000760
wdenkc6097192002-11-03 00:24:07 +0000761 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000762 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000763 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000764#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000765 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000766#endif
767 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000768
769 udelay(10000);
770
771 return (0);
772}
773#endif /* CFG_CMD_PCMCIA */
774
dzue7df0292003-10-19 21:43:26 +0000775#ifdef CONFIG_NSCU
776static int voltage_set(int slot, int vcc, int vpp)
777{
778 return 0;
779}
780#else
wdenkc6097192002-11-03 00:24:07 +0000781static int voltage_set(int slot, int vcc, int vpp)
782{
783 volatile immap_t *immap;
784 volatile pcmconf8xx_t *pcmp;
785 u_long reg;
786
787 debug ("voltage_set: "
788 PCMCIA_BOARD_MSG
789 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
790 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
791
792 immap = (immap_t *)CFG_IMMR;
793 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
794 /*
795 * Disable PCMCIA buffers (isolate the interface)
796 * and assert RESET signal
797 */
798 debug ("Disable PCMCIA buffers and assert RESET\n");
dzue7df0292003-10-19 21:43:26 +0000799 reg = PCMCIA_PGCRX(slot);
wdenk1f53a412002-12-04 23:39:58 +0000800 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000801#ifndef NSCU_OE_INV
wdenk1f53a412002-12-04 23:39:58 +0000802 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000803#else
804 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
805#endif
806 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000807 udelay(500);
808
wdenkc40b2952004-03-13 23:29:43 +0000809#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000810 /*
811 * Configure Port C pins for
812 * 5 Volts Enable and 3 Volts enable,
813 * Turn off all power
814 */
815 debug ("PCMCIA power OFF\n");
816 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
817 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
818 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
819
820 reg = 0;
821 switch(vcc) {
822 case 0: break;
823 case 33: reg |= 0x0002; break;
824 case 50: reg |= 0x0004; break;
825 default: goto done;
826 }
wdenkc40b2952004-03-13 23:29:43 +0000827#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000828 /*
829 * Configure Port B pins for
830 * 5 Volts Enable and 3 Volts enable,
831 * Turn off all power
832 */
833 debug ("PCMCIA power OFF\n");
834 immap->im_cpm.cp_pbpar &= ~(0x00000300);
835 /* remove all power */
836
837 immap->im_cpm.cp_pbdat |= 0x00000300;
838
839 reg = 0;
840 switch(vcc) {
841 case 0: break;
842 case 33: reg |= 0x00000200; break;
843 case 50: reg |= 0x00000100; break;
844 default: goto done;
845}
wdenkc40b2952004-03-13 23:29:43 +0000846#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000847
848 /* Checking supported voltages */
849
850 debug ("PIPR: 0x%x --> %s\n",
851 pcmp->pcmc_pipr,
852 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
853
wdenkc40b2952004-03-13 23:29:43 +0000854#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000855 immap->im_ioport.iop_pcdat |= reg;
wdenk1f53a412002-12-04 23:39:58 +0000856 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenka522fa02004-01-04 22:51:12 +0000857#else
858 immap->im_cpm.cp_pbdat &= !reg;
859 immap->im_cpm.cp_pbdir |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000860#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000861 if (reg) {
wdenkc40b2952004-03-13 23:29:43 +0000862#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000863 debug ("PCMCIA powered at %sV\n",
864 (reg&0x0004) ? "5.0" : "3.3");
wdenka522fa02004-01-04 22:51:12 +0000865#else
866 debug ("PCMCIA powered at %sV\n",
867 (reg&0x00000200) ? "5.0" : "3.3");
wdenkc40b2952004-03-13 23:29:43 +0000868#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000869 } else {
870 debug ("PCMCIA powered down\n");
871 }
872
873done:
874 debug ("Enable PCMCIA buffers and stop RESET\n");
dzue7df0292003-10-19 21:43:26 +0000875 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +0000876 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000877#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000878 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000879#else
880 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
881#endif
882 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000883 udelay(500);
884
885 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
886 slot+'A');
887 return (0);
888}
dzue7df0292003-10-19 21:43:26 +0000889#endif
wdenkc6097192002-11-03 00:24:07 +0000890
891#endif /* TQM8xxL */
892
893
wdenk1f53a412002-12-04 23:39:58 +0000894/* -------------------------------------------------------------------- */
895/* LWMON Board */
896/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000897
898#if defined(CONFIG_LWMON)
899
900#define PCMCIA_BOARD_MSG "LWMON"
901
902/* #define's for MAX1604 Power Switch */
903#define MAX1604_OP_SUS 0x80
904#define MAX1604_VCCBON 0x40
905#define MAX1604_VCC_35 0x20
906#define MAX1604_VCCBHIZ 0x10
907#define MAX1604_VPPBON 0x08
908#define MAX1604_VPPBPBPGM 0x04
909#define MAX1604_VPPBHIZ 0x02
910/* reserved 0x01 */
911
912static int hardware_enable(int slot)
913{
914 volatile immap_t *immap;
915 volatile cpm8xx_t *cp;
916 volatile pcmconf8xx_t *pcmp;
917 volatile sysconf8xx_t *sysp;
918 uint reg, mask;
919 uchar val;
920
921
922 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
923
924 /* Switch on PCMCIA port in PIC register 0x60 */
925 reg = pic_read (0x60);
926 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
927 reg &= ~0x10;
wdenk1f53a412002-12-04 23:39:58 +0000928 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +0000929 pic_write (0x60, reg);
930#ifdef DEBUG
931 reg = pic_read (0x60);
932 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
933#endif
934 udelay(10000);
935
936 immap = (immap_t *)CFG_IMMR;
937 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
938 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
939 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
940
941 /*
942 * Configure SIUMCR to enable PCMCIA port B
943 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
944 */
945 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
946
947 /* clear interrupt state, and disable interrupts */
948 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
949 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
950
wdenkc6097192002-11-03 00:24:07 +0000951 /*
wdenk1f53a412002-12-04 23:39:58 +0000952 * Disable interrupts, DMA, and PCMCIA buffers
953 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000954 */
955 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000956 reg = 0;
957 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
958 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000959 PCMCIA_PGCRX(_slot_) = reg;
960 udelay(500);
961
962 /*
963 * Make sure there is a card in the slot, then configure the interface.
964 */
965 udelay(10000);
966 debug ("[%d] %s: PIPR(%p)=0x%x\n",
967 __LINE__,__FUNCTION__,
968 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +0000969 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000970 printf (" No Card found\n");
971 return (1);
972 }
973
974 /*
975 * Power On.
976 */
977 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
978 reg = pcmp->pcmc_pipr;
979 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
980 reg,
981 (reg&PCMCIA_VS1(slot))?"n":"ff",
982 (reg&PCMCIA_VS2(slot))?"n":"ff");
983 if ((reg & mask) == mask) {
984 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
985 puts (" 5.0V card found: ");
986 } else {
987 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
988 puts (" 3.3V card found: ");
989 }
990
991 /* switch VCC on */
wdenk1f53a412002-12-04 23:39:58 +0000992 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +0000993 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
994 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
995
996 udelay(500000);
997
998 debug ("Enable PCMCIA buffers and stop RESET\n");
999 reg = PCMCIA_PGCRX(_slot_);
1000 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1001 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1002 PCMCIA_PGCRX(_slot_) = reg;
1003
1004 udelay(250000); /* some cards need >150 ms to come up :-( */
1005
1006 debug ("# hardware_enable done\n");
1007
1008 return (0);
1009}
1010
1011
wdenkc6097192002-11-03 00:24:07 +00001012#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1013static int hardware_disable(int slot)
1014{
1015 volatile immap_t *immap;
1016 volatile pcmconf8xx_t *pcmp;
1017 u_long reg;
1018 uchar val;
1019
1020 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1021
1022 immap = (immap_t *)CFG_IMMR;
1023 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1024
1025 /* remove all power, put output in high impedance state */
1026 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1027 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1028 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1029
1030 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001031 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001032 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001033 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1034 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1035 PCMCIA_PGCRX(_slot_) = reg;
1036
1037 /* Switch off PCMCIA port in PIC register 0x60 */
1038 reg = pic_read (0x60);
1039 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1040 reg |= 0x10;
1041 reg &= ~0x08;
1042 pic_write (0x60, reg);
1043#ifdef DEBUG
1044 reg = pic_read (0x60);
1045 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1046#endif
1047 udelay(10000);
1048
1049 return (0);
1050}
1051#endif /* CFG_CMD_PCMCIA */
1052
1053
wdenkc6097192002-11-03 00:24:07 +00001054static int voltage_set(int slot, int vcc, int vpp)
1055{
1056 volatile immap_t *immap;
1057 volatile pcmconf8xx_t *pcmp;
1058 u_long reg;
1059 uchar val;
1060
1061 debug ("voltage_set: "
1062 PCMCIA_BOARD_MSG
1063 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1064 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1065
1066 immap = (immap_t *)CFG_IMMR;
1067 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1068 /*
1069 * Disable PCMCIA buffers (isolate the interface)
1070 * and assert RESET signal
1071 */
1072 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001073 reg = PCMCIA_PGCRX(_slot_);
1074 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1075 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001076 PCMCIA_PGCRX(_slot_) = reg;
1077 udelay(500);
1078
1079 /*
1080 * Turn off all power (switch to high impedance)
1081 */
1082 debug ("PCMCIA power OFF\n");
1083 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1084 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1085 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1086
1087 val = 0;
1088 switch(vcc) {
1089 case 0: break;
1090 case 33: val = MAX1604_VCC_35; break;
1091 case 50: break;
1092 default: goto done;
1093 }
1094
1095 /* Checking supported voltages */
1096
1097 debug ("PIPR: 0x%x --> %s\n",
1098 pcmp->pcmc_pipr,
1099 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1100
1101 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1102 if (val) {
1103 debug ("PCMCIA powered at %sV\n",
1104 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1105 } else {
1106 debug ("PCMCIA powered down\n");
1107 }
1108
1109done:
1110 debug ("Enable PCMCIA buffers and stop RESET\n");
1111 reg = PCMCIA_PGCRX(_slot_);
1112 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1113 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1114 PCMCIA_PGCRX(_slot_) = reg;
1115 udelay(500);
1116
1117 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1118 slot+'A');
1119 return (0);
1120}
1121
1122#endif /* LWMON */
1123
wdenk1f53a412002-12-04 23:39:58 +00001124/* -------------------------------------------------------------------- */
1125/* GTH board by Corelatus AB */
1126/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001127#if defined(CONFIG_GTH)
1128
1129#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1130
wdenk1f53a412002-12-04 23:39:58 +00001131static int voltage_set (int slot, int vcc, int vpp)
1132{ /* Do nothing */
1133 return 0;
wdenkc6097192002-11-03 00:24:07 +00001134}
1135
1136static int hardware_enable (int slot)
1137{
wdenk1f53a412002-12-04 23:39:58 +00001138 volatile immap_t *immap;
1139 volatile cpm8xx_t *cp;
1140 volatile pcmconf8xx_t *pcmp;
1141 volatile sysconf8xx_t *sysp;
1142 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +00001143
wdenk1f53a412002-12-04 23:39:58 +00001144 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +00001145
wdenk1f53a412002-12-04 23:39:58 +00001146 immap = (immap_t *) CFG_IMMR;
1147 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1148 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1149 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +00001150
wdenk1f53a412002-12-04 23:39:58 +00001151 /* clear interrupt state, and disable interrupts */
1152 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1153 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +00001154
wdenk1f53a412002-12-04 23:39:58 +00001155 /*
1156 * Disable interrupts, DMA, and PCMCIA buffers
1157 * (isolate the interface) and assert RESET signal
1158 */
1159 debug ("Disable PCMCIA buffers and assert RESET\n");
1160 reg = 0;
1161 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1162 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1163 PCMCIA_PGCRX (_slot_) = reg;
1164 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001165
wdenk1f53a412002-12-04 23:39:58 +00001166 /*
1167 * Make sure there is a card in the slot,
1168 * then configure the interface.
1169 */
1170 udelay (10000);
1171 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1172 __LINE__, __FUNCTION__,
1173 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1174 if (pcmp->pcmc_pipr & 0x98000000) {
1175 printf (" No Card found\n");
1176 return (1);
1177 }
wdenkc6097192002-11-03 00:24:07 +00001178
wdenk1f53a412002-12-04 23:39:58 +00001179 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1180 reg = pcmp->pcmc_pipr;
1181 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1182 reg,
1183 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1184 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001185
wdenk1f53a412002-12-04 23:39:58 +00001186 debug ("Enable PCMCIA buffers and stop RESET\n");
1187 reg = PCMCIA_PGCRX (_slot_);
1188 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1189 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1190 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001191
wdenk1f53a412002-12-04 23:39:58 +00001192 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001193
wdenk1f53a412002-12-04 23:39:58 +00001194 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001195
wdenk1f53a412002-12-04 23:39:58 +00001196 return 0;
wdenkc6097192002-11-03 00:24:07 +00001197}
1198#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1199static int hardware_disable(int slot)
1200{
1201 return 0; /* No hardware to disable */
1202}
1203#endif /* CFG_CMD_PCMCIA */
1204#endif /* CONFIG_GTH */
1205
wdenk1f53a412002-12-04 23:39:58 +00001206/* -------------------------------------------------------------------- */
1207/* ICU862 Boards by Cambridge Broadband Ltd. */
1208/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001209
1210#if defined(CONFIG_ICU862)
1211
1212#define PCMCIA_BOARD_MSG "ICU862"
1213
1214static void cfg_port_B (void);
1215
1216static int hardware_enable(int slot)
1217{
1218 volatile immap_t *immap;
1219 volatile cpm8xx_t *cp;
1220 volatile pcmconf8xx_t *pcmp;
1221 volatile sysconf8xx_t *sysp;
1222 uint reg, pipr, mask;
1223 int i;
1224
1225 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1226
1227 udelay(10000);
1228
1229 immap = (immap_t *)CFG_IMMR;
1230 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1231 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1232 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1233
1234 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1235 cfg_port_B ();
1236
1237 /*
1238 * Configure SIUMCR to enable PCMCIA port B
1239 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1240 */
1241 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1242
1243 /* clear interrupt state, and disable interrupts */
1244 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1245 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1246
wdenkc6097192002-11-03 00:24:07 +00001247 /*
wdenk1f53a412002-12-04 23:39:58 +00001248 * Disable interrupts, DMA, and PCMCIA buffers
1249 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001250 */
1251 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001252 reg = 0;
1253 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1254 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001255 PCMCIA_PGCRX(_slot_) = reg;
1256 udelay(500);
1257
1258 /*
1259 * Make sure there is a card in the slot, then configure the interface.
1260 */
1261 udelay(10000);
1262 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1263 __LINE__,__FUNCTION__,
1264 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001265 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001266 printf (" No Card found\n");
1267 return (1);
1268 }
1269
1270 /*
1271 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1272 */
1273 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1274 pipr = pcmp->pcmc_pipr;
1275 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1276 pipr,
1277 (reg&PCMCIA_VS1(slot))?"n":"ff",
1278 (reg&PCMCIA_VS2(slot))?"n":"ff");
1279
1280 reg = cp->cp_pbdat;
1281 if ((pipr & mask) == mask) {
wdenk1f53a412002-12-04 23:39:58 +00001282 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1283 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001284 reg &= ~(TPS2205_VCC5); /* 5V on */
1285 puts (" 5.0V card found: ");
1286 } else {
wdenk1f53a412002-12-04 23:39:58 +00001287 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1288 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001289 reg &= ~(TPS2205_VCC3); /* 3V on */
1290 puts (" 3.3V card found: ");
1291 }
1292
1293 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1294 reg,
1295 (reg & TPS2205_VCC3) ? "off" : "on",
1296 (reg & TPS2205_VCC5) ? "off" : "on",
1297 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1298 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1299
1300 cp->cp_pbdat = reg;
1301
1302 /* Wait 500 ms; use this to check for over-current */
1303 for (i=0; i<5000; ++i) {
1304 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1305 printf (" *** Overcurrent - Safety shutdown ***\n");
1306 cp->cp_pbdat &= ~(TPS2205_SHDN);
1307 return (1);
1308 }
1309 udelay (100);
1310 }
1311
1312 debug ("Enable PCMCIA buffers and stop RESET\n");
1313 reg = PCMCIA_PGCRX(_slot_);
1314 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1315 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1316 PCMCIA_PGCRX(_slot_) = reg;
1317
1318 udelay(250000); /* some cards need >150 ms to come up :-( */
1319
1320 debug ("# hardware_enable done\n");
1321
1322 return (0);
1323}
1324
1325
wdenkc6097192002-11-03 00:24:07 +00001326#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1327static int hardware_disable(int slot)
1328{
1329 volatile immap_t *immap;
1330 volatile cpm8xx_t *cp;
1331 volatile pcmconf8xx_t *pcmp;
1332 u_long reg;
1333
1334 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1335
1336 immap = (immap_t *)CFG_IMMR;
1337 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1338 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1339
1340 /* Shut down */
1341 cp->cp_pbdat &= ~(TPS2205_SHDN);
1342
1343 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001344 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001345 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001346 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1347 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1348 PCMCIA_PGCRX(_slot_) = reg;
1349
1350 udelay(10000);
1351
1352 return (0);
1353}
1354#endif /* CFG_CMD_PCMCIA */
1355
1356
wdenkc6097192002-11-03 00:24:07 +00001357static int voltage_set(int slot, int vcc, int vpp)
1358{
1359 volatile immap_t *immap;
1360 volatile cpm8xx_t *cp;
1361 volatile pcmconf8xx_t *pcmp;
1362 u_long reg;
1363
1364 debug ("voltage_set: "
1365 PCMCIA_BOARD_MSG
1366 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1367 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1368
1369 immap = (immap_t *)CFG_IMMR;
1370 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1371 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1372 /*
1373 * Disable PCMCIA buffers (isolate the interface)
1374 * and assert RESET signal
1375 */
1376 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001377 reg = PCMCIA_PGCRX(_slot_);
1378 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1379 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001380 PCMCIA_PGCRX(_slot_) = reg;
1381 udelay(500);
1382
1383 /*
1384 * Configure Port C pins for
1385 * 5 Volts Enable and 3 Volts enable,
1386 * Turn all power pins to Hi-Z
1387 */
1388 debug ("PCMCIA power OFF\n");
1389 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1390
1391 reg = cp->cp_pbdat;
1392
1393 switch(vcc) {
1394 case 0: break; /* Switch off */
1395 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1396 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1397 default: goto done;
1398 }
1399
1400 /* Checking supported voltages */
1401
1402 debug ("PIPR: 0x%x --> %s\n",
1403 pcmp->pcmc_pipr,
1404 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1405
1406 cp->cp_pbdat = reg;
1407
1408#ifdef DEBUG
1409 {
1410 char *s;
1411
1412 if ((reg & TPS2205_VCC3) == 0) {
1413 s = "at 3.3V";
1414 } else if ((reg & TPS2205_VCC5) == 0) {
1415 s = "at 5.0V";
1416 } else {
1417 s = "down";
1418 }
1419 printf ("PCMCIA powered %s\n", s);
1420 }
1421#endif
1422
1423done:
1424 debug ("Enable PCMCIA buffers and stop RESET\n");
1425 reg = PCMCIA_PGCRX(_slot_);
1426 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1427 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1428 PCMCIA_PGCRX(_slot_) = reg;
1429 udelay(500);
1430
1431 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1432 slot+'A');
1433 return (0);
1434}
1435
1436static void cfg_port_B (void)
1437{
1438 volatile immap_t *immap;
1439 volatile cpm8xx_t *cp;
1440 uint reg;
1441
1442 immap = (immap_t *)CFG_IMMR;
1443 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1444
1445 /*
1446 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1447 *
1448 * Switch off all voltages, assert shutdown
1449 */
1450 reg = cp->cp_pbdat;
wdenk1f53a412002-12-04 23:39:58 +00001451 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1452 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1453 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001454 cp->cp_pbdat = reg;
1455
1456 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1457
1458 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1459 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1460
1461 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1462 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1463}
1464
1465#endif /* ICU862 */
1466
1467
wdenk1f53a412002-12-04 23:39:58 +00001468/* -------------------------------------------------------------------- */
1469/* C2MON Boards by TTTech Computertechnik AG */
1470/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001471
1472#if defined(CONFIG_C2MON)
1473
1474#define PCMCIA_BOARD_MSG "C2MON"
1475
1476static void cfg_ports (void);
1477
1478static int hardware_enable(int slot)
1479{
1480 volatile immap_t *immap;
1481 volatile cpm8xx_t *cp;
1482 volatile pcmconf8xx_t *pcmp;
1483 volatile sysconf8xx_t *sysp;
1484 uint reg, pipr, mask;
1485 ushort sreg;
1486 int i;
1487
1488 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1489
1490 udelay(10000);
1491
1492 immap = (immap_t *)CFG_IMMR;
1493 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1494 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1495 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1496
1497 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1498 cfg_ports ();
1499
1500 /*
1501 * Configure SIUMCR to enable PCMCIA port B
1502 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1503 */
1504 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1505
1506 /* clear interrupt state, and disable interrupts */
1507 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1508 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1509
wdenkc6097192002-11-03 00:24:07 +00001510 /*
wdenk1f53a412002-12-04 23:39:58 +00001511 * Disable interrupts, DMA, and PCMCIA buffers
1512 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001513 */
1514 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001515 reg = 0;
1516 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1517 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001518 PCMCIA_PGCRX(_slot_) = reg;
1519 udelay(500);
1520
1521 /*
1522 * Make sure there is a card in the slot, then configure the interface.
1523 */
1524 udelay(10000);
1525 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1526 __LINE__,__FUNCTION__,
1527 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001528 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001529 printf (" No Card found\n");
1530 return (1);
1531 }
1532
1533 /*
1534 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1535 */
1536 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1537 pipr = pcmp->pcmc_pipr;
1538 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1539 pipr,
1540 (reg&PCMCIA_VS1(slot))?"n":"ff",
1541 (reg&PCMCIA_VS2(slot))?"n":"ff");
1542
1543 sreg = immap->im_ioport.iop_pcdat;
1544 if ((pipr & mask) == mask) {
1545 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1546 TPS2211_VCCD1); /* 5V on */
1547 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1548 puts (" 5.0V card found: ");
1549 } else {
1550 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1551 TPS2211_VCCD0); /* 3V on */
1552 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1553 puts (" 3.3V card found: ");
1554 }
1555
1556 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1557 sreg,
1558 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1559 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1560 );
1561
1562 immap->im_ioport.iop_pcdat = sreg;
1563
1564 /* Wait 500 ms; use this to check for over-current */
1565 for (i=0; i<5000; ++i) {
1566 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1567 printf (" *** Overcurrent - Safety shutdown ***\n");
1568 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1569 return (1);
1570 }
1571 udelay (100);
1572 }
1573
1574 debug ("Enable PCMCIA buffers and stop RESET\n");
1575 reg = PCMCIA_PGCRX(_slot_);
1576 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1577 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1578 PCMCIA_PGCRX(_slot_) = reg;
1579
1580 udelay(250000); /* some cards need >150 ms to come up :-( */
1581
1582 debug ("# hardware_enable done\n");
1583
1584 return (0);
1585}
1586
1587
wdenkc6097192002-11-03 00:24:07 +00001588#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1589static int hardware_disable(int slot)
1590{
1591 volatile immap_t *immap;
1592 volatile cpm8xx_t *cp;
1593 volatile pcmconf8xx_t *pcmp;
1594 u_long reg;
1595
1596 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1597
1598 immap = (immap_t *)CFG_IMMR;
1599 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1600
1601 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001602 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001603 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001604 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1605 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1606 PCMCIA_PGCRX(_slot_) = reg;
1607
1608 /* ALl voltages off / Hi-Z */
1609 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1610 TPS2211_VCCD0 | TPS2211_VCCD1 );
1611
1612 udelay(10000);
1613
1614 return (0);
1615}
1616#endif /* CFG_CMD_PCMCIA */
1617
1618
wdenkc6097192002-11-03 00:24:07 +00001619static int voltage_set(int slot, int vcc, int vpp)
1620{
1621 volatile immap_t *immap;
1622 volatile cpm8xx_t *cp;
1623 volatile pcmconf8xx_t *pcmp;
1624 u_long reg;
1625 ushort sreg;
1626
1627 debug ("voltage_set: "
1628 PCMCIA_BOARD_MSG
1629 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1630 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1631
1632 immap = (immap_t *)CFG_IMMR;
1633 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1634 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1635 /*
1636 * Disable PCMCIA buffers (isolate the interface)
1637 * and assert RESET signal
1638 */
1639 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001640 reg = PCMCIA_PGCRX(_slot_);
1641 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1642 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001643 PCMCIA_PGCRX(_slot_) = reg;
1644 udelay(500);
1645
1646 /*
1647 * Configure Port C pins for
1648 * 5 Volts Enable and 3 Volts enable,
1649 * Turn all power pins to Hi-Z
1650 */
1651 debug ("PCMCIA power OFF\n");
1652 cfg_ports (); /* Enables switch, but all in Hi-Z */
1653
1654 sreg = immap->im_ioport.iop_pcdat;
1655 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1656
1657 switch(vcc) {
1658 case 0: break; /* Switch off */
1659 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1660 sreg &= ~TPS2211_VCCD1;
1661 break;
1662 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1663 sreg |= TPS2211_VCCD1;
1664 break;
1665 default: goto done;
1666 }
1667
1668 /* Checking supported voltages */
1669
1670 debug ("PIPR: 0x%x --> %s\n",
1671 pcmp->pcmc_pipr,
1672 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1673
1674 immap->im_ioport.iop_pcdat = sreg;
1675
1676#ifdef DEBUG
1677 {
1678 char *s;
1679
1680 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1681 s = "at 3.3V";
1682 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1683 s = "at 5.0V";
1684 } else {
1685 s = "down";
1686 }
1687 printf ("PCMCIA powered %s\n", s);
1688 }
1689#endif
1690
1691done:
1692 debug ("Enable PCMCIA buffers and stop RESET\n");
1693 reg = PCMCIA_PGCRX(_slot_);
1694 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1695 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1696 PCMCIA_PGCRX(_slot_) = reg;
1697 udelay(500);
1698
1699 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1700 slot+'A');
1701 return (0);
1702}
1703
1704static void cfg_ports (void)
1705{
1706 volatile immap_t *immap;
1707 volatile cpm8xx_t *cp;
1708 ushort sreg;
1709
1710 immap = (immap_t *)CFG_IMMR;
1711 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1712
1713 /*
1714 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1715 *
1716 * Switch off all voltages, assert shutdown
1717 */
1718 sreg = immap->im_ioport.iop_pcdat;
1719 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1720 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1721 immap->im_ioport.iop_pcdat = sreg;
1722
1723 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1724 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1725
1726 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1727 immap->im_ioport.iop_pcpar,
1728 immap->im_ioport.iop_pcdir,
1729 immap->im_ioport.iop_pcdat);
1730
1731 /*
1732 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1733 *
1734 * Over-Current Input only
1735 */
1736 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1737 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1738
1739 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1740 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1741}
1742
1743#endif /* C2MON */
1744
wdenk1f53a412002-12-04 23:39:58 +00001745/* -------------------------------------------------------------------- */
1746/* MBX board from Morotola */
1747/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001748
1749#if defined( CONFIG_MBX )
1750#include <../board/mbx8xx/csr.h>
1751
1752/* A lot of this has been taken from the RPX code in this file it works from me.
1753 I have added the voltage selection for the MBX board. */
1754
1755/* MBX voltage bit in control register #2 */
1756#define CR2_VPP12 ((uchar)0x10)
1757#define CR2_VPPVDD ((uchar)0x20)
1758#define CR2_VDD5 ((uchar)0x40)
1759#define CR2_VDD3 ((uchar)0x80)
1760
1761#define PCMCIA_BOARD_MSG "MBX860"
1762
1763static int voltage_set (int slot, int vcc, int vpp)
1764{
1765 uchar reg = 0;
1766
1767 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1768 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1769
1770 switch (vcc) {
1771 case 0:
1772 break;
1773 case 33:
1774 reg |= CR2_VDD3;
1775 break;
1776 case 50:
1777 reg |= CR2_VDD5;
1778 break;
1779 default:
1780 return 1;
1781 }
1782
1783 switch (vpp) {
1784 case 0:
1785 break;
1786 case 33:
1787 case 50:
1788 if (vcc == vpp) {
1789 reg |= CR2_VPPVDD;
1790 } else {
1791 return 1;
1792 }
1793 break;
1794 case 120:
1795 reg |= CR2_VPP12;
1796 break;
1797 default:
1798 return 1;
1799 }
1800
1801 /* first, turn off all power */
1802 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1803
1804 /* enable new powersettings */
1805 MBX_CSR2 |= reg;
1806 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1807
1808 return (0);
1809}
1810
1811static int hardware_enable (int slot)
1812{
1813 volatile immap_t *immap;
1814 volatile cpm8xx_t *cp;
1815 volatile pcmconf8xx_t *pcmp;
1816 volatile sysconf8xx_t *sysp;
1817 uint reg, mask;
1818
1819 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1820 'A' + slot);
1821
1822 udelay (10000);
1823
1824 immap = (immap_t *) CFG_IMMR;
1825 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1826 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1827 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1828
1829 /* clear interrupt state, and disable interrupts */
1830 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1831 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1832
wdenkc6097192002-11-03 00:24:07 +00001833 /*
wdenk1f53a412002-12-04 23:39:58 +00001834 * Disable interrupts, DMA, and PCMCIA buffers
1835 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001836 */
1837 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001838 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001839 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1840 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1841 PCMCIA_PGCRX (_slot_) = reg;
1842 udelay (500);
1843
1844 /* remove all power */
1845 voltage_set (slot, 0, 0);
1846 /*
1847 * Make sure there is a card in the slot, then configure the interface.
1848 */
wdenkea909b72002-11-21 23:11:29 +00001849 udelay(10000);
1850 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1851 __LINE__,__FUNCTION__,
1852 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkc40b2952004-03-13 23:29:43 +00001853#ifndef CONFIG_HMI10
wdenkea909b72002-11-21 23:11:29 +00001854 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenka522fa02004-01-04 22:51:12 +00001855#else
1856 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkc40b2952004-03-13 23:29:43 +00001857#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +00001858 printf (" No Card found\n");
1859 return (1);
1860 }
1861
1862 /*
1863 * Power On.
1864 */
1865 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1866 reg = pcmp->pcmc_pipr;
1867 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1868 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1869 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1870
1871 if ((reg & mask) == mask) {
1872 voltage_set (_slot_, 50, 0);
1873 printf (" 5.0V card found: ");
1874 } else {
1875 voltage_set (_slot_, 33, 0);
1876 printf (" 3.3V card found: ");
1877 }
1878
1879 debug ("Enable PCMCIA buffers and stop RESET\n");
1880 reg = PCMCIA_PGCRX (_slot_);
1881 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1882 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1883 PCMCIA_PGCRX (_slot_) = reg;
1884
1885 udelay (250000); /* some cards need >150 ms to come up :-( */
1886
1887 debug ("# hardware_enable done\n");
1888
1889 return (0);
1890}
1891
1892#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1893static int hardware_disable (int slot)
1894{
1895 return 0; /* No hardware to disable */
1896}
1897#endif /* CFG_CMD_PCMCIA */
1898#endif /* CONFIG_MBX */
wdenk1f53a412002-12-04 23:39:58 +00001899/* -------------------------------------------------------------------- */
1900/* R360MPI Board */
1901/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001902
1903#if defined(CONFIG_R360MPI)
1904
1905#define PCMCIA_BOARD_MSG "R360MPI"
1906
1907
1908static int hardware_enable(int slot)
1909{
1910 volatile immap_t *immap;
1911 volatile cpm8xx_t *cp;
1912 volatile pcmconf8xx_t *pcmp;
1913 volatile sysconf8xx_t *sysp;
1914 uint reg, mask;
1915
1916 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1917
1918 udelay(10000);
1919
1920 immap = (immap_t *)CFG_IMMR;
1921 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1922 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1923 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1924
1925 /*
1926 * Configure SIUMCR to enable PCMCIA port B
1927 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1928 */
1929 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1930
1931 /* clear interrupt state, and disable interrupts */
1932 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1933 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1934
wdenkc6097192002-11-03 00:24:07 +00001935 /*
wdenk1f53a412002-12-04 23:39:58 +00001936 * Disable interrupts, DMA, and PCMCIA buffers
1937 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001938 */
1939 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001940 reg = 0;
1941 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1942 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001943 PCMCIA_PGCRX(_slot_) = reg;
1944 udelay(500);
1945
1946 /*
1947 * Configure Ports A, B & C pins for
1948 * 5 Volts Enable and 3 Volts enable
1949 */
1950 immap->im_ioport.iop_pcpar &= ~(0x0400);
1951 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1952 immap->im_ioport.iop_pcdir |= 0x0400;*/
1953
1954 immap->im_ioport.iop_papar &= ~(0x0200);/*
1955 immap->im_ioport.iop_padir |= 0x0200;*/
1956#if 0
1957 immap->im_ioport.iop_pbpar &= ~(0xC000);
1958 immap->im_ioport.iop_pbdir &= ~(0xC000);
1959#endif
1960 /* remove all power */
1961
1962 immap->im_ioport.iop_pcdat |= 0x0400;
1963 immap->im_ioport.iop_padat |= 0x0200;
1964
1965 /*
1966 * Make sure there is a card in the slot, then configure the interface.
1967 */
1968 udelay(10000);
1969 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1970 __LINE__,__FUNCTION__,
1971 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001972 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001973 printf (" No Card found\n");
1974 return (1);
1975 }
1976
1977 /*
1978 * Power On.
1979 */
1980 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1981 reg = pcmp->pcmc_pipr;
1982 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1983 reg,
1984 (reg&PCMCIA_VS1(slot))?"n":"ff",
1985 (reg&PCMCIA_VS2(slot))?"n":"ff");
1986 if ((reg & mask) == mask) {
1987 immap->im_ioport.iop_pcdat &= ~(0x4000);
1988 puts (" 5.0V card found: ");
1989 } else {
1990 immap->im_ioport.iop_padat &= ~(0x0002);
1991 puts (" 3.3V card found: ");
1992 }
1993 immap->im_ioport.iop_pcdir |= 0x0400;
1994 immap->im_ioport.iop_padir |= 0x0200;
1995#if 0
1996 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
1997 cp->cp_pbdir &= ~(0x0020 | 0x0010);
1998 cp->cp_pbpar &= ~(0x0020 | 0x0010);
1999 udelay(500000);
2000#endif
2001 debug ("Enable PCMCIA buffers and stop RESET\n");
2002 reg = PCMCIA_PGCRX(_slot_);
2003 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2004 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2005 PCMCIA_PGCRX(_slot_) = reg;
2006
2007 udelay(250000); /* some cards need >150 ms to come up :-( */
2008
2009 debug ("# hardware_enable done\n");
2010
2011 return (0);
2012}
2013
2014
wdenkc6097192002-11-03 00:24:07 +00002015#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2016static int hardware_disable(int slot)
2017{
2018 volatile immap_t *immap;
2019 volatile pcmconf8xx_t *pcmp;
2020 u_long reg;
2021
2022 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2023
2024 immap = (immap_t *)CFG_IMMR;
2025 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2026
2027 /* remove all power */
2028 immap->im_ioport.iop_pcdat |= 0x0400;
2029 immap->im_ioport.iop_padat |= 0x0200;
2030
2031 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00002032 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002033 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00002034 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2035 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2036 PCMCIA_PGCRX(_slot_) = reg;
2037
2038 udelay(10000);
2039
2040 return (0);
2041}
2042#endif /* CFG_CMD_PCMCIA */
2043
2044
wdenkc6097192002-11-03 00:24:07 +00002045static int voltage_set(int slot, int vcc, int vpp)
2046{
2047 volatile immap_t *immap;
2048 volatile pcmconf8xx_t *pcmp;
2049 u_long reg;
2050
2051 debug ("voltage_set: "
2052 PCMCIA_BOARD_MSG
2053 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2054 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2055
2056 immap = (immap_t *)CFG_IMMR;
2057 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2058 /*
2059 * Disable PCMCIA buffers (isolate the interface)
2060 * and assert RESET signal
2061 */
2062 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002063 reg = PCMCIA_PGCRX(_slot_);
2064 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2065 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002066 PCMCIA_PGCRX(_slot_) = reg;
2067 udelay(500);
2068
2069 /*
2070 * Configure Ports A & C pins for
2071 * 5 Volts Enable and 3 Volts enable,
2072 * Turn off all power
2073 */
2074 debug ("PCMCIA power OFF\n");
2075 immap->im_ioport.iop_pcpar &= ~(0x0400);
2076 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2077 immap->im_ioport.iop_pcdir |= 0x0400;*/
2078
2079 immap->im_ioport.iop_papar &= ~(0x0200);/*
2080 immap->im_ioport.iop_padir |= 0x0200;*/
2081
2082 immap->im_ioport.iop_pcdat |= 0x0400;
2083 immap->im_ioport.iop_padat |= 0x0200;
2084
2085 reg = 0;
2086 switch(vcc) {
2087 case 0: break;
2088 case 33: reg |= 0x0200; break;
2089 case 50: reg |= 0x0400; break;
2090 default: goto done;
2091 }
2092
2093 /* Checking supported voltages */
2094
2095 debug ("PIPR: 0x%x --> %s\n",
2096 pcmp->pcmc_pipr,
2097 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2098
2099 if (reg & 0x0200)
2100 immap->im_ioport.iop_pcdat &= !reg;
2101 if (reg & 0x0400)
2102 immap->im_ioport.iop_padat &= !reg;
wdenk1f53a412002-12-04 23:39:58 +00002103 immap->im_ioport.iop_pcdir |= 0x0200;
2104 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00002105 if (reg) {
2106 debug ("PCMCIA powered at %sV\n",
2107 (reg&0x0400) ? "5.0" : "3.3");
2108 } else {
2109 debug ("PCMCIA powered down\n");
2110 }
2111
2112done:
2113 debug ("Enable PCMCIA buffers and stop RESET\n");
2114 reg = PCMCIA_PGCRX(_slot_);
2115 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2116 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2117 PCMCIA_PGCRX(_slot_) = reg;
2118 udelay(500);
2119
2120 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2121 slot+'A');
2122 return (0);
2123}
2124
2125#endif /* R360MPI */
2126
wdenk1f53a412002-12-04 23:39:58 +00002127/* -------------------------------------------------------------------- */
wdenk0608e042004-03-25 19:29:38 +00002128/* KUP4K and KUP4X Boards */
wdenk1f53a412002-12-04 23:39:58 +00002129/* -------------------------------------------------------------------- */
wdenk0608e042004-03-25 19:29:38 +00002130#if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
wdenk56f94be2002-11-05 16:35:14 +00002131
wdenk0608e042004-03-25 19:29:38 +00002132#define PCMCIA_BOARD_MSG "KUP"
wdenk56f94be2002-11-05 16:35:14 +00002133
2134#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2135
2136static int hardware_enable(int slot)
2137{
2138 volatile immap_t *immap;
2139 volatile cpm8xx_t *cp;
2140 volatile pcmconf8xx_t *pcmp;
2141 volatile sysconf8xx_t *sysp;
2142 uint reg, mask;
2143
2144 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2145
2146 udelay(10000);
2147
2148 immap = (immap_t *)CFG_IMMR;
2149 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2150 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2151 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2152
2153 /*
2154 * Configure SIUMCR to enable PCMCIA port B
2155 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2156 */
2157 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2158
2159 /* clear interrupt state, and disable interrupts */
wdenkea909b72002-11-21 23:11:29 +00002160 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2161 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002162
wdenk56f94be2002-11-05 16:35:14 +00002163 /*
wdenk1f53a412002-12-04 23:39:58 +00002164 * Disable interrupts, DMA, and PCMCIA buffers
2165 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002166 */
2167 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002168 reg = 0;
2169 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2170 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002171 PCMCIA_PGCRX(slot) = reg;
2172 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002173
2174 /*
2175 * Configure Port B pins for
2176 * 3 Volts enable
2177 */
wdenkea909b72002-11-21 23:11:29 +00002178 if (slot) { /* Slot A is built-in */
2179 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2180 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2181 /* remove all power */
2182 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2183 }
wdenk56f94be2002-11-05 16:35:14 +00002184 /*
2185 * Make sure there is a card in the slot, then configure the interface.
2186 */
2187 udelay(10000);
2188 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2189 __LINE__,__FUNCTION__,
2190 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002191 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002192 printf (" No Card found\n");
2193 return (1);
2194 }
2195
2196 /*
2197 * Power On.
2198 */
wdenka6c7ad22002-12-03 21:28:10 +00002199 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002200 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2201 reg = pcmp->pcmc_pipr;
2202 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2203 reg,
2204 (reg&PCMCIA_VS1(slot))?"n":"ff",
2205 (reg&PCMCIA_VS2(slot))?"n":"ff");
2206 if ((reg & mask) == mask) {
2207 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2208 } else {
wdenkea909b72002-11-21 23:11:29 +00002209 if(slot)
2210 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002211 puts (" 3.3V card found: ");
2212 }
2213#if 0
2214 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2215 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2216 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2217 udelay(500000);
2218#endif
2219 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002220 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002221 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2222 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002223 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002224
2225 udelay(250000); /* some cards need >150 ms to come up :-( */
2226
2227 debug ("# hardware_enable done\n");
2228
2229 return (0);
2230}
2231
2232
wdenk56f94be2002-11-05 16:35:14 +00002233#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2234static int hardware_disable(int slot)
2235{
2236 volatile immap_t *immap;
2237 volatile cpm8xx_t *cp;
2238 volatile pcmconf8xx_t *pcmp;
2239 u_long reg;
2240
2241 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2242
2243 immap = (immap_t *)CFG_IMMR;
2244 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2245 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk1f53a412002-12-04 23:39:58 +00002246
wdenk56f94be2002-11-05 16:35:14 +00002247 /* remove all power */
wdenkea909b72002-11-21 23:11:29 +00002248 if (slot)
2249 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002250
2251 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002252 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002253 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002254 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2255 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002256 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002257
2258 udelay(10000);
2259
2260 return (0);
2261}
2262#endif /* CFG_CMD_PCMCIA */
2263
2264
wdenk56f94be2002-11-05 16:35:14 +00002265static int voltage_set(int slot, int vcc, int vpp)
2266{
2267 volatile immap_t *immap;
2268 volatile cpm8xx_t *cp;
2269 volatile pcmconf8xx_t *pcmp;
2270 u_long reg;
2271
2272 debug ("voltage_set: " \
2273 PCMCIA_BOARD_MSG \
2274 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2275 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2276
wdenkea909b72002-11-21 23:11:29 +00002277 if (!slot) /* Slot A is not configurable */
2278 return 0;
2279
wdenk56f94be2002-11-05 16:35:14 +00002280 immap = (immap_t *)CFG_IMMR;
2281 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2282 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2283
2284 /*
2285 * Disable PCMCIA buffers (isolate the interface)
2286 * and assert RESET signal
2287 */
2288 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002289 reg = PCMCIA_PGCRX(slot);
2290 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2291 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002292 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002293 udelay(500);
2294
2295 debug ("PCMCIA power OFF\n");
2296 /*
2297 * Configure Port B pins for
2298 * 3 Volts enable
2299 */
2300 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2301 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2302 /* remove all power */
2303 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2304
2305 switch(vcc) {
2306 case 0: break;
2307 case 33:
2308 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2309 debug ("PCMCIA powered at 3.3V\n");
2310 break;
2311 case 50:
2312 debug ("PCMCIA: 5Volt vcc not supported\n");
2313 break;
2314 default:
2315 puts("PCMCIA: vcc not supported");
2316 break;
2317 }
wdenkea909b72002-11-21 23:11:29 +00002318 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002319 /* Checking supported voltages */
2320
2321 debug ("PIPR: 0x%x --> %s\n",
2322 pcmp->pcmc_pipr,
wdenkea909b72002-11-21 23:11:29 +00002323 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002324 ? "only 5 V --> NOT SUPPORTED"
2325 : "can do 3.3V");
2326
2327
2328 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002329 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002330 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2331 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002332 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002333 udelay(500);
2334
2335 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2336 slot+'A');
2337 return (0);
2338}
2339
wdenk0608e042004-03-25 19:29:38 +00002340#endif /* KUP4K || KUP4X */
wdenk56f94be2002-11-05 16:35:14 +00002341
2342
wdenk1f53a412002-12-04 23:39:58 +00002343/* -------------------------------------------------------------------- */
2344/* End of Board Specific Stuff */
2345/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002346
2347
wdenk1f53a412002-12-04 23:39:58 +00002348/* -------------------------------------------------------------------- */
2349/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2350/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002351
2352/*
2353 * Search this table to see if the windowsize is
2354 * supported...
2355 */
2356
2357#define M8XX_SIZES_NO 32
2358
2359static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2360{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2361 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2362 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2363 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2364
2365 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2366 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2367 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2368 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2369
2370
wdenk1f53a412002-12-04 23:39:58 +00002371/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002372
wdenk7f70e852003-05-20 14:25:27 +00002373#ifndef CONFIG_I82365
2374
wdenkc6097192002-11-03 00:24:07 +00002375static u_int m8xx_get_graycode(u_int size)
2376{
2377 u_int k;
2378
2379 for (k = 0; k < M8XX_SIZES_NO; k++) {
2380 if(m8xx_size_to_gray[k] == size)
2381 break;
2382 }
2383
2384 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2385 k = -1;
2386
2387 return k;
2388}
2389
wdenk7f70e852003-05-20 14:25:27 +00002390#endif /* CONFIG_I82365 */
2391
wdenk1f53a412002-12-04 23:39:58 +00002392/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002393
2394#if 0
2395static u_int m8xx_get_speed(u_int ns, u_int is_io)
2396{
2397 u_int reg, clocks, psst, psl, psht;
2398
2399 if(!ns) {
2400
2401 /*
2402 * We get called with IO maps setup to 0ns
2403 * if not specified by the user.
2404 * They should be 255ns.
2405 */
2406
2407 if(is_io)
2408 ns = 255;
2409 else
2410 ns = 100; /* fast memory if 0 */
2411 }
2412
2413 /*
2414 * In PSST, PSL, PSHT fields we tell the controller
2415 * timing parameters in CLKOUT clock cycles.
2416 * CLKOUT is the same as GCLK2_50.
2417 */
2418
2419/* how we want to adjust the timing - in percent */
2420
2421#define ADJ 180 /* 80 % longer accesstime - to be sure */
2422
2423 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2424 clocks = (clocks * ADJ) / (100*1000);
2425
2426 if(clocks >= PCMCIA_BMT_LIMIT) {
2427 DEBUG(0, "Max access time limit reached\n");
2428 clocks = PCMCIA_BMT_LIMIT-1;
2429 }
2430
2431 psst = clocks / 7; /* setup time */
2432 psht = clocks / 7; /* hold time */
2433 psl = (clocks * 5) / 7; /* strobe length */
2434
2435 psst += clocks - (psst + psht + psl);
2436
2437 reg = psst << 12;
2438 reg |= psl << 7;
2439 reg |= psht << 16;
2440
2441 return reg;
2442}
2443#endif
2444
wdenk1f53a412002-12-04 23:39:58 +00002445/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002446
2447#ifdef CONFIG_IDE_8xx_PCCARD
2448static void print_funcid (int func)
2449{
2450 puts (indent);
2451 switch (func) {
2452 case CISTPL_FUNCID_MULTI:
2453 puts (" Multi-Function");
2454 break;
2455 case CISTPL_FUNCID_MEMORY:
2456 puts (" Memory");
2457 break;
2458 case CISTPL_FUNCID_SERIAL:
2459 puts (" Serial Port");
2460 break;
2461 case CISTPL_FUNCID_PARALLEL:
2462 puts (" Parallel Port");
2463 break;
2464 case CISTPL_FUNCID_FIXED:
2465 puts (" Fixed Disk");
2466 break;
2467 case CISTPL_FUNCID_VIDEO:
2468 puts (" Video Adapter");
2469 break;
2470 case CISTPL_FUNCID_NETWORK:
2471 puts (" Network Adapter");
2472 break;
2473 case CISTPL_FUNCID_AIMS:
2474 puts (" AIMS Card");
2475 break;
2476 case CISTPL_FUNCID_SCSI:
2477 puts (" SCSI Adapter");
2478 break;
2479 default:
2480 puts (" Unknown");
2481 break;
2482 }
2483 puts (" Card\n");
2484}
2485#endif /* CONFIG_IDE_8xx_PCCARD */
2486
wdenk1f53a412002-12-04 23:39:58 +00002487/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002488
2489#ifdef CONFIG_IDE_8xx_PCCARD
2490static void print_fixed (volatile uchar *p)
2491{
2492 if (p == NULL)
2493 return;
2494
2495 puts(indent);
2496
2497 switch (*p) {
2498 case CISTPL_FUNCE_IDE_IFACE:
2499 { uchar iface = *(p+2);
2500
2501 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2502 puts (" interface ");
2503 break;
2504 }
2505 case CISTPL_FUNCE_IDE_MASTER:
2506 case CISTPL_FUNCE_IDE_SLAVE:
2507 { uchar f1 = *(p+2);
2508 uchar f2 = *(p+4);
2509
2510 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2511
2512 if (f1 & CISTPL_IDE_UNIQUE)
2513 puts (" [unique]");
2514
2515 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2516
2517 if (f2 & CISTPL_IDE_HAS_SLEEP)
2518 puts (" [sleep]");
2519
2520 if (f2 & CISTPL_IDE_HAS_STANDBY)
2521 puts (" [standby]");
2522
2523 if (f2 & CISTPL_IDE_HAS_IDLE)
2524 puts (" [idle]");
2525
2526 if (f2 & CISTPL_IDE_LOW_POWER)
2527 puts (" [low power]");
2528
2529 if (f2 & CISTPL_IDE_REG_INHIBIT)
2530 puts (" [reg inhibit]");
2531
2532 if (f2 & CISTPL_IDE_HAS_INDEX)
2533 puts (" [index]");
2534
2535 if (f2 & CISTPL_IDE_IOIS16)
2536 puts (" [IOis16]");
2537
2538 break;
2539 }
2540 }
2541 putc ('\n');
2542}
2543#endif /* CONFIG_IDE_8xx_PCCARD */
2544
wdenk1f53a412002-12-04 23:39:58 +00002545/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002546
2547#ifdef CONFIG_IDE_8xx_PCCARD
2548
2549#define MAX_IDENT_CHARS 64
2550#define MAX_IDENT_FIELDS 4
2551
2552static uchar *known_cards[] = {
2553 "ARGOSY PnPIDE D5",
2554 NULL
2555};
2556
2557static int identify (volatile uchar *p)
2558{
2559 uchar id_str[MAX_IDENT_CHARS];
2560 uchar data;
2561 uchar *t;
2562 uchar **card;
2563 int i, done;
2564
2565 if (p == NULL)
2566 return (0); /* Don't know */
2567
2568 t = id_str;
2569 done =0;
2570
2571 for (i=0; i<=4 && !done; ++i, p+=2) {
2572 while ((data = *p) != '\0') {
2573 if (data == 0xFF) {
2574 done = 1;
2575 break;
2576 }
2577 *t++ = data;
2578 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2579 done = 1;
2580 break;
2581 }
2582 p += 2;
2583 }
2584 if (!done)
2585 *t++ = ' ';
2586 }
2587 *t = '\0';
2588 while (--t > id_str) {
2589 if (*t == ' ')
2590 *t = '\0';
2591 else
2592 break;
2593 }
2594 puts (id_str);
2595 putc ('\n');
2596
2597 for (card=known_cards; *card; ++card) {
2598 debug ("## Compare against \"%s\"\n", *card);
2599 if (strcmp(*card, id_str) == 0) { /* found! */
2600 debug ("## CARD FOUND ##\n");
2601 return (1);
2602 }
2603 }
2604
2605 return (0); /* don't know */
2606}
2607#endif /* CONFIG_IDE_8xx_PCCARD */
2608
wdenk1f53a412002-12-04 23:39:58 +00002609/* -------------------------------------------------------------------- */
wdenk04a85b32004-04-15 18:22:41 +00002610/* NETTA board by Intracom S.A. */
2611/* -------------------------------------------------------------------- */
2612
2613#if defined(CONFIG_NETTA)
2614
2615/* some sane bit macros */
2616#define _BD(_b) (1U << (31-(_b)))
2617#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2618
2619#define _BW(_b) (1U << (15-(_b)))
2620#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2621
2622#define _BB(_b) (1U << (7-(_b)))
2623#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2624
2625#define _B(_b) _BD(_b)
2626#define _BR(_l, _h) _BDR(_l, _h)
2627
2628#define PCMCIA_BOARD_MSG "NETTA"
2629
2630static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2631
2632static void cfg_vppd(int no)
2633{
2634 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2635 unsigned short mask;
2636
2637 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2638 return;
2639
2640 mask = vppd_masks[no];
2641
2642 immap->im_ioport.iop_papar &= ~mask;
2643 immap->im_ioport.iop_paodr &= ~mask;
2644 immap->im_ioport.iop_padir |= mask;
2645}
2646
2647static void set_vppd(int no, int what)
2648{
2649 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2650 unsigned short mask;
2651
2652 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2653 return;
2654
2655 mask = vppd_masks[no];
2656
2657 if (what)
2658 immap->im_ioport.iop_padat |= mask;
2659 else
2660 immap->im_ioport.iop_padat &= ~mask;
2661}
2662
2663static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2664
2665static void cfg_vccd(int no)
2666{
2667 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2668 unsigned short mask;
2669
2670 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2671 return;
2672
2673 mask = vccd_masks[no];
2674
2675 immap->im_ioport.iop_papar &= ~mask;
2676 immap->im_ioport.iop_paodr &= ~mask;
2677 immap->im_ioport.iop_padir |= mask;
2678}
2679
2680static void set_vccd(int no, int what)
2681{
2682 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2683 unsigned short mask;
2684
2685 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2686 return;
2687
2688 mask = vccd_masks[no];
2689
2690 if (what)
2691 immap->im_ioport.iop_padat |= mask;
2692 else
2693 immap->im_ioport.iop_padat &= ~mask;
2694}
2695
2696static const unsigned short oc_mask = _BW(8);
2697
2698static void cfg_oc(void)
2699{
2700 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2701 unsigned short mask = oc_mask;
2702
2703 immap->im_ioport.iop_pcdir &= ~mask;
2704 immap->im_ioport.iop_pcso &= ~mask;
2705 immap->im_ioport.iop_pcint &= ~mask;
2706 immap->im_ioport.iop_pcpar &= ~mask;
2707}
2708
2709static int get_oc(void)
2710{
2711 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2712 unsigned short mask = oc_mask;
2713 int what;
2714
2715 what = !!(immap->im_ioport.iop_pcdat & mask);;
2716 return what;
2717}
2718
2719static const unsigned short shdn_mask = _BW(12);
2720
2721static void cfg_shdn(void)
2722{
2723 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2724 unsigned short mask;
2725
2726 mask = shdn_mask;
2727
2728 immap->im_ioport.iop_papar &= ~mask;
2729 immap->im_ioport.iop_paodr &= ~mask;
2730 immap->im_ioport.iop_padir |= mask;
2731}
2732
2733static void set_shdn(int what)
2734{
2735 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2736 unsigned short mask;
2737
2738 mask = shdn_mask;
2739
2740 if (what)
2741 immap->im_ioport.iop_padat |= mask;
2742 else
2743 immap->im_ioport.iop_padat &= ~mask;
2744}
2745
2746static void cfg_ports (void);
2747
2748static int hardware_enable(int slot)
2749{
2750 volatile immap_t *immap;
2751 volatile cpm8xx_t *cp;
2752 volatile pcmconf8xx_t *pcmp;
2753 volatile sysconf8xx_t *sysp;
2754 uint reg, pipr, mask;
2755 int i;
2756
2757 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2758
2759 udelay(10000);
2760
2761 immap = (immap_t *)CFG_IMMR;
2762 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2763 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2764 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2765
2766 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
2767 cfg_ports ();
2768
2769 /* clear interrupt state, and disable interrupts */
2770 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2771 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2772
2773 /*
2774 * Disable interrupts, DMA, and PCMCIA buffers
2775 * (isolate the interface) and assert RESET signal
2776 */
2777 debug ("Disable PCMCIA buffers and assert RESET\n");
2778 reg = 0;
2779 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2780 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2781 PCMCIA_PGCRX(_slot_) = reg;
2782
2783 udelay(500);
2784
2785 /*
2786 * Make sure there is a card in the slot, then configure the interface.
2787 */
2788 udelay(10000);
2789 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2790 __LINE__,__FUNCTION__,
2791 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2792 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2793 printf (" No Card found\n");
2794 return (1);
2795 }
2796
2797 /*
2798 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
2799 */
2800 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2801 pipr = pcmp->pcmc_pipr;
2802 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2803 pipr,
2804 (reg&PCMCIA_VS1(slot))?"n":"ff",
2805 (reg&PCMCIA_VS2(slot))?"n":"ff");
2806
2807 if ((pipr & mask) == mask) {
2808 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
2809 set_vccd(0, 0); set_vccd(1, 1); /* 5V on, 3V off */
2810 puts (" 5.0V card found: ");
2811 } else {
2812 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
2813 set_vccd(0, 1); set_vccd(1, 0); /* 5V off, 3V on */
2814 puts (" 3.3V card found: ");
2815 }
2816
2817 /* Wait 500 ms; use this to check for over-current */
2818 for (i=0; i<5000; ++i) {
2819 if (!get_oc()) {
2820 printf (" *** Overcurrent - Safety shutdown ***\n");
2821 set_vccd(0, 0); set_vccd(1, 0); /* VAVPP => Hi-Z */
2822 return (1);
2823 }
2824 udelay (100);
2825 }
2826
2827 debug ("Enable PCMCIA buffers and stop RESET\n");
2828 reg = PCMCIA_PGCRX(_slot_);
2829 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2830 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2831 PCMCIA_PGCRX(_slot_) = reg;
2832
2833 udelay(250000); /* some cards need >150 ms to come up :-( */
2834
2835 debug ("# hardware_enable done\n");
2836
2837 return (0);
2838}
2839
2840
2841#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2842static int hardware_disable(int slot)
2843{
2844 volatile immap_t *immap;
2845 volatile pcmconf8xx_t *pcmp;
2846 u_long reg;
2847
2848 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2849
2850 immap = (immap_t *)CFG_IMMR;
2851 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2852
2853 /* Configure PCMCIA General Control Register */
2854 debug ("Disable PCMCIA buffers and assert RESET\n");
2855 reg = 0;
2856 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2857 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2858 PCMCIA_PGCRX(_slot_) = reg;
2859
2860 /* All voltages off / Hi-Z */
2861 set_vppd(0, 1); set_vppd(1, 1);
2862 set_vccd(0, 1); set_vccd(1, 1);
2863
2864 udelay(10000);
2865
2866 return (0);
2867}
2868#endif /* CFG_CMD_PCMCIA */
2869
2870
2871static int voltage_set(int slot, int vcc, int vpp)
2872{
2873 volatile immap_t *immap;
2874 volatile cpm8xx_t *cp;
2875 volatile pcmconf8xx_t *pcmp;
2876 u_long reg;
2877 ushort sreg;
2878
2879 debug ("voltage_set: "
2880 PCMCIA_BOARD_MSG
2881 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2882 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2883
2884 immap = (immap_t *)CFG_IMMR;
2885 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2886 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2887 /*
2888 * Disable PCMCIA buffers (isolate the interface)
2889 * and assert RESET signal
2890 */
2891 debug ("Disable PCMCIA buffers and assert RESET\n");
2892 reg = PCMCIA_PGCRX(_slot_);
2893 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2894 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2895 PCMCIA_PGCRX(_slot_) = reg;
2896 udelay(500);
2897
2898 /*
2899 * Configure Port C pins for
2900 * 5 Volts Enable and 3 Volts enable,
2901 * Turn all power pins to Hi-Z
2902 */
2903 debug ("PCMCIA power OFF\n");
2904 cfg_ports (); /* Enables switch, but all in Hi-Z */
2905
2906 sreg = immap->im_ioport.iop_pcdat;
2907 set_vppd(0, 1); set_vppd(1, 1);
2908
2909 switch(vcc) {
2910 case 0:
2911 break; /* Switch off */
2912
2913 case 33:
2914 set_vccd(0, 1); set_vccd(1, 0);
2915 break;
2916
2917 case 50:
2918 set_vccd(0, 0); set_vccd(1, 1);
2919 break;
2920
2921 default:
2922 goto done;
2923 }
2924
2925 /* Checking supported voltages */
2926
2927 debug ("PIPR: 0x%x --> %s\n",
2928 pcmp->pcmc_pipr,
2929 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2930
2931done:
2932 debug ("Enable PCMCIA buffers and stop RESET\n");
2933 reg = PCMCIA_PGCRX(_slot_);
2934 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2935 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2936 PCMCIA_PGCRX(_slot_) = reg;
2937 udelay(500);
2938
2939 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2940 slot+'A');
2941 return (0);
2942}
2943
2944static void cfg_ports (void)
2945{
2946 volatile immap_t *immap;
2947 volatile cpm8xx_t *cp;
2948
2949 immap = (immap_t *)CFG_IMMR;
2950 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2951
2952
2953 cfg_vppd(0); cfg_vppd(1); /* VPPD0,VPPD1 VAVPP => Hi-Z */
2954 cfg_vccd(0); cfg_vccd(1); /* 3V and 5V off */
2955 cfg_shdn();
2956 cfg_oc();
2957
2958 /*
2959 * Configure Port A for TPS2211 PC-Card Power-Interface Switch
2960 *
2961 * Switch off all voltages, assert shutdown
2962 */
2963 set_vppd(0, 1); set_vppd(1, 1);
2964 set_vccd(0, 0); set_vccd(1, 0);
2965 set_shdn(1);
2966
2967 udelay(100000);
2968}
2969
2970#endif /* NETTA */
2971
2972
2973/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002974
2975#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
wdenk8bde7f72003-06-27 21:31:46 +00002976
2977/**************************************************/
2978
2979#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenk0d498392003-07-01 21:06:45 +00002980U_BOOT_CMD(
2981 pinit, 2, 1, do_pinit,
wdenk8bde7f72003-06-27 21:31:46 +00002982 "pinit - PCMCIA sub-system\n",
2983 "on - power on PCMCIA socket\n"
2984 "pinit off - power off PCMCIA socket\n"
2985);
2986#endif