blob: 1bd4bc532d39b62e7f757165fe542205ffeed749 [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>
wdenk444f22b2003-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);
wdenke5d61c72003-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
wdenk0893c472003-05-20 14:25:27 +000089#ifndef CONFIG_I82365
wdenkc6097192002-11-03 00:24:07 +000090static u_int m8xx_get_graycode(u_int size);
wdenk0893c472003-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
wdenk90e7e422002-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
wdenke5d61c72003-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
wdenk90e7e422002-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
wdenk90e7e422002-12-04 23:39:58 +0000143/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000144
wdenke5d61c72003-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
dzub02ed682003-10-19 21:43:26 +0000163#if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
wdenkc6097192002-11-03 00:24:07 +0000164# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
165#else
166# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
167#endif
168
169int pcmcia_on (void)
170{
171 int i;
172 u_long reg, base;
173 pcmcia_win_t *win;
wdenk2029f4d2002-11-21 23:11:29 +0000174 u_int slotbit;
175 u_int rc, slot;
wdenkc6097192002-11-03 00:24:07 +0000176
177 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
178
179 /* intialize the fixed memory windows */
180 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
181 base = CFG_PCMCIA_MEM_ADDR;
182
183 if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
184 printf ("Cannot set window size to 0x%08x\n",
185 CFG_PCMCIA_MEM_SIZE);
186 return (1);
187 }
188
wdenk2029f4d2002-11-21 23:11:29 +0000189 slotbit = PCMCIA_SLOT_x;
wdenkc6097192002-11-03 00:24:07 +0000190 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
191 win->br = base;
192
wdenk2029f4d2002-11-21 23:11:29 +0000193#if (PCMCIA_SOCKETS_NO == 2)
194 if (i == 4) /* Another slot starting from win 4 */
195 slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
196#endif
wdenkc6097192002-11-03 00:24:07 +0000197 switch (i) {
198#ifdef CONFIG_IDE_8xx_PCCARD
wdenk2029f4d2002-11-21 23:11:29 +0000199 case 4:
wdenkc6097192002-11-03 00:24:07 +0000200 case 0: { /* map attribute memory */
201 win->or = ( PCMCIA_BSIZE_64M
202 | PCMCIA_PPS_8
203 | PCMCIA_PRS_ATTR
wdenk2029f4d2002-11-21 23:11:29 +0000204 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000205 | PCMCIA_PV
206 | CFG_PCMCIA_TIMING );
207 break;
208 }
wdenk2029f4d2002-11-21 23:11:29 +0000209 case 5:
wdenkc6097192002-11-03 00:24:07 +0000210 case 1: { /* map I/O window for data reg */
211 win->or = ( PCMCIA_BSIZE_1K
212 | PCMCIA_PPS_16
213 | PCMCIA_PRS_IO
wdenk2029f4d2002-11-21 23:11:29 +0000214 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000215 | PCMCIA_PV
216 | CFG_PCMCIA_TIMING );
217 break;
218 }
wdenk2029f4d2002-11-21 23:11:29 +0000219 case 6:
wdenk90e7e422002-12-04 23:39:58 +0000220 case 2: { /* map I/O window for cmd/ctrl reg block */
wdenkc6097192002-11-03 00:24:07 +0000221 win->or = ( PCMCIA_BSIZE_1K
222 | PCMCIA_PPS_8
223 | PCMCIA_PRS_IO
wdenk2029f4d2002-11-21 23:11:29 +0000224 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000225 | PCMCIA_PV
226 | CFG_PCMCIA_TIMING );
227 break;
228 }
229#endif /* CONFIG_IDE_8xx_PCCARD */
wdenk67f13362003-12-27 19:24:54 +0000230#ifdef CONFIG_BMS2003
231 case 3: { /* map I/O window for 4xUART data/ctrl */
232 win->br += 0x140000;
233 win->or = ( PCMCIA_BSIZE_256K
234 | PCMCIA_PPS_8
235 | PCMCIA_PRS_IO
236 | slotbit
237 | PCMCIA_PV
238 | CFG_PCMCIA_TIMING );
239 break;
240 }
241#endif /* CONFIG_BMS2003 */
wdenkc6097192002-11-03 00:24:07 +0000242 default: /* set to not valid */
243 win->or = 0;
244 break;
245 }
246
247 debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
248 i, win->br, win->or);
249 base += CFG_PCMCIA_MEM_SIZE;
250 ++win;
251 }
252
wdenk90e7e422002-12-04 23:39:58 +0000253 for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
wdenk2029f4d2002-11-21 23:11:29 +0000254 /* turn off voltage */
255 if ((rc = voltage_set(slot, 0, 0)))
256 continue;
wdenk90e7e422002-12-04 23:39:58 +0000257
wdenk2029f4d2002-11-21 23:11:29 +0000258 /* Enable external hardware */
259 if ((rc = hardware_enable(slot)))
260 continue;
wdenk90e7e422002-12-04 23:39:58 +0000261
wdenkc6097192002-11-03 00:24:07 +0000262#ifdef CONFIG_IDE_8xx_PCCARD
wdenk2029f4d2002-11-21 23:11:29 +0000263 if ((rc = check_ide_device(i)))
264 continue;
wdenkc6097192002-11-03 00:24:07 +0000265#endif
wdenk2029f4d2002-11-21 23:11:29 +0000266 }
267 return (rc);
wdenkc6097192002-11-03 00:24:07 +0000268}
wdenke5d61c72003-05-18 11:30:09 +0000269#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000270
wdenk90e7e422002-12-04 23:39:58 +0000271/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000272
273#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
274
wdenke5d61c72003-05-18 11:30:09 +0000275#ifdef CONFIG_I82365
276static int pcmcia_off (void)
277{
278 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
279
280 i82365_exit();
281
282 return 0;
283}
284#else
wdenkc6097192002-11-03 00:24:07 +0000285static int pcmcia_off (void)
286{
287 int i;
288 pcmcia_win_t *win;
289
290 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
291
292 /* clear interrupt state, and disable interrupts */
293 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
294 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
295
296 /* turn off interrupt and disable CxOE */
297 PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
298
299 /* turn off memory windows */
300 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
301
302 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
303 /* disable memory window */
304 win->or = 0;
305 ++win;
306 }
307
308 /* turn off voltage */
309 voltage_set(_slot_, 0, 0);
310
311 /* disable external hardware */
312 printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
313 hardware_disable(_slot_);
314 return 0;
315}
wdenke5d61c72003-05-18 11:30:09 +0000316#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000317
318#endif /* CFG_CMD_PCMCIA */
319
wdenk90e7e422002-12-04 23:39:58 +0000320/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000321
322#ifdef CONFIG_IDE_8xx_PCCARD
323
324#define MAX_TUPEL_SZ 512
325#define MAX_FEATURES 4
326
wdenk4fc95692003-02-28 00:49:47 +0000327int ide_devices_found;
wdenk2029f4d2002-11-21 23:11:29 +0000328static int check_ide_device (int slot)
wdenkc6097192002-11-03 00:24:07 +0000329{
330 volatile uchar *ident = NULL;
331 volatile uchar *feature_p[MAX_FEATURES];
wdenk2029f4d2002-11-21 23:11:29 +0000332 volatile uchar *p, *start, *addr;
wdenkc6097192002-11-03 00:24:07 +0000333 int n_features = 0;
334 uchar func_id = ~0;
335 uchar code, len;
336 ushort config_base = 0;
337 int found = 0;
338 int i;
339
wdenk90e7e422002-12-04 23:39:58 +0000340 addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
341 CFG_PCMCIA_MEM_SIZE * (slot * 4));
wdenke7f34c62003-01-11 09:48:40 +0000342 debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
wdenkc6097192002-11-03 00:24:07 +0000343
wdenk2029f4d2002-11-21 23:11:29 +0000344 start = p = (volatile uchar *) addr;
wdenkc6097192002-11-03 00:24:07 +0000345
346 while ((p - start) < MAX_TUPEL_SZ) {
347
348 code = *p; p += 2;
349
350 if (code == 0xFF) { /* End of chain */
351 break;
352 }
353
354 len = *p; p += 2;
355#if defined(DEBUG) && (DEBUG > 1)
356 { volatile uchar *q = p;
357 printf ("\nTuple code %02x length %d\n\tData:",
358 code, len);
359
360 for (i = 0; i < len; ++i) {
361 printf (" %02x", *q);
362 q+= 2;
363 }
364 }
365#endif /* DEBUG */
366 switch (code) {
367 case CISTPL_VERS_1:
368 ident = p + 4;
369 break;
370 case CISTPL_FUNCID:
371 /* Fix for broken SanDisk which may have 0x80 bit set */
372 func_id = *p & 0x7F;
373 break;
374 case CISTPL_FUNCE:
375 if (n_features < MAX_FEATURES)
376 feature_p[n_features++] = p;
377 break;
378 case CISTPL_CONFIG:
379 config_base = (*(p+6) << 8) + (*(p+4));
380 debug ("\n## Config_base = %04x ###\n", config_base);
381 default:
382 break;
383 }
384 p += 2 * len;
385 }
386
387 found = identify (ident);
388
389 if (func_id != ((uchar)~0)) {
390 print_funcid (func_id);
391
392 if (func_id == CISTPL_FUNCID_FIXED)
393 found = 1;
394 else
395 return (1); /* no disk drive */
396 }
397
398 for (i=0; i<n_features; ++i) {
399 print_fixed (feature_p[i]);
400 }
401
402 if (!found) {
403 printf ("unknown card type\n");
404 return (1);
405 }
406
wdenk4fc95692003-02-28 00:49:47 +0000407 ide_devices_found |= (1 << slot);
408
wdenkc6097192002-11-03 00:24:07 +0000409 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
wdenk2029f4d2002-11-21 23:11:29 +0000410 *((uchar *)(addr + config_base)) = 1;
wdenkc6097192002-11-03 00:24:07 +0000411
412 return (0);
413}
414#endif /* CONFIG_IDE_8xx_PCCARD */
415
wdenk90e7e422002-12-04 23:39:58 +0000416/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000417
418
wdenk90e7e422002-12-04 23:39:58 +0000419/* -------------------------------------------------------------------- */
420/* board specific stuff: */
421/* voltage_set(), hardware_enable() and hardware_disable() */
422/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000423
wdenk90e7e422002-12-04 23:39:58 +0000424/* -------------------------------------------------------------------- */
425/* RPX Boards from Embedded Planet */
426/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000427
428#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
429
430/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
431 * SYPCR is write once only, therefore must the slowest memory be faster
432 * than the bus monitor or we will get a machine check due to the bus timeout.
433 */
434
435#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
436
437#undef PCMCIA_BMT_LIMIT
438#define PCMCIA_BMT_LIMIT (6*8)
439
440static int voltage_set(int slot, int vcc, int vpp)
441{
442 u_long reg = 0;
443
444 switch(vcc) {
445 case 0: break;
446 case 33: reg |= BCSR1_PCVCTL4; break;
447 case 50: reg |= BCSR1_PCVCTL5; break;
448 default: return 1;
449 }
450
451 switch(vpp) {
452 case 0: break;
453 case 33:
454 case 50:
455 if(vcc == vpp)
456 reg |= BCSR1_PCVCTL6;
457 else
458 return 1;
459 break;
460 case 120:
461 reg |= BCSR1_PCVCTL7;
462 default: return 1;
463 }
464
465 if(vcc == 120)
466 return 1;
467
468 /* first, turn off all power */
469
470 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
471 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
472
473 /* enable new powersettings */
474
475 *((uint *)RPX_CSR_ADDR) |= reg;
476
477 return 0;
478}
479
480#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
481static int hardware_enable (int slot)
482{
483 return 0; /* No hardware to enable */
484}
485#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
486static int hardware_disable(int slot)
487{
488 return 0; /* No hardware to disable */
489}
490#endif /* CFG_CMD_PCMCIA */
491#endif /* CONFIG_RPXCLASSIC */
492
wdenk90e7e422002-12-04 23:39:58 +0000493/* -------------------------------------------------------------------- */
494/* (F)ADS Boards from Motorola */
495/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000496
497#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
498
499#ifdef CONFIG_ADS
500#define PCMCIA_BOARD_MSG "ADS"
501#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
502#else
503#define PCMCIA_BOARD_MSG "FADS"
504#endif
505
506static int voltage_set(int slot, int vcc, int vpp)
507{
508 u_long reg = 0;
509
510 switch(vpp) {
511 case 0: reg = 0; break;
512 case 50: reg = 1; break;
513 case 120: reg = 2; break;
514 default: return 1;
515 }
516
517 switch(vcc) {
518 case 0: reg = 0; break;
519#ifdef CONFIG_ADS
520 case 50: reg = BCSR1_PCCVCCON; break;
521#endif
522#ifdef CONFIG_FADS
523 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
524 case 50: reg = BCSR1_PCCVCC1; break;
525#endif
526 default: return 1;
527 }
528
529 /* first, turn off all power */
530
531#ifdef CONFIG_ADS
532 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
533#endif
534#ifdef CONFIG_FADS
535 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
536#endif
537 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
538
539 /* enable new powersettings */
540
541#ifdef CONFIG_ADS
542 *((uint *)BCSR1) &= ~reg;
543#endif
544#ifdef CONFIG_FADS
545 *((uint *)BCSR1) |= reg;
546#endif
547
548 *((uint *)BCSR1) |= reg << 20;
549
550 return 0;
551}
552
553#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
554
555static int hardware_enable(int slot)
556{
557 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
558 return 0;
559}
560
561#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
562static int hardware_disable(int slot)
563{
564 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
565 return 0;
566}
567#endif /* CFG_CMD_PCMCIA */
568
569#endif /* (F)ADS */
570
wdenk90e7e422002-12-04 23:39:58 +0000571/* -------------------------------------------------------------------- */
572/* TQM8xxL Boards by TQ Components */
wdenkc8434db2003-03-26 06:55:25 +0000573/* SC8xx Boards by SinoVee Microsystems */
wdenk90e7e422002-12-04 23:39:58 +0000574/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000575
wdenkc8434db2003-03-26 06:55:25 +0000576#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
wdenkc6097192002-11-03 00:24:07 +0000577
wdenkc8434db2003-03-26 06:55:25 +0000578#if defined(CONFIG_TQM8xxL)
wdenkc6097192002-11-03 00:24:07 +0000579#define PCMCIA_BOARD_MSG "TQM8xxL"
wdenkc8434db2003-03-26 06:55:25 +0000580#endif
581#if defined(CONFIG_SVM_SC8xx)
582#define PCMCIA_BOARD_MSG "SC8xx"
583#endif
wdenkc6097192002-11-03 00:24:07 +0000584
585static int hardware_enable(int slot)
586{
587 volatile immap_t *immap;
588 volatile cpm8xx_t *cp;
589 volatile pcmconf8xx_t *pcmp;
590 volatile sysconf8xx_t *sysp;
591 uint reg, mask;
592
593 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
594
595 udelay(10000);
596
597 immap = (immap_t *)CFG_IMMR;
598 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
599 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
600 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
601
602 /*
603 * Configure SIUMCR to enable PCMCIA port B
604 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
605 */
606 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
607
608 /* clear interrupt state, and disable interrupts */
dzub02ed682003-10-19 21:43:26 +0000609 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
610 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenkc6097192002-11-03 00:24:07 +0000611
wdenkc6097192002-11-03 00:24:07 +0000612 /*
wdenk90e7e422002-12-04 23:39:58 +0000613 * Disable interrupts, DMA, and PCMCIA buffers
614 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000615 */
616 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000617 reg = 0;
618 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzub02ed682003-10-19 21:43:26 +0000619#ifndef NSCU_OE_INV
wdenk90e7e422002-12-04 23:39:58 +0000620 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzub02ed682003-10-19 21:43:26 +0000621#endif
622 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000623 udelay(500);
624
dzub02ed682003-10-19 21:43:26 +0000625#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000626 /*
627 * Configure Port C pins for
628 * 5 Volts Enable and 3 Volts enable
629 */
630 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
631 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
632 /* remove all power */
633
634 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzub02ed682003-10-19 21:43:26 +0000635#endif
wdenkc6097192002-11-03 00:24:07 +0000636
637 /*
638 * Make sure there is a card in the slot, then configure the interface.
639 */
640 udelay(10000);
641 debug ("[%d] %s: PIPR(%p)=0x%x\n",
642 __LINE__,__FUNCTION__,
643 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +0000644 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000645 printf (" No Card found\n");
646 return (1);
647 }
648
649 /*
650 * Power On.
651 */
652 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
653 reg = pcmp->pcmc_pipr;
654 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
655 reg,
656 (reg&PCMCIA_VS1(slot))?"n":"ff",
657 (reg&PCMCIA_VS2(slot))?"n":"ff");
dzub02ed682003-10-19 21:43:26 +0000658#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000659 if ((reg & mask) == mask) {
660 immap->im_ioport.iop_pcdat |= 0x0004;
661 puts (" 5.0V card found: ");
662 } else {
663 immap->im_ioport.iop_pcdat |= 0x0002;
664 puts (" 3.3V card found: ");
665 }
wdenk90e7e422002-12-04 23:39:58 +0000666 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
dzub02ed682003-10-19 21:43:26 +0000667#else
668 if ((reg & mask) == mask) {
669 puts (" 5.0V card found: ");
670 } else {
671 puts (" 3.3V card found: ");
672 }
673#endif
wdenkc6097192002-11-03 00:24:07 +0000674#if 0
675 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
676 cp->cp_pbdir &= ~(0x0020 | 0x0010);
677 cp->cp_pbpar &= ~(0x0020 | 0x0010);
678 udelay(500000);
679#endif
680 udelay(1000);
681 debug ("Enable PCMCIA buffers and stop RESET\n");
dzub02ed682003-10-19 21:43:26 +0000682 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +0000683 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzub02ed682003-10-19 21:43:26 +0000684#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000685 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzub02ed682003-10-19 21:43:26 +0000686#else
687 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
688#endif
689 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000690
691 udelay(250000); /* some cards need >150 ms to come up :-( */
692
693 debug ("# hardware_enable done\n");
694
695 return (0);
696}
697
698
wdenkc6097192002-11-03 00:24:07 +0000699#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
700static int hardware_disable(int slot)
701{
702 volatile immap_t *immap;
703 volatile pcmconf8xx_t *pcmp;
704 u_long reg;
705
706 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
707
708 immap = (immap_t *)CFG_IMMR;
709 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
710
dzub02ed682003-10-19 21:43:26 +0000711#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000712 /* remove all power */
713 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzub02ed682003-10-19 21:43:26 +0000714#endif
wdenkc6097192002-11-03 00:24:07 +0000715
wdenkc6097192002-11-03 00:24:07 +0000716 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000717 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000718 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzub02ed682003-10-19 21:43:26 +0000719#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000720 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzub02ed682003-10-19 21:43:26 +0000721#endif
722 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000723
724 udelay(10000);
725
726 return (0);
727}
728#endif /* CFG_CMD_PCMCIA */
729
dzub02ed682003-10-19 21:43:26 +0000730#ifdef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000731static int voltage_set(int slot, int vcc, int vpp)
732{
dzub02ed682003-10-19 21:43:26 +0000733 return 0;
734}
735#else
736static int voltage_set(int slot, int vcc, int vpp)
737{
wdenkc6097192002-11-03 00:24:07 +0000738 volatile immap_t *immap;
739 volatile pcmconf8xx_t *pcmp;
740 u_long reg;
741
742 debug ("voltage_set: "
743 PCMCIA_BOARD_MSG
744 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
745 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
746
747 immap = (immap_t *)CFG_IMMR;
748 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
749 /*
750 * Disable PCMCIA buffers (isolate the interface)
751 * and assert RESET signal
752 */
753 debug ("Disable PCMCIA buffers and assert RESET\n");
dzub02ed682003-10-19 21:43:26 +0000754 reg = PCMCIA_PGCRX(slot);
wdenk90e7e422002-12-04 23:39:58 +0000755 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzub02ed682003-10-19 21:43:26 +0000756#ifndef NSCU_OE_INV
wdenk90e7e422002-12-04 23:39:58 +0000757 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzub02ed682003-10-19 21:43:26 +0000758#else
759 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
760#endif
761 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000762 udelay(500);
763
764 /*
765 * Configure Port C pins for
766 * 5 Volts Enable and 3 Volts enable,
767 * Turn off all power
768 */
769 debug ("PCMCIA power OFF\n");
770 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
771 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
772 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
773
774 reg = 0;
775 switch(vcc) {
776 case 0: break;
777 case 33: reg |= 0x0002; break;
778 case 50: reg |= 0x0004; break;
779 default: goto done;
780 }
781
782 /* Checking supported voltages */
783
784 debug ("PIPR: 0x%x --> %s\n",
785 pcmp->pcmc_pipr,
786 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
787
788 immap->im_ioport.iop_pcdat |= reg;
wdenk90e7e422002-12-04 23:39:58 +0000789 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000790 if (reg) {
791 debug ("PCMCIA powered at %sV\n",
792 (reg&0x0004) ? "5.0" : "3.3");
793 } else {
794 debug ("PCMCIA powered down\n");
795 }
796
797done:
798 debug ("Enable PCMCIA buffers and stop RESET\n");
dzub02ed682003-10-19 21:43:26 +0000799 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +0000800 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzub02ed682003-10-19 21:43:26 +0000801#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000802 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzub02ed682003-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
809 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
810 slot+'A');
811 return (0);
812}
dzub02ed682003-10-19 21:43:26 +0000813#endif
wdenkc6097192002-11-03 00:24:07 +0000814
815#endif /* TQM8xxL */
816
817
wdenk90e7e422002-12-04 23:39:58 +0000818/* -------------------------------------------------------------------- */
819/* LWMON Board */
820/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000821
822#if defined(CONFIG_LWMON)
823
824#define PCMCIA_BOARD_MSG "LWMON"
825
826/* #define's for MAX1604 Power Switch */
827#define MAX1604_OP_SUS 0x80
828#define MAX1604_VCCBON 0x40
829#define MAX1604_VCC_35 0x20
830#define MAX1604_VCCBHIZ 0x10
831#define MAX1604_VPPBON 0x08
832#define MAX1604_VPPBPBPGM 0x04
833#define MAX1604_VPPBHIZ 0x02
834/* reserved 0x01 */
835
836static int hardware_enable(int slot)
837{
838 volatile immap_t *immap;
839 volatile cpm8xx_t *cp;
840 volatile pcmconf8xx_t *pcmp;
841 volatile sysconf8xx_t *sysp;
842 uint reg, mask;
843 uchar val;
844
845
846 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
847
848 /* Switch on PCMCIA port in PIC register 0x60 */
849 reg = pic_read (0x60);
850 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
851 reg &= ~0x10;
wdenk90e7e422002-12-04 23:39:58 +0000852 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +0000853 pic_write (0x60, reg);
854#ifdef DEBUG
855 reg = pic_read (0x60);
856 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
857#endif
858 udelay(10000);
859
860 immap = (immap_t *)CFG_IMMR;
861 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
862 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
863 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
864
865 /*
866 * Configure SIUMCR to enable PCMCIA port B
867 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
868 */
869 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
870
871 /* clear interrupt state, and disable interrupts */
872 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
873 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
874
wdenkc6097192002-11-03 00:24:07 +0000875 /*
wdenk90e7e422002-12-04 23:39:58 +0000876 * Disable interrupts, DMA, and PCMCIA buffers
877 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000878 */
879 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000880 reg = 0;
881 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
882 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000883 PCMCIA_PGCRX(_slot_) = reg;
884 udelay(500);
885
886 /*
887 * Make sure there is a card in the slot, then configure the interface.
888 */
889 udelay(10000);
890 debug ("[%d] %s: PIPR(%p)=0x%x\n",
891 __LINE__,__FUNCTION__,
892 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +0000893 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000894 printf (" No Card found\n");
895 return (1);
896 }
897
898 /*
899 * Power On.
900 */
901 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
902 reg = pcmp->pcmc_pipr;
903 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
904 reg,
905 (reg&PCMCIA_VS1(slot))?"n":"ff",
906 (reg&PCMCIA_VS2(slot))?"n":"ff");
907 if ((reg & mask) == mask) {
908 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
909 puts (" 5.0V card found: ");
910 } else {
911 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
912 puts (" 3.3V card found: ");
913 }
914
915 /* switch VCC on */
wdenk90e7e422002-12-04 23:39:58 +0000916 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +0000917 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
918 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
919
920 udelay(500000);
921
922 debug ("Enable PCMCIA buffers and stop RESET\n");
923 reg = PCMCIA_PGCRX(_slot_);
924 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
925 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
926 PCMCIA_PGCRX(_slot_) = reg;
927
928 udelay(250000); /* some cards need >150 ms to come up :-( */
929
930 debug ("# hardware_enable done\n");
931
932 return (0);
933}
934
935
wdenkc6097192002-11-03 00:24:07 +0000936#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
937static int hardware_disable(int slot)
938{
939 volatile immap_t *immap;
940 volatile pcmconf8xx_t *pcmp;
941 u_long reg;
942 uchar val;
943
944 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
945
946 immap = (immap_t *)CFG_IMMR;
947 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
948
949 /* remove all power, put output in high impedance state */
950 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
951 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
952 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
953
954 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +0000955 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000956 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000957 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
958 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
959 PCMCIA_PGCRX(_slot_) = reg;
960
961 /* Switch off PCMCIA port in PIC register 0x60 */
962 reg = pic_read (0x60);
963 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
964 reg |= 0x10;
965 reg &= ~0x08;
966 pic_write (0x60, reg);
967#ifdef DEBUG
968 reg = pic_read (0x60);
969 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
970#endif
971 udelay(10000);
972
973 return (0);
974}
975#endif /* CFG_CMD_PCMCIA */
976
977
wdenkc6097192002-11-03 00:24:07 +0000978static int voltage_set(int slot, int vcc, int vpp)
979{
980 volatile immap_t *immap;
981 volatile pcmconf8xx_t *pcmp;
982 u_long reg;
983 uchar val;
984
985 debug ("voltage_set: "
986 PCMCIA_BOARD_MSG
987 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
988 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
989
990 immap = (immap_t *)CFG_IMMR;
991 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
992 /*
993 * Disable PCMCIA buffers (isolate the interface)
994 * and assert RESET signal
995 */
996 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000997 reg = PCMCIA_PGCRX(_slot_);
998 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
999 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001000 PCMCIA_PGCRX(_slot_) = reg;
1001 udelay(500);
1002
1003 /*
1004 * Turn off all power (switch to high impedance)
1005 */
1006 debug ("PCMCIA power OFF\n");
1007 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1008 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1009 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1010
1011 val = 0;
1012 switch(vcc) {
1013 case 0: break;
1014 case 33: val = MAX1604_VCC_35; break;
1015 case 50: break;
1016 default: goto done;
1017 }
1018
1019 /* Checking supported voltages */
1020
1021 debug ("PIPR: 0x%x --> %s\n",
1022 pcmp->pcmc_pipr,
1023 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1024
1025 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1026 if (val) {
1027 debug ("PCMCIA powered at %sV\n",
1028 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1029 } else {
1030 debug ("PCMCIA powered down\n");
1031 }
1032
1033done:
1034 debug ("Enable PCMCIA buffers and stop RESET\n");
1035 reg = PCMCIA_PGCRX(_slot_);
1036 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1037 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1038 PCMCIA_PGCRX(_slot_) = reg;
1039 udelay(500);
1040
1041 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1042 slot+'A');
1043 return (0);
1044}
1045
1046#endif /* LWMON */
1047
wdenk90e7e422002-12-04 23:39:58 +00001048/* -------------------------------------------------------------------- */
1049/* GTH board by Corelatus AB */
1050/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001051#if defined(CONFIG_GTH)
1052
1053#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1054
wdenk90e7e422002-12-04 23:39:58 +00001055static int voltage_set (int slot, int vcc, int vpp)
1056{ /* Do nothing */
1057 return 0;
wdenkc6097192002-11-03 00:24:07 +00001058}
1059
1060static int hardware_enable (int slot)
1061{
wdenk90e7e422002-12-04 23:39:58 +00001062 volatile immap_t *immap;
1063 volatile cpm8xx_t *cp;
1064 volatile pcmconf8xx_t *pcmp;
1065 volatile sysconf8xx_t *sysp;
1066 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +00001067
wdenk90e7e422002-12-04 23:39:58 +00001068 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +00001069
wdenk90e7e422002-12-04 23:39:58 +00001070 immap = (immap_t *) CFG_IMMR;
1071 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1072 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1073 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +00001074
wdenk90e7e422002-12-04 23:39:58 +00001075 /* clear interrupt state, and disable interrupts */
1076 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1077 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +00001078
wdenk90e7e422002-12-04 23:39:58 +00001079 /*
1080 * Disable interrupts, DMA, and PCMCIA buffers
1081 * (isolate the interface) and assert RESET signal
1082 */
1083 debug ("Disable PCMCIA buffers and assert RESET\n");
1084 reg = 0;
1085 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1086 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1087 PCMCIA_PGCRX (_slot_) = reg;
1088 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001089
wdenk90e7e422002-12-04 23:39:58 +00001090 /*
1091 * Make sure there is a card in the slot,
1092 * then configure the interface.
1093 */
1094 udelay (10000);
1095 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1096 __LINE__, __FUNCTION__,
1097 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1098 if (pcmp->pcmc_pipr & 0x98000000) {
1099 printf (" No Card found\n");
1100 return (1);
1101 }
wdenkc6097192002-11-03 00:24:07 +00001102
wdenk90e7e422002-12-04 23:39:58 +00001103 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1104 reg = pcmp->pcmc_pipr;
1105 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1106 reg,
1107 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1108 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001109
wdenk90e7e422002-12-04 23:39:58 +00001110 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;
wdenkc6097192002-11-03 00:24:07 +00001115
wdenk90e7e422002-12-04 23:39:58 +00001116 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001117
wdenk90e7e422002-12-04 23:39:58 +00001118 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001119
wdenk90e7e422002-12-04 23:39:58 +00001120 return 0;
wdenkc6097192002-11-03 00:24:07 +00001121}
1122#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1123static int hardware_disable(int slot)
1124{
1125 return 0; /* No hardware to disable */
1126}
1127#endif /* CFG_CMD_PCMCIA */
1128#endif /* CONFIG_GTH */
1129
wdenk90e7e422002-12-04 23:39:58 +00001130/* -------------------------------------------------------------------- */
1131/* ICU862 Boards by Cambridge Broadband Ltd. */
1132/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001133
1134#if defined(CONFIG_ICU862)
1135
1136#define PCMCIA_BOARD_MSG "ICU862"
1137
1138static void cfg_port_B (void);
1139
1140static int hardware_enable(int slot)
1141{
1142 volatile immap_t *immap;
1143 volatile cpm8xx_t *cp;
1144 volatile pcmconf8xx_t *pcmp;
1145 volatile sysconf8xx_t *sysp;
1146 uint reg, pipr, mask;
1147 int i;
1148
1149 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1150
1151 udelay(10000);
1152
1153 immap = (immap_t *)CFG_IMMR;
1154 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1155 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1156 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1157
1158 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1159 cfg_port_B ();
1160
1161 /*
1162 * Configure SIUMCR to enable PCMCIA port B
1163 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1164 */
1165 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1166
1167 /* clear interrupt state, and disable interrupts */
1168 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1169 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1170
wdenkc6097192002-11-03 00:24:07 +00001171 /*
wdenk90e7e422002-12-04 23:39:58 +00001172 * Disable interrupts, DMA, and PCMCIA buffers
1173 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001174 */
1175 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001176 reg = 0;
1177 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1178 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001179 PCMCIA_PGCRX(_slot_) = reg;
1180 udelay(500);
1181
1182 /*
1183 * Make sure there is a card in the slot, then configure the interface.
1184 */
1185 udelay(10000);
1186 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1187 __LINE__,__FUNCTION__,
1188 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00001189 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001190 printf (" No Card found\n");
1191 return (1);
1192 }
1193
1194 /*
1195 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1196 */
1197 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1198 pipr = pcmp->pcmc_pipr;
1199 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1200 pipr,
1201 (reg&PCMCIA_VS1(slot))?"n":"ff",
1202 (reg&PCMCIA_VS2(slot))?"n":"ff");
1203
1204 reg = cp->cp_pbdat;
1205 if ((pipr & mask) == mask) {
wdenk90e7e422002-12-04 23:39:58 +00001206 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1207 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001208 reg &= ~(TPS2205_VCC5); /* 5V on */
1209 puts (" 5.0V card found: ");
1210 } else {
wdenk90e7e422002-12-04 23:39:58 +00001211 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1212 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001213 reg &= ~(TPS2205_VCC3); /* 3V on */
1214 puts (" 3.3V card found: ");
1215 }
1216
1217 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1218 reg,
1219 (reg & TPS2205_VCC3) ? "off" : "on",
1220 (reg & TPS2205_VCC5) ? "off" : "on",
1221 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1222 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1223
1224 cp->cp_pbdat = reg;
1225
1226 /* Wait 500 ms; use this to check for over-current */
1227 for (i=0; i<5000; ++i) {
1228 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1229 printf (" *** Overcurrent - Safety shutdown ***\n");
1230 cp->cp_pbdat &= ~(TPS2205_SHDN);
1231 return (1);
1232 }
1233 udelay (100);
1234 }
1235
1236 debug ("Enable PCMCIA buffers and stop RESET\n");
1237 reg = PCMCIA_PGCRX(_slot_);
1238 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1239 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1240 PCMCIA_PGCRX(_slot_) = reg;
1241
1242 udelay(250000); /* some cards need >150 ms to come up :-( */
1243
1244 debug ("# hardware_enable done\n");
1245
1246 return (0);
1247}
1248
1249
wdenkc6097192002-11-03 00:24:07 +00001250#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1251static int hardware_disable(int slot)
1252{
1253 volatile immap_t *immap;
1254 volatile cpm8xx_t *cp;
1255 volatile pcmconf8xx_t *pcmp;
1256 u_long reg;
1257
1258 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1259
1260 immap = (immap_t *)CFG_IMMR;
1261 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1262 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1263
1264 /* Shut down */
1265 cp->cp_pbdat &= ~(TPS2205_SHDN);
1266
1267 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001268 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001269 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001270 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1271 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1272 PCMCIA_PGCRX(_slot_) = reg;
1273
1274 udelay(10000);
1275
1276 return (0);
1277}
1278#endif /* CFG_CMD_PCMCIA */
1279
1280
wdenkc6097192002-11-03 00:24:07 +00001281static int voltage_set(int slot, int vcc, int vpp)
1282{
1283 volatile immap_t *immap;
1284 volatile cpm8xx_t *cp;
1285 volatile pcmconf8xx_t *pcmp;
1286 u_long reg;
1287
1288 debug ("voltage_set: "
1289 PCMCIA_BOARD_MSG
1290 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1291 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1292
1293 immap = (immap_t *)CFG_IMMR;
1294 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1295 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1296 /*
1297 * Disable PCMCIA buffers (isolate the interface)
1298 * and assert RESET signal
1299 */
1300 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001301 reg = PCMCIA_PGCRX(_slot_);
1302 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1303 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001304 PCMCIA_PGCRX(_slot_) = reg;
1305 udelay(500);
1306
1307 /*
1308 * Configure Port C pins for
1309 * 5 Volts Enable and 3 Volts enable,
1310 * Turn all power pins to Hi-Z
1311 */
1312 debug ("PCMCIA power OFF\n");
1313 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1314
1315 reg = cp->cp_pbdat;
1316
1317 switch(vcc) {
1318 case 0: break; /* Switch off */
1319 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1320 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1321 default: goto done;
1322 }
1323
1324 /* Checking supported voltages */
1325
1326 debug ("PIPR: 0x%x --> %s\n",
1327 pcmp->pcmc_pipr,
1328 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1329
1330 cp->cp_pbdat = reg;
1331
1332#ifdef DEBUG
1333 {
1334 char *s;
1335
1336 if ((reg & TPS2205_VCC3) == 0) {
1337 s = "at 3.3V";
1338 } else if ((reg & TPS2205_VCC5) == 0) {
1339 s = "at 5.0V";
1340 } else {
1341 s = "down";
1342 }
1343 printf ("PCMCIA powered %s\n", s);
1344 }
1345#endif
1346
1347done:
1348 debug ("Enable PCMCIA buffers and stop RESET\n");
1349 reg = PCMCIA_PGCRX(_slot_);
1350 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1351 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1352 PCMCIA_PGCRX(_slot_) = reg;
1353 udelay(500);
1354
1355 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1356 slot+'A');
1357 return (0);
1358}
1359
1360static void cfg_port_B (void)
1361{
1362 volatile immap_t *immap;
1363 volatile cpm8xx_t *cp;
1364 uint reg;
1365
1366 immap = (immap_t *)CFG_IMMR;
1367 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1368
1369 /*
1370 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1371 *
1372 * Switch off all voltages, assert shutdown
1373 */
1374 reg = cp->cp_pbdat;
wdenk90e7e422002-12-04 23:39:58 +00001375 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1376 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1377 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001378 cp->cp_pbdat = reg;
1379
1380 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1381
1382 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1383 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1384
1385 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1386 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1387}
1388
1389#endif /* ICU862 */
1390
1391
wdenk90e7e422002-12-04 23:39:58 +00001392/* -------------------------------------------------------------------- */
1393/* C2MON Boards by TTTech Computertechnik AG */
1394/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001395
1396#if defined(CONFIG_C2MON)
1397
1398#define PCMCIA_BOARD_MSG "C2MON"
1399
1400static void cfg_ports (void);
1401
1402static int hardware_enable(int slot)
1403{
1404 volatile immap_t *immap;
1405 volatile cpm8xx_t *cp;
1406 volatile pcmconf8xx_t *pcmp;
1407 volatile sysconf8xx_t *sysp;
1408 uint reg, pipr, mask;
1409 ushort sreg;
1410 int i;
1411
1412 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1413
1414 udelay(10000);
1415
1416 immap = (immap_t *)CFG_IMMR;
1417 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1418 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1419 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1420
1421 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1422 cfg_ports ();
1423
1424 /*
1425 * Configure SIUMCR to enable PCMCIA port B
1426 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1427 */
1428 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1429
1430 /* clear interrupt state, and disable interrupts */
1431 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1432 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1433
wdenkc6097192002-11-03 00:24:07 +00001434 /*
wdenk90e7e422002-12-04 23:39:58 +00001435 * Disable interrupts, DMA, and PCMCIA buffers
1436 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001437 */
1438 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001439 reg = 0;
1440 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1441 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001442 PCMCIA_PGCRX(_slot_) = reg;
1443 udelay(500);
1444
1445 /*
1446 * Make sure there is a card in the slot, then configure the interface.
1447 */
1448 udelay(10000);
1449 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1450 __LINE__,__FUNCTION__,
1451 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00001452 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001453 printf (" No Card found\n");
1454 return (1);
1455 }
1456
1457 /*
1458 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1459 */
1460 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1461 pipr = pcmp->pcmc_pipr;
1462 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1463 pipr,
1464 (reg&PCMCIA_VS1(slot))?"n":"ff",
1465 (reg&PCMCIA_VS2(slot))?"n":"ff");
1466
1467 sreg = immap->im_ioport.iop_pcdat;
1468 if ((pipr & mask) == mask) {
1469 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1470 TPS2211_VCCD1); /* 5V on */
1471 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1472 puts (" 5.0V card found: ");
1473 } else {
1474 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1475 TPS2211_VCCD0); /* 3V on */
1476 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1477 puts (" 3.3V card found: ");
1478 }
1479
1480 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1481 sreg,
1482 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1483 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1484 );
1485
1486 immap->im_ioport.iop_pcdat = sreg;
1487
1488 /* Wait 500 ms; use this to check for over-current */
1489 for (i=0; i<5000; ++i) {
1490 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1491 printf (" *** Overcurrent - Safety shutdown ***\n");
1492 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1493 return (1);
1494 }
1495 udelay (100);
1496 }
1497
1498 debug ("Enable PCMCIA buffers and stop RESET\n");
1499 reg = PCMCIA_PGCRX(_slot_);
1500 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1501 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1502 PCMCIA_PGCRX(_slot_) = reg;
1503
1504 udelay(250000); /* some cards need >150 ms to come up :-( */
1505
1506 debug ("# hardware_enable done\n");
1507
1508 return (0);
1509}
1510
1511
wdenkc6097192002-11-03 00:24:07 +00001512#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1513static int hardware_disable(int slot)
1514{
1515 volatile immap_t *immap;
1516 volatile cpm8xx_t *cp;
1517 volatile pcmconf8xx_t *pcmp;
1518 u_long reg;
1519
1520 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1521
1522 immap = (immap_t *)CFG_IMMR;
1523 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1524
1525 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001526 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001527 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001528 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1529 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1530 PCMCIA_PGCRX(_slot_) = reg;
1531
1532 /* ALl voltages off / Hi-Z */
1533 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1534 TPS2211_VCCD0 | TPS2211_VCCD1 );
1535
1536 udelay(10000);
1537
1538 return (0);
1539}
1540#endif /* CFG_CMD_PCMCIA */
1541
1542
wdenkc6097192002-11-03 00:24:07 +00001543static int voltage_set(int slot, int vcc, int vpp)
1544{
1545 volatile immap_t *immap;
1546 volatile cpm8xx_t *cp;
1547 volatile pcmconf8xx_t *pcmp;
1548 u_long reg;
1549 ushort sreg;
1550
1551 debug ("voltage_set: "
1552 PCMCIA_BOARD_MSG
1553 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1554 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1555
1556 immap = (immap_t *)CFG_IMMR;
1557 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1558 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1559 /*
1560 * Disable PCMCIA buffers (isolate the interface)
1561 * and assert RESET signal
1562 */
1563 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001564 reg = PCMCIA_PGCRX(_slot_);
1565 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1566 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001567 PCMCIA_PGCRX(_slot_) = reg;
1568 udelay(500);
1569
1570 /*
1571 * Configure Port C pins for
1572 * 5 Volts Enable and 3 Volts enable,
1573 * Turn all power pins to Hi-Z
1574 */
1575 debug ("PCMCIA power OFF\n");
1576 cfg_ports (); /* Enables switch, but all in Hi-Z */
1577
1578 sreg = immap->im_ioport.iop_pcdat;
1579 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1580
1581 switch(vcc) {
1582 case 0: break; /* Switch off */
1583 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1584 sreg &= ~TPS2211_VCCD1;
1585 break;
1586 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1587 sreg |= TPS2211_VCCD1;
1588 break;
1589 default: goto done;
1590 }
1591
1592 /* Checking supported voltages */
1593
1594 debug ("PIPR: 0x%x --> %s\n",
1595 pcmp->pcmc_pipr,
1596 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1597
1598 immap->im_ioport.iop_pcdat = sreg;
1599
1600#ifdef DEBUG
1601 {
1602 char *s;
1603
1604 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1605 s = "at 3.3V";
1606 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1607 s = "at 5.0V";
1608 } else {
1609 s = "down";
1610 }
1611 printf ("PCMCIA powered %s\n", s);
1612 }
1613#endif
1614
1615done:
1616 debug ("Enable PCMCIA buffers and stop RESET\n");
1617 reg = PCMCIA_PGCRX(_slot_);
1618 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1619 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1620 PCMCIA_PGCRX(_slot_) = reg;
1621 udelay(500);
1622
1623 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1624 slot+'A');
1625 return (0);
1626}
1627
1628static void cfg_ports (void)
1629{
1630 volatile immap_t *immap;
1631 volatile cpm8xx_t *cp;
1632 ushort sreg;
1633
1634 immap = (immap_t *)CFG_IMMR;
1635 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1636
1637 /*
1638 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1639 *
1640 * Switch off all voltages, assert shutdown
1641 */
1642 sreg = immap->im_ioport.iop_pcdat;
1643 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1644 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1645 immap->im_ioport.iop_pcdat = sreg;
1646
1647 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1648 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1649
1650 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1651 immap->im_ioport.iop_pcpar,
1652 immap->im_ioport.iop_pcdir,
1653 immap->im_ioport.iop_pcdat);
1654
1655 /*
1656 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1657 *
1658 * Over-Current Input only
1659 */
1660 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1661 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1662
1663 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1664 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1665}
1666
1667#endif /* C2MON */
1668
wdenk90e7e422002-12-04 23:39:58 +00001669/* -------------------------------------------------------------------- */
1670/* MBX board from Morotola */
1671/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001672
1673#if defined( CONFIG_MBX )
1674#include <../board/mbx8xx/csr.h>
1675
1676/* A lot of this has been taken from the RPX code in this file it works from me.
1677 I have added the voltage selection for the MBX board. */
1678
1679/* MBX voltage bit in control register #2 */
1680#define CR2_VPP12 ((uchar)0x10)
1681#define CR2_VPPVDD ((uchar)0x20)
1682#define CR2_VDD5 ((uchar)0x40)
1683#define CR2_VDD3 ((uchar)0x80)
1684
1685#define PCMCIA_BOARD_MSG "MBX860"
1686
1687static int voltage_set (int slot, int vcc, int vpp)
1688{
1689 uchar reg = 0;
1690
1691 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1692 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1693
1694 switch (vcc) {
1695 case 0:
1696 break;
1697 case 33:
1698 reg |= CR2_VDD3;
1699 break;
1700 case 50:
1701 reg |= CR2_VDD5;
1702 break;
1703 default:
1704 return 1;
1705 }
1706
1707 switch (vpp) {
1708 case 0:
1709 break;
1710 case 33:
1711 case 50:
1712 if (vcc == vpp) {
1713 reg |= CR2_VPPVDD;
1714 } else {
1715 return 1;
1716 }
1717 break;
1718 case 120:
1719 reg |= CR2_VPP12;
1720 break;
1721 default:
1722 return 1;
1723 }
1724
1725 /* first, turn off all power */
1726 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1727
1728 /* enable new powersettings */
1729 MBX_CSR2 |= reg;
1730 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1731
1732 return (0);
1733}
1734
1735static int hardware_enable (int slot)
1736{
1737 volatile immap_t *immap;
1738 volatile cpm8xx_t *cp;
1739 volatile pcmconf8xx_t *pcmp;
1740 volatile sysconf8xx_t *sysp;
1741 uint reg, mask;
1742
1743 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1744 'A' + slot);
1745
1746 udelay (10000);
1747
1748 immap = (immap_t *) CFG_IMMR;
1749 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1750 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1751 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1752
1753 /* clear interrupt state, and disable interrupts */
1754 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1755 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1756
wdenkc6097192002-11-03 00:24:07 +00001757 /*
wdenk90e7e422002-12-04 23:39:58 +00001758 * Disable interrupts, DMA, and PCMCIA buffers
1759 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001760 */
1761 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001762 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001763 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1764 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1765 PCMCIA_PGCRX (_slot_) = reg;
1766 udelay (500);
1767
1768 /* remove all power */
1769 voltage_set (slot, 0, 0);
1770 /*
1771 * Make sure there is a card in the slot, then configure the interface.
1772 */
wdenk2029f4d2002-11-21 23:11:29 +00001773 udelay(10000);
1774 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1775 __LINE__,__FUNCTION__,
1776 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1777 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001778 printf (" No Card found\n");
1779 return (1);
1780 }
1781
1782 /*
1783 * Power On.
1784 */
1785 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1786 reg = pcmp->pcmc_pipr;
1787 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1788 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1789 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1790
1791 if ((reg & mask) == mask) {
1792 voltage_set (_slot_, 50, 0);
1793 printf (" 5.0V card found: ");
1794 } else {
1795 voltage_set (_slot_, 33, 0);
1796 printf (" 3.3V card found: ");
1797 }
1798
1799 debug ("Enable PCMCIA buffers and stop RESET\n");
1800 reg = PCMCIA_PGCRX (_slot_);
1801 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1802 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1803 PCMCIA_PGCRX (_slot_) = reg;
1804
1805 udelay (250000); /* some cards need >150 ms to come up :-( */
1806
1807 debug ("# hardware_enable done\n");
1808
1809 return (0);
1810}
1811
1812#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1813static int hardware_disable (int slot)
1814{
1815 return 0; /* No hardware to disable */
1816}
1817#endif /* CFG_CMD_PCMCIA */
1818#endif /* CONFIG_MBX */
wdenk90e7e422002-12-04 23:39:58 +00001819/* -------------------------------------------------------------------- */
1820/* R360MPI Board */
1821/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001822
1823#if defined(CONFIG_R360MPI)
1824
1825#define PCMCIA_BOARD_MSG "R360MPI"
1826
1827
1828static int hardware_enable(int slot)
1829{
1830 volatile immap_t *immap;
1831 volatile cpm8xx_t *cp;
1832 volatile pcmconf8xx_t *pcmp;
1833 volatile sysconf8xx_t *sysp;
1834 uint reg, mask;
1835
1836 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1837
1838 udelay(10000);
1839
1840 immap = (immap_t *)CFG_IMMR;
1841 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1842 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1843 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1844
1845 /*
1846 * Configure SIUMCR to enable PCMCIA port B
1847 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1848 */
1849 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1850
1851 /* clear interrupt state, and disable interrupts */
1852 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1853 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1854
wdenkc6097192002-11-03 00:24:07 +00001855 /*
wdenk90e7e422002-12-04 23:39:58 +00001856 * Disable interrupts, DMA, and PCMCIA buffers
1857 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001858 */
1859 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001860 reg = 0;
1861 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1862 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001863 PCMCIA_PGCRX(_slot_) = reg;
1864 udelay(500);
1865
1866 /*
1867 * Configure Ports A, B & C pins for
1868 * 5 Volts Enable and 3 Volts enable
1869 */
1870 immap->im_ioport.iop_pcpar &= ~(0x0400);
1871 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1872 immap->im_ioport.iop_pcdir |= 0x0400;*/
1873
1874 immap->im_ioport.iop_papar &= ~(0x0200);/*
1875 immap->im_ioport.iop_padir |= 0x0200;*/
1876#if 0
1877 immap->im_ioport.iop_pbpar &= ~(0xC000);
1878 immap->im_ioport.iop_pbdir &= ~(0xC000);
1879#endif
1880 /* remove all power */
1881
1882 immap->im_ioport.iop_pcdat |= 0x0400;
1883 immap->im_ioport.iop_padat |= 0x0200;
1884
1885 /*
1886 * Make sure there is a card in the slot, then configure the interface.
1887 */
1888 udelay(10000);
1889 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1890 __LINE__,__FUNCTION__,
1891 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00001892 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001893 printf (" No Card found\n");
1894 return (1);
1895 }
1896
1897 /*
1898 * Power On.
1899 */
1900 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1901 reg = pcmp->pcmc_pipr;
1902 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1903 reg,
1904 (reg&PCMCIA_VS1(slot))?"n":"ff",
1905 (reg&PCMCIA_VS2(slot))?"n":"ff");
1906 if ((reg & mask) == mask) {
1907 immap->im_ioport.iop_pcdat &= ~(0x4000);
1908 puts (" 5.0V card found: ");
1909 } else {
1910 immap->im_ioport.iop_padat &= ~(0x0002);
1911 puts (" 3.3V card found: ");
1912 }
1913 immap->im_ioport.iop_pcdir |= 0x0400;
1914 immap->im_ioport.iop_padir |= 0x0200;
1915#if 0
1916 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
1917 cp->cp_pbdir &= ~(0x0020 | 0x0010);
1918 cp->cp_pbpar &= ~(0x0020 | 0x0010);
1919 udelay(500000);
1920#endif
1921 debug ("Enable PCMCIA buffers and stop RESET\n");
1922 reg = PCMCIA_PGCRX(_slot_);
1923 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1924 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1925 PCMCIA_PGCRX(_slot_) = reg;
1926
1927 udelay(250000); /* some cards need >150 ms to come up :-( */
1928
1929 debug ("# hardware_enable done\n");
1930
1931 return (0);
1932}
1933
1934
wdenkc6097192002-11-03 00:24:07 +00001935#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1936static int hardware_disable(int slot)
1937{
1938 volatile immap_t *immap;
1939 volatile pcmconf8xx_t *pcmp;
1940 u_long reg;
1941
1942 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1943
1944 immap = (immap_t *)CFG_IMMR;
1945 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1946
1947 /* remove all power */
1948 immap->im_ioport.iop_pcdat |= 0x0400;
1949 immap->im_ioport.iop_padat |= 0x0200;
1950
1951 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001952 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001953 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001954 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1955 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1956 PCMCIA_PGCRX(_slot_) = reg;
1957
1958 udelay(10000);
1959
1960 return (0);
1961}
1962#endif /* CFG_CMD_PCMCIA */
1963
1964
wdenkc6097192002-11-03 00:24:07 +00001965static int voltage_set(int slot, int vcc, int vpp)
1966{
1967 volatile immap_t *immap;
1968 volatile pcmconf8xx_t *pcmp;
1969 u_long reg;
1970
1971 debug ("voltage_set: "
1972 PCMCIA_BOARD_MSG
1973 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1974 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1975
1976 immap = (immap_t *)CFG_IMMR;
1977 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1978 /*
1979 * Disable PCMCIA buffers (isolate the interface)
1980 * and assert RESET signal
1981 */
1982 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001983 reg = PCMCIA_PGCRX(_slot_);
1984 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1985 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001986 PCMCIA_PGCRX(_slot_) = reg;
1987 udelay(500);
1988
1989 /*
1990 * Configure Ports A & C pins for
1991 * 5 Volts Enable and 3 Volts enable,
1992 * Turn off all power
1993 */
1994 debug ("PCMCIA power OFF\n");
1995 immap->im_ioport.iop_pcpar &= ~(0x0400);
1996 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1997 immap->im_ioport.iop_pcdir |= 0x0400;*/
1998
1999 immap->im_ioport.iop_papar &= ~(0x0200);/*
2000 immap->im_ioport.iop_padir |= 0x0200;*/
2001
2002 immap->im_ioport.iop_pcdat |= 0x0400;
2003 immap->im_ioport.iop_padat |= 0x0200;
2004
2005 reg = 0;
2006 switch(vcc) {
2007 case 0: break;
2008 case 33: reg |= 0x0200; break;
2009 case 50: reg |= 0x0400; break;
2010 default: goto done;
2011 }
2012
2013 /* Checking supported voltages */
2014
2015 debug ("PIPR: 0x%x --> %s\n",
2016 pcmp->pcmc_pipr,
2017 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2018
2019 if (reg & 0x0200)
2020 immap->im_ioport.iop_pcdat &= !reg;
2021 if (reg & 0x0400)
2022 immap->im_ioport.iop_padat &= !reg;
wdenk90e7e422002-12-04 23:39:58 +00002023 immap->im_ioport.iop_pcdir |= 0x0200;
2024 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00002025 if (reg) {
2026 debug ("PCMCIA powered at %sV\n",
2027 (reg&0x0400) ? "5.0" : "3.3");
2028 } else {
2029 debug ("PCMCIA powered down\n");
2030 }
2031
2032done:
2033 debug ("Enable PCMCIA buffers and stop RESET\n");
2034 reg = PCMCIA_PGCRX(_slot_);
2035 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2036 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2037 PCMCIA_PGCRX(_slot_) = reg;
2038 udelay(500);
2039
2040 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2041 slot+'A');
2042 return (0);
2043}
2044
2045#endif /* R360MPI */
2046
wdenk90e7e422002-12-04 23:39:58 +00002047/* -------------------------------------------------------------------- */
2048/* KUP4K Board */
2049/* -------------------------------------------------------------------- */
wdenk56f94be2002-11-05 16:35:14 +00002050#if defined(CONFIG_KUP4K)
2051
2052#define PCMCIA_BOARD_MSG "KUP4K"
2053
2054#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2055
2056static int hardware_enable(int slot)
2057{
2058 volatile immap_t *immap;
2059 volatile cpm8xx_t *cp;
2060 volatile pcmconf8xx_t *pcmp;
2061 volatile sysconf8xx_t *sysp;
2062 uint reg, mask;
2063
2064 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2065
2066 udelay(10000);
2067
2068 immap = (immap_t *)CFG_IMMR;
2069 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2070 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2071 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2072
2073 /*
2074 * Configure SIUMCR to enable PCMCIA port B
2075 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2076 */
2077 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2078
2079 /* clear interrupt state, and disable interrupts */
wdenk2029f4d2002-11-21 23:11:29 +00002080 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2081 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002082
wdenk56f94be2002-11-05 16:35:14 +00002083 /*
wdenk90e7e422002-12-04 23:39:58 +00002084 * Disable interrupts, DMA, and PCMCIA buffers
2085 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002086 */
2087 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002088 reg = 0;
2089 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2090 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002091 PCMCIA_PGCRX(slot) = reg;
2092 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002093
2094 /*
2095 * Configure Port B pins for
2096 * 3 Volts enable
2097 */
wdenk2029f4d2002-11-21 23:11:29 +00002098 if (slot) { /* Slot A is built-in */
2099 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2100 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2101 /* remove all power */
2102 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2103 }
wdenk56f94be2002-11-05 16:35:14 +00002104 /*
2105 * Make sure there is a card in the slot, then configure the interface.
2106 */
2107 udelay(10000);
2108 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2109 __LINE__,__FUNCTION__,
2110 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00002111 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002112 printf (" No Card found\n");
2113 return (1);
2114 }
2115
2116 /*
2117 * Power On.
2118 */
wdenk9dd2b882002-12-03 21:28:10 +00002119 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002120 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2121 reg = pcmp->pcmc_pipr;
2122 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2123 reg,
2124 (reg&PCMCIA_VS1(slot))?"n":"ff",
2125 (reg&PCMCIA_VS2(slot))?"n":"ff");
2126 if ((reg & mask) == mask) {
2127 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2128 } else {
wdenk2029f4d2002-11-21 23:11:29 +00002129 if(slot)
2130 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002131 puts (" 3.3V card found: ");
2132 }
2133#if 0
2134 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2135 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2136 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2137 udelay(500000);
2138#endif
2139 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenk2029f4d2002-11-21 23:11:29 +00002140 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002141 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2142 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002143 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002144
2145 udelay(250000); /* some cards need >150 ms to come up :-( */
2146
2147 debug ("# hardware_enable done\n");
2148
2149 return (0);
2150}
2151
2152
wdenk56f94be2002-11-05 16:35:14 +00002153#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2154static int hardware_disable(int slot)
2155{
2156 volatile immap_t *immap;
2157 volatile cpm8xx_t *cp;
2158 volatile pcmconf8xx_t *pcmp;
2159 u_long reg;
2160
2161 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2162
2163 immap = (immap_t *)CFG_IMMR;
2164 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2165 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk90e7e422002-12-04 23:39:58 +00002166
wdenk56f94be2002-11-05 16:35:14 +00002167 /* remove all power */
wdenk2029f4d2002-11-21 23:11:29 +00002168 if (slot)
2169 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002170
2171 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002172 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002173 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002174 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2175 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002176 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002177
2178 udelay(10000);
2179
2180 return (0);
2181}
2182#endif /* CFG_CMD_PCMCIA */
2183
2184
wdenk56f94be2002-11-05 16:35:14 +00002185static int voltage_set(int slot, int vcc, int vpp)
2186{
2187 volatile immap_t *immap;
2188 volatile cpm8xx_t *cp;
2189 volatile pcmconf8xx_t *pcmp;
2190 u_long reg;
2191
2192 debug ("voltage_set: " \
2193 PCMCIA_BOARD_MSG \
2194 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2195 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2196
wdenk2029f4d2002-11-21 23:11:29 +00002197 if (!slot) /* Slot A is not configurable */
2198 return 0;
2199
wdenk56f94be2002-11-05 16:35:14 +00002200 immap = (immap_t *)CFG_IMMR;
2201 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2202 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2203
2204 /*
2205 * Disable PCMCIA buffers (isolate the interface)
2206 * and assert RESET signal
2207 */
2208 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002209 reg = PCMCIA_PGCRX(slot);
2210 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2211 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002212 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002213 udelay(500);
2214
2215 debug ("PCMCIA power OFF\n");
2216 /*
2217 * Configure Port B pins for
2218 * 3 Volts enable
2219 */
2220 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2221 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2222 /* remove all power */
2223 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2224
2225 switch(vcc) {
2226 case 0: break;
2227 case 33:
2228 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2229 debug ("PCMCIA powered at 3.3V\n");
2230 break;
2231 case 50:
2232 debug ("PCMCIA: 5Volt vcc not supported\n");
2233 break;
2234 default:
2235 puts("PCMCIA: vcc not supported");
2236 break;
2237 }
wdenk2029f4d2002-11-21 23:11:29 +00002238 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002239 /* Checking supported voltages */
2240
2241 debug ("PIPR: 0x%x --> %s\n",
2242 pcmp->pcmc_pipr,
wdenk2029f4d2002-11-21 23:11:29 +00002243 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002244 ? "only 5 V --> NOT SUPPORTED"
2245 : "can do 3.3V");
2246
2247
2248 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenk2029f4d2002-11-21 23:11:29 +00002249 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002250 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2251 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002252 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002253 udelay(500);
2254
2255 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2256 slot+'A');
2257 return (0);
2258}
2259
2260#endif /* KUP4K */
2261
2262
wdenk90e7e422002-12-04 23:39:58 +00002263/* -------------------------------------------------------------------- */
2264/* End of Board Specific Stuff */
2265/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002266
2267
wdenk90e7e422002-12-04 23:39:58 +00002268/* -------------------------------------------------------------------- */
2269/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2270/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002271
2272/*
2273 * Search this table to see if the windowsize is
2274 * supported...
2275 */
2276
2277#define M8XX_SIZES_NO 32
2278
2279static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2280{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2281 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2282 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2283 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2284
2285 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2286 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2287 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2288 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2289
2290
wdenk90e7e422002-12-04 23:39:58 +00002291/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002292
wdenk0893c472003-05-20 14:25:27 +00002293#ifndef CONFIG_I82365
2294
wdenkc6097192002-11-03 00:24:07 +00002295static u_int m8xx_get_graycode(u_int size)
2296{
2297 u_int k;
2298
2299 for (k = 0; k < M8XX_SIZES_NO; k++) {
2300 if(m8xx_size_to_gray[k] == size)
2301 break;
2302 }
2303
2304 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2305 k = -1;
2306
2307 return k;
2308}
2309
wdenk0893c472003-05-20 14:25:27 +00002310#endif /* CONFIG_I82365 */
2311
wdenk90e7e422002-12-04 23:39:58 +00002312/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002313
2314#if 0
2315static u_int m8xx_get_speed(u_int ns, u_int is_io)
2316{
2317 u_int reg, clocks, psst, psl, psht;
2318
2319 if(!ns) {
2320
2321 /*
2322 * We get called with IO maps setup to 0ns
2323 * if not specified by the user.
2324 * They should be 255ns.
2325 */
2326
2327 if(is_io)
2328 ns = 255;
2329 else
2330 ns = 100; /* fast memory if 0 */
2331 }
2332
2333 /*
2334 * In PSST, PSL, PSHT fields we tell the controller
2335 * timing parameters in CLKOUT clock cycles.
2336 * CLKOUT is the same as GCLK2_50.
2337 */
2338
2339/* how we want to adjust the timing - in percent */
2340
2341#define ADJ 180 /* 80 % longer accesstime - to be sure */
2342
2343 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2344 clocks = (clocks * ADJ) / (100*1000);
2345
2346 if(clocks >= PCMCIA_BMT_LIMIT) {
2347 DEBUG(0, "Max access time limit reached\n");
2348 clocks = PCMCIA_BMT_LIMIT-1;
2349 }
2350
2351 psst = clocks / 7; /* setup time */
2352 psht = clocks / 7; /* hold time */
2353 psl = (clocks * 5) / 7; /* strobe length */
2354
2355 psst += clocks - (psst + psht + psl);
2356
2357 reg = psst << 12;
2358 reg |= psl << 7;
2359 reg |= psht << 16;
2360
2361 return reg;
2362}
2363#endif
2364
wdenk90e7e422002-12-04 23:39:58 +00002365/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002366
2367#ifdef CONFIG_IDE_8xx_PCCARD
2368static void print_funcid (int func)
2369{
2370 puts (indent);
2371 switch (func) {
2372 case CISTPL_FUNCID_MULTI:
2373 puts (" Multi-Function");
2374 break;
2375 case CISTPL_FUNCID_MEMORY:
2376 puts (" Memory");
2377 break;
2378 case CISTPL_FUNCID_SERIAL:
2379 puts (" Serial Port");
2380 break;
2381 case CISTPL_FUNCID_PARALLEL:
2382 puts (" Parallel Port");
2383 break;
2384 case CISTPL_FUNCID_FIXED:
2385 puts (" Fixed Disk");
2386 break;
2387 case CISTPL_FUNCID_VIDEO:
2388 puts (" Video Adapter");
2389 break;
2390 case CISTPL_FUNCID_NETWORK:
2391 puts (" Network Adapter");
2392 break;
2393 case CISTPL_FUNCID_AIMS:
2394 puts (" AIMS Card");
2395 break;
2396 case CISTPL_FUNCID_SCSI:
2397 puts (" SCSI Adapter");
2398 break;
2399 default:
2400 puts (" Unknown");
2401 break;
2402 }
2403 puts (" Card\n");
2404}
2405#endif /* CONFIG_IDE_8xx_PCCARD */
2406
wdenk90e7e422002-12-04 23:39:58 +00002407/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002408
2409#ifdef CONFIG_IDE_8xx_PCCARD
2410static void print_fixed (volatile uchar *p)
2411{
2412 if (p == NULL)
2413 return;
2414
2415 puts(indent);
2416
2417 switch (*p) {
2418 case CISTPL_FUNCE_IDE_IFACE:
2419 { uchar iface = *(p+2);
2420
2421 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2422 puts (" interface ");
2423 break;
2424 }
2425 case CISTPL_FUNCE_IDE_MASTER:
2426 case CISTPL_FUNCE_IDE_SLAVE:
2427 { uchar f1 = *(p+2);
2428 uchar f2 = *(p+4);
2429
2430 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2431
2432 if (f1 & CISTPL_IDE_UNIQUE)
2433 puts (" [unique]");
2434
2435 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2436
2437 if (f2 & CISTPL_IDE_HAS_SLEEP)
2438 puts (" [sleep]");
2439
2440 if (f2 & CISTPL_IDE_HAS_STANDBY)
2441 puts (" [standby]");
2442
2443 if (f2 & CISTPL_IDE_HAS_IDLE)
2444 puts (" [idle]");
2445
2446 if (f2 & CISTPL_IDE_LOW_POWER)
2447 puts (" [low power]");
2448
2449 if (f2 & CISTPL_IDE_REG_INHIBIT)
2450 puts (" [reg inhibit]");
2451
2452 if (f2 & CISTPL_IDE_HAS_INDEX)
2453 puts (" [index]");
2454
2455 if (f2 & CISTPL_IDE_IOIS16)
2456 puts (" [IOis16]");
2457
2458 break;
2459 }
2460 }
2461 putc ('\n');
2462}
2463#endif /* CONFIG_IDE_8xx_PCCARD */
2464
wdenk90e7e422002-12-04 23:39:58 +00002465/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002466
2467#ifdef CONFIG_IDE_8xx_PCCARD
2468
2469#define MAX_IDENT_CHARS 64
2470#define MAX_IDENT_FIELDS 4
2471
2472static uchar *known_cards[] = {
2473 "ARGOSY PnPIDE D5",
2474 NULL
2475};
2476
2477static int identify (volatile uchar *p)
2478{
2479 uchar id_str[MAX_IDENT_CHARS];
2480 uchar data;
2481 uchar *t;
2482 uchar **card;
2483 int i, done;
2484
2485 if (p == NULL)
2486 return (0); /* Don't know */
2487
2488 t = id_str;
2489 done =0;
2490
2491 for (i=0; i<=4 && !done; ++i, p+=2) {
2492 while ((data = *p) != '\0') {
2493 if (data == 0xFF) {
2494 done = 1;
2495 break;
2496 }
2497 *t++ = data;
2498 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2499 done = 1;
2500 break;
2501 }
2502 p += 2;
2503 }
2504 if (!done)
2505 *t++ = ' ';
2506 }
2507 *t = '\0';
2508 while (--t > id_str) {
2509 if (*t == ' ')
2510 *t = '\0';
2511 else
2512 break;
2513 }
2514 puts (id_str);
2515 putc ('\n');
2516
2517 for (card=known_cards; *card; ++card) {
2518 debug ("## Compare against \"%s\"\n", *card);
2519 if (strcmp(*card, id_str) == 0) { /* found! */
2520 debug ("## CARD FOUND ##\n");
2521 return (1);
2522 }
2523 }
2524
2525 return (0); /* don't know */
2526}
2527#endif /* CONFIG_IDE_8xx_PCCARD */
2528
wdenk90e7e422002-12-04 23:39:58 +00002529/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002530
2531#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
wdenk57b2d802003-06-27 21:31:46 +00002532
2533/**************************************************/
2534
2535#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenkf287a242003-07-01 21:06:45 +00002536U_BOOT_CMD(
2537 pinit, 2, 1, do_pinit,
wdenk57b2d802003-06-27 21:31:46 +00002538 "pinit - PCMCIA sub-system\n",
2539 "on - power on PCMCIA socket\n"
2540 "pinit off - power off PCMCIA socket\n"
2541);
2542#endif