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