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 --- |