xref: /netbsd-src/sys/arch/evbarm/gumstix/gxio.c (revision 413d532bcc3f62d122e56d92e13ac64825a40baf)
1 /*	$NetBSD: gxio.c,v 1.20 2012/12/24 06:50:35 kiyohara Exp $ */
2 /*
3  * Copyright (C) 2005, 2006, 2007 WIDE Project and SOUM Corporation.
4  * All rights reserved.
5  *
6  * Written by Takashi Kiyohara and Susumu Miki for WIDE Project and SOUM
7  * Corporation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the name of SOUM Corporation
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT and SOUM CORPORATION ``AS IS''
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT AND SOUM CORPORATION
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: gxio.c,v 1.20 2012/12/24 06:50:35 kiyohara Exp $");
35 
36 #include "opt_cputypes.h"
37 #include "opt_gumstix.h"
38 #include "opt_gxio.h"
39 #if defined(OVERO)
40 #include "opt_omap.h"
41 #endif
42 
43 #include <sys/param.h>
44 #include <sys/device.h>
45 #include <sys/errno.h>
46 #include <sys/kernel.h>
47 
48 #include <sys/systm.h>
49 
50 #include <machine/bootconfig.h>
51 
52 #if defined(OVERO)
53 #include <arm/omap/omap2_gpmcreg.h>
54 #include <arm/omap/omap2_reg.h>
55 #if defined(OMAP3530)
56 #include <arm/omap/omap2_intr.h>
57 #endif
58 #include <arm/omap/omap_var.h>
59 #endif
60 #if defined(CPU_XSCALE_PXA270) || defined(CPU_XSCALE_PXA250)
61 #include <arm/xscale/pxa2x0cpu.h>
62 #endif
63 #include <arm/xscale/pxa2x0reg.h>
64 #include <arm/xscale/pxa2x0var.h>
65 #include <arm/xscale/pxa2x0_gpio.h>
66 #include <evbarm/gumstix/gumstixreg.h>
67 #include <evbarm/gumstix/gumstixvar.h>
68 
69 #include "ioconf.h"
70 #include "locators.h"
71 
72 
73 struct gxioconf {
74 	const char *name;
75 	void (*config)(void);
76 };
77 
78 #if defined(GUMSTIX)
79 static int gxiomatch(device_t, cfdata_t, void *);
80 static void gxioattach(device_t, device_t, void *);
81 static int gxiosearch(device_t, cfdata_t, const int *, void *);
82 static int gxioprint(void *, const char *);
83 
84 CFATTACH_DECL_NEW(gxio, sizeof(struct gxio_softc),
85     gxiomatch, gxioattach, NULL, NULL);
86 #endif
87 
88 void gxio_config_pin(void);
89 void gxio_config_expansion(char *);
90 static void gxio_config_gpio(const struct gxioconf *, char *);
91 #if defined(GUMSTIX)
92 static void basix_config(void);
93 static void cfstix_config(void);
94 static void etherstix_config(void);
95 static void netcf_config(void);
96 static void netcf_vx_config(void);
97 static void netduommc_config(void);
98 static void netduo_config(void);
99 static void netmicrosd_config(void);
100 static void netwifimicrosd_config(void);
101 static void netmmc_config(void);
102 static void wifistix_config(void);
103 static void wifistix_cf_config(void);
104 #elif defined(OVERO)
105 static void eth0_config(void);
106 static void eth1_config(void);
107 static void chestnut_config(void);
108 static void tobi_config(void);
109 static void tobiduo_config(void);
110 #endif
111 
112 #if defined(CPU_XSCALE_PXA250)
113 static struct pxa2x0_gpioconf pxa255dep_gpioconf[] = {
114 	/* Bluetooth module configuration */
115 	{  7, GPIO_OUT | GPIO_SET },	/* power on */
116 	{ 12, GPIO_ALT_FN_1_OUT },	/* 32kHz out. required by SingleStone */
117 
118 	/* AC97 configuration */
119 	{ 29, GPIO_ALT_FN_1_IN },	/* SDATA_IN0 */
120 
121 	/* FFUART configuration */
122 	{ 35, GPIO_ALT_FN_1_IN },	/* CTS */
123 	{ 41, GPIO_ALT_FN_2_OUT },	/* RTS */
124 
125 #ifndef GXIO_BLUETOOTH_ON_HWUART
126 	/* BTUART configuration */
127 	{ 44, GPIO_ALT_FN_1_IN },	/* BTCTS */
128 	{ 45, GPIO_ALT_FN_2_OUT },	/* BTRTS */
129 #else
130 	/* HWUART configuration */
131 	{ 42, GPIO_ALT_FN_3_IN },	/* HWRXD */
132 	{ 43, GPIO_ALT_FN_3_OUT },	/* HWTXD */
133 	{ 44, GPIO_ALT_FN_3_IN },	/* HWCTS */
134 	{ 45, GPIO_ALT_FN_3_OUT },	/* HWRTS */
135 #endif
136 
137 #ifndef GXIO_BLUETOOTH_ON_HWUART
138 	/* HWUART configuration */
139 	{ 48, GPIO_ALT_FN_1_OUT },	/* HWTXD */
140 	{ 49, GPIO_ALT_FN_1_IN },	/* HWRXD */
141 	{ 50, GPIO_ALT_FN_1_IN },	/* HWCTS */
142 	{ 51, GPIO_ALT_FN_1_OUT },	/* HWRTS */
143 #endif
144 
145 	{ -1 }
146 };
147 #endif
148 #if defined(CPU_XSCALE_PXA270)
149 static struct pxa2x0_gpioconf verdexdep_gpioconf[] = {
150 	/* Bluetooth module configuration */
151 	{   9, GPIO_ALT_FN_3_OUT },	/* CHOUT<0> */
152 	{  12, GPIO_OUT | GPIO_SET },
153 
154 	/* LCD configuration */
155 	{  17, GPIO_IN },		/* backlight on */
156 
157 	/* FFUART configuration */
158 	{  34, GPIO_ALT_FN_1_IN },	/* FFRXD */
159 	{  39, GPIO_ALT_FN_2_OUT },	/* FFTXD */
160 
161 	/* BTUART configuration */
162 	{  42, GPIO_ALT_FN_1_IN },	/* BTRXD */
163 	{  43, GPIO_ALT_FN_2_OUT },	/* BTTXD */
164 	{  44, GPIO_ALT_FN_1_IN },	/* BTCTS */
165 	{  45, GPIO_ALT_FN_2_OUT },	/* BTRTS */
166 
167 	/* AC97 configuration */
168 	{  29, GPIO_ALT_FN_1_IN },	/* SDATA_IN0 */
169 
170 	{ -1 }
171 };
172 #endif
173 
174 static const struct gxioconf busheader_conf[] = {
175 #if defined(GUMSTIX)
176 	{ "basix",		basix_config },
177 	{ "cfstix",		cfstix_config },
178 	{ "etherstix",		etherstix_config },
179 	{ "netcf",		netcf_config },
180 	{ "netcf-vx",		netcf_vx_config },
181 	{ "netduo-mmc",		netduommc_config },
182 	{ "netduo",		netduo_config },
183 	{ "netmicrosd",		netmicrosd_config },
184 	{ "netmicrosd-vx",	netmicrosd_config },
185 	{ "netwifimicrosd",	netwifimicrosd_config },
186 	{ "netmmc",		netmmc_config },
187 	{ "netpro-vx",		netwifimicrosd_config },
188 	{ "wifistix-cf",	wifistix_cf_config },
189 	{ "wifistix",		wifistix_config },
190 #elif defined(OVERO)
191 	{ "chestnut43",		chestnut_config },
192 	{ "tobi",		tobi_config },
193 	{ "tobi-duo",		tobiduo_config },
194 #endif
195 	{ NULL }
196 };
197 
198 int gxpcic_gpio_reset;
199 struct gxpcic_slot_irqs gxpcic_slot_irqs[2] = { { 0, -1, -1 }, { 0, -1, -1 } };
200 
201 
202 #if defined(GUMSTIX)
203 /* ARGSUSED */
204 static int
205 gxiomatch(device_t parent, cfdata_t match, void *aux)
206 {
207 
208 	struct pxaip_attach_args *pxa = aux;
209 	bus_space_tag_t iot = &pxa2x0_bs_tag;
210 	bus_space_handle_t ioh;
211 
212 	if (strcmp(pxa->pxa_name, match->cf_name) != 0 ||
213 	    pxa->pxa_addr != PXAIPCF_ADDR_DEFAULT)
214 		 return 0;
215 
216 	if (bus_space_map(iot,
217 	    PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 0, &ioh))
218 		return 0;
219 	bus_space_unmap(iot, ioh, PXA2X0_MEMCTL_SIZE);
220 
221 	/* nothing */
222 	return 1;
223 }
224 
225 /* ARGSUSED */
226 static void
227 gxioattach(device_t parent, device_t self, void *aux)
228 {
229 	struct gxio_softc *sc = device_private(self);
230 
231 	aprint_normal("\n");
232 	aprint_naive("\n");
233 
234 	sc->sc_dev = self;
235 	sc->sc_iot = &pxa2x0_bs_tag;
236 
237 	if (bus_space_map(sc->sc_iot,
238 	    PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 0, &sc->sc_ioh))
239 		return;
240 
241 	/*
242 	 *  Attach each gumstix(busheader)/overo expansion board devices.
243 	 */
244 	config_search_ia(gxiosearch, self, "gxio", NULL);
245 }
246 
247 /* ARGSUSED */
248 static int
249 gxiosearch(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
250 {
251 	struct gxio_softc *sc = device_private(parent);
252 	struct gxio_attach_args gxa;
253 
254 	gxa.gxa_sc = sc;
255 	gxa.gxa_iot = sc->sc_iot;
256 	gxa.gxa_addr = cf->cf_loc[GXIOCF_ADDR];
257 	gxa.gxa_gpirq = cf->cf_loc[GXIOCF_GPIRQ];
258 
259 	if (config_match(parent, cf, &gxa))
260 		config_attach(parent, cf, &gxa, gxioprint);
261 
262 	return 0;
263 }
264 
265 /* ARGSUSED */
266 static int
267 gxioprint(void *aux, const char *name)
268 {
269 	struct gxio_attach_args *gxa = (struct gxio_attach_args *)aux;
270 
271 	if (gxa->gxa_addr != GXIOCF_ADDR_DEFAULT)
272 		printf(" addr 0x%lx", gxa->gxa_addr);
273 	if (gxa->gxa_gpirq > 0)
274 		printf(" gpirq %d", gxa->gxa_gpirq);
275 	return UNCONF;
276 }
277 #endif
278 
279 
280 /*
281  * configure for GPIO pin and expansion boards.
282  */
283 void
284 gxio_config_pin(void)
285 {
286 #if defined(CPU_XSCALE_PXA250)
287 	struct pxa2x0_gpioconf *gumstix_gpioconf[] = {
288 		pxa25x_com_ffuart_gpioconf,
289 		pxa25x_com_stuart_gpioconf,
290 #ifndef GXIO_BLUETOOTH_ON_HWUART
291 		pxa25x_com_btuart_gpioconf,
292 #endif
293 		pxa25x_com_hwuart_gpioconf,
294 		pxa25x_i2c_gpioconf,
295 		pxa25x_pxaacu_gpioconf,
296 		pxa255dep_gpioconf,
297 		NULL
298 	};
299 #endif
300 #if defined(CPU_XSCALE_PXA270)
301 	struct pxa2x0_gpioconf *verdex_gpioconf[] = {
302 		pxa27x_com_ffuart_gpioconf,
303 		pxa27x_com_stuart_gpioconf,
304 		pxa27x_com_btuart_gpioconf,
305 		pxa27x_i2c_gpioconf,
306 		pxa27x_pxaacu_gpioconf,
307 		pxa27x_pxamci_gpioconf,
308 		pxa27x_ohci_gpioconf,
309 		verdexdep_gpioconf,
310 		NULL
311 	};
312 #endif
313 
314 	/* XXX: turn off for power of bluetooth module */
315 #if defined(CPU_XSCALE_PXA250)
316 	pxa2x0_gpio_set_function(7, GPIO_OUT | GPIO_CLR);
317 #elif defined(CPU_XSCALE_PXA270)
318 	pxa2x0_gpio_set_function(12, GPIO_OUT | GPIO_CLR);
319 #endif
320 	delay(100);
321 
322 #if defined(CPU_XSCALE_PXA270) && defined(CPU_XSCALE_PXA250)
323 	pxa2x0_gpio_config(
324 	    (CPU_IS_PXA250) ? gumstix_gpioconf : verdex_gpioconf);
325 #elif defined(CPU_XSCALE_PXA270) || defined(CPU_XSCALE_PXA250)
326 #if defined(CPU_XSCALE_PXA270)
327 	pxa2x0_gpio_config(verdex_gpioconf);
328 #else
329 	pxa2x0_gpio_config(gumstix_gpioconf);
330 #endif
331 #endif
332 }
333 
334 void
335 gxio_config_expansion(char *expansion)
336 {
337 
338 	if (expansion == NULL) {
339 		printf("not specified 'expansion=' in the boot args.\n");
340 #ifdef GXIO_DEFAULT_EXPANSION
341 		printf("configure default expansion (%s)\n",
342 		    GXIO_DEFAULT_EXPANSION);
343 		expansion = __UNCONST(GXIO_DEFAULT_EXPANSION);
344 #else
345 		return;
346 #endif
347 	}
348 	gxio_config_gpio(busheader_conf, expansion);
349 }
350 
351 static void
352 gxio_config_gpio(const struct gxioconf *gxioconflist, char *expansion)
353 {
354 	int i, rv;
355 
356 	for (i = 0; i < strlen(expansion); i++)
357 		expansion[i] = tolower(expansion[i]);
358 	for (i = 0; gxioconflist[i].name != NULL; i++) {
359 		rv = strncmp(expansion, gxioconflist[i].name,
360 		    strlen(gxioconflist[i].name) + 1);
361 		if (rv == 0) {
362 			gxioconflist[i].config();
363 			break;
364 		}
365 	}
366 }
367 
368 
369 #if defined(GUMSTIX)
370 
371 static void
372 basix_config(void)
373 {
374 
375 	pxa2x0_gpio_set_function(8, GPIO_ALT_FN_1_OUT);		/* MMCCS0 */
376 	pxa2x0_gpio_set_function(53, GPIO_ALT_FN_1_OUT);	/* MMCCLK */
377 #if 0
378 	/* this configuration set by gxmci.c::pxamci_attach() */
379 	pxa2x0_gpio_set_function(11, GPIO_IN);			/* nSD_DETECT */
380 	pxa2x0_gpio_set_function(22, GPIO_IN);			/* nSD_WP */
381 #endif
382 }
383 
384 static void
385 cfstix_config(void)
386 {
387 	u_int gpio, npoe_fn;
388 #if defined(CPU_XSCALE_PXA270) && defined(CPU_XSCALE_PXA250)
389 	int bvd = (CPU_IS_PXA250) ? 4 : 111;
390 #else
391 #if defined(CPU_XSCALE_PXA270)
392 	const int bvd = 111;
393 #else
394 	const int bvd = 4;
395 #endif
396 #endif
397 
398 	if (CPU_IS_PXA250) {
399 		gxpcic_slot_irqs[0].valid = 1;
400 		gxpcic_slot_irqs[0].cd = 11;
401 		gxpcic_slot_irqs[0].prdy = 26;
402 		gxpcic_gpio_reset = 8;
403 	} else {
404 		gxpcic_slot_irqs[0].valid = 1;
405 		gxpcic_slot_irqs[0].cd = 104;
406 		gxpcic_slot_irqs[0].prdy = 96;
407 		gxpcic_gpio_reset = 97;
408 	}
409 
410 #if 1
411 	/* PCD/PRDY set by pxa2x0_pcic.c::pxapcic_attach_common() */
412 #else
413 	pxa2x0_gpio_set_function(11, GPIO_IN);		/* PCD1 */
414 	pxa2x0_gpio_set_function(26, GPIO_IN);		/* PRDY1/~IRQ1 */
415 #endif
416 	pxa2x0_gpio_set_function(bvd, GPIO_IN); 	/* BVD1/~STSCHG1 */
417 
418 	for (gpio = 48, npoe_fn = 0; gpio <= 53 ; gpio++)
419 		npoe_fn |= pxa2x0_gpio_get_function(gpio);
420 	npoe_fn &= GPIO_SET;
421 
422 	pxa2x0_gpio_set_function(48, GPIO_ALT_FN_2_OUT | npoe_fn); /* nPOE */
423 	pxa2x0_gpio_set_function(49, GPIO_ALT_FN_2_OUT);	/* nPWE */
424 	pxa2x0_gpio_set_function(50, GPIO_ALT_FN_2_OUT);	/* nPIOR */
425 	pxa2x0_gpio_set_function(51, GPIO_ALT_FN_2_OUT);	/* nPIOW */
426 	if (CPU_IS_PXA250) {
427 		pxa2x0_gpio_set_function(52, GPIO_ALT_FN_2_OUT); /* nPCE1 */
428 		pxa2x0_gpio_set_function(53, GPIO_ALT_FN_2_OUT); /* nPCE2 */
429 		pxa2x0_gpio_set_function(54, GPIO_ALT_FN_2_OUT); /* pSKTSEL */
430 	} else {
431 		pxa2x0_gpio_set_function(102, GPIO_ALT_FN_1_OUT); /* nPCE1 */
432 		pxa2x0_gpio_set_function(105, GPIO_ALT_FN_1_OUT); /* nPCE2 */
433 		pxa2x0_gpio_set_function(79, GPIO_ALT_FN_1_OUT);  /* pSKTSEL */
434 	}
435 	pxa2x0_gpio_set_function(55, GPIO_ALT_FN_2_OUT);	/* nPREG */
436 	pxa2x0_gpio_set_function(56, GPIO_ALT_FN_1_IN);		/* nPWAIT */
437 	pxa2x0_gpio_set_function(57, GPIO_ALT_FN_1_IN);		/* nIOIS16 */
438 }
439 
440 static void
441 etherstix_config(void)
442 {
443 	extern struct cfdata cfdata[];
444 #if defined(CPU_XSCALE_PXA270) && defined(CPU_XSCALE_PXA250)
445 	int rst = (CPU_IS_PXA250) ? 80 : 32;
446 	int irq = (CPU_IS_PXA250) ? 36 : 99;
447 #else
448 #if defined(CPU_XSCALE_PXA270)
449 	const int rst = 32, irq = 99;
450 #else
451 	const int rst = 80, irq = 36;
452 #endif
453 #endif
454 	int i;
455 
456 	pxa2x0_gpio_set_function(49, GPIO_ALT_FN_2_OUT);	/* nPWE */
457 	pxa2x0_gpio_set_function(15, GPIO_ALT_FN_2_OUT);	/* nCS 1 */
458 	pxa2x0_gpio_set_function(rst, GPIO_OUT | GPIO_SET);	/* RESET 1 */
459 	delay(1);
460 	pxa2x0_gpio_set_function(rst, GPIO_OUT | GPIO_CLR);
461 	delay(50000);
462 
463 	for (i = 0; cfdata[i].cf_name != NULL; i++)
464 		if (strcmp(cfdata[i].cf_name, "sm") == 0 &&
465 		    strcmp(cfdata[i].cf_atname, "sm_gxio") == 0 &&
466 		    cfdata[i].cf_loc[GXIOCF_ADDR] == 0x04000300 &&
467 		    cfdata[i].cf_loc[GXIOCF_GPIRQ] == GXIOCF_GPIRQ_DEFAULT)
468 			cfdata[i].cf_loc[GXIOCF_GPIRQ] = irq;
469 }
470 
471 static void
472 netcf_config(void)
473 {
474 
475 	etherstix_config();
476 	cfstix_config();
477 }
478 
479 static void
480 netcf_vx_config(void)
481 {
482 
483 	/*
484 	 * XXXX: More power is necessary for NIC and USB???
485 	 * (no document.  from Linux)
486 	 */
487 
488 	pxa2x0_gpio_set_function(27, GPIO_IN);
489 	pxa2x0_gpio_set_function(107, GPIO_OUT | GPIO_CLR);
490 	pxa2x0_gpio_set_function(118, GPIO_ALT_FN_1_IN | GPIO_CLR);
491 
492 	etherstix_config();
493 	cfstix_config();
494 	if (CPU_IS_PXA270) {
495 		/* Overwrite */
496 		gxpcic_slot_irqs[0].cd = 104;
497 		gxpcic_slot_irqs[0].prdy = 109;
498 		gxpcic_gpio_reset = 110;
499 	};
500 }
501 
502 static void
503 netduommc_config(void)
504 {
505 
506 	netduo_config();
507 	basix_config();
508 }
509 
510 static void
511 netduo_config(void)
512 {
513 
514 	etherstix_config();
515 
516 	pxa2x0_gpio_set_function(78, GPIO_ALT_FN_2_OUT);	/* nCS 2 */
517 	pxa2x0_gpio_set_function(52, GPIO_OUT | GPIO_SET);	/* RESET 2 */
518 	delay(1);
519 	pxa2x0_gpio_set_function(52, GPIO_OUT | GPIO_CLR);
520 	delay(50000);
521 }
522 
523 static void
524 netmicrosd_config(void)
525 {
526 
527 	/* MicroSD(mci) always configure on PXA270 */
528 
529 	pxa2x0_gpio_set_function(49, GPIO_ALT_FN_2_OUT);	/* nPWE */
530 	pxa2x0_gpio_set_function(15, GPIO_ALT_FN_2_OUT);	/* nCS 1 */
531 	pxa2x0_gpio_set_function(107, GPIO_OUT | GPIO_CLR);	/* RESET 1 */
532 	delay(hz / 2);
533 	pxa2x0_gpio_set_function(107, GPIO_OUT | GPIO_SET);
534 	delay(50000);
535 }
536 
537 static void
538 netwifimicrosd_config(void)
539 {
540 
541 	netmicrosd_config();
542 
543 	cfstix_config();
544 	/* However use pxamci. */
545 	pxa2x0_gpio_set_function(111, GPIO_CLR | GPIO_ALT_FN_1_IN);
546 	/* Power to Marvell 88W8385 */
547 	pxa2x0_gpio_set_function(80, GPIO_OUT | GPIO_SET);
548 }
549 
550 static void
551 netmmc_config(void)
552 {
553 
554 	etherstix_config();
555 	basix_config();
556 }
557 
558 static void
559 wifistix_config(void)
560 {
561 
562 	cfstix_config();
563 
564 	/* Power to Marvell 88W8385 */
565 	pxa2x0_gpio_set_function(80, GPIO_OUT | GPIO_SET);
566 }
567 
568 static void
569 wifistix_cf_config(void)
570 {
571 
572 	gxpcic_slot_irqs[1].valid = 1;
573 	gxpcic_slot_irqs[1].cd = 36;
574 	gxpcic_slot_irqs[1].prdy = 27;
575 
576 #if 1
577 	/* this configuration set by pxa2x0_pcic.c::pxapcic_attach_common() */
578 #else
579 	pxa2x0_gpio_set_function(36, GPIO_IN);		/* PCD2 */
580 	pxa2x0_gpio_set_function(27, GPIO_IN);		/* PRDY2/~IRQ2 */
581 #endif
582 	pxa2x0_gpio_set_function(18, GPIO_IN); 		/* BVD2/~STSCHG2 */
583 
584 	cfstix_config();
585 
586 	/* Power to Marvell 88W8385 */
587 	pxa2x0_gpio_set_function(80, GPIO_OUT | GPIO_SET);
588 }
589 
590 #elif defined(OVERO)
591 
592 static void
593 eth0_config(void)
594 {
595 	extern struct cfdata cfdata[];
596 	cfdata_t cf = &cfdata[0];
597 
598 	/*
599 	 * ETH0 connects via CS5.  It use GPIO 176 for IRQ.
600 	 * Also GPIO 64 is NRESET.
601 	 *
602 	 * Basically use current settings by U-Boot.
603 	 * However remap physical address to configured address.
604 	 */
605 
606 	while (cf->cf_name != NULL) {
607 		if (strcmp(cf->cf_name, "smsh") == 0 &&
608 		    cf->cf_loc[GPMCCF_INTR] == PIC_MAXSOURCES + 176)
609 			break;
610 		cf++;
611 	}
612 	if (cf->cf_name == NULL ||
613 	    cf->cf_loc[GPMCCF_ADDR] == GPMCCF_ADDR_DEFAULT)
614 		return;
615 
616 	ioreg_write(OVERO_GPMC_VBASE + GPMC_CONFIG7_5,
617 	    GPMC_CONFIG7_CSVALID |
618 	    GPMC_CONFIG7(GPMC_CONFIG7_MASK_16M, cf->cf_loc[GPMCCF_ADDR]));
619 
620 	/*
621 	 * Maybe need NRESET and delay(9).
622 	 * However delay(9) needs to attach mputmr.
623 	 */
624 }
625 
626 static void
627 eth1_config(void)
628 {
629 	extern struct cfdata cfdata[];
630 	cfdata_t cf = &cfdata[0];
631 
632 	/*
633 	 * ETH1 connects via CS4.  It use GPIO 65 for IRQ.
634 	 *
635 	 * Basically use current settings by U-Boot.
636 	 * However remap physical address to configured address.
637 	 */
638 
639 	while (cf->cf_name != NULL) {
640 		if (strcmp(cf->cf_name, "smsh") == 0 &&
641 		    cf->cf_loc[GPMCCF_INTR] == PIC_MAXSOURCES + 65)
642 			break;
643 		cf++;
644 	}
645 	if (cf->cf_name == NULL ||
646 	    cf->cf_loc[GPMCCF_ADDR] == GPMCCF_ADDR_DEFAULT)
647 		return;
648 
649 	ioreg_write(OVERO_GPMC_VBASE + GPMC_CONFIG7_4,
650 	    GPMC_CONFIG7_CSVALID |
651 	    GPMC_CONFIG7(GPMC_CONFIG7_MASK_16M, cf->cf_loc[GPMCCF_ADDR]));
652 
653 	/* ETH1 is sure to be reset with ETH0. */
654 }
655 
656 static void
657 chestnut_config(void)
658 {
659 
660 	eth0_config();
661 }
662 
663 static void
664 tobi_config(void)
665 {
666 
667 	eth0_config();
668 }
669 
670 static void
671 tobiduo_config(void)
672 {
673 
674 	eth0_config();
675 	eth1_config();
676 }
677 #endif
678