blob: 10ba84c16e923ec9fa737e0e7109822e4dabfd79 [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
wdenk7f70e852003-05-20 14:25:27 +000090#ifndef CONFIG_I82365
wdenkc6097192002-11-03 00:24:07 +000091static u_int m8xx_get_graycode(u_int size);
wdenk7f70e852003-05-20 14:25:27 +000092#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +000093#if 0
94static u_int m8xx_get_speed(u_int ns, u_int is_io);
95#endif
96
wdenk1f53a412002-12-04 23:39:58 +000097/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +000098
99/* look up table for pgcrx registers */
100
101static u_int *pcmcia_pgcrx[2] = {
102 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
103 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
104};
105
106#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
107
wdenk66fd3d12003-05-18 11:30:09 +0000108#endif /* CONFIG_I82365 */
109
110#ifdef CONFIG_IDE_8xx_PCCARD
111static void print_funcid (int func);
112static void print_fixed (volatile uchar *p);
113static int identify (volatile uchar *p);
114static int check_ide_device (int slot);
115#endif /* CONFIG_IDE_8xx_PCCARD */
116
wdenkc6097192002-11-03 00:24:07 +0000117const char *indent = "\t ";
118
wdenk1f53a412002-12-04 23:39:58 +0000119/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000120
121#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
122
123int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
124{
125 int rcode = 0;
126
127 if (argc != 2) {
128 printf ("Usage: pinit {on | off}\n");
129 return 1;
130 }
131 if (strcmp(argv[1],"on") == 0) {
132 rcode = pcmcia_on ();
133 } else if (strcmp(argv[1],"off") == 0) {
134 rcode = pcmcia_off ();
135 } else {
136 printf ("Usage: pinit {on | off}\n");
137 return 1;
138 }
139
140 return rcode;
141}
142#endif /* CFG_CMD_PCMCIA */
143
wdenk1f53a412002-12-04 23:39:58 +0000144/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000145
wdenk66fd3d12003-05-18 11:30:09 +0000146#ifdef CONFIG_I82365
147int pcmcia_on (void)
148{
149 u_int rc;
150
151 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
152
153 rc = i82365_init();
154
155 if (rc == 0)
156 {
157 rc = check_ide_device(0);
158 }
159
160 return (rc);
161}
162#else
163
wdenkc6097192002-11-03 00:24:07 +0000164#if defined(CONFIG_LWMON)
165# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
166#else
167# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
168#endif
169
170int pcmcia_on (void)
171{
172 int i;
173 u_long reg, base;
174 pcmcia_win_t *win;
wdenkea909b72002-11-21 23:11:29 +0000175 u_int slotbit;
176 u_int rc, slot;
wdenkc6097192002-11-03 00:24:07 +0000177
178 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
179
180 /* intialize the fixed memory windows */
181 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
182 base = CFG_PCMCIA_MEM_ADDR;
183
184 if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
185 printf ("Cannot set window size to 0x%08x\n",
186 CFG_PCMCIA_MEM_SIZE);
187 return (1);
188 }
189
wdenkea909b72002-11-21 23:11:29 +0000190 slotbit = PCMCIA_SLOT_x;
wdenkc6097192002-11-03 00:24:07 +0000191 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
192 win->br = base;
193
wdenkea909b72002-11-21 23:11:29 +0000194#if (PCMCIA_SOCKETS_NO == 2)
195 if (i == 4) /* Another slot starting from win 4 */
196 slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
197#endif
wdenkc6097192002-11-03 00:24:07 +0000198 switch (i) {
199#ifdef CONFIG_IDE_8xx_PCCARD
wdenkea909b72002-11-21 23:11:29 +0000200 case 4:
wdenkc6097192002-11-03 00:24:07 +0000201 case 0: { /* map attribute memory */
202 win->or = ( PCMCIA_BSIZE_64M
203 | PCMCIA_PPS_8
204 | PCMCIA_PRS_ATTR
wdenkea909b72002-11-21 23:11:29 +0000205 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000206 | PCMCIA_PV
207 | CFG_PCMCIA_TIMING );
208 break;
209 }
wdenkea909b72002-11-21 23:11:29 +0000210 case 5:
wdenkc6097192002-11-03 00:24:07 +0000211 case 1: { /* map I/O window for data reg */
212 win->or = ( PCMCIA_BSIZE_1K
213 | PCMCIA_PPS_16
214 | PCMCIA_PRS_IO
wdenkea909b72002-11-21 23:11:29 +0000215 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000216 | PCMCIA_PV
217 | CFG_PCMCIA_TIMING );
218 break;
219 }
wdenkea909b72002-11-21 23:11:29 +0000220 case 6:
wdenk1f53a412002-12-04 23:39:58 +0000221 case 2: { /* map I/O window for cmd/ctrl reg block */
wdenkc6097192002-11-03 00:24:07 +0000222 win->or = ( PCMCIA_BSIZE_1K
223 | PCMCIA_PPS_8
224 | PCMCIA_PRS_IO
wdenkea909b72002-11-21 23:11:29 +0000225 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000226 | PCMCIA_PV
227 | CFG_PCMCIA_TIMING );
228 break;
229 }
230#endif /* CONFIG_IDE_8xx_PCCARD */
231 default: /* set to not valid */
232 win->or = 0;
233 break;
234 }
235
236 debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
237 i, win->br, win->or);
238 base += CFG_PCMCIA_MEM_SIZE;
239 ++win;
240 }
241
wdenk1f53a412002-12-04 23:39:58 +0000242 for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
wdenkea909b72002-11-21 23:11:29 +0000243 /* turn off voltage */
244 if ((rc = voltage_set(slot, 0, 0)))
245 continue;
wdenk1f53a412002-12-04 23:39:58 +0000246
wdenkea909b72002-11-21 23:11:29 +0000247 /* Enable external hardware */
248 if ((rc = hardware_enable(slot)))
249 continue;
wdenk1f53a412002-12-04 23:39:58 +0000250
wdenkc6097192002-11-03 00:24:07 +0000251#ifdef CONFIG_IDE_8xx_PCCARD
wdenkea909b72002-11-21 23:11:29 +0000252 if ((rc = check_ide_device(i)))
253 continue;
wdenkc6097192002-11-03 00:24:07 +0000254#endif
wdenkea909b72002-11-21 23:11:29 +0000255 }
256 return (rc);
wdenkc6097192002-11-03 00:24:07 +0000257}
wdenk66fd3d12003-05-18 11:30:09 +0000258#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000259
wdenk1f53a412002-12-04 23:39:58 +0000260/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000261
262#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
263
wdenk66fd3d12003-05-18 11:30:09 +0000264#ifdef CONFIG_I82365
265static int pcmcia_off (void)
266{
267 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
268
269 i82365_exit();
270
271 return 0;
272}
273#else
wdenkc6097192002-11-03 00:24:07 +0000274static int pcmcia_off (void)
275{
276 int i;
277 pcmcia_win_t *win;
278
279 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
280
281 /* clear interrupt state, and disable interrupts */
282 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
283 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
284
285 /* turn off interrupt and disable CxOE */
286 PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
287
288 /* turn off memory windows */
289 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
290
291 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
292 /* disable memory window */
293 win->or = 0;
294 ++win;
295 }
296
297 /* turn off voltage */
298 voltage_set(_slot_, 0, 0);
299
300 /* disable external hardware */
301 printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
302 hardware_disable(_slot_);
303 return 0;
304}
wdenk66fd3d12003-05-18 11:30:09 +0000305#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000306
307#endif /* CFG_CMD_PCMCIA */
308
wdenk1f53a412002-12-04 23:39:58 +0000309/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000310
311#ifdef CONFIG_IDE_8xx_PCCARD
312
313#define MAX_TUPEL_SZ 512
314#define MAX_FEATURES 4
315
wdenk6069ff22003-02-28 00:49:47 +0000316int ide_devices_found;
wdenkea909b72002-11-21 23:11:29 +0000317static int check_ide_device (int slot)
wdenkc6097192002-11-03 00:24:07 +0000318{
319 volatile uchar *ident = NULL;
320 volatile uchar *feature_p[MAX_FEATURES];
wdenkea909b72002-11-21 23:11:29 +0000321 volatile uchar *p, *start, *addr;
wdenkc6097192002-11-03 00:24:07 +0000322 int n_features = 0;
323 uchar func_id = ~0;
324 uchar code, len;
325 ushort config_base = 0;
326 int found = 0;
327 int i;
328
wdenk1f53a412002-12-04 23:39:58 +0000329 addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
330 CFG_PCMCIA_MEM_SIZE * (slot * 4));
wdenkd0fb80c2003-01-11 09:48:40 +0000331 debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
wdenkc6097192002-11-03 00:24:07 +0000332
wdenkea909b72002-11-21 23:11:29 +0000333 start = p = (volatile uchar *) addr;
wdenkc6097192002-11-03 00:24:07 +0000334
335 while ((p - start) < MAX_TUPEL_SZ) {
336
337 code = *p; p += 2;
338
339 if (code == 0xFF) { /* End of chain */
340 break;
341 }
342
343 len = *p; p += 2;
344#if defined(DEBUG) && (DEBUG > 1)
345 { volatile uchar *q = p;
346 printf ("\nTuple code %02x length %d\n\tData:",
347 code, len);
348
349 for (i = 0; i < len; ++i) {
350 printf (" %02x", *q);
351 q+= 2;
352 }
353 }
354#endif /* DEBUG */
355 switch (code) {
356 case CISTPL_VERS_1:
357 ident = p + 4;
358 break;
359 case CISTPL_FUNCID:
360 /* Fix for broken SanDisk which may have 0x80 bit set */
361 func_id = *p & 0x7F;
362 break;
363 case CISTPL_FUNCE:
364 if (n_features < MAX_FEATURES)
365 feature_p[n_features++] = p;
366 break;
367 case CISTPL_CONFIG:
368 config_base = (*(p+6) << 8) + (*(p+4));
369 debug ("\n## Config_base = %04x ###\n", config_base);
370 default:
371 break;
372 }
373 p += 2 * len;
374 }
375
376 found = identify (ident);
377
378 if (func_id != ((uchar)~0)) {
379 print_funcid (func_id);
380
381 if (func_id == CISTPL_FUNCID_FIXED)
382 found = 1;
383 else
384 return (1); /* no disk drive */
385 }
386
387 for (i=0; i<n_features; ++i) {
388 print_fixed (feature_p[i]);
389 }
390
391 if (!found) {
392 printf ("unknown card type\n");
393 return (1);
394 }
395
wdenk6069ff22003-02-28 00:49:47 +0000396 ide_devices_found |= (1 << slot);
397
wdenkc6097192002-11-03 00:24:07 +0000398 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
wdenkea909b72002-11-21 23:11:29 +0000399 *((uchar *)(addr + config_base)) = 1;
wdenkc6097192002-11-03 00:24:07 +0000400
401 return (0);
402}
403#endif /* CONFIG_IDE_8xx_PCCARD */
404
wdenk1f53a412002-12-04 23:39:58 +0000405/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000406
407
wdenk1f53a412002-12-04 23:39:58 +0000408/* -------------------------------------------------------------------- */
409/* board specific stuff: */
410/* voltage_set(), hardware_enable() and hardware_disable() */
411/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000412
wdenk1f53a412002-12-04 23:39:58 +0000413/* -------------------------------------------------------------------- */
414/* RPX Boards from Embedded Planet */
415/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000416
417#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
418
419/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
420 * SYPCR is write once only, therefore must the slowest memory be faster
421 * than the bus monitor or we will get a machine check due to the bus timeout.
422 */
423
424#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
425
426#undef PCMCIA_BMT_LIMIT
427#define PCMCIA_BMT_LIMIT (6*8)
428
429static int voltage_set(int slot, int vcc, int vpp)
430{
431 u_long reg = 0;
432
433 switch(vcc) {
434 case 0: break;
435 case 33: reg |= BCSR1_PCVCTL4; break;
436 case 50: reg |= BCSR1_PCVCTL5; break;
437 default: return 1;
438 }
439
440 switch(vpp) {
441 case 0: break;
442 case 33:
443 case 50:
444 if(vcc == vpp)
445 reg |= BCSR1_PCVCTL6;
446 else
447 return 1;
448 break;
449 case 120:
450 reg |= BCSR1_PCVCTL7;
451 default: return 1;
452 }
453
454 if(vcc == 120)
455 return 1;
456
457 /* first, turn off all power */
458
459 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
460 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
461
462 /* enable new powersettings */
463
464 *((uint *)RPX_CSR_ADDR) |= reg;
465
466 return 0;
467}
468
469#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
470static int hardware_enable (int slot)
471{
472 return 0; /* No hardware to enable */
473}
474#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
475static int hardware_disable(int slot)
476{
477 return 0; /* No hardware to disable */
478}
479#endif /* CFG_CMD_PCMCIA */
480#endif /* CONFIG_RPXCLASSIC */
481
wdenk1f53a412002-12-04 23:39:58 +0000482/* -------------------------------------------------------------------- */
483/* (F)ADS Boards from Motorola */
484/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000485
486#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
487
488#ifdef CONFIG_ADS
489#define PCMCIA_BOARD_MSG "ADS"
490#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
491#else
492#define PCMCIA_BOARD_MSG "FADS"
493#endif
494
495static int voltage_set(int slot, int vcc, int vpp)
496{
497 u_long reg = 0;
498
499 switch(vpp) {
500 case 0: reg = 0; break;
501 case 50: reg = 1; break;
502 case 120: reg = 2; break;
503 default: return 1;
504 }
505
506 switch(vcc) {
507 case 0: reg = 0; break;
508#ifdef CONFIG_ADS
509 case 50: reg = BCSR1_PCCVCCON; break;
510#endif
511#ifdef CONFIG_FADS
512 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
513 case 50: reg = BCSR1_PCCVCC1; break;
514#endif
515 default: return 1;
516 }
517
518 /* first, turn off all power */
519
520#ifdef CONFIG_ADS
521 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
522#endif
523#ifdef CONFIG_FADS
524 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
525#endif
526 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
527
528 /* enable new powersettings */
529
530#ifdef CONFIG_ADS
531 *((uint *)BCSR1) &= ~reg;
532#endif
533#ifdef CONFIG_FADS
534 *((uint *)BCSR1) |= reg;
535#endif
536
537 *((uint *)BCSR1) |= reg << 20;
538
539 return 0;
540}
541
542#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
543
544static int hardware_enable(int slot)
545{
546 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
547 return 0;
548}
549
550#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
551static int hardware_disable(int slot)
552{
553 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
554 return 0;
555}
556#endif /* CFG_CMD_PCMCIA */
557
558#endif /* (F)ADS */
559
wdenk1f53a412002-12-04 23:39:58 +0000560/* -------------------------------------------------------------------- */
561/* TQM8xxL Boards by TQ Components */
wdenkdc7c9a12003-03-26 06:55:25 +0000562/* SC8xx Boards by SinoVee Microsystems */
wdenk1f53a412002-12-04 23:39:58 +0000563/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000564
wdenkdc7c9a12003-03-26 06:55:25 +0000565#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
566
wdenkc6097192002-11-03 00:24:07 +0000567#if defined(CONFIG_TQM8xxL)
wdenkc6097192002-11-03 00:24:07 +0000568#define PCMCIA_BOARD_MSG "TQM8xxL"
wdenkdc7c9a12003-03-26 06:55:25 +0000569#endif
570#if defined(CONFIG_SVM_SC8xx)
571#define PCMCIA_BOARD_MSG "SC8xx"
572#endif
wdenkc6097192002-11-03 00:24:07 +0000573
574static int hardware_enable(int slot)
575{
576 volatile immap_t *immap;
577 volatile cpm8xx_t *cp;
578 volatile pcmconf8xx_t *pcmp;
579 volatile sysconf8xx_t *sysp;
580 uint reg, mask;
581
582 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
583
584 udelay(10000);
585
586 immap = (immap_t *)CFG_IMMR;
587 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
588 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
589 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
590
591 /*
592 * Configure SIUMCR to enable PCMCIA port B
593 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
594 */
595 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
596
597 /* clear interrupt state, and disable interrupts */
598 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
599 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
600
wdenkc6097192002-11-03 00:24:07 +0000601 /*
wdenk1f53a412002-12-04 23:39:58 +0000602 * Disable interrupts, DMA, and PCMCIA buffers
603 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000604 */
605 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000606 reg = 0;
607 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
608 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000609 PCMCIA_PGCRX(_slot_) = reg;
610 udelay(500);
611
612 /*
613 * Configure Port C pins for
614 * 5 Volts Enable and 3 Volts enable
615 */
616 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
617 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
618 /* remove all power */
619
620 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
621
622 /*
623 * Make sure there is a card in the slot, then configure the interface.
624 */
625 udelay(10000);
626 debug ("[%d] %s: PIPR(%p)=0x%x\n",
627 __LINE__,__FUNCTION__,
628 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +0000629 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000630 printf (" No Card found\n");
631 return (1);
632 }
633
634 /*
635 * Power On.
636 */
637 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
638 reg = pcmp->pcmc_pipr;
639 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
640 reg,
641 (reg&PCMCIA_VS1(slot))?"n":"ff",
642 (reg&PCMCIA_VS2(slot))?"n":"ff");
643 if ((reg & mask) == mask) {
644 immap->im_ioport.iop_pcdat |= 0x0004;
645 puts (" 5.0V card found: ");
646 } else {
647 immap->im_ioport.iop_pcdat |= 0x0002;
648 puts (" 3.3V card found: ");
649 }
wdenk1f53a412002-12-04 23:39:58 +0000650 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000651#if 0
652 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
653 cp->cp_pbdir &= ~(0x0020 | 0x0010);
654 cp->cp_pbpar &= ~(0x0020 | 0x0010);
655 udelay(500000);
656#endif
657 udelay(1000);
658 debug ("Enable PCMCIA buffers and stop RESET\n");
659 reg = PCMCIA_PGCRX(_slot_);
660 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
661 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
662 PCMCIA_PGCRX(_slot_) = reg;
663
664 udelay(250000); /* some cards need >150 ms to come up :-( */
665
666 debug ("# hardware_enable done\n");
667
668 return (0);
669}
670
671
672
673#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
674static int hardware_disable(int slot)
675{
676 volatile immap_t *immap;
677 volatile pcmconf8xx_t *pcmp;
678 u_long reg;
679
680 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
681
682 immap = (immap_t *)CFG_IMMR;
683 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
684
685 /* remove all power */
686 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
687
wdenkc6097192002-11-03 00:24:07 +0000688 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000689 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000690 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
691 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
692 PCMCIA_PGCRX(_slot_) = reg;
693
694 udelay(10000);
695
696 return (0);
697}
698#endif /* CFG_CMD_PCMCIA */
699
700
701
702static int voltage_set(int slot, int vcc, int vpp)
703{
704 volatile immap_t *immap;
705 volatile pcmconf8xx_t *pcmp;
706 u_long reg;
707
708 debug ("voltage_set: "
709 PCMCIA_BOARD_MSG
710 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
711 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
712
713 immap = (immap_t *)CFG_IMMR;
714 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
715 /*
716 * Disable PCMCIA buffers (isolate the interface)
717 * and assert RESET signal
718 */
719 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000720 reg = PCMCIA_PGCRX(_slot_);
721 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
722 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000723 PCMCIA_PGCRX(_slot_) = reg;
724 udelay(500);
725
726 /*
727 * Configure Port C pins for
728 * 5 Volts Enable and 3 Volts enable,
729 * Turn off all power
730 */
731 debug ("PCMCIA power OFF\n");
732 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
733 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
734 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
735
736 reg = 0;
737 switch(vcc) {
738 case 0: break;
739 case 33: reg |= 0x0002; break;
740 case 50: reg |= 0x0004; break;
741 default: goto done;
742 }
743
744 /* Checking supported voltages */
745
746 debug ("PIPR: 0x%x --> %s\n",
747 pcmp->pcmc_pipr,
748 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
749
750 immap->im_ioport.iop_pcdat |= reg;
wdenk1f53a412002-12-04 23:39:58 +0000751 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000752 if (reg) {
753 debug ("PCMCIA powered at %sV\n",
754 (reg&0x0004) ? "5.0" : "3.3");
755 } else {
756 debug ("PCMCIA powered down\n");
757 }
758
759done:
760 debug ("Enable PCMCIA buffers and stop RESET\n");
761 reg = PCMCIA_PGCRX(_slot_);
762 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
763 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
764 PCMCIA_PGCRX(_slot_) = reg;
765 udelay(500);
766
767 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
768 slot+'A');
769 return (0);
770}
771
772#endif /* TQM8xxL */
773
774
wdenk1f53a412002-12-04 23:39:58 +0000775/* -------------------------------------------------------------------- */
776/* LWMON Board */
777/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000778
779#if defined(CONFIG_LWMON)
780
781#define PCMCIA_BOARD_MSG "LWMON"
782
783/* #define's for MAX1604 Power Switch */
784#define MAX1604_OP_SUS 0x80
785#define MAX1604_VCCBON 0x40
786#define MAX1604_VCC_35 0x20
787#define MAX1604_VCCBHIZ 0x10
788#define MAX1604_VPPBON 0x08
789#define MAX1604_VPPBPBPGM 0x04
790#define MAX1604_VPPBHIZ 0x02
791/* reserved 0x01 */
792
793static int hardware_enable(int slot)
794{
795 volatile immap_t *immap;
796 volatile cpm8xx_t *cp;
797 volatile pcmconf8xx_t *pcmp;
798 volatile sysconf8xx_t *sysp;
799 uint reg, mask;
800 uchar val;
801
802
803 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
804
805 /* Switch on PCMCIA port in PIC register 0x60 */
806 reg = pic_read (0x60);
807 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
808 reg &= ~0x10;
wdenk1f53a412002-12-04 23:39:58 +0000809 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +0000810 pic_write (0x60, reg);
811#ifdef DEBUG
812 reg = pic_read (0x60);
813 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
814#endif
815 udelay(10000);
816
817 immap = (immap_t *)CFG_IMMR;
818 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
819 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
820 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
821
822 /*
823 * Configure SIUMCR to enable PCMCIA port B
824 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
825 */
826 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
827
828 /* clear interrupt state, and disable interrupts */
829 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
830 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
831
wdenkc6097192002-11-03 00:24:07 +0000832 /*
wdenk1f53a412002-12-04 23:39:58 +0000833 * Disable interrupts, DMA, and PCMCIA buffers
834 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000835 */
836 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000837 reg = 0;
838 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
839 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000840 PCMCIA_PGCRX(_slot_) = reg;
841 udelay(500);
842
843 /*
844 * Make sure there is a card in the slot, then configure the interface.
845 */
846 udelay(10000);
847 debug ("[%d] %s: PIPR(%p)=0x%x\n",
848 __LINE__,__FUNCTION__,
849 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +0000850 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000851 printf (" No Card found\n");
852 return (1);
853 }
854
855 /*
856 * Power On.
857 */
858 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
859 reg = pcmp->pcmc_pipr;
860 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
861 reg,
862 (reg&PCMCIA_VS1(slot))?"n":"ff",
863 (reg&PCMCIA_VS2(slot))?"n":"ff");
864 if ((reg & mask) == mask) {
865 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
866 puts (" 5.0V card found: ");
867 } else {
868 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
869 puts (" 3.3V card found: ");
870 }
871
872 /* switch VCC on */
wdenk1f53a412002-12-04 23:39:58 +0000873 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +0000874 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
875 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
876
877 udelay(500000);
878
879 debug ("Enable PCMCIA buffers and stop RESET\n");
880 reg = PCMCIA_PGCRX(_slot_);
881 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
882 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
883 PCMCIA_PGCRX(_slot_) = reg;
884
885 udelay(250000); /* some cards need >150 ms to come up :-( */
886
887 debug ("# hardware_enable done\n");
888
889 return (0);
890}
891
892
893
894#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
895static int hardware_disable(int slot)
896{
897 volatile immap_t *immap;
898 volatile pcmconf8xx_t *pcmp;
899 u_long reg;
900 uchar val;
901
902 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
903
904 immap = (immap_t *)CFG_IMMR;
905 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
906
907 /* remove all power, put output in high impedance state */
908 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
909 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
910 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
911
912 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +0000913 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000914 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000915 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
916 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
917 PCMCIA_PGCRX(_slot_) = reg;
918
919 /* Switch off PCMCIA port in PIC register 0x60 */
920 reg = pic_read (0x60);
921 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
922 reg |= 0x10;
923 reg &= ~0x08;
924 pic_write (0x60, reg);
925#ifdef DEBUG
926 reg = pic_read (0x60);
927 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
928#endif
929 udelay(10000);
930
931 return (0);
932}
933#endif /* CFG_CMD_PCMCIA */
934
935
936
937static int voltage_set(int slot, int vcc, int vpp)
938{
939 volatile immap_t *immap;
940 volatile pcmconf8xx_t *pcmp;
941 u_long reg;
942 uchar val;
943
944 debug ("voltage_set: "
945 PCMCIA_BOARD_MSG
946 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
947 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
948
949 immap = (immap_t *)CFG_IMMR;
950 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
951 /*
952 * Disable PCMCIA buffers (isolate the interface)
953 * and assert RESET signal
954 */
955 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000956 reg = PCMCIA_PGCRX(_slot_);
957 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
958 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000959 PCMCIA_PGCRX(_slot_) = reg;
960 udelay(500);
961
962 /*
963 * Turn off all power (switch to high impedance)
964 */
965 debug ("PCMCIA power OFF\n");
966 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
967 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
968 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
969
970 val = 0;
971 switch(vcc) {
972 case 0: break;
973 case 33: val = MAX1604_VCC_35; break;
974 case 50: break;
975 default: goto done;
976 }
977
978 /* Checking supported voltages */
979
980 debug ("PIPR: 0x%x --> %s\n",
981 pcmp->pcmc_pipr,
982 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
983
984 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
985 if (val) {
986 debug ("PCMCIA powered at %sV\n",
987 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
988 } else {
989 debug ("PCMCIA powered down\n");
990 }
991
992done:
993 debug ("Enable PCMCIA buffers and stop RESET\n");
994 reg = PCMCIA_PGCRX(_slot_);
995 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
996 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
997 PCMCIA_PGCRX(_slot_) = reg;
998 udelay(500);
999
1000 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1001 slot+'A');
1002 return (0);
1003}
1004
1005#endif /* LWMON */
1006
wdenk1f53a412002-12-04 23:39:58 +00001007/* -------------------------------------------------------------------- */
1008/* GTH board by Corelatus AB */
1009/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001010#if defined(CONFIG_GTH)
1011
1012#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1013
wdenk1f53a412002-12-04 23:39:58 +00001014static int voltage_set (int slot, int vcc, int vpp)
1015{ /* Do nothing */
1016 return 0;
wdenkc6097192002-11-03 00:24:07 +00001017}
1018
1019static int hardware_enable (int slot)
1020{
wdenk1f53a412002-12-04 23:39:58 +00001021 volatile immap_t *immap;
1022 volatile cpm8xx_t *cp;
1023 volatile pcmconf8xx_t *pcmp;
1024 volatile sysconf8xx_t *sysp;
1025 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +00001026
wdenk1f53a412002-12-04 23:39:58 +00001027 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +00001028
wdenk1f53a412002-12-04 23:39:58 +00001029 immap = (immap_t *) CFG_IMMR;
1030 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1031 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1032 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +00001033
wdenk1f53a412002-12-04 23:39:58 +00001034 /* clear interrupt state, and disable interrupts */
1035 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1036 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +00001037
wdenk1f53a412002-12-04 23:39:58 +00001038 /*
1039 * Disable interrupts, DMA, and PCMCIA buffers
1040 * (isolate the interface) and assert RESET signal
1041 */
1042 debug ("Disable PCMCIA buffers and assert RESET\n");
1043 reg = 0;
1044 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1045 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1046 PCMCIA_PGCRX (_slot_) = reg;
1047 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001048
wdenk1f53a412002-12-04 23:39:58 +00001049 /*
1050 * Make sure there is a card in the slot,
1051 * then configure the interface.
1052 */
1053 udelay (10000);
1054 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1055 __LINE__, __FUNCTION__,
1056 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1057 if (pcmp->pcmc_pipr & 0x98000000) {
1058 printf (" No Card found\n");
1059 return (1);
1060 }
wdenkc6097192002-11-03 00:24:07 +00001061
wdenk1f53a412002-12-04 23:39:58 +00001062 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1063 reg = pcmp->pcmc_pipr;
1064 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1065 reg,
1066 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1067 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001068
wdenk1f53a412002-12-04 23:39:58 +00001069 debug ("Enable PCMCIA buffers and stop RESET\n");
1070 reg = PCMCIA_PGCRX (_slot_);
1071 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1072 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1073 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001074
wdenk1f53a412002-12-04 23:39:58 +00001075 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001076
wdenk1f53a412002-12-04 23:39:58 +00001077 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001078
wdenk1f53a412002-12-04 23:39:58 +00001079 return 0;
wdenkc6097192002-11-03 00:24:07 +00001080}
1081#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1082static int hardware_disable(int slot)
1083{
1084 return 0; /* No hardware to disable */
1085}
1086#endif /* CFG_CMD_PCMCIA */
1087#endif /* CONFIG_GTH */
1088
wdenk1f53a412002-12-04 23:39:58 +00001089/* -------------------------------------------------------------------- */
1090/* ICU862 Boards by Cambridge Broadband Ltd. */
1091/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001092
1093#if defined(CONFIG_ICU862)
1094
1095#define PCMCIA_BOARD_MSG "ICU862"
1096
1097static void cfg_port_B (void);
1098
1099static int hardware_enable(int slot)
1100{
1101 volatile immap_t *immap;
1102 volatile cpm8xx_t *cp;
1103 volatile pcmconf8xx_t *pcmp;
1104 volatile sysconf8xx_t *sysp;
1105 uint reg, pipr, mask;
1106 int i;
1107
1108 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1109
1110 udelay(10000);
1111
1112 immap = (immap_t *)CFG_IMMR;
1113 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1114 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1115 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1116
1117 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1118 cfg_port_B ();
1119
1120 /*
1121 * Configure SIUMCR to enable PCMCIA port B
1122 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1123 */
1124 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1125
1126 /* clear interrupt state, and disable interrupts */
1127 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1128 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1129
wdenkc6097192002-11-03 00:24:07 +00001130 /*
wdenk1f53a412002-12-04 23:39:58 +00001131 * Disable interrupts, DMA, and PCMCIA buffers
1132 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001133 */
1134 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001135 reg = 0;
1136 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1137 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001138 PCMCIA_PGCRX(_slot_) = reg;
1139 udelay(500);
1140
1141 /*
1142 * Make sure there is a card in the slot, then configure the interface.
1143 */
1144 udelay(10000);
1145 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1146 __LINE__,__FUNCTION__,
1147 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001148 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001149 printf (" No Card found\n");
1150 return (1);
1151 }
1152
1153 /*
1154 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1155 */
1156 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1157 pipr = pcmp->pcmc_pipr;
1158 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1159 pipr,
1160 (reg&PCMCIA_VS1(slot))?"n":"ff",
1161 (reg&PCMCIA_VS2(slot))?"n":"ff");
1162
1163 reg = cp->cp_pbdat;
1164 if ((pipr & mask) == mask) {
wdenk1f53a412002-12-04 23:39:58 +00001165 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1166 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001167 reg &= ~(TPS2205_VCC5); /* 5V on */
1168 puts (" 5.0V card found: ");
1169 } else {
wdenk1f53a412002-12-04 23:39:58 +00001170 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1171 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001172 reg &= ~(TPS2205_VCC3); /* 3V on */
1173 puts (" 3.3V card found: ");
1174 }
1175
1176 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1177 reg,
1178 (reg & TPS2205_VCC3) ? "off" : "on",
1179 (reg & TPS2205_VCC5) ? "off" : "on",
1180 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1181 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1182
1183 cp->cp_pbdat = reg;
1184
1185 /* Wait 500 ms; use this to check for over-current */
1186 for (i=0; i<5000; ++i) {
1187 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1188 printf (" *** Overcurrent - Safety shutdown ***\n");
1189 cp->cp_pbdat &= ~(TPS2205_SHDN);
1190 return (1);
1191 }
1192 udelay (100);
1193 }
1194
1195 debug ("Enable PCMCIA buffers and stop RESET\n");
1196 reg = PCMCIA_PGCRX(_slot_);
1197 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1198 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1199 PCMCIA_PGCRX(_slot_) = reg;
1200
1201 udelay(250000); /* some cards need >150 ms to come up :-( */
1202
1203 debug ("# hardware_enable done\n");
1204
1205 return (0);
1206}
1207
1208
1209
1210#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1211static int hardware_disable(int slot)
1212{
1213 volatile immap_t *immap;
1214 volatile cpm8xx_t *cp;
1215 volatile pcmconf8xx_t *pcmp;
1216 u_long reg;
1217
1218 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1219
1220 immap = (immap_t *)CFG_IMMR;
1221 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1222 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1223
1224 /* Shut down */
1225 cp->cp_pbdat &= ~(TPS2205_SHDN);
1226
1227 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001228 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001229 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001230 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1231 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1232 PCMCIA_PGCRX(_slot_) = reg;
1233
1234 udelay(10000);
1235
1236 return (0);
1237}
1238#endif /* CFG_CMD_PCMCIA */
1239
1240
1241
1242static int voltage_set(int slot, int vcc, int vpp)
1243{
1244 volatile immap_t *immap;
1245 volatile cpm8xx_t *cp;
1246 volatile pcmconf8xx_t *pcmp;
1247 u_long reg;
1248
1249 debug ("voltage_set: "
1250 PCMCIA_BOARD_MSG
1251 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1252 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1253
1254 immap = (immap_t *)CFG_IMMR;
1255 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1256 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1257 /*
1258 * Disable PCMCIA buffers (isolate the interface)
1259 * and assert RESET signal
1260 */
1261 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001262 reg = PCMCIA_PGCRX(_slot_);
1263 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1264 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001265 PCMCIA_PGCRX(_slot_) = reg;
1266 udelay(500);
1267
1268 /*
1269 * Configure Port C pins for
1270 * 5 Volts Enable and 3 Volts enable,
1271 * Turn all power pins to Hi-Z
1272 */
1273 debug ("PCMCIA power OFF\n");
1274 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1275
1276 reg = cp->cp_pbdat;
1277
1278 switch(vcc) {
1279 case 0: break; /* Switch off */
1280 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1281 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1282 default: goto done;
1283 }
1284
1285 /* Checking supported voltages */
1286
1287 debug ("PIPR: 0x%x --> %s\n",
1288 pcmp->pcmc_pipr,
1289 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1290
1291 cp->cp_pbdat = reg;
1292
1293#ifdef DEBUG
1294 {
1295 char *s;
1296
1297 if ((reg & TPS2205_VCC3) == 0) {
1298 s = "at 3.3V";
1299 } else if ((reg & TPS2205_VCC5) == 0) {
1300 s = "at 5.0V";
1301 } else {
1302 s = "down";
1303 }
1304 printf ("PCMCIA powered %s\n", s);
1305 }
1306#endif
1307
1308done:
1309 debug ("Enable PCMCIA buffers and stop RESET\n");
1310 reg = PCMCIA_PGCRX(_slot_);
1311 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1312 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1313 PCMCIA_PGCRX(_slot_) = reg;
1314 udelay(500);
1315
1316 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1317 slot+'A');
1318 return (0);
1319}
1320
1321static void cfg_port_B (void)
1322{
1323 volatile immap_t *immap;
1324 volatile cpm8xx_t *cp;
1325 uint reg;
1326
1327 immap = (immap_t *)CFG_IMMR;
1328 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1329
1330 /*
1331 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1332 *
1333 * Switch off all voltages, assert shutdown
1334 */
1335 reg = cp->cp_pbdat;
wdenk1f53a412002-12-04 23:39:58 +00001336 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1337 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1338 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001339 cp->cp_pbdat = reg;
1340
1341 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1342
1343 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1344 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1345
1346 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1347 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1348}
1349
1350#endif /* ICU862 */
1351
1352
wdenk1f53a412002-12-04 23:39:58 +00001353/* -------------------------------------------------------------------- */
1354/* C2MON Boards by TTTech Computertechnik AG */
1355/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001356
1357#if defined(CONFIG_C2MON)
1358
1359#define PCMCIA_BOARD_MSG "C2MON"
1360
1361static void cfg_ports (void);
1362
1363static int hardware_enable(int slot)
1364{
1365 volatile immap_t *immap;
1366 volatile cpm8xx_t *cp;
1367 volatile pcmconf8xx_t *pcmp;
1368 volatile sysconf8xx_t *sysp;
1369 uint reg, pipr, mask;
1370 ushort sreg;
1371 int i;
1372
1373 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1374
1375 udelay(10000);
1376
1377 immap = (immap_t *)CFG_IMMR;
1378 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1379 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1380 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1381
1382 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1383 cfg_ports ();
1384
1385 /*
1386 * Configure SIUMCR to enable PCMCIA port B
1387 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1388 */
1389 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1390
1391 /* clear interrupt state, and disable interrupts */
1392 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1393 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1394
wdenkc6097192002-11-03 00:24:07 +00001395 /*
wdenk1f53a412002-12-04 23:39:58 +00001396 * Disable interrupts, DMA, and PCMCIA buffers
1397 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001398 */
1399 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001400 reg = 0;
1401 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1402 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001403 PCMCIA_PGCRX(_slot_) = reg;
1404 udelay(500);
1405
1406 /*
1407 * Make sure there is a card in the slot, then configure the interface.
1408 */
1409 udelay(10000);
1410 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1411 __LINE__,__FUNCTION__,
1412 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001413 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001414 printf (" No Card found\n");
1415 return (1);
1416 }
1417
1418 /*
1419 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1420 */
1421 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1422 pipr = pcmp->pcmc_pipr;
1423 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1424 pipr,
1425 (reg&PCMCIA_VS1(slot))?"n":"ff",
1426 (reg&PCMCIA_VS2(slot))?"n":"ff");
1427
1428 sreg = immap->im_ioport.iop_pcdat;
1429 if ((pipr & mask) == mask) {
1430 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1431 TPS2211_VCCD1); /* 5V on */
1432 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1433 puts (" 5.0V card found: ");
1434 } else {
1435 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1436 TPS2211_VCCD0); /* 3V on */
1437 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1438 puts (" 3.3V card found: ");
1439 }
1440
1441 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1442 sreg,
1443 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1444 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1445 );
1446
1447 immap->im_ioport.iop_pcdat = sreg;
1448
1449 /* Wait 500 ms; use this to check for over-current */
1450 for (i=0; i<5000; ++i) {
1451 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1452 printf (" *** Overcurrent - Safety shutdown ***\n");
1453 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1454 return (1);
1455 }
1456 udelay (100);
1457 }
1458
1459 debug ("Enable PCMCIA buffers and stop RESET\n");
1460 reg = PCMCIA_PGCRX(_slot_);
1461 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1462 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1463 PCMCIA_PGCRX(_slot_) = reg;
1464
1465 udelay(250000); /* some cards need >150 ms to come up :-( */
1466
1467 debug ("# hardware_enable done\n");
1468
1469 return (0);
1470}
1471
1472
1473
1474#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1475static int hardware_disable(int slot)
1476{
1477 volatile immap_t *immap;
1478 volatile cpm8xx_t *cp;
1479 volatile pcmconf8xx_t *pcmp;
1480 u_long reg;
1481
1482 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1483
1484 immap = (immap_t *)CFG_IMMR;
1485 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1486
1487 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001488 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001489 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001490 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1491 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1492 PCMCIA_PGCRX(_slot_) = reg;
1493
1494 /* ALl voltages off / Hi-Z */
1495 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1496 TPS2211_VCCD0 | TPS2211_VCCD1 );
1497
1498 udelay(10000);
1499
1500 return (0);
1501}
1502#endif /* CFG_CMD_PCMCIA */
1503
1504
1505
1506static int voltage_set(int slot, int vcc, int vpp)
1507{
1508 volatile immap_t *immap;
1509 volatile cpm8xx_t *cp;
1510 volatile pcmconf8xx_t *pcmp;
1511 u_long reg;
1512 ushort sreg;
1513
1514 debug ("voltage_set: "
1515 PCMCIA_BOARD_MSG
1516 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1517 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1518
1519 immap = (immap_t *)CFG_IMMR;
1520 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1521 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1522 /*
1523 * Disable PCMCIA buffers (isolate the interface)
1524 * and assert RESET signal
1525 */
1526 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001527 reg = PCMCIA_PGCRX(_slot_);
1528 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1529 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001530 PCMCIA_PGCRX(_slot_) = reg;
1531 udelay(500);
1532
1533 /*
1534 * Configure Port C pins for
1535 * 5 Volts Enable and 3 Volts enable,
1536 * Turn all power pins to Hi-Z
1537 */
1538 debug ("PCMCIA power OFF\n");
1539 cfg_ports (); /* Enables switch, but all in Hi-Z */
1540
1541 sreg = immap->im_ioport.iop_pcdat;
1542 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1543
1544 switch(vcc) {
1545 case 0: break; /* Switch off */
1546 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1547 sreg &= ~TPS2211_VCCD1;
1548 break;
1549 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1550 sreg |= TPS2211_VCCD1;
1551 break;
1552 default: goto done;
1553 }
1554
1555 /* Checking supported voltages */
1556
1557 debug ("PIPR: 0x%x --> %s\n",
1558 pcmp->pcmc_pipr,
1559 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1560
1561 immap->im_ioport.iop_pcdat = sreg;
1562
1563#ifdef DEBUG
1564 {
1565 char *s;
1566
1567 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1568 s = "at 3.3V";
1569 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1570 s = "at 5.0V";
1571 } else {
1572 s = "down";
1573 }
1574 printf ("PCMCIA powered %s\n", s);
1575 }
1576#endif
1577
1578done:
1579 debug ("Enable PCMCIA buffers and stop RESET\n");
1580 reg = PCMCIA_PGCRX(_slot_);
1581 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1582 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1583 PCMCIA_PGCRX(_slot_) = reg;
1584 udelay(500);
1585
1586 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1587 slot+'A');
1588 return (0);
1589}
1590
1591static void cfg_ports (void)
1592{
1593 volatile immap_t *immap;
1594 volatile cpm8xx_t *cp;
1595 ushort sreg;
1596
1597 immap = (immap_t *)CFG_IMMR;
1598 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1599
1600 /*
1601 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1602 *
1603 * Switch off all voltages, assert shutdown
1604 */
1605 sreg = immap->im_ioport.iop_pcdat;
1606 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1607 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1608 immap->im_ioport.iop_pcdat = sreg;
1609
1610 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1611 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1612
1613 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1614 immap->im_ioport.iop_pcpar,
1615 immap->im_ioport.iop_pcdir,
1616 immap->im_ioport.iop_pcdat);
1617
1618 /*
1619 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1620 *
1621 * Over-Current Input only
1622 */
1623 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1624 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1625
1626 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1627 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1628}
1629
1630#endif /* C2MON */
1631
wdenk1f53a412002-12-04 23:39:58 +00001632/* -------------------------------------------------------------------- */
1633/* MBX board from Morotola */
1634/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001635
1636#if defined( CONFIG_MBX )
1637#include <../board/mbx8xx/csr.h>
1638
1639/* A lot of this has been taken from the RPX code in this file it works from me.
1640 I have added the voltage selection for the MBX board. */
1641
1642/* MBX voltage bit in control register #2 */
1643#define CR2_VPP12 ((uchar)0x10)
1644#define CR2_VPPVDD ((uchar)0x20)
1645#define CR2_VDD5 ((uchar)0x40)
1646#define CR2_VDD3 ((uchar)0x80)
1647
1648#define PCMCIA_BOARD_MSG "MBX860"
1649
1650static int voltage_set (int slot, int vcc, int vpp)
1651{
1652 uchar reg = 0;
1653
1654 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1655 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1656
1657 switch (vcc) {
1658 case 0:
1659 break;
1660 case 33:
1661 reg |= CR2_VDD3;
1662 break;
1663 case 50:
1664 reg |= CR2_VDD5;
1665 break;
1666 default:
1667 return 1;
1668 }
1669
1670 switch (vpp) {
1671 case 0:
1672 break;
1673 case 33:
1674 case 50:
1675 if (vcc == vpp) {
1676 reg |= CR2_VPPVDD;
1677 } else {
1678 return 1;
1679 }
1680 break;
1681 case 120:
1682 reg |= CR2_VPP12;
1683 break;
1684 default:
1685 return 1;
1686 }
1687
1688 /* first, turn off all power */
1689 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1690
1691 /* enable new powersettings */
1692 MBX_CSR2 |= reg;
1693 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1694
1695 return (0);
1696}
1697
1698static int hardware_enable (int slot)
1699{
1700 volatile immap_t *immap;
1701 volatile cpm8xx_t *cp;
1702 volatile pcmconf8xx_t *pcmp;
1703 volatile sysconf8xx_t *sysp;
1704 uint reg, mask;
1705
1706 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1707 'A' + slot);
1708
1709 udelay (10000);
1710
1711 immap = (immap_t *) CFG_IMMR;
1712 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1713 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1714 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1715
1716 /* clear interrupt state, and disable interrupts */
1717 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1718 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1719
wdenkc6097192002-11-03 00:24:07 +00001720 /*
wdenk1f53a412002-12-04 23:39:58 +00001721 * Disable interrupts, DMA, and PCMCIA buffers
1722 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001723 */
1724 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001725 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001726 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1727 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1728 PCMCIA_PGCRX (_slot_) = reg;
1729 udelay (500);
1730
1731 /* remove all power */
1732 voltage_set (slot, 0, 0);
1733 /*
1734 * Make sure there is a card in the slot, then configure the interface.
1735 */
wdenkea909b72002-11-21 23:11:29 +00001736 udelay(10000);
1737 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1738 __LINE__,__FUNCTION__,
1739 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1740 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001741 printf (" No Card found\n");
1742 return (1);
1743 }
1744
1745 /*
1746 * Power On.
1747 */
1748 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1749 reg = pcmp->pcmc_pipr;
1750 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1751 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1752 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1753
1754 if ((reg & mask) == mask) {
1755 voltage_set (_slot_, 50, 0);
1756 printf (" 5.0V card found: ");
1757 } else {
1758 voltage_set (_slot_, 33, 0);
1759 printf (" 3.3V card found: ");
1760 }
1761
1762 debug ("Enable PCMCIA buffers and stop RESET\n");
1763 reg = PCMCIA_PGCRX (_slot_);
1764 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1765 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1766 PCMCIA_PGCRX (_slot_) = reg;
1767
1768 udelay (250000); /* some cards need >150 ms to come up :-( */
1769
1770 debug ("# hardware_enable done\n");
1771
1772 return (0);
1773}
1774
1775#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1776static int hardware_disable (int slot)
1777{
1778 return 0; /* No hardware to disable */
1779}
1780#endif /* CFG_CMD_PCMCIA */
1781#endif /* CONFIG_MBX */
wdenk1f53a412002-12-04 23:39:58 +00001782/* -------------------------------------------------------------------- */
1783/* R360MPI Board */
1784/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001785
1786#if defined(CONFIG_R360MPI)
1787
1788#define PCMCIA_BOARD_MSG "R360MPI"
1789
1790
1791static int hardware_enable(int slot)
1792{
1793 volatile immap_t *immap;
1794 volatile cpm8xx_t *cp;
1795 volatile pcmconf8xx_t *pcmp;
1796 volatile sysconf8xx_t *sysp;
1797 uint reg, mask;
1798
1799 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1800
1801 udelay(10000);
1802
1803 immap = (immap_t *)CFG_IMMR;
1804 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1805 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1806 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1807
1808 /*
1809 * Configure SIUMCR to enable PCMCIA port B
1810 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1811 */
1812 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1813
1814 /* clear interrupt state, and disable interrupts */
1815 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1816 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1817
wdenkc6097192002-11-03 00:24:07 +00001818 /*
wdenk1f53a412002-12-04 23:39:58 +00001819 * Disable interrupts, DMA, and PCMCIA buffers
1820 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001821 */
1822 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001823 reg = 0;
1824 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1825 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001826 PCMCIA_PGCRX(_slot_) = reg;
1827 udelay(500);
1828
1829 /*
1830 * Configure Ports A, B & C pins for
1831 * 5 Volts Enable and 3 Volts enable
1832 */
1833 immap->im_ioport.iop_pcpar &= ~(0x0400);
1834 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1835 immap->im_ioport.iop_pcdir |= 0x0400;*/
1836
1837 immap->im_ioport.iop_papar &= ~(0x0200);/*
1838 immap->im_ioport.iop_padir |= 0x0200;*/
1839#if 0
1840 immap->im_ioport.iop_pbpar &= ~(0xC000);
1841 immap->im_ioport.iop_pbdir &= ~(0xC000);
1842#endif
1843 /* remove all power */
1844
1845 immap->im_ioport.iop_pcdat |= 0x0400;
1846 immap->im_ioport.iop_padat |= 0x0200;
1847
1848 /*
1849 * Make sure there is a card in the slot, then configure the interface.
1850 */
1851 udelay(10000);
1852 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1853 __LINE__,__FUNCTION__,
1854 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001855 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001856 printf (" No Card found\n");
1857 return (1);
1858 }
1859
1860 /*
1861 * Power On.
1862 */
1863 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1864 reg = pcmp->pcmc_pipr;
1865 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1866 reg,
1867 (reg&PCMCIA_VS1(slot))?"n":"ff",
1868 (reg&PCMCIA_VS2(slot))?"n":"ff");
1869 if ((reg & mask) == mask) {
1870 immap->im_ioport.iop_pcdat &= ~(0x4000);
1871 puts (" 5.0V card found: ");
1872 } else {
1873 immap->im_ioport.iop_padat &= ~(0x0002);
1874 puts (" 3.3V card found: ");
1875 }
1876 immap->im_ioport.iop_pcdir |= 0x0400;
1877 immap->im_ioport.iop_padir |= 0x0200;
1878#if 0
1879 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
1880 cp->cp_pbdir &= ~(0x0020 | 0x0010);
1881 cp->cp_pbpar &= ~(0x0020 | 0x0010);
1882 udelay(500000);
1883#endif
1884 debug ("Enable PCMCIA buffers and stop RESET\n");
1885 reg = PCMCIA_PGCRX(_slot_);
1886 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1887 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1888 PCMCIA_PGCRX(_slot_) = reg;
1889
1890 udelay(250000); /* some cards need >150 ms to come up :-( */
1891
1892 debug ("# hardware_enable done\n");
1893
1894 return (0);
1895}
1896
1897
1898
1899#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1900static int hardware_disable(int slot)
1901{
1902 volatile immap_t *immap;
1903 volatile pcmconf8xx_t *pcmp;
1904 u_long reg;
1905
1906 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1907
1908 immap = (immap_t *)CFG_IMMR;
1909 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1910
1911 /* remove all power */
1912 immap->im_ioport.iop_pcdat |= 0x0400;
1913 immap->im_ioport.iop_padat |= 0x0200;
1914
1915 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001916 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001917 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001918 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1919 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1920 PCMCIA_PGCRX(_slot_) = reg;
1921
1922 udelay(10000);
1923
1924 return (0);
1925}
1926#endif /* CFG_CMD_PCMCIA */
1927
1928
1929
1930static int voltage_set(int slot, int vcc, int vpp)
1931{
1932 volatile immap_t *immap;
1933 volatile pcmconf8xx_t *pcmp;
1934 u_long reg;
1935
1936 debug ("voltage_set: "
1937 PCMCIA_BOARD_MSG
1938 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1939 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1940
1941 immap = (immap_t *)CFG_IMMR;
1942 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1943 /*
1944 * Disable PCMCIA buffers (isolate the interface)
1945 * and assert RESET signal
1946 */
1947 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001948 reg = PCMCIA_PGCRX(_slot_);
1949 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1950 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001951 PCMCIA_PGCRX(_slot_) = reg;
1952 udelay(500);
1953
1954 /*
1955 * Configure Ports A & C pins for
1956 * 5 Volts Enable and 3 Volts enable,
1957 * Turn off all power
1958 */
1959 debug ("PCMCIA power OFF\n");
1960 immap->im_ioport.iop_pcpar &= ~(0x0400);
1961 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1962 immap->im_ioport.iop_pcdir |= 0x0400;*/
1963
1964 immap->im_ioport.iop_papar &= ~(0x0200);/*
1965 immap->im_ioport.iop_padir |= 0x0200;*/
1966
1967 immap->im_ioport.iop_pcdat |= 0x0400;
1968 immap->im_ioport.iop_padat |= 0x0200;
1969
1970 reg = 0;
1971 switch(vcc) {
1972 case 0: break;
1973 case 33: reg |= 0x0200; break;
1974 case 50: reg |= 0x0400; break;
1975 default: goto done;
1976 }
1977
1978 /* Checking supported voltages */
1979
1980 debug ("PIPR: 0x%x --> %s\n",
1981 pcmp->pcmc_pipr,
1982 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1983
1984 if (reg & 0x0200)
1985 immap->im_ioport.iop_pcdat &= !reg;
1986 if (reg & 0x0400)
1987 immap->im_ioport.iop_padat &= !reg;
wdenk1f53a412002-12-04 23:39:58 +00001988 immap->im_ioport.iop_pcdir |= 0x0200;
1989 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00001990 if (reg) {
1991 debug ("PCMCIA powered at %sV\n",
1992 (reg&0x0400) ? "5.0" : "3.3");
1993 } else {
1994 debug ("PCMCIA powered down\n");
1995 }
1996
1997done:
1998 debug ("Enable PCMCIA buffers and stop RESET\n");
1999 reg = PCMCIA_PGCRX(_slot_);
2000 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2001 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2002 PCMCIA_PGCRX(_slot_) = reg;
2003 udelay(500);
2004
2005 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2006 slot+'A');
2007 return (0);
2008}
2009
2010#endif /* R360MPI */
2011
wdenk1f53a412002-12-04 23:39:58 +00002012/* -------------------------------------------------------------------- */
2013/* KUP4K Board */
2014/* -------------------------------------------------------------------- */
wdenk56f94be2002-11-05 16:35:14 +00002015#if defined(CONFIG_KUP4K)
2016
2017#define PCMCIA_BOARD_MSG "KUP4K"
2018
2019#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2020
2021static int hardware_enable(int slot)
2022{
2023 volatile immap_t *immap;
2024 volatile cpm8xx_t *cp;
2025 volatile pcmconf8xx_t *pcmp;
2026 volatile sysconf8xx_t *sysp;
2027 uint reg, mask;
2028
2029 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2030
2031 udelay(10000);
2032
2033 immap = (immap_t *)CFG_IMMR;
2034 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2035 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2036 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2037
2038 /*
2039 * Configure SIUMCR to enable PCMCIA port B
2040 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2041 */
2042 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2043
2044 /* clear interrupt state, and disable interrupts */
wdenkea909b72002-11-21 23:11:29 +00002045 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2046 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002047
wdenk56f94be2002-11-05 16:35:14 +00002048 /*
wdenk1f53a412002-12-04 23:39:58 +00002049 * Disable interrupts, DMA, and PCMCIA buffers
2050 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002051 */
2052 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002053 reg = 0;
2054 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2055 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002056 PCMCIA_PGCRX(slot) = reg;
2057 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002058
2059 /*
2060 * Configure Port B pins for
2061 * 3 Volts enable
2062 */
wdenkea909b72002-11-21 23:11:29 +00002063 if (slot) { /* Slot A is built-in */
2064 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2065 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2066 /* remove all power */
2067 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2068 }
wdenk56f94be2002-11-05 16:35:14 +00002069 /*
2070 * Make sure there is a card in the slot, then configure the interface.
2071 */
2072 udelay(10000);
2073 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2074 __LINE__,__FUNCTION__,
2075 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002076 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002077 printf (" No Card found\n");
2078 return (1);
2079 }
2080
2081 /*
2082 * Power On.
2083 */
wdenka6c7ad22002-12-03 21:28:10 +00002084 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002085 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2086 reg = pcmp->pcmc_pipr;
2087 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2088 reg,
2089 (reg&PCMCIA_VS1(slot))?"n":"ff",
2090 (reg&PCMCIA_VS2(slot))?"n":"ff");
2091 if ((reg & mask) == mask) {
2092 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2093 } else {
wdenkea909b72002-11-21 23:11:29 +00002094 if(slot)
2095 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002096 puts (" 3.3V card found: ");
2097 }
2098#if 0
2099 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2100 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2101 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2102 udelay(500000);
2103#endif
2104 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002105 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002106 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2107 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002108 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002109
2110 udelay(250000); /* some cards need >150 ms to come up :-( */
2111
2112 debug ("# hardware_enable done\n");
2113
2114 return (0);
2115}
2116
2117
2118
2119#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2120static int hardware_disable(int slot)
2121{
2122 volatile immap_t *immap;
2123 volatile cpm8xx_t *cp;
2124 volatile pcmconf8xx_t *pcmp;
2125 u_long reg;
2126
2127 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2128
2129 immap = (immap_t *)CFG_IMMR;
2130 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2131 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk1f53a412002-12-04 23:39:58 +00002132
wdenk56f94be2002-11-05 16:35:14 +00002133 /* remove all power */
wdenkea909b72002-11-21 23:11:29 +00002134 if (slot)
2135 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002136
2137 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002138 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002139 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002140 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2141 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002142 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002143
2144 udelay(10000);
2145
2146 return (0);
2147}
2148#endif /* CFG_CMD_PCMCIA */
2149
2150
2151
2152static int voltage_set(int slot, int vcc, int vpp)
2153{
2154 volatile immap_t *immap;
2155 volatile cpm8xx_t *cp;
2156 volatile pcmconf8xx_t *pcmp;
2157 u_long reg;
2158
2159 debug ("voltage_set: " \
2160 PCMCIA_BOARD_MSG \
2161 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2162 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2163
wdenkea909b72002-11-21 23:11:29 +00002164 if (!slot) /* Slot A is not configurable */
2165 return 0;
2166
wdenk56f94be2002-11-05 16:35:14 +00002167 immap = (immap_t *)CFG_IMMR;
2168 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2169 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2170
2171 /*
2172 * Disable PCMCIA buffers (isolate the interface)
2173 * and assert RESET signal
2174 */
2175 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002176 reg = PCMCIA_PGCRX(slot);
2177 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2178 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002179 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002180 udelay(500);
2181
2182 debug ("PCMCIA power OFF\n");
2183 /*
2184 * Configure Port B pins for
2185 * 3 Volts enable
2186 */
2187 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2188 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2189 /* remove all power */
2190 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2191
2192 switch(vcc) {
2193 case 0: break;
2194 case 33:
2195 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2196 debug ("PCMCIA powered at 3.3V\n");
2197 break;
2198 case 50:
2199 debug ("PCMCIA: 5Volt vcc not supported\n");
2200 break;
2201 default:
2202 puts("PCMCIA: vcc not supported");
2203 break;
2204 }
wdenkea909b72002-11-21 23:11:29 +00002205 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002206 /* Checking supported voltages */
2207
2208 debug ("PIPR: 0x%x --> %s\n",
2209 pcmp->pcmc_pipr,
wdenkea909b72002-11-21 23:11:29 +00002210 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002211 ? "only 5 V --> NOT SUPPORTED"
2212 : "can do 3.3V");
2213
2214
2215 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002216 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002217 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2218 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002219 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002220 udelay(500);
2221
2222 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2223 slot+'A');
2224 return (0);
2225}
2226
2227#endif /* KUP4K */
2228
2229
2230
2231
wdenkc6097192002-11-03 00:24:07 +00002232
wdenk1f53a412002-12-04 23:39:58 +00002233/* -------------------------------------------------------------------- */
2234/* End of Board Specific Stuff */
2235/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002236
2237
wdenk1f53a412002-12-04 23:39:58 +00002238/* -------------------------------------------------------------------- */
2239/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2240/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002241
2242/*
2243 * Search this table to see if the windowsize is
2244 * supported...
2245 */
2246
2247#define M8XX_SIZES_NO 32
2248
2249static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2250{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2251 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2252 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2253 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2254
2255 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2256 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2257 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2258 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2259
2260
wdenk1f53a412002-12-04 23:39:58 +00002261/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002262
wdenk7f70e852003-05-20 14:25:27 +00002263#ifndef CONFIG_I82365
2264
wdenkc6097192002-11-03 00:24:07 +00002265static u_int m8xx_get_graycode(u_int size)
2266{
2267 u_int k;
2268
2269 for (k = 0; k < M8XX_SIZES_NO; k++) {
2270 if(m8xx_size_to_gray[k] == size)
2271 break;
2272 }
2273
2274 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2275 k = -1;
2276
2277 return k;
2278}
2279
wdenk7f70e852003-05-20 14:25:27 +00002280#endif /* CONFIG_I82365 */
2281
wdenk1f53a412002-12-04 23:39:58 +00002282/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002283
2284#if 0
2285static u_int m8xx_get_speed(u_int ns, u_int is_io)
2286{
2287 u_int reg, clocks, psst, psl, psht;
2288
2289 if(!ns) {
2290
2291 /*
2292 * We get called with IO maps setup to 0ns
2293 * if not specified by the user.
2294 * They should be 255ns.
2295 */
2296
2297 if(is_io)
2298 ns = 255;
2299 else
2300 ns = 100; /* fast memory if 0 */
2301 }
2302
2303 /*
2304 * In PSST, PSL, PSHT fields we tell the controller
2305 * timing parameters in CLKOUT clock cycles.
2306 * CLKOUT is the same as GCLK2_50.
2307 */
2308
2309/* how we want to adjust the timing - in percent */
2310
2311#define ADJ 180 /* 80 % longer accesstime - to be sure */
2312
2313 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2314 clocks = (clocks * ADJ) / (100*1000);
2315
2316 if(clocks >= PCMCIA_BMT_LIMIT) {
2317 DEBUG(0, "Max access time limit reached\n");
2318 clocks = PCMCIA_BMT_LIMIT-1;
2319 }
2320
2321 psst = clocks / 7; /* setup time */
2322 psht = clocks / 7; /* hold time */
2323 psl = (clocks * 5) / 7; /* strobe length */
2324
2325 psst += clocks - (psst + psht + psl);
2326
2327 reg = psst << 12;
2328 reg |= psl << 7;
2329 reg |= psht << 16;
2330
2331 return reg;
2332}
2333#endif
2334
wdenk1f53a412002-12-04 23:39:58 +00002335/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002336
2337#ifdef CONFIG_IDE_8xx_PCCARD
2338static void print_funcid (int func)
2339{
2340 puts (indent);
2341 switch (func) {
2342 case CISTPL_FUNCID_MULTI:
2343 puts (" Multi-Function");
2344 break;
2345 case CISTPL_FUNCID_MEMORY:
2346 puts (" Memory");
2347 break;
2348 case CISTPL_FUNCID_SERIAL:
2349 puts (" Serial Port");
2350 break;
2351 case CISTPL_FUNCID_PARALLEL:
2352 puts (" Parallel Port");
2353 break;
2354 case CISTPL_FUNCID_FIXED:
2355 puts (" Fixed Disk");
2356 break;
2357 case CISTPL_FUNCID_VIDEO:
2358 puts (" Video Adapter");
2359 break;
2360 case CISTPL_FUNCID_NETWORK:
2361 puts (" Network Adapter");
2362 break;
2363 case CISTPL_FUNCID_AIMS:
2364 puts (" AIMS Card");
2365 break;
2366 case CISTPL_FUNCID_SCSI:
2367 puts (" SCSI Adapter");
2368 break;
2369 default:
2370 puts (" Unknown");
2371 break;
2372 }
2373 puts (" Card\n");
2374}
2375#endif /* CONFIG_IDE_8xx_PCCARD */
2376
wdenk1f53a412002-12-04 23:39:58 +00002377/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002378
2379#ifdef CONFIG_IDE_8xx_PCCARD
2380static void print_fixed (volatile uchar *p)
2381{
2382 if (p == NULL)
2383 return;
2384
2385 puts(indent);
2386
2387 switch (*p) {
2388 case CISTPL_FUNCE_IDE_IFACE:
2389 { uchar iface = *(p+2);
2390
2391 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2392 puts (" interface ");
2393 break;
2394 }
2395 case CISTPL_FUNCE_IDE_MASTER:
2396 case CISTPL_FUNCE_IDE_SLAVE:
2397 { uchar f1 = *(p+2);
2398 uchar f2 = *(p+4);
2399
2400 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2401
2402 if (f1 & CISTPL_IDE_UNIQUE)
2403 puts (" [unique]");
2404
2405 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2406
2407 if (f2 & CISTPL_IDE_HAS_SLEEP)
2408 puts (" [sleep]");
2409
2410 if (f2 & CISTPL_IDE_HAS_STANDBY)
2411 puts (" [standby]");
2412
2413 if (f2 & CISTPL_IDE_HAS_IDLE)
2414 puts (" [idle]");
2415
2416 if (f2 & CISTPL_IDE_LOW_POWER)
2417 puts (" [low power]");
2418
2419 if (f2 & CISTPL_IDE_REG_INHIBIT)
2420 puts (" [reg inhibit]");
2421
2422 if (f2 & CISTPL_IDE_HAS_INDEX)
2423 puts (" [index]");
2424
2425 if (f2 & CISTPL_IDE_IOIS16)
2426 puts (" [IOis16]");
2427
2428 break;
2429 }
2430 }
2431 putc ('\n');
2432}
2433#endif /* CONFIG_IDE_8xx_PCCARD */
2434
wdenk1f53a412002-12-04 23:39:58 +00002435/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002436
2437#ifdef CONFIG_IDE_8xx_PCCARD
2438
2439#define MAX_IDENT_CHARS 64
2440#define MAX_IDENT_FIELDS 4
2441
2442static uchar *known_cards[] = {
2443 "ARGOSY PnPIDE D5",
2444 NULL
2445};
2446
2447static int identify (volatile uchar *p)
2448{
2449 uchar id_str[MAX_IDENT_CHARS];
2450 uchar data;
2451 uchar *t;
2452 uchar **card;
2453 int i, done;
2454
2455 if (p == NULL)
2456 return (0); /* Don't know */
2457
2458 t = id_str;
2459 done =0;
2460
2461 for (i=0; i<=4 && !done; ++i, p+=2) {
2462 while ((data = *p) != '\0') {
2463 if (data == 0xFF) {
2464 done = 1;
2465 break;
2466 }
2467 *t++ = data;
2468 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2469 done = 1;
2470 break;
2471 }
2472 p += 2;
2473 }
2474 if (!done)
2475 *t++ = ' ';
2476 }
2477 *t = '\0';
2478 while (--t > id_str) {
2479 if (*t == ' ')
2480 *t = '\0';
2481 else
2482 break;
2483 }
2484 puts (id_str);
2485 putc ('\n');
2486
2487 for (card=known_cards; *card; ++card) {
2488 debug ("## Compare against \"%s\"\n", *card);
2489 if (strcmp(*card, id_str) == 0) { /* found! */
2490 debug ("## CARD FOUND ##\n");
2491 return (1);
2492 }
2493 }
2494
2495 return (0); /* don't know */
2496}
2497#endif /* CONFIG_IDE_8xx_PCCARD */
2498
wdenk1f53a412002-12-04 23:39:58 +00002499/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002500
2501#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */