Deleted Added
full compact
avila_ata.c (170068) avila_ata.c (186352)
1/*-
2 * Copyright (c) 2006 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 14 unchanged lines hidden (view full) ---

23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2006 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 14 unchanged lines hidden (view full) ---

23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/avila_ata.c 170068 2007-05-28 18:45:16Z jhay $");
31__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/avila_ata.c 186352 2008-12-20 03:26:09Z sam $");
32
33/*
34 * Compact Flash Support for the Avila Gateworks XScale boards.
35 * The CF slot is operated in "True IDE" mode. Registers are on
36 * the Expansion Bus connected to CS1 and CS2. Interrupts are
37 * tied to GPIO pin 12. No DMA, just PIO.
38 *
39 * The ADI Pronghorn Metro is very similar. It use CS3 and CS4 and

--- 22 unchanged lines hidden (view full) ---

62
63#include <sys/ata.h>
64#include <sys/sema.h>
65#include <sys/taskqueue.h>
66#include <vm/uma.h>
67#include <dev/ata/ata-all.h>
68#include <ata_if.h>
69
32
33/*
34 * Compact Flash Support for the Avila Gateworks XScale boards.
35 * The CF slot is operated in "True IDE" mode. Registers are on
36 * the Expansion Bus connected to CS1 and CS2. Interrupts are
37 * tied to GPIO pin 12. No DMA, just PIO.
38 *
39 * The ADI Pronghorn Metro is very similar. It use CS3 and CS4 and

--- 22 unchanged lines hidden (view full) ---

62
63#include <sys/ata.h>
64#include <sys/sema.h>
65#include <sys/taskqueue.h>
66#include <vm/uma.h>
67#include <dev/ata/ata-all.h>
68#include <ata_if.h>
69
70#define AVILA_IDE_GPIN 12 /* GPIO pin # */
71#define AVILA_IDE_IRQ IXP425_INT_GPIO_12
72#define AVILA_IDE_CTRL 0x06 /* control register */
70#define AVILA_IDE_CTRL 0x06
73
71
74#define PRONGHORN_IDE_GPIN 0 /* GPIO pin # */
75#define PRONGHORN_IDE_IRQ IXP425_INT_GPIO_0
76#define PRONGHORN_IDE_CNTRL 0x06 /* control register */
72struct ata_config {
73 const char *desc; /* description for probe */
74 uint8_t gpin; /* GPIO pin */
75 uint8_t irq; /* IRQ */
76 uint32_t base16; /* CS base addr for 16-bit */
77 uint32_t size16; /* CS size for 16-bit */
78 uint32_t off16; /* CS offset for 16-bit */
79 uint32_t basealt; /* CS base addr for alt */
80 uint32_t sizealt; /* CS size for alt */
81 uint32_t offalt; /* CS offset for alt */
82};
77
83
84static const struct ata_config *
85ata_getconfig(struct ixp425_softc *sa)
86{
87 static const struct ata_config configs[] = {
88 { .desc = "Gateworks Avila IDE/CF Controller",
89 .gpin = 12,
90 .irq = IXP425_INT_GPIO_12,
91 .base16 = IXP425_EXP_BUS_CS1_HWBASE,
92 .size16 = IXP425_EXP_BUS_CS1_SIZE,
93 .off16 = EXP_TIMING_CS1_OFFSET,
94 .basealt = IXP425_EXP_BUS_CS2_HWBASE,
95 .sizealt = IXP425_EXP_BUS_CS2_SIZE,
96 .offalt = EXP_TIMING_CS2_OFFSET,
97 },
98 { .desc = "Gateworks Cambria IDE/CF Controller",
99 .gpin = 12,
100 .irq = IXP425_INT_GPIO_12,
101 .base16 = CAMBRIA_CFSEL0_HWBASE,
102 .size16 = CAMBRIA_CFSEL0_SIZE,
103 .off16 = EXP_TIMING_CS3_OFFSET,
104 .basealt = CAMBRIA_CFSEL1_HWBASE,
105 .sizealt = CAMBRIA_CFSEL1_SIZE,
106 .offalt = EXP_TIMING_CS4_OFFSET,
107 },
108 { .desc = "ADI Pronghorn Metro IDE/CF Controller",
109 .gpin = 0,
110 .irq = IXP425_INT_GPIO_0,
111 .base16 = IXP425_EXP_BUS_CS3_HWBASE,
112 .size16 = IXP425_EXP_BUS_CS3_SIZE,
113 .off16 = EXP_TIMING_CS3_OFFSET,
114 .basealt = IXP425_EXP_BUS_CS4_HWBASE,
115 .sizealt = IXP425_EXP_BUS_CS4_SIZE,
116 .offalt = EXP_TIMING_CS4_OFFSET,
117 },
118 };
119
120 /* XXX honor hint? (but then no multi-board support) */
121 /* XXX total hack */
122 if ((cpu_id() & CPU_ID_CPU_MASK) == CPU_ID_IXP435)
123 return &configs[1]; /* Cambria */
124 if (EXP_BUS_READ_4(sa, EXP_TIMING_CS2_OFFSET) != 0)
125 return &configs[0]; /* Avila */
126 return &configs[2]; /* Pronghorn */
127}
128
78struct ata_avila_softc {
79 device_t sc_dev;
80 bus_space_tag_t sc_iot;
81 bus_space_handle_t sc_exp_ioh; /* Exp Bus config registers */
82 bus_space_handle_t sc_ioh; /* CS1/3 data registers */
83 bus_space_handle_t sc_alt_ioh; /* CS2/4 data registers */
84 struct bus_space sc_expbus_tag;
85 struct resource sc_ata; /* hand-crafted for ATA */

--- 14 unchanged lines hidden (view full) ---

100 u_int16_t *, bus_size_t);
101static void ata_bs_wm_2_s(void *, bus_space_handle_t, bus_size_t,
102 const u_int16_t *, bus_size_t);
103
104static int
105ata_avila_probe(device_t dev)
106{
107 struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
129struct ata_avila_softc {
130 device_t sc_dev;
131 bus_space_tag_t sc_iot;
132 bus_space_handle_t sc_exp_ioh; /* Exp Bus config registers */
133 bus_space_handle_t sc_ioh; /* CS1/3 data registers */
134 bus_space_handle_t sc_alt_ioh; /* CS2/4 data registers */
135 struct bus_space sc_expbus_tag;
136 struct resource sc_ata; /* hand-crafted for ATA */

--- 14 unchanged lines hidden (view full) ---

151 u_int16_t *, bus_size_t);
152static void ata_bs_wm_2_s(void *, bus_space_handle_t, bus_size_t,
153 const u_int16_t *, bus_size_t);
154
155static int
156ata_avila_probe(device_t dev)
157{
158 struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
159 const struct ata_config *config;
108
160
109 /* XXX any way to check? */
110 if (EXP_BUS_READ_4(sa, EXP_TIMING_CS2_OFFSET) != 0)
111 device_set_desc_copy(dev, "Gateworks Avila IDE/CF Controller");
112 else
113 device_set_desc_copy(dev,
114 "ADI Pronghorn Metro IDE/CF Controller");
115 return 0;
161 config = ata_getconfig(sa);
162 if (config != NULL) {
163 device_set_desc_copy(dev, config->desc);
164 return 0;
165 }
166 return ENXIO;
116}
117
118static int
119ata_avila_attach(device_t dev)
120{
121 struct ata_avila_softc *sc = device_get_softc(dev);
122 struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
167}
168
169static int
170ata_avila_attach(device_t dev)
171{
172 struct ata_avila_softc *sc = device_get_softc(dev);
173 struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
123 u_int32_t alt_t_off, ide_gpin, ide_irq;
174 const struct ata_config *config;
124
175
176 config = ata_getconfig(sa);
177 KASSERT(config != NULL, ("no board config"));
178
125 sc->sc_dev = dev;
126 /* NB: borrow from parent */
127 sc->sc_iot = sa->sc_iot;
128 sc->sc_exp_ioh = sa->sc_exp_ioh;
179 sc->sc_dev = dev;
180 /* NB: borrow from parent */
181 sc->sc_iot = sa->sc_iot;
182 sc->sc_exp_ioh = sa->sc_exp_ioh;
129 if (EXP_BUS_READ_4(sc, EXP_TIMING_CS2_OFFSET) != 0) {
130 /* Avila board */
131 if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS1_HWBASE,
132 IXP425_EXP_BUS_CS1_SIZE, 0, &sc->sc_ioh))
133 panic("%s: unable to map Expansion Bus CS1 window",
134 __func__);
135 if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS2_HWBASE,
136 IXP425_EXP_BUS_CS2_SIZE, 0, &sc->sc_alt_ioh))
137 panic("%s: unable to map Expansion Bus CS2 window",
138 __func__);
139 ide_gpin = AVILA_IDE_GPIN;
140 ide_irq = AVILA_IDE_IRQ;
141 sc->sc_16bit_off = EXP_TIMING_CS1_OFFSET;
142 alt_t_off = EXP_TIMING_CS2_OFFSET;
143 } else {
144 /* Pronghorn */
145 if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS3_HWBASE,
146 IXP425_EXP_BUS_CS3_SIZE, 0, &sc->sc_ioh))
147 panic("%s: unable to map Expansion Bus CS3 window",
148 __func__);
149 if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS4_HWBASE,
150 IXP425_EXP_BUS_CS4_SIZE, 0, &sc->sc_alt_ioh))
151 panic("%s: unable to map Expansion Bus CS4 window",
152 __func__);
153 ide_gpin = PRONGHORN_IDE_GPIN;
154 ide_irq = PRONGHORN_IDE_IRQ;
155 sc->sc_16bit_off = EXP_TIMING_CS3_OFFSET;
156 alt_t_off = EXP_TIMING_CS4_OFFSET;
157 }
158
183
184 if (bus_space_map(sc->sc_iot, config->base16, config->size16,
185 0, &sc->sc_ioh))
186 panic("%s: cannot map 16-bit window (0x%x/0x%x)",
187 __func__, config->base16, config->size16);
188 if (bus_space_map(sc->sc_iot, config->basealt, config->sizealt,
189 0, &sc->sc_alt_ioh))
190 panic("%s: cannot map alt window (0x%x/0x%x)",
191 __func__, config->basealt, config->sizealt);
192 sc->sc_16bit_off = config->off16;
193
159 /*
160 * Craft special resource for ATA bus space ops
161 * that go through the expansion bus and require
162 * special hackery to ena/dis 16-bit operations.
163 *
164 * XXX probably should just make this generic for
165 * accessing the expansion bus.
166 */

--- 12 unchanged lines hidden (view full) ---

179 sc->sc_expbus_tag.bs_wm_2_s = ata_bs_wm_2_s,
180
181 rman_set_bustag(&sc->sc_ata, &sc->sc_expbus_tag);
182 rman_set_bushandle(&sc->sc_ata, sc->sc_ioh);
183 rman_set_bustag(&sc->sc_alt_ata, &sc->sc_expbus_tag);
184 rman_set_bushandle(&sc->sc_alt_ata, sc->sc_alt_ioh);
185
186 GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPOER,
194 /*
195 * Craft special resource for ATA bus space ops
196 * that go through the expansion bus and require
197 * special hackery to ena/dis 16-bit operations.
198 *
199 * XXX probably should just make this generic for
200 * accessing the expansion bus.
201 */

--- 12 unchanged lines hidden (view full) ---

214 sc->sc_expbus_tag.bs_wm_2_s = ata_bs_wm_2_s,
215
216 rman_set_bustag(&sc->sc_ata, &sc->sc_expbus_tag);
217 rman_set_bushandle(&sc->sc_ata, sc->sc_ioh);
218 rman_set_bustag(&sc->sc_alt_ata, &sc->sc_expbus_tag);
219 rman_set_bushandle(&sc->sc_alt_ata, sc->sc_alt_ioh);
220
221 GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPOER,
187 GPIO_CONF_READ_4(sa, IXP425_GPIO_GPOER) | (1<<ide_gpin));
222 GPIO_CONF_READ_4(sa, IXP425_GPIO_GPOER) | (1<<config->gpin));
188 /* set interrupt type */
223 /* set interrupt type */
189 GPIO_CONF_WRITE_4(sa, GPIO_TYPE_REG(ide_gpin),
190 (GPIO_CONF_READ_4(sa, GPIO_TYPE_REG(ide_gpin)) &~
191 GPIO_TYPE(ide_gpin, GPIO_TYPE_MASK)) |
192 GPIO_TYPE(ide_gpin, GPIO_TYPE_EDG_RISING));
224 GPIO_CONF_WRITE_4(sa, GPIO_TYPE_REG(config->gpin),
225 (GPIO_CONF_READ_4(sa, GPIO_TYPE_REG(config->gpin)) &~
226 GPIO_TYPE(config->gpin, GPIO_TYPE_MASK)) |
227 GPIO_TYPE(config->gpin, GPIO_TYPE_EDG_RISING));
193
194 /* clear ISR */
228
229 /* clear ISR */
195 GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPISR, (1<<ide_gpin));
230 GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPISR, (1<<config->gpin));
196
197 /* configure CS1/3 window, leaving timing unchanged */
198 EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
199 EXP_BUS_READ_4(sc, sc->sc_16bit_off) |
200 EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
201 /* configure CS2/4 window, leaving timing unchanged */
231
232 /* configure CS1/3 window, leaving timing unchanged */
233 EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
234 EXP_BUS_READ_4(sc, sc->sc_16bit_off) |
235 EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
236 /* configure CS2/4 window, leaving timing unchanged */
202 EXP_BUS_WRITE_4(sc, alt_t_off,
203 EXP_BUS_READ_4(sc, alt_t_off) |
237 EXP_BUS_WRITE_4(sc, config->offalt,
238 EXP_BUS_READ_4(sc, config->offalt) |
204 EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
205
206 /* setup interrupt */
207 sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_rid,
239 EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
240
241 /* setup interrupt */
242 sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_rid,
208 ide_irq, ide_irq, 1, RF_ACTIVE);
243 config->irq, config->irq, 1, RF_ACTIVE);
209 if (!sc->sc_irq)
244 if (!sc->sc_irq)
210 panic("Unable to allocate irq %u.\n", ide_irq);
245 panic("Unable to allocate irq %u.\n", config->irq);
211 bus_setup_intr(dev, sc->sc_irq,
212 INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY,
213 NULL, ata_avila_intr, sc, &sc->sc_ih);
214
215 /* attach channel on this controller */
216 device_add_child(dev, "ata", devclass_find_free_unit(ata_devclass, 0));
217 bus_generic_attach(dev);
218

--- 6 unchanged lines hidden (view full) ---

225 struct ata_avila_softc *sc = device_get_softc(dev);
226 device_t *children;
227 int nc;
228
229 /* XXX quiesce gpio? */
230
231 /* detach & delete all children */
232 if (device_get_children(dev, &children, &nc) == 0) {
246 bus_setup_intr(dev, sc->sc_irq,
247 INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY,
248 NULL, ata_avila_intr, sc, &sc->sc_ih);
249
250 /* attach channel on this controller */
251 device_add_child(dev, "ata", devclass_find_free_unit(ata_devclass, 0));
252 bus_generic_attach(dev);
253

--- 6 unchanged lines hidden (view full) ---

260 struct ata_avila_softc *sc = device_get_softc(dev);
261 device_t *children;
262 int nc;
263
264 /* XXX quiesce gpio? */
265
266 /* detach & delete all children */
267 if (device_get_children(dev, &children, &nc) == 0) {
233 if (nc > 0)
234 device_delete_child(dev, children[0]);
235 free(children, M_TEMP);
268 if (nc > 0)
269 device_delete_child(dev, children[0]);
270 free(children, M_TEMP);
236 }
237
238 bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
239 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_irq);
240
241 return 0;
242}
243

--- 59 unchanged lines hidden (view full) ---

303
304/*
305 * Bus space accessors for CF-IDE PIO operations.
306 */
307
308/*
309 * Enable/disable 16-bit ops on the expansion bus.
310 */
271 }
272
273 bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
274 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_irq);
275
276 return 0;
277}
278

--- 59 unchanged lines hidden (view full) ---

338
339/*
340 * Bus space accessors for CF-IDE PIO operations.
341 */
342
343/*
344 * Enable/disable 16-bit ops on the expansion bus.
345 */
311static void __inline
346static __inline void
312enable_16(struct ata_avila_softc *sc)
313{
314 EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
315 EXP_BUS_READ_4(sc, sc->sc_16bit_off) &~ EXP_BYTE_EN);
316 DELAY(100); /* XXX? */
317}
318
347enable_16(struct ata_avila_softc *sc)
348{
349 EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
350 EXP_BUS_READ_4(sc, sc->sc_16bit_off) &~ EXP_BYTE_EN);
351 DELAY(100); /* XXX? */
352}
353
319static void __inline
354static __inline void
320disable_16(struct ata_avila_softc *sc)
321{
322 DELAY(100); /* XXX? */
323 EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
324 EXP_BUS_READ_4(sc, sc->sc_16bit_off) | EXP_BYTE_EN);
325}
326
327uint8_t

--- 196 unchanged lines hidden ---
355disable_16(struct ata_avila_softc *sc)
356{
357 DELAY(100); /* XXX? */
358 EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
359 EXP_BUS_READ_4(sc, sc->sc_16bit_off) | EXP_BYTE_EN);
360}
361
362uint8_t

--- 196 unchanged lines hidden ---