gxio.c revision 1.1 1 /*
2 * Copyright (C) 2005, 2006 WIDE Project and SOUM Corporation.
3 * All rights reserved.
4 *
5 * Written by Takashi Kiyohara and Susumu Miki for WIDE Project and SOUM
6 * Corporation.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the name of SOUM Corporation
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT and SOUM CORPORATION ``AS IS''
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT AND SOUM CORPORATION
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: gxio.c,v 1.1 2006/10/16 16:40:14 kiyohara Exp $");
34
35 #include <sys/param.h>
36 #include <sys/device.h>
37 #include <sys/errno.h>
38
39 #include <sys/systm.h>
40
41 #include <machine/bootconfig.h>
42
43 #include <arm/xscale/pxa2x0cpu.h>
44 #include <arm/xscale/pxa2x0reg.h>
45 #include <arm/xscale/pxa2x0var.h>
46 #include <arm/xscale/pxa2x0_gpio.h>
47 #include <evbarm/gumstix/gumstixvar.h>
48
49 #include "locators.h"
50
51
52 static int gxiomatch(struct device *, struct cfdata *, void *);
53 static void gxioattach(struct device *, struct device *, void *);
54 static int gxiosearch(struct device *, struct cfdata *, const int *, void *);
55 static int gxioprint(void *, const char *);
56
57 static void gxio_config_gpio(struct gxio_softc *);
58 static void cfstix_config(struct gxio_softc *);
59 static void etherstix_config(struct gxio_softc *);
60 static void netcf_config(struct gxio_softc *);
61 static void netduo_config(struct gxio_softc *);
62 static void netmmc_config(struct gxio_softc *);
63
64 CFATTACH_DECL(
65 gxio, sizeof(struct gxio_softc), gxiomatch, gxioattach, NULL, NULL);
66
67 char hirose60p[MAX_BOOT_STRING];
68 char busheader[MAX_BOOT_STRING];
69
70 struct gxioconf {
71 const char *name;
72 void (*config)(struct gxio_softc *);
73 uint32_t searchdrv;
74 };
75
76 static const struct gxioconf hirose60p_conf[] = {
77 { NULL }
78 };
79 static const struct gxioconf busheader_conf[] = {
80 { "cfstix", cfstix_config },
81 { "etherstix", etherstix_config },
82 { "netcf", netcf_config },
83 { "netduo", netduo_config },
84 { "netmmc", netmmc_config },
85 { NULL }
86 };
87
88
89 /* ARGSUSED */
90 static int
91 gxiomatch(struct device *parent, struct cfdata *match, void *aux)
92 {
93 bus_space_tag_t iot = &pxa2x0_bs_tag;
94 bus_space_handle_t ioh;
95
96 if (bus_space_map(iot,
97 PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 0, &ioh))
98 return (0);
99 bus_space_unmap(iot, ioh, PXA2X0_MEMCTL_SIZE);
100
101 /* nothing */
102 return (1);
103 }
104
105 /* ARGSUSED */
106 static void
107 gxioattach(struct device *parent, struct device *self, void *aux)
108 {
109 struct gxio_softc *sc = (struct gxio_softc *)self;
110
111 printf("\n");
112
113 sc->sc_iot = &pxa2x0_bs_tag;
114
115 if (bus_space_map(sc->sc_iot,
116 PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 0, &sc->sc_ioh))
117 return;
118
119 /* configuration for GPIO */
120 gxio_config_gpio(sc);
121
122 /*
123 * Attach each gumstix expantion devices
124 */
125 config_search_ia(gxiosearch, self, "gxio", NULL);
126 }
127
128 /* ARGSUSED */
129 static int
130 gxiosearch(
131 struct device *parent, struct cfdata *cf, const int *ldesc, void *aux)
132 {
133 struct gxio_softc *sc = (struct gxio_softc *)parent;
134 struct gxio_attach_args gxa;
135
136 gxa.gxa_sc = sc;
137 gxa.gxa_iot = sc->sc_iot;
138 gxa.gxa_addr = cf->cf_loc[GXIOCF_ADDR];
139 gxa.gxa_gpirq = cf->cf_loc[GXIOCF_GPIRQ];
140
141 if (config_match(parent, cf, &gxa))
142 config_attach(parent, cf, &gxa, gxioprint);
143
144 return (0);
145 }
146
147 /* ARGSUSED */
148 static int
149 gxioprint(void *aux, const char *name)
150 {
151 struct gxio_attach_args *gxa = (struct gxio_attach_args *)aux;
152
153 if (gxa->gxa_addr != GXIOCF_ADDR_DEFAULT)
154 printf(" addr 0x%lx", gxa->gxa_addr);
155 if (gxa->gxa_gpirq > 0)
156 printf(" gpirq %d", gxa->gxa_gpirq);
157 return (UNCONF);
158 }
159
160
161 /*
162 * configure for expansion boards.
163 */
164 void
165 gxio_config_gpio(struct gxio_softc *sc)
166 {
167 int i, rv;
168
169 for (i = 0; i < strlen(hirose60p); i++)
170 hirose60p[i] = tolower(hirose60p[i]);
171 for (i = 0; hirose60p_conf[i].name != NULL; i++) {
172 rv = strncmp(hirose60p, hirose60p_conf[i].name,
173 strlen(hirose60p_conf[i].name) + 1);
174 if (rv == 0) {
175 hirose60p_conf[i].config(sc);
176 break;
177 }
178 }
179
180 for (i = 0; i < strlen(busheader); i++)
181 busheader[i] = tolower(busheader[i]);
182 for (i = 0; busheader_conf[i].name != NULL; i++) {
183 rv = strncmp(busheader, busheader_conf[i].name,
184 strlen(busheader_conf[i].name) + 1);
185 if (rv == 0) {
186 busheader_conf[i].config(sc);
187 break;
188 }
189 }
190 }
191
192 static void
193 cfstix_config(struct gxio_softc *sc)
194 {
195 u_int gpio, npoe_fn;
196
197 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MEMCTL_MECR,
198 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MEMCTL_MECR) & ~MECR_NOS);
199
200 pxa2x0_gpio_set_function(8, GPIO_OUT | GPIO_SET); /* RESET */
201 delay(50);
202 pxa2x0_gpio_set_function(8, GPIO_OUT | GPIO_CLR);
203
204 pxa2x0_gpio_set_function(4, GPIO_IN); /* nBVD1/nSTSCHG */
205 pxa2x0_gpio_set_function(27, GPIO_IN); /* ~INPACK */
206 pxa2x0_gpio_set_function(11, GPIO_IN); /* nPCD1 */
207 pxa2x0_gpio_set_function(26, GPIO_IN); /* PRDY/IRQ */
208
209 for (gpio = 48, npoe_fn = 0; gpio <= 53 ; gpio++)
210 npoe_fn |= pxa2x0_gpio_get_function(gpio);
211 npoe_fn &= GPIO_SET;
212
213 pxa2x0_gpio_set_function(48, GPIO_ALT_FN_2_OUT | npoe_fn); /* nPOE */
214 pxa2x0_gpio_set_function(49, GPIO_ALT_FN_2_OUT); /* nPWE */
215 pxa2x0_gpio_set_function(50, GPIO_ALT_FN_2_OUT); /* nPIOR */
216 pxa2x0_gpio_set_function(51, GPIO_ALT_FN_2_OUT); /* nPIOW */
217 pxa2x0_gpio_set_function(52, GPIO_ALT_FN_2_OUT); /* nPCE1 */
218 pxa2x0_gpio_set_function(54, GPIO_ALT_FN_2_OUT); /* pSKTSEL */
219 pxa2x0_gpio_set_function(55, GPIO_ALT_FN_2_OUT); /* nPREG */
220 pxa2x0_gpio_set_function(56, GPIO_ALT_FN_1_IN); /* nPWAIT */
221 pxa2x0_gpio_set_function(57, GPIO_ALT_FN_1_IN); /* nIOIS16 */
222 }
223
224 /* ARGSUSED */
225 static void
226 etherstix_config(struct gxio_softc *sc)
227 {
228
229 pxa2x0_gpio_set_function(49, GPIO_ALT_FN_2_OUT); /* nPWE */
230 pxa2x0_gpio_set_function(15, GPIO_ALT_FN_2_OUT); /* nCS 1 */
231 pxa2x0_gpio_set_function(80, GPIO_OUT | GPIO_SET); /* RESET 1 */
232 delay(1);
233 pxa2x0_gpio_set_function(80, GPIO_OUT | GPIO_CLR);
234 delay(50000);
235 }
236
237 static void
238 netcf_config(struct gxio_softc *sc)
239 {
240
241 etherstix_config(sc);
242 cfstix_config(sc);
243 }
244
245 static void
246 netduo_config(struct gxio_softc *sc)
247 {
248
249 etherstix_config(sc);
250
251 pxa2x0_gpio_set_function(78, GPIO_ALT_FN_2_OUT); /* nCS 2 */
252 pxa2x0_gpio_set_function(52, GPIO_OUT | GPIO_SET); /* RESET 2 */
253 delay(1);
254 pxa2x0_gpio_set_function(52, GPIO_OUT | GPIO_CLR);
255 delay(50000);
256 }
257
258 static void
259 netmmc_config(struct gxio_softc *sc)
260 {
261
262 etherstix_config(sc);
263
264 /* mmc not yet... */
265 }
266