blob: cb7600c2af24957992d5f8a83618cb96f7d30387 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * (C) Copyright 2000-2002
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 *
23 ********************************************************************
24 *
25 * Lots of code copied from:
26 *
27 * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
28 * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
29 *
30 * "The ExCA standard specifies that socket controllers should provide
31 * two IO and five memory windows per socket, which can be independently
32 * configured and positioned in the host address space and mapped to
33 * arbitrary segments of card address space. " - David A Hinds. 1999
34 *
35 * This controller does _not_ meet the ExCA standard.
36 *
37 * m8xx pcmcia controller brief info:
38 * + 8 windows (attrib, mem, i/o)
39 * + up to two slots (SLOT_A and SLOT_B)
40 * + inputpins, outputpins, event and mask registers.
41 * - no offset register. sigh.
42 *
43 * Because of the lacking offset register we must map the whole card.
44 * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
45 * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
46 * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
47 * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
48 * They are maximum 64KByte each...
49 */
50
51/* #define DEBUG 1 */
52
53/*
54 * PCMCIA support
55 */
56#include <common.h>
57#include <command.h>
58#include <config.h>
59#include <pcmcia.h>
60#include <cmd_pcmcia.h>
61#if defined(CONFIG_IDE_8xx_PCCARD) && defined(CONFIG_8xx)
62#include <mpc8xx.h>
63#endif
64#if defined(CONFIG_LWMON)
65#include <i2c.h>
66#endif
67
68#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
69 ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
70
71int pcmcia_on (void);
72
73#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
74static int pcmcia_off (void);
wdenk66fd3d12003-05-18 11:30:09 +000075#endif
76
77#ifdef CONFIG_I82365
78
79extern int i82365_init (void);
80extern void i82365_exit (void);
81
82#else /* ! CONFIG_I82365 */
83
84#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +000085static int hardware_disable(int slot);
86#endif
87static int hardware_enable (int slot);
88static int voltage_set(int slot, int vcc, int vpp);
wdenkc6097192002-11-03 00:24:07 +000089
90static u_int m8xx_get_graycode(u_int size);
91#if 0
92static u_int m8xx_get_speed(u_int ns, u_int is_io);
93#endif
94
wdenk1f53a412002-12-04 23:39:58 +000095/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +000096
97/* look up table for pgcrx registers */
98
99static u_int *pcmcia_pgcrx[2] = {
100 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
101 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
102};
103
104#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
105
wdenk66fd3d12003-05-18 11:30:09 +0000106#endif /* CONFIG_I82365 */
107
108#ifdef CONFIG_IDE_8xx_PCCARD
109static void print_funcid (int func);
110static void print_fixed (volatile uchar *p);
111static int identify (volatile uchar *p);
112static int check_ide_device (int slot);
113#endif /* CONFIG_IDE_8xx_PCCARD */
114
wdenkc6097192002-11-03 00:24:07 +0000115const char *indent = "\t ";
116
wdenk1f53a412002-12-04 23:39:58 +0000117/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000118
119#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
120
121int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
122{
123 int rcode = 0;
124
125 if (argc != 2) {
126 printf ("Usage: pinit {on | off}\n");
127 return 1;
128 }
129 if (strcmp(argv[1],"on") == 0) {
130 rcode = pcmcia_on ();
131 } else if (strcmp(argv[1],"off") == 0) {
132 rcode = pcmcia_off ();
133 } else {
134 printf ("Usage: pinit {on | off}\n");
135 return 1;
136 }
137
138 return rcode;
139}
140#endif /* CFG_CMD_PCMCIA */
141
wdenk1f53a412002-12-04 23:39:58 +0000142/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000143
wdenk66fd3d12003-05-18 11:30:09 +0000144#ifdef CONFIG_I82365
145int pcmcia_on (void)
146{
147 u_int rc;
148
149 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
150
151 rc = i82365_init();
152
153 if (rc == 0)
154 {
155 rc = check_ide_device(0);
156 }
157
158 return (rc);
159}
160#else
161
wdenkc6097192002-11-03 00:24:07 +0000162#if defined(CONFIG_LWMON)
163# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
164#else
165# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
166#endif
167
168int pcmcia_on (void)
169{
170 int i;
171 u_long reg, base;
172 pcmcia_win_t *win;
wdenkea909b72002-11-21 23:11:29 +0000173 u_int slotbit;
174 u_int rc, slot;
wdenkc6097192002-11-03 00:24:07 +0000175
176 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
177
178 /* intialize the fixed memory windows */
179 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
180 base = CFG_PCMCIA_MEM_ADDR;
181
182 if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
183 printf ("Cannot set window size to 0x%08x\n",
184 CFG_PCMCIA_MEM_SIZE);
185 return (1);
186 }
187
wdenkea909b72002-11-21 23:11:29 +0000188 slotbit = PCMCIA_SLOT_x;
wdenkc6097192002-11-03 00:24:07 +0000189 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
190 win->br = base;
191
wdenkea909b72002-11-21 23:11:29 +0000192#if (PCMCIA_SOCKETS_NO == 2)
193 if (i == 4) /* Another slot starting from win 4 */
194 slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
195#endif
wdenkc6097192002-11-03 00:24:07 +0000196 switch (i) {
197#ifdef CONFIG_IDE_8xx_PCCARD
wdenkea909b72002-11-21 23:11:29 +0000198 case 4:
wdenkc6097192002-11-03 00:24:07 +0000199 case 0: { /* map attribute memory */
200 win->or = ( PCMCIA_BSIZE_64M
201 | PCMCIA_PPS_8
202 | PCMCIA_PRS_ATTR
wdenkea909b72002-11-21 23:11:29 +0000203 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000204 | PCMCIA_PV
205 | CFG_PCMCIA_TIMING );
206 break;
207 }
wdenkea909b72002-11-21 23:11:29 +0000208 case 5:
wdenkc6097192002-11-03 00:24:07 +0000209 case 1: { /* map I/O window for data reg */
210 win->or = ( PCMCIA_BSIZE_1K
211 | PCMCIA_PPS_16
212 | PCMCIA_PRS_IO
wdenkea909b72002-11-21 23:11:29 +0000213 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000214 | PCMCIA_PV
215 | CFG_PCMCIA_TIMING );
216 break;
217 }
wdenkea909b72002-11-21 23:11:29 +0000218 case 6:
wdenk1f53a412002-12-04 23:39:58 +0000219 case 2: { /* map I/O window for cmd/ctrl reg block */
wdenkc6097192002-11-03 00:24:07 +0000220 win->or = ( PCMCIA_BSIZE_1K
221 | PCMCIA_PPS_8
222 | PCMCIA_PRS_IO
wdenkea909b72002-11-21 23:11:29 +0000223 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000224 | PCMCIA_PV
225 | CFG_PCMCIA_TIMING );
226 break;
227 }
228#endif /* CONFIG_IDE_8xx_PCCARD */
229 default: /* set to not valid */
230 win->or = 0;
231 break;
232 }
233
234 debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
235 i, win->br, win->or);
236 base += CFG_PCMCIA_MEM_SIZE;
237 ++win;
238 }
239
wdenk1f53a412002-12-04 23:39:58 +0000240 for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
wdenkea909b72002-11-21 23:11:29 +0000241 /* turn off voltage */
242 if ((rc = voltage_set(slot, 0, 0)))
243 continue;
wdenk1f53a412002-12-04 23:39:58 +0000244
wdenkea909b72002-11-21 23:11:29 +0000245 /* Enable external hardware */
246 if ((rc = hardware_enable(slot)))
247 continue;
wdenk1f53a412002-12-04 23:39:58 +0000248
wdenkc6097192002-11-03 00:24:07 +0000249#ifdef CONFIG_IDE_8xx_PCCARD
wdenkea909b72002-11-21 23:11:29 +0000250 if ((rc = check_ide_device(i)))
251 continue;
wdenkc6097192002-11-03 00:24:07 +0000252#endif
wdenkea909b72002-11-21 23:11:29 +0000253 }
254 return (rc);
wdenkc6097192002-11-03 00:24:07 +0000255}
wdenk66fd3d12003-05-18 11:30:09 +0000256#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000257
wdenk1f53a412002-12-04 23:39:58 +0000258/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000259
260#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
261
wdenk66fd3d12003-05-18 11:30:09 +0000262#ifdef CONFIG_I82365
263static int pcmcia_off (void)
264{
265 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
266
267 i82365_exit();
268
269 return 0;
270}
271#else
wdenkc6097192002-11-03 00:24:07 +0000272static int pcmcia_off (void)
273{
274 int i;
275 pcmcia_win_t *win;
276
277 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
278
279 /* clear interrupt state, and disable interrupts */
280 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
281 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
282
283 /* turn off interrupt and disable CxOE */
284 PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
285
286 /* turn off memory windows */
287 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
288
289 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
290 /* disable memory window */
291 win->or = 0;
292 ++win;
293 }
294
295 /* turn off voltage */
296 voltage_set(_slot_, 0, 0);
297
298 /* disable external hardware */
299 printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
300 hardware_disable(_slot_);
301 return 0;
302}
wdenk66fd3d12003-05-18 11:30:09 +0000303#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000304
305#endif /* CFG_CMD_PCMCIA */
306
wdenk1f53a412002-12-04 23:39:58 +0000307/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000308
309#ifdef CONFIG_IDE_8xx_PCCARD
310
311#define MAX_TUPEL_SZ 512
312#define MAX_FEATURES 4
313
wdenk6069ff22003-02-28 00:49:47 +0000314int ide_devices_found;
wdenkea909b72002-11-21 23:11:29 +0000315static int check_ide_device (int slot)
wdenkc6097192002-11-03 00:24:07 +0000316{
317 volatile uchar *ident = NULL;
318 volatile uchar *feature_p[MAX_FEATURES];
wdenkea909b72002-11-21 23:11:29 +0000319 volatile uchar *p, *start, *addr;
wdenkc6097192002-11-03 00:24:07 +0000320 int n_features = 0;
321 uchar func_id = ~0;
322 uchar code, len;
323 ushort config_base = 0;
324 int found = 0;
325 int i;
326
wdenk1f53a412002-12-04 23:39:58 +0000327 addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
328 CFG_PCMCIA_MEM_SIZE * (slot * 4));
wdenkd0fb80c2003-01-11 09:48:40 +0000329 debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
wdenkc6097192002-11-03 00:24:07 +0000330
wdenkea909b72002-11-21 23:11:29 +0000331 start = p = (volatile uchar *) addr;
wdenkc6097192002-11-03 00:24:07 +0000332
333 while ((p - start) < MAX_TUPEL_SZ) {
334
335 code = *p; p += 2;
336
337 if (code == 0xFF) { /* End of chain */
338 break;
339 }
340
341 len = *p; p += 2;
342#if defined(DEBUG) && (DEBUG > 1)
343 { volatile uchar *q = p;
344 printf ("\nTuple code %02x length %d\n\tData:",
345 code, len);
346
347 for (i = 0; i < len; ++i) {
348 printf (" %02x", *q);
349 q+= 2;
350 }
351 }
352#endif /* DEBUG */
353 switch (code) {
354 case CISTPL_VERS_1:
355 ident = p + 4;
356 break;
357 case CISTPL_FUNCID:
358 /* Fix for broken SanDisk which may have 0x80 bit set */
359 func_id = *p & 0x7F;
360 break;
361 case CISTPL_FUNCE:
362 if (n_features < MAX_FEATURES)
363 feature_p[n_features++] = p;
364 break;
365 case CISTPL_CONFIG:
366 config_base = (*(p+6) << 8) + (*(p+4));
367 debug ("\n## Config_base = %04x ###\n", config_base);
368 default:
369 break;
370 }
371 p += 2 * len;
372 }
373
374 found = identify (ident);
375
376 if (func_id != ((uchar)~0)) {
377 print_funcid (func_id);
378
379 if (func_id == CISTPL_FUNCID_FIXED)
380 found = 1;
381 else
382 return (1); /* no disk drive */
383 }
384
385 for (i=0; i<n_features; ++i) {
386 print_fixed (feature_p[i]);
387 }
388
389 if (!found) {
390 printf ("unknown card type\n");
391 return (1);
392 }
393
wdenk6069ff22003-02-28 00:49:47 +0000394 ide_devices_found |= (1 << slot);
395
wdenkc6097192002-11-03 00:24:07 +0000396 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
wdenkea909b72002-11-21 23:11:29 +0000397 *((uchar *)(addr + config_base)) = 1;
wdenkc6097192002-11-03 00:24:07 +0000398
399 return (0);
400}
401#endif /* CONFIG_IDE_8xx_PCCARD */
402
wdenk1f53a412002-12-04 23:39:58 +0000403/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000404
405
wdenk1f53a412002-12-04 23:39:58 +0000406/* -------------------------------------------------------------------- */
407/* board specific stuff: */
408/* voltage_set(), hardware_enable() and hardware_disable() */
409/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000410
wdenk1f53a412002-12-04 23:39:58 +0000411/* -------------------------------------------------------------------- */
412/* RPX Boards from Embedded Planet */
413/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000414
415#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
416
417/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
418 * SYPCR is write once only, therefore must the slowest memory be faster
419 * than the bus monitor or we will get a machine check due to the bus timeout.
420 */
421
422#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
423
424#undef PCMCIA_BMT_LIMIT
425#define PCMCIA_BMT_LIMIT (6*8)
426
427static int voltage_set(int slot, int vcc, int vpp)
428{
429 u_long reg = 0;
430
431 switch(vcc) {
432 case 0: break;
433 case 33: reg |= BCSR1_PCVCTL4; break;
434 case 50: reg |= BCSR1_PCVCTL5; break;
435 default: return 1;
436 }
437
438 switch(vpp) {
439 case 0: break;
440 case 33:
441 case 50:
442 if(vcc == vpp)
443 reg |= BCSR1_PCVCTL6;
444 else
445 return 1;
446 break;
447 case 120:
448 reg |= BCSR1_PCVCTL7;
449 default: return 1;
450 }
451
452 if(vcc == 120)
453 return 1;
454
455 /* first, turn off all power */
456
457 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
458 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
459
460 /* enable new powersettings */
461
462 *((uint *)RPX_CSR_ADDR) |= reg;
463
464 return 0;
465}
466
467#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
468static int hardware_enable (int slot)
469{
470 return 0; /* No hardware to enable */
471}
472#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
473static int hardware_disable(int slot)
474{
475 return 0; /* No hardware to disable */
476}
477#endif /* CFG_CMD_PCMCIA */
478#endif /* CONFIG_RPXCLASSIC */
479
wdenk1f53a412002-12-04 23:39:58 +0000480/* -------------------------------------------------------------------- */
481/* (F)ADS Boards from Motorola */
482/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000483
484#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
485
486#ifdef CONFIG_ADS
487#define PCMCIA_BOARD_MSG "ADS"
488#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
489#else
490#define PCMCIA_BOARD_MSG "FADS"
491#endif
492
493static int voltage_set(int slot, int vcc, int vpp)
494{
495 u_long reg = 0;
496
497 switch(vpp) {
498 case 0: reg = 0; break;
499 case 50: reg = 1; break;
500 case 120: reg = 2; break;
501 default: return 1;
502 }
503
504 switch(vcc) {
505 case 0: reg = 0; break;
506#ifdef CONFIG_ADS
507 case 50: reg = BCSR1_PCCVCCON; break;
508#endif
509#ifdef CONFIG_FADS
510 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
511 case 50: reg = BCSR1_PCCVCC1; break;
512#endif
513 default: return 1;
514 }
515
516 /* first, turn off all power */
517
518#ifdef CONFIG_ADS
519 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
520#endif
521#ifdef CONFIG_FADS
522 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
523#endif
524 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
525
526 /* enable new powersettings */
527
528#ifdef CONFIG_ADS
529 *((uint *)BCSR1) &= ~reg;
530#endif
531#ifdef CONFIG_FADS
532 *((uint *)BCSR1) |= reg;
533#endif
534
535 *((uint *)BCSR1) |= reg << 20;
536
537 return 0;
538}
539
540#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
541
542static int hardware_enable(int slot)
543{
544 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
545 return 0;
546}
547
548#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
549static int hardware_disable(int slot)
550{
551 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
552 return 0;
553}
554#endif /* CFG_CMD_PCMCIA */
555
556#endif /* (F)ADS */
557
wdenk1f53a412002-12-04 23:39:58 +0000558/* -------------------------------------------------------------------- */
559/* TQM8xxL Boards by TQ Components */
wdenkdc7c9a12003-03-26 06:55:25 +0000560/* SC8xx Boards by SinoVee Microsystems */
wdenk1f53a412002-12-04 23:39:58 +0000561/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000562
wdenkdc7c9a12003-03-26 06:55:25 +0000563#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
564
wdenkc6097192002-11-03 00:24:07 +0000565#if defined(CONFIG_TQM8xxL)
wdenkc6097192002-11-03 00:24:07 +0000566#define PCMCIA_BOARD_MSG "TQM8xxL"
wdenkdc7c9a12003-03-26 06:55:25 +0000567#endif
568#if defined(CONFIG_SVM_SC8xx)
569#define PCMCIA_BOARD_MSG "SC8xx"
570#endif
wdenkc6097192002-11-03 00:24:07 +0000571
572static int hardware_enable(int slot)
573{
574 volatile immap_t *immap;
575 volatile cpm8xx_t *cp;
576 volatile pcmconf8xx_t *pcmp;
577 volatile sysconf8xx_t *sysp;
578 uint reg, mask;
579
580 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
581
582 udelay(10000);
583
584 immap = (immap_t *)CFG_IMMR;
585 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
586 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
587 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
588
589 /*
590 * Configure SIUMCR to enable PCMCIA port B
591 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
592 */
593 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
594
595 /* clear interrupt state, and disable interrupts */
596 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
597 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
598
wdenkc6097192002-11-03 00:24:07 +0000599 /*
wdenk1f53a412002-12-04 23:39:58 +0000600 * Disable interrupts, DMA, and PCMCIA buffers
601 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000602 */
603 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000604 reg = 0;
605 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
606 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000607 PCMCIA_PGCRX(_slot_) = reg;
608 udelay(500);
609
610 /*
611 * Configure Port C pins for
612 * 5 Volts Enable and 3 Volts enable
613 */
614 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
615 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
616 /* remove all power */
617
618 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
619
620 /*
621 * Make sure there is a card in the slot, then configure the interface.
622 */
623 udelay(10000);
624 debug ("[%d] %s: PIPR(%p)=0x%x\n",
625 __LINE__,__FUNCTION__,
626 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +0000627 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000628 printf (" No Card found\n");
629 return (1);
630 }
631
632 /*
633 * Power On.
634 */
635 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
636 reg = pcmp->pcmc_pipr;
637 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
638 reg,
639 (reg&PCMCIA_VS1(slot))?"n":"ff",
640 (reg&PCMCIA_VS2(slot))?"n":"ff");
641 if ((reg & mask) == mask) {
642 immap->im_ioport.iop_pcdat |= 0x0004;
643 puts (" 5.0V card found: ");
644 } else {
645 immap->im_ioport.iop_pcdat |= 0x0002;
646 puts (" 3.3V card found: ");
647 }
wdenk1f53a412002-12-04 23:39:58 +0000648 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000649#if 0
650 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
651 cp->cp_pbdir &= ~(0x0020 | 0x0010);
652 cp->cp_pbpar &= ~(0x0020 | 0x0010);
653 udelay(500000);
654#endif
655 udelay(1000);
656 debug ("Enable PCMCIA buffers and stop RESET\n");
657 reg = PCMCIA_PGCRX(_slot_);
658 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
659 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
660 PCMCIA_PGCRX(_slot_) = reg;
661
662 udelay(250000); /* some cards need >150 ms to come up :-( */
663
664 debug ("# hardware_enable done\n");
665
666 return (0);
667}
668
669
670
671#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
672static int hardware_disable(int slot)
673{
674 volatile immap_t *immap;
675 volatile pcmconf8xx_t *pcmp;
676 u_long reg;
677
678 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
679
680 immap = (immap_t *)CFG_IMMR;
681 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
682
683 /* remove all power */
684 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
685
wdenkc6097192002-11-03 00:24:07 +0000686 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000687 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000688 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
689 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
690 PCMCIA_PGCRX(_slot_) = reg;
691
692 udelay(10000);
693
694 return (0);
695}
696#endif /* CFG_CMD_PCMCIA */
697
698
699
700static int voltage_set(int slot, int vcc, int vpp)
701{
702 volatile immap_t *immap;
703 volatile pcmconf8xx_t *pcmp;
704 u_long reg;
705
706 debug ("voltage_set: "
707 PCMCIA_BOARD_MSG
708 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
709 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
710
711 immap = (immap_t *)CFG_IMMR;
712 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
713 /*
714 * Disable PCMCIA buffers (isolate the interface)
715 * and assert RESET signal
716 */
717 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000718 reg = PCMCIA_PGCRX(_slot_);
719 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
720 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000721 PCMCIA_PGCRX(_slot_) = reg;
722 udelay(500);
723
724 /*
725 * Configure Port C pins for
726 * 5 Volts Enable and 3 Volts enable,
727 * Turn off all power
728 */
729 debug ("PCMCIA power OFF\n");
730 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
731 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
732 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
733
734 reg = 0;
735 switch(vcc) {
736 case 0: break;
737 case 33: reg |= 0x0002; break;
738 case 50: reg |= 0x0004; break;
739 default: goto done;
740 }
741
742 /* Checking supported voltages */
743
744 debug ("PIPR: 0x%x --> %s\n",
745 pcmp->pcmc_pipr,
746 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
747
748 immap->im_ioport.iop_pcdat |= reg;
wdenk1f53a412002-12-04 23:39:58 +0000749 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000750 if (reg) {
751 debug ("PCMCIA powered at %sV\n",
752 (reg&0x0004) ? "5.0" : "3.3");
753 } else {
754 debug ("PCMCIA powered down\n");
755 }
756
757done:
758 debug ("Enable PCMCIA buffers and stop RESET\n");
759 reg = PCMCIA_PGCRX(_slot_);
760 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
761 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
762 PCMCIA_PGCRX(_slot_) = reg;
763 udelay(500);
764
765 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
766 slot+'A');
767 return (0);
768}
769
770#endif /* TQM8xxL */
771
772
wdenk1f53a412002-12-04 23:39:58 +0000773/* -------------------------------------------------------------------- */
774/* LWMON Board */
775/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000776
777#if defined(CONFIG_LWMON)
778
779#define PCMCIA_BOARD_MSG "LWMON"
780
781/* #define's for MAX1604 Power Switch */
782#define MAX1604_OP_SUS 0x80
783#define MAX1604_VCCBON 0x40
784#define MAX1604_VCC_35 0x20
785#define MAX1604_VCCBHIZ 0x10
786#define MAX1604_VPPBON 0x08
787#define MAX1604_VPPBPBPGM 0x04
788#define MAX1604_VPPBHIZ 0x02
789/* reserved 0x01 */
790
791static int hardware_enable(int slot)
792{
793 volatile immap_t *immap;
794 volatile cpm8xx_t *cp;
795 volatile pcmconf8xx_t *pcmp;
796 volatile sysconf8xx_t *sysp;
797 uint reg, mask;
798 uchar val;
799
800
801 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
802
803 /* Switch on PCMCIA port in PIC register 0x60 */
804 reg = pic_read (0x60);
805 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
806 reg &= ~0x10;
wdenk1f53a412002-12-04 23:39:58 +0000807 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +0000808 pic_write (0x60, reg);
809#ifdef DEBUG
810 reg = pic_read (0x60);
811 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
812#endif
813 udelay(10000);
814
815 immap = (immap_t *)CFG_IMMR;
816 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
817 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
818 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
819
820 /*
821 * Configure SIUMCR to enable PCMCIA port B
822 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
823 */
824 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
825
826 /* clear interrupt state, and disable interrupts */
827 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
828 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
829
wdenkc6097192002-11-03 00:24:07 +0000830 /*
wdenk1f53a412002-12-04 23:39:58 +0000831 * Disable interrupts, DMA, and PCMCIA buffers
832 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000833 */
834 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000835 reg = 0;
836 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
837 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000838 PCMCIA_PGCRX(_slot_) = reg;
839 udelay(500);
840
841 /*
842 * Make sure there is a card in the slot, then configure the interface.
843 */
844 udelay(10000);
845 debug ("[%d] %s: PIPR(%p)=0x%x\n",
846 __LINE__,__FUNCTION__,
847 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +0000848 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000849 printf (" No Card found\n");
850 return (1);
851 }
852
853 /*
854 * Power On.
855 */
856 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
857 reg = pcmp->pcmc_pipr;
858 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
859 reg,
860 (reg&PCMCIA_VS1(slot))?"n":"ff",
861 (reg&PCMCIA_VS2(slot))?"n":"ff");
862 if ((reg & mask) == mask) {
863 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
864 puts (" 5.0V card found: ");
865 } else {
866 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
867 puts (" 3.3V card found: ");
868 }
869
870 /* switch VCC on */
wdenk1f53a412002-12-04 23:39:58 +0000871 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +0000872 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
873 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
874
875 udelay(500000);
876
877 debug ("Enable PCMCIA buffers and stop RESET\n");
878 reg = PCMCIA_PGCRX(_slot_);
879 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
880 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
881 PCMCIA_PGCRX(_slot_) = reg;
882
883 udelay(250000); /* some cards need >150 ms to come up :-( */
884
885 debug ("# hardware_enable done\n");
886
887 return (0);
888}
889
890
891
892#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
893static int hardware_disable(int slot)
894{
895 volatile immap_t *immap;
896 volatile pcmconf8xx_t *pcmp;
897 u_long reg;
898 uchar val;
899
900 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
901
902 immap = (immap_t *)CFG_IMMR;
903 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
904
905 /* remove all power, put output in high impedance state */
906 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
907 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
908 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
909
910 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +0000911 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000912 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000913 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
914 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
915 PCMCIA_PGCRX(_slot_) = reg;
916
917 /* Switch off PCMCIA port in PIC register 0x60 */
918 reg = pic_read (0x60);
919 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
920 reg |= 0x10;
921 reg &= ~0x08;
922 pic_write (0x60, reg);
923#ifdef DEBUG
924 reg = pic_read (0x60);
925 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
926#endif
927 udelay(10000);
928
929 return (0);
930}
931#endif /* CFG_CMD_PCMCIA */
932
933
934
935static int voltage_set(int slot, int vcc, int vpp)
936{
937 volatile immap_t *immap;
938 volatile pcmconf8xx_t *pcmp;
939 u_long reg;
940 uchar val;
941
942 debug ("voltage_set: "
943 PCMCIA_BOARD_MSG
944 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
945 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
946
947 immap = (immap_t *)CFG_IMMR;
948 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
949 /*
950 * Disable PCMCIA buffers (isolate the interface)
951 * and assert RESET signal
952 */
953 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000954 reg = PCMCIA_PGCRX(_slot_);
955 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
956 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000957 PCMCIA_PGCRX(_slot_) = reg;
958 udelay(500);
959
960 /*
961 * Turn off all power (switch to high impedance)
962 */
963 debug ("PCMCIA power OFF\n");
964 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
965 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
966 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
967
968 val = 0;
969 switch(vcc) {
970 case 0: break;
971 case 33: val = MAX1604_VCC_35; break;
972 case 50: break;
973 default: goto done;
974 }
975
976 /* Checking supported voltages */
977
978 debug ("PIPR: 0x%x --> %s\n",
979 pcmp->pcmc_pipr,
980 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
981
982 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
983 if (val) {
984 debug ("PCMCIA powered at %sV\n",
985 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
986 } else {
987 debug ("PCMCIA powered down\n");
988 }
989
990done:
991 debug ("Enable PCMCIA buffers and stop RESET\n");
992 reg = PCMCIA_PGCRX(_slot_);
993 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
994 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
995 PCMCIA_PGCRX(_slot_) = reg;
996 udelay(500);
997
998 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
999 slot+'A');
1000 return (0);
1001}
1002
1003#endif /* LWMON */
1004
wdenk1f53a412002-12-04 23:39:58 +00001005/* -------------------------------------------------------------------- */
1006/* GTH board by Corelatus AB */
1007/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001008#if defined(CONFIG_GTH)
1009
1010#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1011
wdenk1f53a412002-12-04 23:39:58 +00001012static int voltage_set (int slot, int vcc, int vpp)
1013{ /* Do nothing */
1014 return 0;
wdenkc6097192002-11-03 00:24:07 +00001015}
1016
1017static int hardware_enable (int slot)
1018{
wdenk1f53a412002-12-04 23:39:58 +00001019 volatile immap_t *immap;
1020 volatile cpm8xx_t *cp;
1021 volatile pcmconf8xx_t *pcmp;
1022 volatile sysconf8xx_t *sysp;
1023 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +00001024
wdenk1f53a412002-12-04 23:39:58 +00001025 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +00001026
wdenk1f53a412002-12-04 23:39:58 +00001027 immap = (immap_t *) CFG_IMMR;
1028 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1029 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1030 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +00001031
wdenk1f53a412002-12-04 23:39:58 +00001032 /* clear interrupt state, and disable interrupts */
1033 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1034 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +00001035
wdenk1f53a412002-12-04 23:39:58 +00001036 /*
1037 * Disable interrupts, DMA, and PCMCIA buffers
1038 * (isolate the interface) and assert RESET signal
1039 */
1040 debug ("Disable PCMCIA buffers and assert RESET\n");
1041 reg = 0;
1042 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1043 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1044 PCMCIA_PGCRX (_slot_) = reg;
1045 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001046
wdenk1f53a412002-12-04 23:39:58 +00001047 /*
1048 * Make sure there is a card in the slot,
1049 * then configure the interface.
1050 */
1051 udelay (10000);
1052 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1053 __LINE__, __FUNCTION__,
1054 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1055 if (pcmp->pcmc_pipr & 0x98000000) {
1056 printf (" No Card found\n");
1057 return (1);
1058 }
wdenkc6097192002-11-03 00:24:07 +00001059
wdenk1f53a412002-12-04 23:39:58 +00001060 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1061 reg = pcmp->pcmc_pipr;
1062 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1063 reg,
1064 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1065 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001066
wdenk1f53a412002-12-04 23:39:58 +00001067 debug ("Enable PCMCIA buffers and stop RESET\n");
1068 reg = PCMCIA_PGCRX (_slot_);
1069 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1070 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1071 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001072
wdenk1f53a412002-12-04 23:39:58 +00001073 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001074
wdenk1f53a412002-12-04 23:39:58 +00001075 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001076
wdenk1f53a412002-12-04 23:39:58 +00001077 return 0;
wdenkc6097192002-11-03 00:24:07 +00001078}
1079#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1080static int hardware_disable(int slot)
1081{
1082 return 0; /* No hardware to disable */
1083}
1084#endif /* CFG_CMD_PCMCIA */
1085#endif /* CONFIG_GTH */
1086
wdenk1f53a412002-12-04 23:39:58 +00001087/* -------------------------------------------------------------------- */
1088/* ICU862 Boards by Cambridge Broadband Ltd. */
1089/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001090
1091#if defined(CONFIG_ICU862)
1092
1093#define PCMCIA_BOARD_MSG "ICU862"
1094
1095static void cfg_port_B (void);
1096
1097static int hardware_enable(int slot)
1098{
1099 volatile immap_t *immap;
1100 volatile cpm8xx_t *cp;
1101 volatile pcmconf8xx_t *pcmp;
1102 volatile sysconf8xx_t *sysp;
1103 uint reg, pipr, mask;
1104 int i;
1105
1106 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1107
1108 udelay(10000);
1109
1110 immap = (immap_t *)CFG_IMMR;
1111 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1112 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1113 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1114
1115 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1116 cfg_port_B ();
1117
1118 /*
1119 * Configure SIUMCR to enable PCMCIA port B
1120 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1121 */
1122 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1123
1124 /* clear interrupt state, and disable interrupts */
1125 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1126 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1127
wdenkc6097192002-11-03 00:24:07 +00001128 /*
wdenk1f53a412002-12-04 23:39:58 +00001129 * Disable interrupts, DMA, and PCMCIA buffers
1130 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001131 */
1132 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001133 reg = 0;
1134 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1135 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001136 PCMCIA_PGCRX(_slot_) = reg;
1137 udelay(500);
1138
1139 /*
1140 * Make sure there is a card in the slot, then configure the interface.
1141 */
1142 udelay(10000);
1143 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1144 __LINE__,__FUNCTION__,
1145 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001146 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001147 printf (" No Card found\n");
1148 return (1);
1149 }
1150
1151 /*
1152 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1153 */
1154 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1155 pipr = pcmp->pcmc_pipr;
1156 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1157 pipr,
1158 (reg&PCMCIA_VS1(slot))?"n":"ff",
1159 (reg&PCMCIA_VS2(slot))?"n":"ff");
1160
1161 reg = cp->cp_pbdat;
1162 if ((pipr & mask) == mask) {
wdenk1f53a412002-12-04 23:39:58 +00001163 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1164 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001165 reg &= ~(TPS2205_VCC5); /* 5V on */
1166 puts (" 5.0V card found: ");
1167 } else {
wdenk1f53a412002-12-04 23:39:58 +00001168 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1169 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001170 reg &= ~(TPS2205_VCC3); /* 3V on */
1171 puts (" 3.3V card found: ");
1172 }
1173
1174 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1175 reg,
1176 (reg & TPS2205_VCC3) ? "off" : "on",
1177 (reg & TPS2205_VCC5) ? "off" : "on",
1178 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1179 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1180
1181 cp->cp_pbdat = reg;
1182
1183 /* Wait 500 ms; use this to check for over-current */
1184 for (i=0; i<5000; ++i) {
1185 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1186 printf (" *** Overcurrent - Safety shutdown ***\n");
1187 cp->cp_pbdat &= ~(TPS2205_SHDN);
1188 return (1);
1189 }
1190 udelay (100);
1191 }
1192
1193 debug ("Enable PCMCIA buffers and stop RESET\n");
1194 reg = PCMCIA_PGCRX(_slot_);
1195 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1196 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1197 PCMCIA_PGCRX(_slot_) = reg;
1198
1199 udelay(250000); /* some cards need >150 ms to come up :-( */
1200
1201 debug ("# hardware_enable done\n");
1202
1203 return (0);
1204}
1205
1206
1207
1208#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1209static int hardware_disable(int slot)
1210{
1211 volatile immap_t *immap;
1212 volatile cpm8xx_t *cp;
1213 volatile pcmconf8xx_t *pcmp;
1214 u_long reg;
1215
1216 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1217
1218 immap = (immap_t *)CFG_IMMR;
1219 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1220 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1221
1222 /* Shut down */
1223 cp->cp_pbdat &= ~(TPS2205_SHDN);
1224
1225 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001226 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001227 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001228 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1229 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1230 PCMCIA_PGCRX(_slot_) = reg;
1231
1232 udelay(10000);
1233
1234 return (0);
1235}
1236#endif /* CFG_CMD_PCMCIA */
1237
1238
1239
1240static int voltage_set(int slot, int vcc, int vpp)
1241{
1242 volatile immap_t *immap;
1243 volatile cpm8xx_t *cp;
1244 volatile pcmconf8xx_t *pcmp;
1245 u_long reg;
1246
1247 debug ("voltage_set: "
1248 PCMCIA_BOARD_MSG
1249 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1250 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1251
1252 immap = (immap_t *)CFG_IMMR;
1253 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1254 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1255 /*
1256 * Disable PCMCIA buffers (isolate the interface)
1257 * and assert RESET signal
1258 */
1259 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001260 reg = PCMCIA_PGCRX(_slot_);
1261 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1262 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001263 PCMCIA_PGCRX(_slot_) = reg;
1264 udelay(500);
1265
1266 /*
1267 * Configure Port C pins for
1268 * 5 Volts Enable and 3 Volts enable,
1269 * Turn all power pins to Hi-Z
1270 */
1271 debug ("PCMCIA power OFF\n");
1272 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1273
1274 reg = cp->cp_pbdat;
1275
1276 switch(vcc) {
1277 case 0: break; /* Switch off */
1278 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1279 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1280 default: goto done;
1281 }
1282
1283 /* Checking supported voltages */
1284
1285 debug ("PIPR: 0x%x --> %s\n",
1286 pcmp->pcmc_pipr,
1287 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1288
1289 cp->cp_pbdat = reg;
1290
1291#ifdef DEBUG
1292 {
1293 char *s;
1294
1295 if ((reg & TPS2205_VCC3) == 0) {
1296 s = "at 3.3V";
1297 } else if ((reg & TPS2205_VCC5) == 0) {
1298 s = "at 5.0V";
1299 } else {
1300 s = "down";
1301 }
1302 printf ("PCMCIA powered %s\n", s);
1303 }
1304#endif
1305
1306done:
1307 debug ("Enable PCMCIA buffers and stop RESET\n");
1308 reg = PCMCIA_PGCRX(_slot_);
1309 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1310 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1311 PCMCIA_PGCRX(_slot_) = reg;
1312 udelay(500);
1313
1314 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1315 slot+'A');
1316 return (0);
1317}
1318
1319static void cfg_port_B (void)
1320{
1321 volatile immap_t *immap;
1322 volatile cpm8xx_t *cp;
1323 uint reg;
1324
1325 immap = (immap_t *)CFG_IMMR;
1326 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1327
1328 /*
1329 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1330 *
1331 * Switch off all voltages, assert shutdown
1332 */
1333 reg = cp->cp_pbdat;
wdenk1f53a412002-12-04 23:39:58 +00001334 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1335 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1336 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001337 cp->cp_pbdat = reg;
1338
1339 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1340
1341 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1342 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1343
1344 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1345 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1346}
1347
1348#endif /* ICU862 */
1349
1350
wdenk1f53a412002-12-04 23:39:58 +00001351/* -------------------------------------------------------------------- */
1352/* C2MON Boards by TTTech Computertechnik AG */
1353/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001354
1355#if defined(CONFIG_C2MON)
1356
1357#define PCMCIA_BOARD_MSG "C2MON"
1358
1359static void cfg_ports (void);
1360
1361static int hardware_enable(int slot)
1362{
1363 volatile immap_t *immap;
1364 volatile cpm8xx_t *cp;
1365 volatile pcmconf8xx_t *pcmp;
1366 volatile sysconf8xx_t *sysp;
1367 uint reg, pipr, mask;
1368 ushort sreg;
1369 int i;
1370
1371 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1372
1373 udelay(10000);
1374
1375 immap = (immap_t *)CFG_IMMR;
1376 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1377 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1378 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1379
1380 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1381 cfg_ports ();
1382
1383 /*
1384 * Configure SIUMCR to enable PCMCIA port B
1385 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1386 */
1387 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1388
1389 /* clear interrupt state, and disable interrupts */
1390 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1391 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1392
wdenkc6097192002-11-03 00:24:07 +00001393 /*
wdenk1f53a412002-12-04 23:39:58 +00001394 * Disable interrupts, DMA, and PCMCIA buffers
1395 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001396 */
1397 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001398 reg = 0;
1399 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1400 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001401 PCMCIA_PGCRX(_slot_) = reg;
1402 udelay(500);
1403
1404 /*
1405 * Make sure there is a card in the slot, then configure the interface.
1406 */
1407 udelay(10000);
1408 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1409 __LINE__,__FUNCTION__,
1410 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001411 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001412 printf (" No Card found\n");
1413 return (1);
1414 }
1415
1416 /*
1417 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1418 */
1419 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1420 pipr = pcmp->pcmc_pipr;
1421 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1422 pipr,
1423 (reg&PCMCIA_VS1(slot))?"n":"ff",
1424 (reg&PCMCIA_VS2(slot))?"n":"ff");
1425
1426 sreg = immap->im_ioport.iop_pcdat;
1427 if ((pipr & mask) == mask) {
1428 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1429 TPS2211_VCCD1); /* 5V on */
1430 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1431 puts (" 5.0V card found: ");
1432 } else {
1433 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1434 TPS2211_VCCD0); /* 3V on */
1435 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1436 puts (" 3.3V card found: ");
1437 }
1438
1439 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1440 sreg,
1441 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1442 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1443 );
1444
1445 immap->im_ioport.iop_pcdat = sreg;
1446
1447 /* Wait 500 ms; use this to check for over-current */
1448 for (i=0; i<5000; ++i) {
1449 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1450 printf (" *** Overcurrent - Safety shutdown ***\n");
1451 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1452 return (1);
1453 }
1454 udelay (100);
1455 }
1456
1457 debug ("Enable PCMCIA buffers and stop RESET\n");
1458 reg = PCMCIA_PGCRX(_slot_);
1459 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1460 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1461 PCMCIA_PGCRX(_slot_) = reg;
1462
1463 udelay(250000); /* some cards need >150 ms to come up :-( */
1464
1465 debug ("# hardware_enable done\n");
1466
1467 return (0);
1468}
1469
1470
1471
1472#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1473static int hardware_disable(int slot)
1474{
1475 volatile immap_t *immap;
1476 volatile cpm8xx_t *cp;
1477 volatile pcmconf8xx_t *pcmp;
1478 u_long reg;
1479
1480 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1481
1482 immap = (immap_t *)CFG_IMMR;
1483 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1484
1485 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001486 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001487 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001488 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1489 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1490 PCMCIA_PGCRX(_slot_) = reg;
1491
1492 /* ALl voltages off / Hi-Z */
1493 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1494 TPS2211_VCCD0 | TPS2211_VCCD1 );
1495
1496 udelay(10000);
1497
1498 return (0);
1499}
1500#endif /* CFG_CMD_PCMCIA */
1501
1502
1503
1504static int voltage_set(int slot, int vcc, int vpp)
1505{
1506 volatile immap_t *immap;
1507 volatile cpm8xx_t *cp;
1508 volatile pcmconf8xx_t *pcmp;
1509 u_long reg;
1510 ushort sreg;
1511
1512 debug ("voltage_set: "
1513 PCMCIA_BOARD_MSG
1514 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1515 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1516
1517 immap = (immap_t *)CFG_IMMR;
1518 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1519 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1520 /*
1521 * Disable PCMCIA buffers (isolate the interface)
1522 * and assert RESET signal
1523 */
1524 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001525 reg = PCMCIA_PGCRX(_slot_);
1526 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1527 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001528 PCMCIA_PGCRX(_slot_) = reg;
1529 udelay(500);
1530
1531 /*
1532 * Configure Port C pins for
1533 * 5 Volts Enable and 3 Volts enable,
1534 * Turn all power pins to Hi-Z
1535 */
1536 debug ("PCMCIA power OFF\n");
1537 cfg_ports (); /* Enables switch, but all in Hi-Z */
1538
1539 sreg = immap->im_ioport.iop_pcdat;
1540 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1541
1542 switch(vcc) {
1543 case 0: break; /* Switch off */
1544 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1545 sreg &= ~TPS2211_VCCD1;
1546 break;
1547 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1548 sreg |= TPS2211_VCCD1;
1549 break;
1550 default: goto done;
1551 }
1552
1553 /* Checking supported voltages */
1554
1555 debug ("PIPR: 0x%x --> %s\n",
1556 pcmp->pcmc_pipr,
1557 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1558
1559 immap->im_ioport.iop_pcdat = sreg;
1560
1561#ifdef DEBUG
1562 {
1563 char *s;
1564
1565 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1566 s = "at 3.3V";
1567 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1568 s = "at 5.0V";
1569 } else {
1570 s = "down";
1571 }
1572 printf ("PCMCIA powered %s\n", s);
1573 }
1574#endif
1575
1576done:
1577 debug ("Enable PCMCIA buffers and stop RESET\n");
1578 reg = PCMCIA_PGCRX(_slot_);
1579 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1580 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1581 PCMCIA_PGCRX(_slot_) = reg;
1582 udelay(500);
1583
1584 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1585 slot+'A');
1586 return (0);
1587}
1588
1589static void cfg_ports (void)
1590{
1591 volatile immap_t *immap;
1592 volatile cpm8xx_t *cp;
1593 ushort sreg;
1594
1595 immap = (immap_t *)CFG_IMMR;
1596 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1597
1598 /*
1599 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1600 *
1601 * Switch off all voltages, assert shutdown
1602 */
1603 sreg = immap->im_ioport.iop_pcdat;
1604 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1605 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1606 immap->im_ioport.iop_pcdat = sreg;
1607
1608 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1609 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1610
1611 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1612 immap->im_ioport.iop_pcpar,
1613 immap->im_ioport.iop_pcdir,
1614 immap->im_ioport.iop_pcdat);
1615
1616 /*
1617 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1618 *
1619 * Over-Current Input only
1620 */
1621 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1622 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1623
1624 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1625 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1626}
1627
1628#endif /* C2MON */
1629
wdenk1f53a412002-12-04 23:39:58 +00001630/* -------------------------------------------------------------------- */
1631/* MBX board from Morotola */
1632/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001633
1634#if defined( CONFIG_MBX )
1635#include <../board/mbx8xx/csr.h>
1636
1637/* A lot of this has been taken from the RPX code in this file it works from me.
1638 I have added the voltage selection for the MBX board. */
1639
1640/* MBX voltage bit in control register #2 */
1641#define CR2_VPP12 ((uchar)0x10)
1642#define CR2_VPPVDD ((uchar)0x20)
1643#define CR2_VDD5 ((uchar)0x40)
1644#define CR2_VDD3 ((uchar)0x80)
1645
1646#define PCMCIA_BOARD_MSG "MBX860"
1647
1648static int voltage_set (int slot, int vcc, int vpp)
1649{
1650 uchar reg = 0;
1651
1652 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1653 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1654
1655 switch (vcc) {
1656 case 0:
1657 break;
1658 case 33:
1659 reg |= CR2_VDD3;
1660 break;
1661 case 50:
1662 reg |= CR2_VDD5;
1663 break;
1664 default:
1665 return 1;
1666 }
1667
1668 switch (vpp) {
1669 case 0:
1670 break;
1671 case 33:
1672 case 50:
1673 if (vcc == vpp) {
1674 reg |= CR2_VPPVDD;
1675 } else {
1676 return 1;
1677 }
1678 break;
1679 case 120:
1680 reg |= CR2_VPP12;
1681 break;
1682 default:
1683 return 1;
1684 }
1685
1686 /* first, turn off all power */
1687 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1688
1689 /* enable new powersettings */
1690 MBX_CSR2 |= reg;
1691 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1692
1693 return (0);
1694}
1695
1696static int hardware_enable (int slot)
1697{
1698 volatile immap_t *immap;
1699 volatile cpm8xx_t *cp;
1700 volatile pcmconf8xx_t *pcmp;
1701 volatile sysconf8xx_t *sysp;
1702 uint reg, mask;
1703
1704 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1705 'A' + slot);
1706
1707 udelay (10000);
1708
1709 immap = (immap_t *) CFG_IMMR;
1710 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1711 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1712 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1713
1714 /* clear interrupt state, and disable interrupts */
1715 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1716 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1717
wdenkc6097192002-11-03 00:24:07 +00001718 /*
wdenk1f53a412002-12-04 23:39:58 +00001719 * Disable interrupts, DMA, and PCMCIA buffers
1720 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001721 */
1722 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001723 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001724 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1725 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1726 PCMCIA_PGCRX (_slot_) = reg;
1727 udelay (500);
1728
1729 /* remove all power */
1730 voltage_set (slot, 0, 0);
1731 /*
1732 * Make sure there is a card in the slot, then configure the interface.
1733 */
wdenkea909b72002-11-21 23:11:29 +00001734 udelay(10000);
1735 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1736 __LINE__,__FUNCTION__,
1737 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1738 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001739 printf (" No Card found\n");
1740 return (1);
1741 }
1742
1743 /*
1744 * Power On.
1745 */
1746 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1747 reg = pcmp->pcmc_pipr;
1748 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1749 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1750 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1751
1752 if ((reg & mask) == mask) {
1753 voltage_set (_slot_, 50, 0);
1754 printf (" 5.0V card found: ");
1755 } else {
1756 voltage_set (_slot_, 33, 0);
1757 printf (" 3.3V card found: ");
1758 }
1759
1760 debug ("Enable PCMCIA buffers and stop RESET\n");
1761 reg = PCMCIA_PGCRX (_slot_);
1762 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1763 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1764 PCMCIA_PGCRX (_slot_) = reg;
1765
1766 udelay (250000); /* some cards need >150 ms to come up :-( */
1767
1768 debug ("# hardware_enable done\n");
1769
1770 return (0);
1771}
1772
1773#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1774static int hardware_disable (int slot)
1775{
1776 return 0; /* No hardware to disable */
1777}
1778#endif /* CFG_CMD_PCMCIA */
1779#endif /* CONFIG_MBX */
wdenk1f53a412002-12-04 23:39:58 +00001780/* -------------------------------------------------------------------- */
1781/* R360MPI Board */
1782/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001783
1784#if defined(CONFIG_R360MPI)
1785
1786#define PCMCIA_BOARD_MSG "R360MPI"
1787
1788
1789static int hardware_enable(int slot)
1790{
1791 volatile immap_t *immap;
1792 volatile cpm8xx_t *cp;
1793 volatile pcmconf8xx_t *pcmp;
1794 volatile sysconf8xx_t *sysp;
1795 uint reg, mask;
1796
1797 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1798
1799 udelay(10000);
1800
1801 immap = (immap_t *)CFG_IMMR;
1802 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1803 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1804 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1805
1806 /*
1807 * Configure SIUMCR to enable PCMCIA port B
1808 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1809 */
1810 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1811
1812 /* clear interrupt state, and disable interrupts */
1813 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1814 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1815
wdenkc6097192002-11-03 00:24:07 +00001816 /*
wdenk1f53a412002-12-04 23:39:58 +00001817 * Disable interrupts, DMA, and PCMCIA buffers
1818 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001819 */
1820 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001821 reg = 0;
1822 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1823 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001824 PCMCIA_PGCRX(_slot_) = reg;
1825 udelay(500);
1826
1827 /*
1828 * Configure Ports A, B & C pins for
1829 * 5 Volts Enable and 3 Volts enable
1830 */
1831 immap->im_ioport.iop_pcpar &= ~(0x0400);
1832 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1833 immap->im_ioport.iop_pcdir |= 0x0400;*/
1834
1835 immap->im_ioport.iop_papar &= ~(0x0200);/*
1836 immap->im_ioport.iop_padir |= 0x0200;*/
1837#if 0
1838 immap->im_ioport.iop_pbpar &= ~(0xC000);
1839 immap->im_ioport.iop_pbdir &= ~(0xC000);
1840#endif
1841 /* remove all power */
1842
1843 immap->im_ioport.iop_pcdat |= 0x0400;
1844 immap->im_ioport.iop_padat |= 0x0200;
1845
1846 /*
1847 * Make sure there is a card in the slot, then configure the interface.
1848 */
1849 udelay(10000);
1850 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1851 __LINE__,__FUNCTION__,
1852 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001853 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001854 printf (" No Card found\n");
1855 return (1);
1856 }
1857
1858 /*
1859 * Power On.
1860 */
1861 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1862 reg = pcmp->pcmc_pipr;
1863 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1864 reg,
1865 (reg&PCMCIA_VS1(slot))?"n":"ff",
1866 (reg&PCMCIA_VS2(slot))?"n":"ff");
1867 if ((reg & mask) == mask) {
1868 immap->im_ioport.iop_pcdat &= ~(0x4000);
1869 puts (" 5.0V card found: ");
1870 } else {
1871 immap->im_ioport.iop_padat &= ~(0x0002);
1872 puts (" 3.3V card found: ");
1873 }
1874 immap->im_ioport.iop_pcdir |= 0x0400;
1875 immap->im_ioport.iop_padir |= 0x0200;
1876#if 0
1877 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
1878 cp->cp_pbdir &= ~(0x0020 | 0x0010);
1879 cp->cp_pbpar &= ~(0x0020 | 0x0010);
1880 udelay(500000);
1881#endif
1882 debug ("Enable PCMCIA buffers and stop RESET\n");
1883 reg = PCMCIA_PGCRX(_slot_);
1884 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1885 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1886 PCMCIA_PGCRX(_slot_) = reg;
1887
1888 udelay(250000); /* some cards need >150 ms to come up :-( */
1889
1890 debug ("# hardware_enable done\n");
1891
1892 return (0);
1893}
1894
1895
1896
1897#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1898static int hardware_disable(int slot)
1899{
1900 volatile immap_t *immap;
1901 volatile pcmconf8xx_t *pcmp;
1902 u_long reg;
1903
1904 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1905
1906 immap = (immap_t *)CFG_IMMR;
1907 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1908
1909 /* remove all power */
1910 immap->im_ioport.iop_pcdat |= 0x0400;
1911 immap->im_ioport.iop_padat |= 0x0200;
1912
1913 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001914 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001915 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001916 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1917 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1918 PCMCIA_PGCRX(_slot_) = reg;
1919
1920 udelay(10000);
1921
1922 return (0);
1923}
1924#endif /* CFG_CMD_PCMCIA */
1925
1926
1927
1928static int voltage_set(int slot, int vcc, int vpp)
1929{
1930 volatile immap_t *immap;
1931 volatile pcmconf8xx_t *pcmp;
1932 u_long reg;
1933
1934 debug ("voltage_set: "
1935 PCMCIA_BOARD_MSG
1936 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1937 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1938
1939 immap = (immap_t *)CFG_IMMR;
1940 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1941 /*
1942 * Disable PCMCIA buffers (isolate the interface)
1943 * and assert RESET signal
1944 */
1945 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001946 reg = PCMCIA_PGCRX(_slot_);
1947 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1948 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001949 PCMCIA_PGCRX(_slot_) = reg;
1950 udelay(500);
1951
1952 /*
1953 * Configure Ports A & C pins for
1954 * 5 Volts Enable and 3 Volts enable,
1955 * Turn off all power
1956 */
1957 debug ("PCMCIA power OFF\n");
1958 immap->im_ioport.iop_pcpar &= ~(0x0400);
1959 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1960 immap->im_ioport.iop_pcdir |= 0x0400;*/
1961
1962 immap->im_ioport.iop_papar &= ~(0x0200);/*
1963 immap->im_ioport.iop_padir |= 0x0200;*/
1964
1965 immap->im_ioport.iop_pcdat |= 0x0400;
1966 immap->im_ioport.iop_padat |= 0x0200;
1967
1968 reg = 0;
1969 switch(vcc) {
1970 case 0: break;
1971 case 33: reg |= 0x0200; break;
1972 case 50: reg |= 0x0400; break;
1973 default: goto done;
1974 }
1975
1976 /* Checking supported voltages */
1977
1978 debug ("PIPR: 0x%x --> %s\n",
1979 pcmp->pcmc_pipr,
1980 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1981
1982 if (reg & 0x0200)
1983 immap->im_ioport.iop_pcdat &= !reg;
1984 if (reg & 0x0400)
1985 immap->im_ioport.iop_padat &= !reg;
wdenk1f53a412002-12-04 23:39:58 +00001986 immap->im_ioport.iop_pcdir |= 0x0200;
1987 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00001988 if (reg) {
1989 debug ("PCMCIA powered at %sV\n",
1990 (reg&0x0400) ? "5.0" : "3.3");
1991 } else {
1992 debug ("PCMCIA powered down\n");
1993 }
1994
1995done:
1996 debug ("Enable PCMCIA buffers and stop RESET\n");
1997 reg = PCMCIA_PGCRX(_slot_);
1998 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1999 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2000 PCMCIA_PGCRX(_slot_) = reg;
2001 udelay(500);
2002
2003 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2004 slot+'A');
2005 return (0);
2006}
2007
2008#endif /* R360MPI */
2009
wdenk1f53a412002-12-04 23:39:58 +00002010/* -------------------------------------------------------------------- */
2011/* KUP4K Board */
2012/* -------------------------------------------------------------------- */
wdenk56f94be2002-11-05 16:35:14 +00002013#if defined(CONFIG_KUP4K)
2014
2015#define PCMCIA_BOARD_MSG "KUP4K"
2016
2017#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2018
2019static int hardware_enable(int slot)
2020{
2021 volatile immap_t *immap;
2022 volatile cpm8xx_t *cp;
2023 volatile pcmconf8xx_t *pcmp;
2024 volatile sysconf8xx_t *sysp;
2025 uint reg, mask;
2026
2027 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2028
2029 udelay(10000);
2030
2031 immap = (immap_t *)CFG_IMMR;
2032 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2033 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2034 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2035
2036 /*
2037 * Configure SIUMCR to enable PCMCIA port B
2038 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2039 */
2040 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2041
2042 /* clear interrupt state, and disable interrupts */
wdenkea909b72002-11-21 23:11:29 +00002043 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2044 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002045
wdenk56f94be2002-11-05 16:35:14 +00002046 /*
wdenk1f53a412002-12-04 23:39:58 +00002047 * Disable interrupts, DMA, and PCMCIA buffers
2048 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002049 */
2050 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002051 reg = 0;
2052 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2053 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002054 PCMCIA_PGCRX(slot) = reg;
2055 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002056
2057 /*
2058 * Configure Port B pins for
2059 * 3 Volts enable
2060 */
wdenkea909b72002-11-21 23:11:29 +00002061 if (slot) { /* Slot A is built-in */
2062 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2063 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2064 /* remove all power */
2065 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2066 }
wdenk56f94be2002-11-05 16:35:14 +00002067 /*
2068 * Make sure there is a card in the slot, then configure the interface.
2069 */
2070 udelay(10000);
2071 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2072 __LINE__,__FUNCTION__,
2073 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002074 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002075 printf (" No Card found\n");
2076 return (1);
2077 }
2078
2079 /*
2080 * Power On.
2081 */
wdenka6c7ad22002-12-03 21:28:10 +00002082 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002083 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2084 reg = pcmp->pcmc_pipr;
2085 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2086 reg,
2087 (reg&PCMCIA_VS1(slot))?"n":"ff",
2088 (reg&PCMCIA_VS2(slot))?"n":"ff");
2089 if ((reg & mask) == mask) {
2090 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2091 } else {
wdenkea909b72002-11-21 23:11:29 +00002092 if(slot)
2093 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002094 puts (" 3.3V card found: ");
2095 }
2096#if 0
2097 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2098 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2099 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2100 udelay(500000);
2101#endif
2102 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002103 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002104 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2105 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002106 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002107
2108 udelay(250000); /* some cards need >150 ms to come up :-( */
2109
2110 debug ("# hardware_enable done\n");
2111
2112 return (0);
2113}
2114
2115
2116
2117#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2118static int hardware_disable(int slot)
2119{
2120 volatile immap_t *immap;
2121 volatile cpm8xx_t *cp;
2122 volatile pcmconf8xx_t *pcmp;
2123 u_long reg;
2124
2125 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2126
2127 immap = (immap_t *)CFG_IMMR;
2128 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2129 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk1f53a412002-12-04 23:39:58 +00002130
wdenk56f94be2002-11-05 16:35:14 +00002131 /* remove all power */
wdenkea909b72002-11-21 23:11:29 +00002132 if (slot)
2133 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002134
2135 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002136 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002137 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002138 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2139 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002140 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002141
2142 udelay(10000);
2143
2144 return (0);
2145}
2146#endif /* CFG_CMD_PCMCIA */
2147
2148
2149
2150static int voltage_set(int slot, int vcc, int vpp)
2151{
2152 volatile immap_t *immap;
2153 volatile cpm8xx_t *cp;
2154 volatile pcmconf8xx_t *pcmp;
2155 u_long reg;
2156
2157 debug ("voltage_set: " \
2158 PCMCIA_BOARD_MSG \
2159 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2160 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2161
wdenkea909b72002-11-21 23:11:29 +00002162 if (!slot) /* Slot A is not configurable */
2163 return 0;
2164
wdenk56f94be2002-11-05 16:35:14 +00002165 immap = (immap_t *)CFG_IMMR;
2166 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2167 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2168
2169 /*
2170 * Disable PCMCIA buffers (isolate the interface)
2171 * and assert RESET signal
2172 */
2173 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002174 reg = PCMCIA_PGCRX(slot);
2175 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2176 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002177 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002178 udelay(500);
2179
2180 debug ("PCMCIA power OFF\n");
2181 /*
2182 * Configure Port B pins for
2183 * 3 Volts enable
2184 */
2185 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2186 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2187 /* remove all power */
2188 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2189
2190 switch(vcc) {
2191 case 0: break;
2192 case 33:
2193 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2194 debug ("PCMCIA powered at 3.3V\n");
2195 break;
2196 case 50:
2197 debug ("PCMCIA: 5Volt vcc not supported\n");
2198 break;
2199 default:
2200 puts("PCMCIA: vcc not supported");
2201 break;
2202 }
wdenkea909b72002-11-21 23:11:29 +00002203 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002204 /* Checking supported voltages */
2205
2206 debug ("PIPR: 0x%x --> %s\n",
2207 pcmp->pcmc_pipr,
wdenkea909b72002-11-21 23:11:29 +00002208 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002209 ? "only 5 V --> NOT SUPPORTED"
2210 : "can do 3.3V");
2211
2212
2213 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002214 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002215 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2216 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002217 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002218 udelay(500);
2219
2220 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2221 slot+'A');
2222 return (0);
2223}
2224
2225#endif /* KUP4K */
2226
2227
2228
2229
wdenkc6097192002-11-03 00:24:07 +00002230
wdenk1f53a412002-12-04 23:39:58 +00002231/* -------------------------------------------------------------------- */
2232/* End of Board Specific Stuff */
2233/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002234
2235
wdenk1f53a412002-12-04 23:39:58 +00002236/* -------------------------------------------------------------------- */
2237/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2238/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002239
2240/*
2241 * Search this table to see if the windowsize is
2242 * supported...
2243 */
2244
2245#define M8XX_SIZES_NO 32
2246
2247static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2248{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2249 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2250 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2251 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2252
2253 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2254 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2255 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2256 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2257
2258
wdenk1f53a412002-12-04 23:39:58 +00002259/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002260
2261static u_int m8xx_get_graycode(u_int size)
2262{
2263 u_int k;
2264
2265 for (k = 0; k < M8XX_SIZES_NO; k++) {
2266 if(m8xx_size_to_gray[k] == size)
2267 break;
2268 }
2269
2270 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2271 k = -1;
2272
2273 return k;
2274}
2275
wdenk1f53a412002-12-04 23:39:58 +00002276/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002277
2278#if 0
2279static u_int m8xx_get_speed(u_int ns, u_int is_io)
2280{
2281 u_int reg, clocks, psst, psl, psht;
2282
2283 if(!ns) {
2284
2285 /*
2286 * We get called with IO maps setup to 0ns
2287 * if not specified by the user.
2288 * They should be 255ns.
2289 */
2290
2291 if(is_io)
2292 ns = 255;
2293 else
2294 ns = 100; /* fast memory if 0 */
2295 }
2296
2297 /*
2298 * In PSST, PSL, PSHT fields we tell the controller
2299 * timing parameters in CLKOUT clock cycles.
2300 * CLKOUT is the same as GCLK2_50.
2301 */
2302
2303/* how we want to adjust the timing - in percent */
2304
2305#define ADJ 180 /* 80 % longer accesstime - to be sure */
2306
2307 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2308 clocks = (clocks * ADJ) / (100*1000);
2309
2310 if(clocks >= PCMCIA_BMT_LIMIT) {
2311 DEBUG(0, "Max access time limit reached\n");
2312 clocks = PCMCIA_BMT_LIMIT-1;
2313 }
2314
2315 psst = clocks / 7; /* setup time */
2316 psht = clocks / 7; /* hold time */
2317 psl = (clocks * 5) / 7; /* strobe length */
2318
2319 psst += clocks - (psst + psht + psl);
2320
2321 reg = psst << 12;
2322 reg |= psl << 7;
2323 reg |= psht << 16;
2324
2325 return reg;
2326}
2327#endif
2328
wdenk1f53a412002-12-04 23:39:58 +00002329/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002330
2331#ifdef CONFIG_IDE_8xx_PCCARD
2332static void print_funcid (int func)
2333{
2334 puts (indent);
2335 switch (func) {
2336 case CISTPL_FUNCID_MULTI:
2337 puts (" Multi-Function");
2338 break;
2339 case CISTPL_FUNCID_MEMORY:
2340 puts (" Memory");
2341 break;
2342 case CISTPL_FUNCID_SERIAL:
2343 puts (" Serial Port");
2344 break;
2345 case CISTPL_FUNCID_PARALLEL:
2346 puts (" Parallel Port");
2347 break;
2348 case CISTPL_FUNCID_FIXED:
2349 puts (" Fixed Disk");
2350 break;
2351 case CISTPL_FUNCID_VIDEO:
2352 puts (" Video Adapter");
2353 break;
2354 case CISTPL_FUNCID_NETWORK:
2355 puts (" Network Adapter");
2356 break;
2357 case CISTPL_FUNCID_AIMS:
2358 puts (" AIMS Card");
2359 break;
2360 case CISTPL_FUNCID_SCSI:
2361 puts (" SCSI Adapter");
2362 break;
2363 default:
2364 puts (" Unknown");
2365 break;
2366 }
2367 puts (" Card\n");
2368}
2369#endif /* CONFIG_IDE_8xx_PCCARD */
2370
wdenk1f53a412002-12-04 23:39:58 +00002371/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002372
2373#ifdef CONFIG_IDE_8xx_PCCARD
2374static void print_fixed (volatile uchar *p)
2375{
2376 if (p == NULL)
2377 return;
2378
2379 puts(indent);
2380
2381 switch (*p) {
2382 case CISTPL_FUNCE_IDE_IFACE:
2383 { uchar iface = *(p+2);
2384
2385 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2386 puts (" interface ");
2387 break;
2388 }
2389 case CISTPL_FUNCE_IDE_MASTER:
2390 case CISTPL_FUNCE_IDE_SLAVE:
2391 { uchar f1 = *(p+2);
2392 uchar f2 = *(p+4);
2393
2394 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2395
2396 if (f1 & CISTPL_IDE_UNIQUE)
2397 puts (" [unique]");
2398
2399 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2400
2401 if (f2 & CISTPL_IDE_HAS_SLEEP)
2402 puts (" [sleep]");
2403
2404 if (f2 & CISTPL_IDE_HAS_STANDBY)
2405 puts (" [standby]");
2406
2407 if (f2 & CISTPL_IDE_HAS_IDLE)
2408 puts (" [idle]");
2409
2410 if (f2 & CISTPL_IDE_LOW_POWER)
2411 puts (" [low power]");
2412
2413 if (f2 & CISTPL_IDE_REG_INHIBIT)
2414 puts (" [reg inhibit]");
2415
2416 if (f2 & CISTPL_IDE_HAS_INDEX)
2417 puts (" [index]");
2418
2419 if (f2 & CISTPL_IDE_IOIS16)
2420 puts (" [IOis16]");
2421
2422 break;
2423 }
2424 }
2425 putc ('\n');
2426}
2427#endif /* CONFIG_IDE_8xx_PCCARD */
2428
wdenk1f53a412002-12-04 23:39:58 +00002429/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002430
2431#ifdef CONFIG_IDE_8xx_PCCARD
2432
2433#define MAX_IDENT_CHARS 64
2434#define MAX_IDENT_FIELDS 4
2435
2436static uchar *known_cards[] = {
2437 "ARGOSY PnPIDE D5",
2438 NULL
2439};
2440
2441static int identify (volatile uchar *p)
2442{
2443 uchar id_str[MAX_IDENT_CHARS];
2444 uchar data;
2445 uchar *t;
2446 uchar **card;
2447 int i, done;
2448
2449 if (p == NULL)
2450 return (0); /* Don't know */
2451
2452 t = id_str;
2453 done =0;
2454
2455 for (i=0; i<=4 && !done; ++i, p+=2) {
2456 while ((data = *p) != '\0') {
2457 if (data == 0xFF) {
2458 done = 1;
2459 break;
2460 }
2461 *t++ = data;
2462 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2463 done = 1;
2464 break;
2465 }
2466 p += 2;
2467 }
2468 if (!done)
2469 *t++ = ' ';
2470 }
2471 *t = '\0';
2472 while (--t > id_str) {
2473 if (*t == ' ')
2474 *t = '\0';
2475 else
2476 break;
2477 }
2478 puts (id_str);
2479 putc ('\n');
2480
2481 for (card=known_cards; *card; ++card) {
2482 debug ("## Compare against \"%s\"\n", *card);
2483 if (strcmp(*card, id_str) == 0) { /* found! */
2484 debug ("## CARD FOUND ##\n");
2485 return (1);
2486 }
2487 }
2488
2489 return (0); /* don't know */
2490}
2491#endif /* CONFIG_IDE_8xx_PCCARD */
2492
wdenk1f53a412002-12-04 23:39:58 +00002493/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002494
2495#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */