Deleted Added
sdiff udiff text old ( 170068 ) new ( 186352 )
full compact
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 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
70#define AVILA_IDE_CTRL 0x06
71
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};
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
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;
160
161 config = ata_getconfig(sa);
162 if (config != NULL) {
163 device_set_desc_copy(dev, config->desc);
164 return 0;
165 }
166 return ENXIO;
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));
174 const struct ata_config *config;
175
176 config = ata_getconfig(sa);
177 KASSERT(config != NULL, ("no board config"));
178
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;
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
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,
222 GPIO_CONF_READ_4(sa, IXP425_GPIO_GPOER) | (1<<config->gpin));
223 /* set interrupt type */
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));
228
229 /* clear ISR */
230 GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPISR, (1<<config->gpin));
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 */
237 EXP_BUS_WRITE_4(sc, config->offalt,
238 EXP_BUS_READ_4(sc, config->offalt) |
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,
243 config->irq, config->irq, 1, RF_ACTIVE);
244 if (!sc->sc_irq)
245 panic("Unable to allocate irq %u.\n", config->irq);
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) {
268 if (nc > 0)
269 device_delete_child(dev, children[0]);
270 free(children, M_TEMP);
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 */
346static __inline void
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
354static __inline void
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 ---