1 1.2 rkujawa /* $NetBSD: dwcsata.c,v 1.2 2026/06/15 19:21:14 rkujawa Exp $ */ 2 1.1 rkujawa 3 1.1 rkujawa /* 4 1.1 rkujawa * Copyright (c) 2025, 2026 The NetBSD Foundation, Inc. 5 1.1 rkujawa * All rights reserved. 6 1.1 rkujawa * 7 1.1 rkujawa * This code is derived from software contributed to The NetBSD Foundation 8 1.1 rkujawa * by Radoslaw Kujawa. 9 1.1 rkujawa * 10 1.1 rkujawa * Redistribution and use in source and binary forms, with or without 11 1.1 rkujawa * modification, are permitted provided that the following conditions 12 1.1 rkujawa * are met: 13 1.1 rkujawa * 1. Redistributions of source code must retain the above copyright 14 1.1 rkujawa * notice, this list of conditions and the following disclaimer. 15 1.1 rkujawa * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 rkujawa * notice, this list of conditions and the following disclaimer in the 17 1.1 rkujawa * documentation and/or other materials provided with the distribution. 18 1.1 rkujawa * 19 1.1 rkujawa * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 1.1 rkujawa * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 1.1 rkujawa * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 1.1 rkujawa * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 1.1 rkujawa * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 1.1 rkujawa * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 1.1 rkujawa * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 1.1 rkujawa * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 1.1 rkujawa * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 1.1 rkujawa * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 1.1 rkujawa */ 30 1.1 rkujawa 31 1.1 rkujawa /* 32 1.1 rkujawa * 460EX on-chip Synopsys DWC SATA-II host 33 1.1 rkujawa * 34 1.2 rkujawa * SATA PHY shares its SerDes lane with PCIE0; firmware routes 35 1.2 rkujawa * and initializes it. Only one of these can work at a given time. 36 1.2 rkujawa * 37 1.2 rkujawa * DMA support is ugly, we mess with USB host controller schedule enables to 38 1.2 rkujawa * work around the DMAC FIFO. Honestly, this is just papering over the true 39 1.2 rkujawa * issue, which is that the DMAC FIFO drain is starved by the AHB bus-mastering. 40 1.2 rkujawa * Or at least, that's what it looks like, we may never know without an NDA 41 1.2 rkujawa * with company that does not exist anymore. 42 1.2 rkujawa * 43 1.2 rkujawa * The on-chip OHCI and EHCI bus-master their periodic/async schedules on 44 1.2 rkujawa * the shared AHB and starve the SATA DMAC FIFO drain. 45 1.2 rkujawa * 46 1.2 rkujawa * sysctl hw.dwcsata.usb_workaround tries to workaround DMAC stalls by pausing 47 1.2 rkujawa * USB for the duration of each SATA DMA burst: 48 1.2 rkujawa * 1=EHCI periodic 2=EHCI async 4=OHCI; 0=off 7=all 49 1.1 rkujawa * 50 1.2 rkujawa * Note that even with EHCI periodic schedule paused, the async schedule can 51 1.2 rkujawa * still cause stall, so don't be fooled into thinking that DMA is working 52 1.2 rkujawa * stable when USB is enabled. It will break sooner or later, depending on the 53 1.2 rkujawa * USB and SATA traffic. 54 1.2 rkujawa * 55 1.2 rkujawa * The only stable option is to either: 56 1.2 rkujawa * - disable USB entirely - then you can use DWC SATA DMA 57 1.2 rkujawa * - drive DWC SATA in PIO mode - then you can use USB and DWC SATA at the same time 58 1.1 rkujawa */ 59 1.1 rkujawa 60 1.1 rkujawa #include <sys/cdefs.h> 61 1.2 rkujawa __KERNEL_RCSID(0, "$NetBSD: dwcsata.c,v 1.2 2026/06/15 19:21:14 rkujawa Exp $"); 62 1.1 rkujawa 63 1.1 rkujawa #ifdef _KERNEL_OPT 64 1.1 rkujawa #include "opt_dwcsata.h" 65 1.1 rkujawa #endif 66 1.1 rkujawa 67 1.1 rkujawa #include <sys/param.h> 68 1.1 rkujawa #include <sys/systm.h> 69 1.1 rkujawa #include <sys/device.h> 70 1.1 rkujawa #include <sys/extent.h> 71 1.1 rkujawa #include <sys/bus.h> 72 1.2 rkujawa #include <sys/sysctl.h> 73 1.1 rkujawa 74 1.1 rkujawa #include <powerpc/ibm4xx/cpu.h> 75 1.1 rkujawa #include <powerpc/ibm4xx/amcc460ex.h> 76 1.1 rkujawa #include <powerpc/ibm4xx/dev/plbvar.h> 77 1.1 rkujawa #include <powerpc/ibm4xx/dev/dwcsatareg.h> 78 1.1 rkujawa #include <powerpc/ibm4xx/dev/dwcdmacreg.h> 79 1.1 rkujawa 80 1.1 rkujawa #include <dev/ata/atavar.h> 81 1.1 rkujawa #include <dev/ata/atareg.h> 82 1.1 rkujawa #include <dev/ic/wdcreg.h> 83 1.1 rkujawa #include <dev/ic/wdcvar.h> 84 1.1 rkujawa 85 1.1 rkujawa #include "locators.h" 86 1.1 rkujawa 87 1.1 rkujawa /* the DMAC channel wired to the SATA core's handshake interface */ 88 1.1 rkujawa #define DWCSATA_DMACH 0 89 1.1 rkujawa /* 90 1.1 rkujawa * Burst sizing (CTL SRC/DST_MSIZE encoding). 91 1.1 rkujawa */ 92 1.1 rkujawa #define DWCSATA_DMA_MEM_MSIZE 3 /* 16 items = 64 bytes, memory side */ 93 1.1 rkujawa #define DWCSATA_DMA_FIFO_MSIZE 0 /* single DWORD, FIFO side */ 94 1.1 rkujawa /* matching FIFO-side burst in bytes for the SATA core's DBTSR */ 95 1.1 rkujawa #define DWCSATA_DMA_FIFO_BURST 4 /* single DWORD */ 96 1.1 rkujawa /* 97 1.1 rkujawa * Worst case for a MAXPHYS transfer is one LLI per map segment plus 98 1.1 rkujawa * one extra per 8KB FIS boundary split; 64 is comfortably above both. 99 1.1 rkujawa */ 100 1.1 rkujawa #define DWCSATA_NLLI 64 101 1.1 rkujawa 102 1.2 rkujawa #ifndef DWCSATA_PIO_ONLY 103 1.2 rkujawa #define DWCSATA_USB_OFFSET 0x1000 104 1.2 rkujawa #define DWCSATA_USB_SIZE 0x800 105 1.2 rkujawa #define DWCSATA_OHCI_HCCONTROL 0x0004 106 1.2 rkujawa #define DWCSATA_OHCI_PLE 0x00000004 107 1.2 rkujawa #define DWCSATA_OHCI_CLE 0x00000010 108 1.2 rkujawa #define DWCSATA_OHCI_BLE 0x00000020 109 1.2 rkujawa #define DWCSATA_EHCI_CAPLEN 0x0400 /* EHCI base; USBCMD = +CAPLENGTH */ 110 1.2 rkujawa #define DWCSATA_EHCI_PSE 0x00000010 111 1.2 rkujawa #define DWCSATA_EHCI_ASE 0x00000020 112 1.2 rkujawa #define DWCSATA_Q_EHCI_PSE 0x1 113 1.2 rkujawa #define DWCSATA_Q_EHCI_ASE 0x2 114 1.2 rkujawa #define DWCSATA_Q_OHCI 0x4 115 1.2 rkujawa /* SATA PHY soft-reset registers (SDR space), for dwcsata_unwedge() */ 116 1.2 rkujawa #define SATA_PESDR0_L0CDRCTL 0x030a 117 1.2 rkujawa #define SATA_PESDR0_L0DRV 0x030b 118 1.2 rkujawa #define SATA_PESDR0_L0CLK 0x030e 119 1.2 rkujawa #define SATA_PESDR0_PHY_CTL_RST 0x030f 120 1.2 rkujawa #endif 121 1.2 rkujawa 122 1.1 rkujawa struct dwcsata_softc { 123 1.1 rkujawa struct wdc_softc sc_wdcdev; 124 1.1 rkujawa struct ata_channel *sc_chanlist[1]; 125 1.1 rkujawa struct ata_channel sc_channel; 126 1.1 rkujawa struct wdc_regs sc_wdc_regs; 127 1.1 rkujawa 128 1.1 rkujawa bus_space_tag_t sc_iot; 129 1.1 rkujawa bus_space_handle_t sc_ioh; 130 1.1 rkujawa 131 1.1 rkujawa bus_dma_tag_t sc_dmat; 132 1.1 rkujawa int sc_irq; /* for interrupt-driven operation, later */ 133 1.1 rkujawa 134 1.1 rkujawa #ifndef DWCSATA_PIO_ONLY 135 1.1 rkujawa bus_space_handle_t sc_dmac_ioh; /* companion AHB DMAC */ 136 1.1 rkujawa bus_dmamap_t sc_dmamap_xfer; /* current data buffer */ 137 1.1 rkujawa struct dwcdmac_lli *sc_lli; /* uncached LLI table */ 138 1.1 rkujawa bus_addr_t sc_lli_phys; 139 1.1 rkujawa bus_dmamap_t sc_lli_map; 140 1.1 rkujawa bus_dma_segment_t sc_lli_seg; 141 1.1 rkujawa int sc_lli_nseg; 142 1.1 rkujawa uint32_t sc_dmadr_phys; /* AHB address of the DMADR window */ 143 1.1 rkujawa int sc_dma_flags; /* WDC_DMA_* of the loaded transfer */ 144 1.1 rkujawa int sc_dma_nlli; /* LLIs in the loaded chain */ 145 1.1 rkujawa bool sc_dma_loaded; /* sc_dmamap_xfer is loaded */ 146 1.1 rkujawa bool sc_dma_ok; /* resources up, hooks registered */ 147 1.1 rkujawa bool sc_dma_active; /* between dma_start and teardown */ 148 1.2 rkujawa 149 1.2 rkujawa /* USB schedule-quiesce */ 150 1.2 rkujawa bus_space_tag_t sc_usb_iot; 151 1.2 rkujawa bus_space_handle_t sc_usb_ioh; 152 1.2 rkujawa bus_size_t sc_ehci_cmd_off; 153 1.2 rkujawa bool sc_usb_mapped; 154 1.2 rkujawa bool sc_usb_quiesced; 155 1.2 rkujawa bool sc_usb_q_ehci; 156 1.2 rkujawa bool sc_usb_q_ohci; 157 1.2 rkujawa uint32_t sc_usb_ohci_ctl; 158 1.2 rkujawa uint32_t sc_usb_ehci_cmd; 159 1.1 rkujawa #endif 160 1.1 rkujawa }; 161 1.1 rkujawa 162 1.1 rkujawa static int dwcsata_match(device_t, cfdata_t, void *); 163 1.1 rkujawa static void dwcsata_attach(device_t, device_t, void *); 164 1.1 rkujawa static void dwcsata_probe(struct ata_channel *); 165 1.1 rkujawa static void dwcsata_reset(struct ata_channel *, int); 166 1.1 rkujawa 167 1.1 rkujawa #ifndef DWCSATA_PIO_ONLY 168 1.1 rkujawa CTASSERT(sizeof(struct dwcdmac_lli) == 28); 169 1.1 rkujawa 170 1.1 rkujawa static bool dwcsata_dma_setup(device_t, struct dwcsata_softc *, 171 1.1 rkujawa struct plb_attach_args *); 172 1.1 rkujawa static int dwcsata_dma_init(void *, int, int, void *, size_t, int); 173 1.1 rkujawa static void dwcsata_dma_start(void *, int, int); 174 1.1 rkujawa static int dwcsata_dma_finish(void *, int, int, int); 175 1.1 rkujawa static int dwcsata_intr(void *); 176 1.1 rkujawa static int dwcsata_dmac_intr(void *); 177 1.2 rkujawa static void dwcsata_unwedge(struct dwcsata_softc *); 178 1.2 rkujawa static void dwcsata_usb_quiesce(struct dwcsata_softc *); 179 1.2 rkujawa static void dwcsata_usb_restore(struct dwcsata_softc *); 180 1.1 rkujawa #endif 181 1.1 rkujawa 182 1.1 rkujawa CFATTACH_DECL_NEW(dwcsata, sizeof(struct dwcsata_softc), 183 1.1 rkujawa dwcsata_match, dwcsata_attach, NULL, NULL); 184 1.1 rkujawa 185 1.1 rkujawa static struct powerpc_bus_space dwcsata_tag = { 186 1.1 rkujawa _BUS_SPACE_LITTLE_ENDIAN | _BUS_SPACE_MEM_TYPE, 187 1.1 rkujawa 0x00000000, 188 1.1 rkujawa }; 189 1.1 rkujawa static char dwcsata_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8)] 190 1.1 rkujawa __attribute__((aligned(8))); 191 1.1 rkujawa 192 1.2 rkujawa #ifndef DWCSATA_PIO_ONLY 193 1.2 rkujawa /* separate little-endian tag for the OHCI/EHCI host window (below the core) */ 194 1.2 rkujawa static struct powerpc_bus_space dwcsata_usb_tag = { 195 1.2 rkujawa _BUS_SPACE_LITTLE_ENDIAN | _BUS_SPACE_MEM_TYPE, 196 1.2 rkujawa 0x00000000, 197 1.2 rkujawa }; 198 1.2 rkujawa static char dwcsata_usb_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8)] 199 1.2 rkujawa __attribute__((aligned(8))); 200 1.2 rkujawa static int dwcsata_usb_workaround = 0; /* hw.dwcsata.usb_workaround */ 201 1.2 rkujawa #endif 202 1.2 rkujawa 203 1.1 rkujawa static int 204 1.1 rkujawa dwcsata_match(device_t parent, cfdata_t match, void *aux) 205 1.1 rkujawa { 206 1.1 rkujawa struct plb_attach_args *paa = aux; 207 1.1 rkujawa 208 1.1 rkujawa if (strcmp(paa->plb_name, match->cf_name) != 0) 209 1.1 rkujawa return 0; 210 1.1 rkujawa 211 1.1 rkujawa if (match->cf_loc[PLBCF_ADDR] == PLBCF_ADDR_DEFAULT) 212 1.1 rkujawa panic("dwcsata_match: wildcard addr not allowed"); 213 1.1 rkujawa if (match->cf_loc[PLBCF_IRQ] == PLBCF_IRQ_DEFAULT) 214 1.1 rkujawa panic("dwcsata_match: wildcard IRQ not allowed"); 215 1.1 rkujawa 216 1.1 rkujawa paa->plb_addr = match->cf_loc[PLBCF_ADDR]; 217 1.1 rkujawa paa->plb_irq = match->cf_loc[PLBCF_IRQ]; 218 1.1 rkujawa return 1; 219 1.1 rkujawa } 220 1.1 rkujawa 221 1.1 rkujawa #ifndef DWCSATA_PIO_ONLY 222 1.1 rkujawa 223 1.1 rkujawa static inline uint32_t 224 1.1 rkujawa dwcdmac_read(struct dwcsata_softc *sc, bus_size_t reg) 225 1.1 rkujawa { 226 1.1 rkujawa 227 1.1 rkujawa return bus_space_read_4(sc->sc_iot, sc->sc_dmac_ioh, reg); 228 1.1 rkujawa } 229 1.1 rkujawa 230 1.1 rkujawa static inline void 231 1.1 rkujawa dwcdmac_write(struct dwcsata_softc *sc, bus_size_t reg, uint32_t val) 232 1.1 rkujawa { 233 1.1 rkujawa 234 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_dmac_ioh, reg, val); 235 1.1 rkujawa } 236 1.1 rkujawa 237 1.1 rkujawa static void 238 1.1 rkujawa dwcdmac_clear_intrs(struct dwcsata_softc *sc) 239 1.1 rkujawa { 240 1.1 rkujawa 241 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CLEAR_TFR, DWCDMAC_CHANBIT(DWCSATA_DMACH)); 242 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CLEAR_BLOCK, DWCDMAC_CHANBIT(DWCSATA_DMACH)); 243 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CLEAR_SRCTRAN, 244 1.1 rkujawa DWCDMAC_CHANBIT(DWCSATA_DMACH)); 245 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CLEAR_DSTTRAN, 246 1.1 rkujawa DWCDMAC_CHANBIT(DWCSATA_DMACH)); 247 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CLEAR_ERR, DWCDMAC_CHANBIT(DWCSATA_DMACH)); 248 1.1 rkujawa } 249 1.1 rkujawa 250 1.1 rkujawa static bool 251 1.1 rkujawa dwcsata_dma_setup(device_t self, struct dwcsata_softc *sc, 252 1.1 rkujawa struct plb_attach_args *paa) 253 1.1 rkujawa { 254 1.1 rkujawa int error; 255 1.1 rkujawa 256 1.1 rkujawa if (bus_space_map(sc->sc_iot, paa->plb_addr - DWCDMAC_OFFSET, 257 1.1 rkujawa DWCDMAC_SIZE, 0, &sc->sc_dmac_ioh)) { 258 1.1 rkujawa aprint_error_dev(self, "can't map the AHB DMAC\n"); 259 1.1 rkujawa return false; 260 1.1 rkujawa } 261 1.1 rkujawa 262 1.1 rkujawa aprint_debug_dev(self, "AHB DMAC id 0x%08x\n", 263 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_ID)); 264 1.1 rkujawa 265 1.1 rkujawa /* 266 1.1 rkujawa * 460EX errata workaround for concurrent AHB use 267 1.1 rkujawa */ 268 1.1 rkujawa { 269 1.1 rkujawa uint32_t ahbcfg = mfsdr(DCR_SDR0_AHB_CFG); 270 1.1 rkujawa 271 1.1 rkujawa aprint_normal_dev(self, "SDR0_AHB_CFG 0x%08x", ahbcfg); 272 1.1 rkujawa ahbcfg |= SDR0_AHB_CFG_A2P_INCR4; 273 1.1 rkujawa ahbcfg &= ~SDR0_AHB_CFG_A2P_PROT2; 274 1.1 rkujawa mtsdr(DCR_SDR0_AHB_CFG, ahbcfg); 275 1.1 rkujawa aprint_normal(" -> 0x%08x (460EX AHB errata)\n", 276 1.1 rkujawa mfsdr(DCR_SDR0_AHB_CFG)); 277 1.1 rkujawa 278 1.1 rkujawa aprint_normal_dev(self, 279 1.1 rkujawa "arbiter: PLB4A0_ACR 0x%08x PLB4A1_ACR 0x%08x " 280 1.1 rkujawa "SDR0_USB2HOST_CFG 0x%08x\n", 281 1.1 rkujawa mfdcr(DCR_PLB4A0_ACR), mfdcr(DCR_PLB4A1_ACR), 282 1.1 rkujawa mfsdr(DCR_SDR0_USB2HOST_CFG)); 283 1.1 rkujawa } 284 1.1 rkujawa 285 1.2 rkujawa /* map the on-chip OHCI + EHCI host-control registers for the USB 286 1.2 rkujawa * schedule-quiesce; EHCI operational regs are at base + CAPLENGTH */ 287 1.2 rkujawa dwcsata_usb_tag.pbs_base = paa->plb_addr - DWCSATA_USB_OFFSET; 288 1.2 rkujawa dwcsata_usb_tag.pbs_limit = paa->plb_addr - DWCSATA_USB_OFFSET + 289 1.2 rkujawa DWCSATA_USB_SIZE; 290 1.2 rkujawa if (bus_space_init(&dwcsata_usb_tag, "dwcsataub", dwcsata_usb_ex_storage, 291 1.2 rkujawa sizeof(dwcsata_usb_ex_storage)) == 0 && 292 1.2 rkujawa bus_space_map(&dwcsata_usb_tag, paa->plb_addr - DWCSATA_USB_OFFSET, 293 1.2 rkujawa DWCSATA_USB_SIZE, 0, &sc->sc_usb_ioh) == 0) { 294 1.2 rkujawa uint8_t caplen = bus_space_read_1(&dwcsata_usb_tag, 295 1.2 rkujawa sc->sc_usb_ioh, DWCSATA_EHCI_CAPLEN); 296 1.2 rkujawa sc->sc_usb_iot = &dwcsata_usb_tag; 297 1.2 rkujawa sc->sc_ehci_cmd_off = DWCSATA_EHCI_CAPLEN + caplen; 298 1.2 rkujawa sc->sc_usb_mapped = true; 299 1.2 rkujawa } else 300 1.2 rkujawa sc->sc_usb_mapped = false; 301 1.2 rkujawa 302 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_MASK_TFR, DWCDMAC_CH_ENABLE(DWCSATA_DMACH)); 303 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_MASK_BLOCK, 304 1.1 rkujawa DWCDMAC_CH_DISABLE(DWCSATA_DMACH)); 305 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_MASK_SRCTRAN, 306 1.1 rkujawa DWCDMAC_CH_DISABLE(DWCSATA_DMACH)); 307 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_MASK_DSTTRAN, 308 1.1 rkujawa DWCDMAC_CH_DISABLE(DWCSATA_DMACH)); 309 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_MASK_ERR, DWCDMAC_CH_ENABLE(DWCSATA_DMACH)); 310 1.1 rkujawa dwcdmac_clear_intrs(sc); 311 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CHEN, DWCDMAC_CH_DISABLE(DWCSATA_DMACH)); 312 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_DMACFG, DWCDMAC_DMACFG_EN); 313 1.1 rkujawa 314 1.1 rkujawa /* burst sizes the LLIs are built for */ 315 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_DBTSR, 316 1.1 rkujawa DWCSATA_DBTSR_MWR(DWCSATA_DMA_FIFO_BURST) | 317 1.1 rkujawa DWCSATA_DBTSR_MRD(DWCSATA_DMA_FIFO_BURST)); 318 1.1 rkujawa 319 1.1 rkujawa sc->sc_dmadr_phys = DWCSATA_DMADR_PHYS(paa->plb_addr); 320 1.1 rkujawa 321 1.1 rkujawa /* 322 1.1 rkujawa * The LLI table is fetched by the DMAC behind the CPU's back... 323 1.1 rkujawa * map it uncached so building it needs no cache gymnastics. 324 1.1 rkujawa */ 325 1.1 rkujawa error = bus_dmamem_alloc(sc->sc_dmat, 326 1.1 rkujawa DWCSATA_NLLI * sizeof(struct dwcdmac_lli), 8, 0, 327 1.1 rkujawa &sc->sc_lli_seg, 1, &sc->sc_lli_nseg, BUS_DMA_NOWAIT); 328 1.1 rkujawa if (error) 329 1.1 rkujawa goto fail0; 330 1.1 rkujawa error = bus_dmamem_map(sc->sc_dmat, &sc->sc_lli_seg, sc->sc_lli_nseg, 331 1.1 rkujawa DWCSATA_NLLI * sizeof(struct dwcdmac_lli), (void **)&sc->sc_lli, 332 1.1 rkujawa BUS_DMA_NOWAIT | BUS_DMA_DONTCACHE); 333 1.1 rkujawa if (error) 334 1.1 rkujawa goto fail1; 335 1.1 rkujawa error = bus_dmamap_create(sc->sc_dmat, 336 1.1 rkujawa DWCSATA_NLLI * sizeof(struct dwcdmac_lli), 1, 337 1.1 rkujawa DWCSATA_NLLI * sizeof(struct dwcdmac_lli), 0, BUS_DMA_NOWAIT, 338 1.1 rkujawa &sc->sc_lli_map); 339 1.1 rkujawa if (error) 340 1.1 rkujawa goto fail2; 341 1.1 rkujawa error = bus_dmamap_load(sc->sc_dmat, sc->sc_lli_map, sc->sc_lli, 342 1.1 rkujawa DWCSATA_NLLI * sizeof(struct dwcdmac_lli), NULL, BUS_DMA_NOWAIT); 343 1.1 rkujawa if (error) 344 1.1 rkujawa goto fail3; 345 1.1 rkujawa sc->sc_lli_phys = sc->sc_lli_map->dm_segs[0].ds_addr; 346 1.1 rkujawa 347 1.1 rkujawa error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, 348 1.1 rkujawa MAXPHYS / PAGE_SIZE + 8, 0x2000, 0x2000, BUS_DMA_NOWAIT, 349 1.1 rkujawa &sc->sc_dmamap_xfer); 350 1.1 rkujawa if (error) 351 1.1 rkujawa goto fail4; 352 1.1 rkujawa 353 1.1 rkujawa return true; 354 1.1 rkujawa 355 1.1 rkujawa fail4: 356 1.1 rkujawa bus_dmamap_unload(sc->sc_dmat, sc->sc_lli_map); 357 1.1 rkujawa fail3: 358 1.1 rkujawa bus_dmamap_destroy(sc->sc_dmat, sc->sc_lli_map); 359 1.1 rkujawa fail2: 360 1.1 rkujawa bus_dmamem_unmap(sc->sc_dmat, sc->sc_lli, 361 1.1 rkujawa DWCSATA_NLLI * sizeof(struct dwcdmac_lli)); 362 1.1 rkujawa fail1: 363 1.1 rkujawa bus_dmamem_free(sc->sc_dmat, &sc->sc_lli_seg, sc->sc_lli_nseg); 364 1.1 rkujawa fail0: 365 1.1 rkujawa bus_space_unmap(sc->sc_iot, sc->sc_dmac_ioh, DWCDMAC_SIZE); 366 1.1 rkujawa return false; 367 1.1 rkujawa } 368 1.1 rkujawa 369 1.1 rkujawa static int 370 1.1 rkujawa dwcsata_dma_init(void *v, int channel, int drive, void *databuf, 371 1.1 rkujawa size_t datalen, int flags) 372 1.1 rkujawa { 373 1.1 rkujawa struct dwcsata_softc *sc = v; 374 1.1 rkujawa bus_dmamap_t map = sc->sc_dmamap_xfer; 375 1.1 rkujawa const bool read = (flags & WDC_DMA_READ) != 0; 376 1.1 rkujawa const u_int lsize = curcpu()->ci_ci.dcache_line_size; 377 1.1 rkujawa uint32_t ctl, serror; 378 1.1 rkujawa u_int idx, fis_len; 379 1.1 rkujawa int i, error; 380 1.1 rkujawa 381 1.1 rkujawa KASSERT(channel == 0 && drive == 0); 382 1.1 rkujawa 383 1.1 rkujawa /* 384 1.1 rkujawa * The channel enable self-clears at the end of the chain; if it 385 1.1 rkujawa * is still set here, a previous abort failed to stop the engine. 386 1.1 rkujawa */ 387 1.1 rkujawa if (dwcdmac_read(sc, DWCDMAC_CHEN) & DWCDMAC_CHANBIT(DWCSATA_DMACH)) { 388 1.1 rkujawa aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, 389 1.1 rkujawa "dma_init: channel still enabled (CHEN 0x%08x)\n", 390 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_CHEN)); 391 1.1 rkujawa return EBUSY; 392 1.1 rkujawa } 393 1.1 rkujawa 394 1.1 rkujawa /* 395 1.1 rkujawa * If the MI code bailed between dma_init and dma_start (e.g. a 396 1.1 rkujawa * not-ready timeout) it never calls dma_finish, leaking the 397 1.1 rkujawa * loaded map; recover instead of failing every later load. 398 1.1 rkujawa */ 399 1.1 rkujawa if (sc->sc_dma_loaded) { 400 1.1 rkujawa aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, 401 1.1 rkujawa "dma_init: recovering leaked dmamap\n"); 402 1.1 rkujawa bus_dmamap_unload(sc->sc_dmat, map); 403 1.1 rkujawa sc->sc_dma_loaded = false; 404 1.1 rkujawa } 405 1.1 rkujawa 406 1.1 rkujawa /* drop any latched SError bits before issuing the command */ 407 1.1 rkujawa serror = bus_space_read_4(sc->sc_iot, sc->sc_ioh, DWCSATA_SERROR); 408 1.1 rkujawa if (serror & DWCSATA_ERRMR_ERR_BITS) 409 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_SERROR, 410 1.1 rkujawa serror); 411 1.1 rkujawa 412 1.1 rkujawa error = bus_dmamap_load(sc->sc_dmat, map, databuf, datalen, NULL, 413 1.1 rkujawa BUS_DMA_NOWAIT | BUS_DMA_STREAMING | 414 1.1 rkujawa (read ? BUS_DMA_READ : BUS_DMA_WRITE)); 415 1.1 rkujawa if (error) { 416 1.1 rkujawa aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, 417 1.1 rkujawa "dma_init: dmamap_load failed: error %d " 418 1.1 rkujawa "(buf %p len %zu)\n", error, databuf, datalen); 419 1.1 rkujawa return error; 420 1.1 rkujawa } 421 1.1 rkujawa sc->sc_dma_loaded = true; 422 1.1 rkujawa 423 1.1 rkujawa /* 424 1.1 rkujawa * The DMAC moves 32-bit items, so segments must be word-aligned. 425 1.1 rkujawa */ 426 1.1 rkujawa for (i = 0; i < map->dm_nsegs; i++) { 427 1.1 rkujawa if ((map->dm_segs[i].ds_addr | map->dm_segs[i].ds_len) & 3) 428 1.1 rkujawa goto fallback; 429 1.1 rkujawa if (read && ((map->dm_segs[i].ds_addr | 430 1.1 rkujawa map->dm_segs[i].ds_len) & (lsize - 1))) 431 1.1 rkujawa goto fallback; 432 1.1 rkujawa } 433 1.1 rkujawa 434 1.1 rkujawa bus_dmamap_sync(sc->sc_dmat, map, 0, datalen, 435 1.1 rkujawa read ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 436 1.1 rkujawa 437 1.1 rkujawa if (read) { 438 1.1 rkujawa /* device->memory: source is the FIFO */ 439 1.1 rkujawa ctl = DWCDMAC_CTL_TTFC(DWCDMAC_TTFC_P2M_DMAC) | 440 1.1 rkujawa DWCDMAC_CTL_SMS(DWCDMAC_MS_PERIPH) | 441 1.1 rkujawa DWCDMAC_CTL_DMS(DWCDMAC_MS_MEM) | 442 1.1 rkujawa DWCDMAC_CTL_SINC_NOCHANGE | 443 1.1 rkujawa DWCDMAC_CTL_SRC_MSIZE(DWCSATA_DMA_FIFO_MSIZE) | 444 1.1 rkujawa DWCDMAC_CTL_DST_MSIZE(DWCSATA_DMA_MEM_MSIZE); 445 1.1 rkujawa } else { 446 1.1 rkujawa /* memory->device: destination is the FIFO */ 447 1.1 rkujawa ctl = DWCDMAC_CTL_TTFC(DWCDMAC_TTFC_M2P_PER) | 448 1.1 rkujawa DWCDMAC_CTL_SMS(DWCDMAC_MS_MEM) | 449 1.1 rkujawa DWCDMAC_CTL_DMS(DWCDMAC_MS_PERIPH) | 450 1.1 rkujawa DWCDMAC_CTL_DINC_NOCHANGE | 451 1.1 rkujawa DWCDMAC_CTL_SRC_MSIZE(DWCSATA_DMA_MEM_MSIZE) | 452 1.1 rkujawa DWCDMAC_CTL_DST_MSIZE(DWCSATA_DMA_FIFO_MSIZE); 453 1.1 rkujawa } 454 1.1 rkujawa ctl |= DWCDMAC_CTL_SRC_TRWID(2) | DWCDMAC_CTL_DST_TRWID(2) | 455 1.1 rkujawa DWCDMAC_CTL_INT_EN | 456 1.1 rkujawa DWCDMAC_CTL_LLP_SRC_EN | DWCDMAC_CTL_LLP_DST_EN; 457 1.1 rkujawa 458 1.1 rkujawa idx = 0; 459 1.1 rkujawa fis_len = 0; 460 1.1 rkujawa for (i = 0; i < map->dm_nsegs; i++) { 461 1.1 rkujawa uint32_t addr = map->dm_segs[i].ds_addr; 462 1.1 rkujawa bus_size_t left = map->dm_segs[i].ds_len; 463 1.1 rkujawa 464 1.1 rkujawa while (left > 0) { 465 1.1 rkujawa struct dwcdmac_lli *lli; 466 1.1 rkujawa uint32_t len; 467 1.1 rkujawa 468 1.1 rkujawa if (idx >= DWCSATA_NLLI) { 469 1.1 rkujawa aprint_error_dev( 470 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_dev, 471 1.1 rkujawa "dma_init: LLI overflow (len %zu, " 472 1.1 rkujawa "%d segs)\n", datalen, map->dm_nsegs); 473 1.1 rkujawa goto fallback; 474 1.1 rkujawa } 475 1.1 rkujawa 476 1.1 rkujawa len = uimin(left, DWCDMAC_MAX_BLOCK_ITEMS * 4); 477 1.1 rkujawa if (fis_len + len > 8192) { 478 1.1 rkujawa len = 8192 - fis_len; 479 1.1 rkujawa fis_len = 0; 480 1.1 rkujawa } else { 481 1.1 rkujawa fis_len += len; 482 1.1 rkujawa if (fis_len == 8192) 483 1.1 rkujawa fis_len = 0; 484 1.1 rkujawa } 485 1.1 rkujawa 486 1.1 rkujawa lli = &sc->sc_lli[idx]; 487 1.1 rkujawa if (read) { 488 1.1 rkujawa lli->sar = htole32(sc->sc_dmadr_phys); 489 1.1 rkujawa lli->dar = htole32(addr); 490 1.1 rkujawa } else { 491 1.1 rkujawa lli->sar = htole32(addr); 492 1.1 rkujawa lli->dar = htole32(sc->sc_dmadr_phys); 493 1.1 rkujawa } 494 1.1 rkujawa lli->llp = htole32((sc->sc_lli_phys + 495 1.1 rkujawa (idx + 1) * sizeof(struct dwcdmac_lli)) | 496 1.1 rkujawa DWCDMAC_MS_MEM); 497 1.1 rkujawa lli->ctl_lo = htole32(ctl); 498 1.1 rkujawa lli->ctl_hi = htole32(DWCDMAC_CTL_BLOCK_TS(len / 4)); 499 1.1 rkujawa lli->dstat_lo = 0; 500 1.1 rkujawa lli->dstat_hi = 0; 501 1.1 rkujawa 502 1.1 rkujawa idx++; 503 1.1 rkujawa addr += len; 504 1.1 rkujawa left -= len; 505 1.1 rkujawa } 506 1.1 rkujawa } 507 1.1 rkujawa KASSERT(idx > 0); 508 1.1 rkujawa sc->sc_lli[idx - 1].llp = 0; 509 1.1 rkujawa sc->sc_lli[idx - 1].ctl_lo &= 510 1.1 rkujawa htole32(~(DWCDMAC_CTL_LLP_SRC_EN | DWCDMAC_CTL_LLP_DST_EN)); 511 1.1 rkujawa /* the table is uncached; order the stores before the enables */ 512 1.1 rkujawa __asm volatile("sync" ::: "memory"); 513 1.1 rkujawa 514 1.1 rkujawa dwcdmac_clear_intrs(sc); 515 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CFG_HI(DWCSATA_DMACH), 516 1.1 rkujawa DWCDMAC_CFG_HS_SRC(DWCSATA_DMACH) | 517 1.1 rkujawa DWCDMAC_CFG_HS_DST(DWCSATA_DMACH) | 518 1.1 rkujawa DWCDMAC_CFG_PROTCTL | DWCDMAC_CFG_FCMODE_REQ); 519 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CFG(DWCSATA_DMACH), 520 1.1 rkujawa DWCDMAC_CFG_CH_PRIOR(DWCSATA_DMACH)); 521 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_LLP(DWCSATA_DMACH), 522 1.1 rkujawa sc->sc_lli_phys | DWCDMAC_MS_MEM); 523 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CTL(DWCSATA_DMACH), 524 1.1 rkujawa DWCDMAC_CTL_LLP_SRC_EN | DWCDMAC_CTL_LLP_DST_EN); 525 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CTL_HI(DWCSATA_DMACH), 0); 526 1.1 rkujawa 527 1.1 rkujawa sc->sc_dma_flags = flags; 528 1.1 rkujawa sc->sc_dma_nlli = idx; 529 1.1 rkujawa return 0; 530 1.1 rkujawa 531 1.1 rkujawa fallback: 532 1.1 rkujawa bus_dmamap_unload(sc->sc_dmat, map); 533 1.1 rkujawa sc->sc_dma_loaded = false; 534 1.1 rkujawa return EINVAL; 535 1.1 rkujawa } 536 1.1 rkujawa 537 1.1 rkujawa static void 538 1.1 rkujawa dwcsata_dma_dump(struct dwcsata_softc *sc, uint32_t tfr, uint32_t err) 539 1.1 rkujawa { 540 1.1 rkujawa device_t dev = sc->sc_wdcdev.sc_atac.atac_dev; 541 1.1 rkujawa uint32_t intpr; 542 1.1 rkujawa int i; 543 1.1 rkujawa 544 1.1 rkujawa intpr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, DWCSATA_INTPR); 545 1.1 rkujawa aprint_error_dev(dev, 546 1.1 rkujawa "DMA state: CHEN 0x%08x tfr/blk/err 0x%08x/0x%08x/0x%08x " 547 1.1 rkujawa "CTL 0x%08x.%08x LLP 0x%08x CFG 0x%08x.%08x DMACR 0x%08x " 548 1.1 rkujawa "INTPR 0x%08x (erraddr 0x%03x) SError 0x%08x\n", 549 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_CHEN), tfr, 550 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_RAW_BLOCK), err, 551 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_CTL_HI(DWCSATA_DMACH)), 552 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_CTL(DWCSATA_DMACH)), 553 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_LLP(DWCSATA_DMACH)), 554 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_CFG_HI(DWCSATA_DMACH)), 555 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_CFG(DWCSATA_DMACH)), 556 1.1 rkujawa bus_space_read_4(sc->sc_iot, sc->sc_ioh, DWCSATA_DMACR), 557 1.1 rkujawa intpr, DWCSATA_INTPR_ERRADDR_GET(intpr), 558 1.1 rkujawa bus_space_read_4(sc->sc_iot, sc->sc_ioh, DWCSATA_SERROR)); 559 1.1 rkujawa for (i = 0; i < sc->sc_dma_nlli; i++) { 560 1.1 rkujawa const struct dwcdmac_lli *lli = &sc->sc_lli[i]; 561 1.1 rkujawa 562 1.1 rkujawa aprint_error_dev(dev, 563 1.1 rkujawa " lli[%d]: sar 0x%08x dar 0x%08x llp 0x%08x " 564 1.1 rkujawa "ctl 0x%08x.%08x\n", i, 565 1.1 rkujawa le32toh(lli->sar), le32toh(lli->dar), le32toh(lli->llp), 566 1.1 rkujawa le32toh(lli->ctl_hi), le32toh(lli->ctl_lo)); 567 1.1 rkujawa } 568 1.1 rkujawa } 569 1.1 rkujawa 570 1.2 rkujawa /* 571 1.2 rkujawa * SDR/DCR SATA reset 572 1.2 rkujawa * 573 1.2 rkujawa * Tries to recover a hung DMAC channel without touching the poisoned AHB 574 1.2 rkujawa * master, so the abort path can proceed without machine check (drop to 575 1.2 rkujawa * DDB or panic). 576 1.2 rkujawa */ 577 1.2 rkujawa static void 578 1.2 rkujawa dwcsata_unwedge(struct dwcsata_softc *sc) 579 1.2 rkujawa { 580 1.2 rkujawa uint32_t reg; 581 1.2 rkujawa 582 1.2 rkujawa mtsdr(DCR_SDR0_SRST1, SDR0_SRST1_SATA_RESET); 583 1.2 rkujawa reg = mfsdr(SATA_PESDR0_PHY_CTL_RST); 584 1.2 rkujawa mtsdr(SATA_PESDR0_PHY_CTL_RST, (reg & 0xeffffffc) | 0x00000001); 585 1.2 rkujawa reg = mfsdr(SATA_PESDR0_L0CLK); 586 1.2 rkujawa mtsdr(SATA_PESDR0_L0CLK, (reg & 0xfffffff8) | 0x00000007); 587 1.2 rkujawa mtsdr(SATA_PESDR0_L0CDRCTL, 0x00003111); 588 1.2 rkujawa mtsdr(SATA_PESDR0_L0DRV, 0x00000104); 589 1.2 rkujawa mtsdr(DCR_SDR0_SRST1, 0); 590 1.2 rkujawa delay(10000); 591 1.2 rkujawa reg = mfsdr(DCR_SDR0_AHB_CFG); /* errata is lost across the reset */ 592 1.2 rkujawa mtsdr(DCR_SDR0_AHB_CFG, 593 1.2 rkujawa (reg | SDR0_AHB_CFG_A2P_INCR4) & ~SDR0_AHB_CFG_A2P_PROT2); 594 1.2 rkujawa (void)sc; 595 1.2 rkujawa } 596 1.2 rkujawa 597 1.2 rkujawa /* clear the selected USB schedule-enable bits; keep the controllers RUNning */ 598 1.2 rkujawa static void 599 1.2 rkujawa dwcsata_usb_quiesce(struct dwcsata_softc *sc) 600 1.2 rkujawa { 601 1.2 rkujawa bus_space_tag_t t = sc->sc_usb_iot; 602 1.2 rkujawa bus_space_handle_t h = sc->sc_usb_ioh; 603 1.2 rkujawa const int mask = dwcsata_usb_workaround; 604 1.2 rkujawa uint32_t ehci_clr, ohci_clr; 605 1.2 rkujawa 606 1.2 rkujawa if (mask == 0 || !sc->sc_usb_mapped || sc->sc_usb_quiesced) 607 1.2 rkujawa return; 608 1.2 rkujawa ehci_clr = ((mask & DWCSATA_Q_EHCI_PSE) ? DWCSATA_EHCI_PSE : 0) | 609 1.2 rkujawa ((mask & DWCSATA_Q_EHCI_ASE) ? DWCSATA_EHCI_ASE : 0); 610 1.2 rkujawa ohci_clr = (mask & DWCSATA_Q_OHCI) ? 611 1.2 rkujawa (DWCSATA_OHCI_PLE | DWCSATA_OHCI_CLE | DWCSATA_OHCI_BLE) : 0; 612 1.2 rkujawa if (ohci_clr != 0) { 613 1.2 rkujawa sc->sc_usb_ohci_ctl = 614 1.2 rkujawa bus_space_read_4(t, h, DWCSATA_OHCI_HCCONTROL); 615 1.2 rkujawa bus_space_write_4(t, h, DWCSATA_OHCI_HCCONTROL, 616 1.2 rkujawa sc->sc_usb_ohci_ctl & ~ohci_clr); 617 1.2 rkujawa sc->sc_usb_q_ohci = true; 618 1.2 rkujawa } 619 1.2 rkujawa if (ehci_clr != 0) { 620 1.2 rkujawa sc->sc_usb_ehci_cmd = 621 1.2 rkujawa bus_space_read_4(t, h, sc->sc_ehci_cmd_off); 622 1.2 rkujawa bus_space_write_4(t, h, sc->sc_ehci_cmd_off, 623 1.2 rkujawa sc->sc_usb_ehci_cmd & ~ehci_clr); 624 1.2 rkujawa sc->sc_usb_q_ehci = true; 625 1.2 rkujawa } 626 1.2 rkujawa sc->sc_usb_quiesced = true; 627 1.2 rkujawa } 628 1.2 rkujawa 629 1.2 rkujawa static void 630 1.2 rkujawa dwcsata_usb_restore(struct dwcsata_softc *sc) 631 1.2 rkujawa { 632 1.2 rkujawa if (!sc->sc_usb_quiesced) 633 1.2 rkujawa return; 634 1.2 rkujawa if (sc->sc_usb_q_ohci) { 635 1.2 rkujawa bus_space_write_4(sc->sc_usb_iot, sc->sc_usb_ioh, 636 1.2 rkujawa DWCSATA_OHCI_HCCONTROL, sc->sc_usb_ohci_ctl); 637 1.2 rkujawa sc->sc_usb_q_ohci = false; 638 1.2 rkujawa } 639 1.2 rkujawa if (sc->sc_usb_q_ehci) { 640 1.2 rkujawa bus_space_write_4(sc->sc_usb_iot, sc->sc_usb_ioh, 641 1.2 rkujawa sc->sc_ehci_cmd_off, sc->sc_usb_ehci_cmd); 642 1.2 rkujawa sc->sc_usb_q_ehci = false; 643 1.2 rkujawa } 644 1.2 rkujawa sc->sc_usb_quiesced = false; 645 1.2 rkujawa } 646 1.2 rkujawa 647 1.1 rkujawa static void 648 1.1 rkujawa dwcsata_dma_start(void *v, int channel, int drive) 649 1.1 rkujawa { 650 1.1 rkujawa struct dwcsata_softc *sc = v; 651 1.1 rkujawa const bool read = (sc->sc_dma_flags & WDC_DMA_READ) != 0; 652 1.1 rkujawa 653 1.2 rkujawa dwcsata_usb_quiesce(sc); 654 1.2 rkujawa 655 1.1 rkujawa /* open the FIS data channel in the SATA core first... */ 656 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_DMACR, 657 1.1 rkujawa read ? DWCSATA_DMACR_RX_START : DWCSATA_DMACR_TX_START); 658 1.1 rkujawa /* ...then let the AHB DMAC run the linked list */ 659 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CHEN, DWCDMAC_CH_ENABLE(DWCSATA_DMACH)); 660 1.1 rkujawa sc->sc_dma_active = true; 661 1.1 rkujawa } 662 1.1 rkujawa 663 1.1 rkujawa static int 664 1.1 rkujawa dwcsata_dma_finish(void *v, int channel, int drive, int force) 665 1.1 rkujawa { 666 1.1 rkujawa struct dwcsata_softc *sc = v; 667 1.1 rkujawa const bool read = (sc->sc_dma_flags & WDC_DMA_READ) != 0; 668 1.1 rkujawa uint32_t tfr, err, dmacr, intpr; 669 1.1 rkujawa int i, status = 0; 670 1.1 rkujawa 671 1.1 rkujawa if (!sc->sc_dma_active) 672 1.1 rkujawa return 0; 673 1.1 rkujawa 674 1.1 rkujawa if (force == WDC_DMAEND_END) { 675 1.1 rkujawa /* 676 1.1 rkujawa * Plain register polling: this core does not write 677 1.1 rkujawa * the DONE bit back to the LLI (measured: the memory 678 1.1 rkujawa * fast path never fired), and bridge traffic during 679 1.1 rkujawa * the transfer has been ruled out as the stall 680 1.1 rkujawa * trigger. 681 1.1 rkujawa */ 682 1.1 rkujawa tfr = dwcdmac_read(sc, DWCDMAC_RAW_TFR); 683 1.1 rkujawa err = dwcdmac_read(sc, DWCDMAC_RAW_ERR); 684 1.1 rkujawa /* still running? wdc_dmawait() polls us again */ 685 1.1 rkujawa if (((tfr | err) & DWCDMAC_CHANBIT(DWCSATA_DMACH)) == 0) 686 1.1 rkujawa return WDC_DMAST_NOIRQ; 687 1.1 rkujawa /* a detectable error deserves the full dump */ 688 1.1 rkujawa if (err & DWCDMAC_CHANBIT(DWCSATA_DMACH)) 689 1.1 rkujawa dwcsata_dma_dump(sc, tfr, err); 690 1.1 rkujawa } else { 691 1.2 rkujawa const uint32_t chanbit = DWCDMAC_CHANBIT(DWCSATA_DMACH); 692 1.2 rkujawa 693 1.2 rkujawa /* 694 1.2 rkujawa * If the channel wedged, clear it through SDR/DCR first 695 1.2 rkujawa * (bridge-safe) before any AHB register access can machine- 696 1.2 rkujawa * check. CHEN stuck with no TFR/ERR is the wedge signature. 697 1.2 rkujawa */ 698 1.2 rkujawa if (dwcdmac_read(sc, DWCDMAC_CHEN) & chanbit) { 699 1.2 rkujawa if (force != WDC_DMAEND_ABRT_QUIET) 700 1.2 rkujawa aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, 701 1.2 rkujawa "DMA wedge: SDR un-wedge before abort\n"); 702 1.2 rkujawa dwcsata_unwedge(sc); 703 1.2 rkujawa } 704 1.2 rkujawa 705 1.1 rkujawa tfr = dwcdmac_read(sc, DWCDMAC_RAW_TFR); 706 1.1 rkujawa err = dwcdmac_read(sc, DWCDMAC_RAW_ERR); 707 1.1 rkujawa 708 1.1 rkujawa /* 709 1.1 rkujawa * Abort. Close the SATA-side channel first so the 710 1.1 rkujawa * handshake stops feeding the DMAC, then follow the 711 1.1 rkujawa * databook: suspend the channel, let its FIFO drain, 712 1.1 rkujawa * and only then clear the enable. 713 1.1 rkujawa */ 714 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_DMACR, 715 1.1 rkujawa DWCSATA_DMACR_TXRXCH_CLEAR); 716 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CFG(DWCSATA_DMACH), 717 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_CFG(DWCSATA_DMACH)) | 718 1.1 rkujawa DWCDMAC_CFG_CH_SUSP); 719 1.1 rkujawa for (i = 0; i < 100; i++) { 720 1.1 rkujawa if (dwcdmac_read(sc, DWCDMAC_CFG(DWCSATA_DMACH)) & 721 1.1 rkujawa DWCDMAC_CFG_FIFO_EMPTY) 722 1.1 rkujawa break; 723 1.1 rkujawa delay(10); 724 1.1 rkujawa } 725 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CHEN, 726 1.1 rkujawa DWCDMAC_CH_DISABLE(DWCSATA_DMACH)); 727 1.1 rkujawa for (i = 0; i < 100; i++) { 728 1.1 rkujawa if ((dwcdmac_read(sc, DWCDMAC_CHEN) & chanbit) == 0) 729 1.1 rkujawa break; 730 1.1 rkujawa delay(10); 731 1.1 rkujawa } 732 1.1 rkujawa if (dwcdmac_read(sc, DWCDMAC_CHEN) & chanbit) { 733 1.1 rkujawa /* 734 1.1 rkujawa * This happens. Not sure why. 735 1.1 rkujawa */ 736 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_DMACFG, 0); 737 1.1 rkujawa delay(100); 738 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_DMACFG, DWCDMAC_DMACFG_EN); 739 1.1 rkujawa if (force != WDC_DMAEND_ABRT_QUIET) 740 1.1 rkujawa aprint_error_dev( 741 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_dev, 742 1.1 rkujawa "DMA channel wedged, reset the DMAC\n"); 743 1.1 rkujawa } 744 1.1 rkujawa /* drop the suspend again for the next transfer */ 745 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CFG(DWCSATA_DMACH), 746 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_CFG(DWCSATA_DMACH)) & 747 1.1 rkujawa ~DWCDMAC_CFG_CH_SUSP); 748 1.1 rkujawa 749 1.1 rkujawa if (force != WDC_DMAEND_ABRT_QUIET) { 750 1.1 rkujawa dwcsata_dma_dump(sc, tfr, err); 751 1.1 rkujawa if ((tfr & chanbit) == 0) 752 1.1 rkujawa status |= WDC_DMAST_NOIRQ; 753 1.1 rkujawa } 754 1.1 rkujawa } 755 1.1 rkujawa 756 1.1 rkujawa if (err & DWCDMAC_CHANBIT(DWCSATA_DMACH)) 757 1.1 rkujawa status |= WDC_DMAST_ERR; 758 1.1 rkujawa 759 1.1 rkujawa /* close the SATA core side, keeping TXMODE set */ 760 1.1 rkujawa dmacr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, DWCSATA_DMACR); 761 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_DMACR, 762 1.1 rkujawa read ? DWCSATA_DMACR_RX_CLEAR(dmacr) : 763 1.1 rkujawa DWCSATA_DMACR_TX_CLEAR(dmacr)); 764 1.1 rkujawa 765 1.1 rkujawa intpr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, DWCSATA_INTPR); 766 1.1 rkujawa if (intpr & DWCSATA_INTPR_ERR) 767 1.1 rkujawa status |= WDC_DMAST_ERR; 768 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_INTPR, 769 1.1 rkujawa DWCSATA_INTPR_DMAT | DWCSATA_INTPR_ERR); 770 1.1 rkujawa if ((status & WDC_DMAST_ERR) != 0 && 771 1.1 rkujawa force != WDC_DMAEND_ABRT_QUIET) { 772 1.1 rkujawa uint32_t serror = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 773 1.1 rkujawa DWCSATA_SERROR); 774 1.1 rkujawa aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, 775 1.1 rkujawa "DMA error: DMAC err 0x%08x INTPR 0x%08x SError 0x%08x\n", 776 1.1 rkujawa err, intpr, serror); 777 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_SERROR, 778 1.1 rkujawa serror); 779 1.1 rkujawa } 780 1.1 rkujawa 781 1.1 rkujawa dwcdmac_clear_intrs(sc); 782 1.1 rkujawa 783 1.1 rkujawa bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0, 784 1.1 rkujawa sc->sc_dmamap_xfer->dm_mapsize, 785 1.1 rkujawa read ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 786 1.1 rkujawa bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_xfer); 787 1.1 rkujawa sc->sc_dma_loaded = false; 788 1.2 rkujawa dwcsata_usb_restore(sc); 789 1.1 rkujawa sc->sc_dma_active = false; 790 1.1 rkujawa 791 1.1 rkujawa return status; 792 1.1 rkujawa } 793 1.1 rkujawa 794 1.1 rkujawa static int 795 1.1 rkujawa dwcsata_intr(void *arg) 796 1.1 rkujawa { 797 1.1 rkujawa struct dwcsata_softc *sc = arg; 798 1.1 rkujawa struct ata_channel *chp = &sc->sc_channel; 799 1.1 rkujawa struct wdc_regs *wdr = &sc->sc_wdc_regs; 800 1.1 rkujawa uint32_t intpr; 801 1.1 rkujawa 802 1.1 rkujawa intpr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, DWCSATA_INTPR); 803 1.1 rkujawa if (intpr == 0) 804 1.1 rkujawa return 0; /* nothing pending; not our line */ 805 1.1 rkujawa 806 1.1 rkujawa if (intpr & (DWCSATA_INTPR_ERR | DWCSATA_INTPR_CMDABORT | 807 1.1 rkujawa DWCSATA_INTPR_PRIMERR)) { 808 1.1 rkujawa uint32_t serror = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 809 1.1 rkujawa DWCSATA_SERROR); 810 1.1 rkujawa aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, 811 1.1 rkujawa "controller error interrupt: INTPR 0x%08x SError 0x%08x\n", 812 1.1 rkujawa intpr, serror); 813 1.1 rkujawa if (serror & DWCSATA_ERRMR_ERR_BITS) 814 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, 815 1.1 rkujawa DWCSATA_SERROR, serror); 816 1.1 rkujawa } 817 1.1 rkujawa 818 1.1 rkujawa /* 819 1.1 rkujawa * Acknowledge the latched INTPR status bits 820 1.1 rkujawa */ 821 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_INTPR, 822 1.1 rkujawa intpr & ~DWCSATA_INTPR_ERRADDR); 823 1.1 rkujawa 824 1.1 rkujawa if (chp->ch_flags & ATACH_DMA_WAIT) { 825 1.1 rkujawa /* 826 1.1 rkujawa * A DMA transfer is in flight 827 1.1 rkujawa */ 828 1.1 rkujawa (void)bus_space_read_1(wdr->cmd_iot, 829 1.1 rkujawa wdr->cmd_iohs[wd_status], 0); 830 1.1 rkujawa return 1; 831 1.1 rkujawa } 832 1.1 rkujawa 833 1.1 rkujawa /* 834 1.1 rkujawa * No DMA pending: a PIO command completion or a stray drive 835 1.1 rkujawa * interrupt. wdcintr reads the status register. 836 1.1 rkujawa */ 837 1.1 rkujawa return wdcintr(chp); 838 1.1 rkujawa } 839 1.1 rkujawa 840 1.1 rkujawa static int 841 1.1 rkujawa dwcsata_dmac_intr(void *arg) 842 1.1 rkujawa { 843 1.1 rkujawa struct dwcsata_softc *sc = arg; 844 1.1 rkujawa struct ata_channel *chp = &sc->sc_channel; 845 1.1 rkujawa const uint32_t chanbit = DWCDMAC_CHANBIT(DWCSATA_DMACH); 846 1.1 rkujawa int rv; 847 1.1 rkujawa 848 1.1 rkujawa if (((dwcdmac_read(sc, DWCDMAC_RAW_TFR) | 849 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_RAW_ERR)) & chanbit) == 0) 850 1.1 rkujawa return 0; /* not our channel */ 851 1.1 rkujawa 852 1.1 rkujawa rv = wdcintr(chp); 853 1.1 rkujawa 854 1.1 rkujawa if ((dwcdmac_read(sc, DWCDMAC_RAW_TFR) | 855 1.1 rkujawa dwcdmac_read(sc, DWCDMAC_RAW_ERR)) & chanbit) { 856 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CLEAR_TFR, chanbit); 857 1.1 rkujawa dwcdmac_write(sc, DWCDMAC_CLEAR_ERR, chanbit); 858 1.1 rkujawa } 859 1.1 rkujawa return rv ? rv : 1; 860 1.1 rkujawa } 861 1.1 rkujawa 862 1.1 rkujawa #endif /* !DWCSATA_PIO_ONLY */ 863 1.1 rkujawa 864 1.1 rkujawa static void 865 1.1 rkujawa dwcsata_attach(device_t parent, device_t self, void *aux) 866 1.1 rkujawa { 867 1.1 rkujawa struct dwcsata_softc *sc = device_private(self); 868 1.1 rkujawa struct plb_attach_args *paa = aux; 869 1.1 rkujawa struct wdc_regs *wdr; 870 1.1 rkujawa struct ata_channel *chp = &sc->sc_channel; 871 1.1 rkujawa uint32_t idr, versionr; 872 1.1 rkujawa int i; 873 1.1 rkujawa 874 1.1 rkujawa sc->sc_dmat = paa->plb_dmat; 875 1.1 rkujawa sc->sc_irq = paa->plb_irq; 876 1.1 rkujawa 877 1.1 rkujawa /* the window also covers the companion AHB DMAC below the core */ 878 1.1 rkujawa dwcsata_tag.pbs_base = paa->plb_addr - DWCDMAC_OFFSET; 879 1.1 rkujawa dwcsata_tag.pbs_limit = paa->plb_addr + DWCSATA_SIZE; 880 1.1 rkujawa sc->sc_iot = &dwcsata_tag; 881 1.1 rkujawa 882 1.1 rkujawa if (bus_space_init(&dwcsata_tag, "dwcsata", dwcsata_ex_storage, 883 1.1 rkujawa sizeof(dwcsata_ex_storage)) || 884 1.1 rkujawa bus_space_map(sc->sc_iot, paa->plb_addr, DWCSATA_SIZE, 0, 885 1.1 rkujawa &sc->sc_ioh)) { 886 1.1 rkujawa aprint_error(": can't map registers\n"); 887 1.1 rkujawa return; 888 1.1 rkujawa } 889 1.1 rkujawa 890 1.1 rkujawa versionr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 891 1.1 rkujawa DWCSATA_VERSIONR); 892 1.1 rkujawa if (versionr == 0 || versionr == 0xffffffff) { 893 1.1 rkujawa aprint_normal(": DWC SATA core not responding\n"); 894 1.1 rkujawa return; 895 1.1 rkujawa } 896 1.1 rkujawa idr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, DWCSATA_IDR); 897 1.1 rkujawa aprint_normal(": DWC SATA-II controller, core version %c.%c%c " 898 1.1 rkujawa "id 0x%02x\n", 899 1.1 rkujawa (int)(versionr >> 24) & 0xff, (int)(versionr >> 16) & 0xff, 900 1.1 rkujawa (int)(versionr >> 8) & 0xff, idr & 0xff); 901 1.1 rkujawa 902 1.1 rkujawa sc->sc_wdcdev.regs = wdr = &sc->sc_wdc_regs; 903 1.1 rkujawa 904 1.1 rkujawa wdr->cmd_iot = wdr->ctl_iot = sc->sc_iot; 905 1.1 rkujawa wdr->cmd_baseioh = sc->sc_ioh; 906 1.1 rkujawa wdr->cmd_ios = DWCSATA_SIZE; 907 1.1 rkujawa for (i = 0; i < WDC_NREG; i++) { 908 1.1 rkujawa if (bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh, 909 1.1 rkujawa DWCSATA_CDR_BASE + i * DWCSATA_CDR_STRIDE, 910 1.1 rkujawa DWCSATA_CDR_STRIDE, &wdr->cmd_iohs[i]) != 0) { 911 1.1 rkujawa aprint_error_dev(self, 912 1.1 rkujawa "couldn't subregion registers\n"); 913 1.1 rkujawa return; 914 1.1 rkujawa } 915 1.1 rkujawa } 916 1.1 rkujawa wdc_init_shadow_regs(wdr); 917 1.1 rkujawa 918 1.1 rkujawa if (bus_space_subregion(wdr->ctl_iot, sc->sc_ioh, DWCSATA_CLR0, 4, 919 1.1 rkujawa &wdr->ctl_ioh) || 920 1.1 rkujawa bus_space_subregion(sc->sc_iot, sc->sc_ioh, DWCSATA_SSTATUS, 4, 921 1.1 rkujawa &wdr->sata_status) || 922 1.1 rkujawa bus_space_subregion(sc->sc_iot, sc->sc_ioh, DWCSATA_SERROR, 4, 923 1.1 rkujawa &wdr->sata_error) || 924 1.1 rkujawa bus_space_subregion(sc->sc_iot, sc->sc_ioh, DWCSATA_SCONTROL, 4, 925 1.1 rkujawa &wdr->sata_control)) { 926 1.1 rkujawa aprint_error_dev(self, "couldn't subregion registers\n"); 927 1.1 rkujawa return; 928 1.1 rkujawa } 929 1.1 rkujawa wdr->ctl_ios = 4; 930 1.1 rkujawa wdr->sata_iot = sc->sc_iot; 931 1.1 rkujawa wdr->sata_baseioh = sc->sc_ioh; 932 1.1 rkujawa 933 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_INTMR, 0); 934 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_ERRMR, 935 1.1 rkujawa DWCSATA_ERRMR_ERR_BITS); 936 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_DMACR, 937 1.1 rkujawa DWCSATA_DMACR_TXRXCH_CLEAR); 938 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_SERROR, 939 1.1 rkujawa 0xffffffff); 940 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_INTPR, 941 1.1 rkujawa 0xffffffff); 942 1.1 rkujawa 943 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_dev = self; 944 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_NOIRQ; 945 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; 946 1.1 rkujawa 947 1.1 rkujawa #ifndef DWCSATA_PIO_ONLY 948 1.1 rkujawa /* 949 1.1 rkujawa * No atac_set_modes: SATA carries the mode in the FIS, there are 950 1.1 rkujawa * no host timings to program, and without the hook the MI code 951 1.1 rkujawa * also skips the (unneeded) SET FEATURES xfer-mode command. 952 1.1 rkujawa */ 953 1.1 rkujawa if (dwcsata_dma_setup(self, sc, paa)) { 954 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | 955 1.1 rkujawa ATAC_CAP_UDMA; 956 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; 957 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; 958 1.1 rkujawa sc->sc_wdcdev.dma_arg = sc; 959 1.1 rkujawa sc->sc_wdcdev.dma_init = dwcsata_dma_init; 960 1.1 rkujawa sc->sc_wdcdev.dma_start = dwcsata_dma_start; 961 1.1 rkujawa sc->sc_wdcdev.dma_finish = dwcsata_dma_finish; 962 1.1 rkujawa chp->ch_flags |= ATACH_DMA_BEFORE_CMD; 963 1.1 rkujawa sc->sc_dma_ok = true; 964 1.1 rkujawa } else 965 1.1 rkujawa aprint_error_dev(self, "DMA setup failed, PIO only\n"); 966 1.2 rkujawa 967 1.2 rkujawa if (sc->sc_dma_ok) { 968 1.2 rkujawa const struct sysctlnode *rnode = NULL; 969 1.2 rkujawa 970 1.2 rkujawa sysctl_createv(NULL, 0, NULL, &rnode, 971 1.2 rkujawa CTLFLAG_PERMANENT, CTLTYPE_NODE, "dwcsata", 972 1.2 rkujawa SYSCTL_DESCR("DWC SATA-II controller"), 973 1.2 rkujawa NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 974 1.2 rkujawa if (rnode != NULL) 975 1.2 rkujawa sysctl_createv(NULL, 0, &rnode, NULL, 976 1.2 rkujawa CTLFLAG_READWRITE, CTLTYPE_INT, "usb_workaround", 977 1.2 rkujawa SYSCTL_DESCR("pause USB schedules during SATA DMA " 978 1.2 rkujawa "(1=EHCI periodic 2=async 4=OHCI; 0=off 7=all)"), 979 1.2 rkujawa NULL, 0, &dwcsata_usb_workaround, 0, 980 1.2 rkujawa CTL_CREATE, CTL_EOL); 981 1.2 rkujawa } 982 1.1 rkujawa #endif 983 1.1 rkujawa 984 1.1 rkujawa sc->sc_chanlist[0] = chp; 985 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_chanlist; 986 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_nchannels = 1; 987 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_probe = dwcsata_probe; 988 1.1 rkujawa sc->sc_wdcdev.wdc_maxdrives = 1; /* point-to-point, no PMP */ 989 1.1 rkujawa sc->sc_wdcdev.reset = dwcsata_reset; /* settle the core post-SRST */ 990 1.1 rkujawa 991 1.1 rkujawa chp->ch_channel = 0; 992 1.1 rkujawa chp->ch_atac = &sc->sc_wdcdev.sc_atac; 993 1.1 rkujawa 994 1.1 rkujawa #ifndef DWCSATA_PIO_ONLY 995 1.1 rkujawa /* 996 1.1 rkujawa * With the DMA engine up, switch to interrupt-driven operation. 997 1.1 rkujawa */ 998 1.1 rkujawa if (sc->sc_dma_ok) { 999 1.1 rkujawa sc->sc_wdcdev.sc_atac.atac_cap &= ~ATAC_CAP_NOIRQ; 1000 1.1 rkujawa 1001 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_SERROR, 1002 1.1 rkujawa 0xffffffff); 1003 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_INTPR, 1004 1.1 rkujawa 0xffffffff); 1005 1.1 rkujawa (void)bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_status], 1006 1.1 rkujawa 0); 1007 1.1 rkujawa 1008 1.1 rkujawa intr_establish_xname(sc->sc_irq, IST_LEVEL, IPL_BIO, 1009 1.1 rkujawa dwcsata_intr, sc, device_xname(self)); 1010 1.1 rkujawa intr_establish_xname(AMCC460EX_SATA_DMA_IRQ, IST_LEVEL, 1011 1.1 rkujawa IPL_BIO, dwcsata_dmac_intr, sc, "dwcsata dmac"); 1012 1.1 rkujawa 1013 1.1 rkujawa /* let SATA link/transport errors raise irq 96 */ 1014 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_INTMR, 1015 1.1 rkujawa DWCSATA_INTMR_ERRM); 1016 1.1 rkujawa } 1017 1.1 rkujawa #endif 1018 1.1 rkujawa 1019 1.1 rkujawa wdcattach(chp); 1020 1.1 rkujawa } 1021 1.1 rkujawa 1022 1.1 rkujawa /* 1023 1.1 rkujawa * Soft-reset hook (installed as wdc->reset, replacing wdc_do_reset). 1024 1.1 rkujawa */ 1025 1.1 rkujawa static void 1026 1.1 rkujawa dwcsata_reset(struct ata_channel *chp, int poll) 1027 1.1 rkujawa { 1028 1.1 rkujawa struct wdc_softc *wdc = CHAN_TO_WDC(chp); 1029 1.1 rkujawa struct wdc_regs *wdr = &wdc->regs[chp->ch_channel]; 1030 1.1 rkujawa uint8_t st = 0; 1031 1.1 rkujawa int i; 1032 1.1 rkujawa 1033 1.1 rkujawa /* SRST pulse, as in wdc_do_reset() */ 1034 1.1 rkujawa bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0, WDSD_IBM); 1035 1.1 rkujawa delay(10); 1036 1.1 rkujawa bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr, 1037 1.1 rkujawa WDCTL_RST | WDCTL_IDS | WDCTL_4BIT); 1038 1.1 rkujawa delay(2000); 1039 1.1 rkujawa (void)bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_error], 0); 1040 1.1 rkujawa bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr, 1041 1.1 rkujawa WDCTL_4BIT | WDCTL_IDS); 1042 1.1 rkujawa 1043 1.1 rkujawa /* 1044 1.1 rkujawa * Let the core finish the reset before the taskfile is touched 1045 1.1 rkujawa * again. 1046 1.1 rkujawa */ 1047 1.1 rkujawa delay(150000); 1048 1.1 rkujawa for (i = 0; i < 100; i++) { 1049 1.1 rkujawa st = bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_status], 1050 1.1 rkujawa 0); 1051 1.1 rkujawa if ((st & WDCS_BSY) == 0) 1052 1.1 rkujawa break; 1053 1.1 rkujawa delay(10000); 1054 1.1 rkujawa } 1055 1.1 rkujawa aprint_normal_dev(wdc->sc_atac.atac_dev, 1056 1.1 rkujawa "soft reset: BSY cleared after %dms, status 0x%02x\n", 1057 1.1 rkujawa 150 + i * 10, st); 1058 1.1 rkujawa } 1059 1.1 rkujawa 1060 1.1 rkujawa static void 1061 1.1 rkujawa dwcsata_probe(struct ata_channel *chp) 1062 1.1 rkujawa { 1063 1.1 rkujawa struct dwcsata_softc *sc = (struct dwcsata_softc *)CHAN_TO_WDC(chp); 1064 1.1 rkujawa 1065 1.1 rkujawa wdc_sataprobe(chp); 1066 1.1 rkujawa 1067 1.1 rkujawa /* drop the diagnostics the PHY bring-up latched into SError */ 1068 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_SERROR, 1069 1.1 rkujawa 0xffffffff); 1070 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_INTPR, 1071 1.1 rkujawa 0xffffffff); 1072 1.1 rkujawa 1073 1.1 rkujawa #ifndef DWCSATA_PIO_ONLY 1074 1.1 rkujawa /* link resets do not touch DMACR/DBTSR, but re-init regardless */ 1075 1.1 rkujawa if (sc->sc_dma_ok) { 1076 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_DMACR, 1077 1.1 rkujawa DWCSATA_DMACR_TXRXCH_CLEAR); 1078 1.1 rkujawa bus_space_write_4(sc->sc_iot, sc->sc_ioh, DWCSATA_DBTSR, 1079 1.1 rkujawa DWCSATA_DBTSR_MWR(DWCSATA_DMA_FIFO_BURST) | 1080 1.1 rkujawa DWCSATA_DBTSR_MRD(DWCSATA_DMA_FIFO_BURST)); 1081 1.1 rkujawa } 1082 1.1 rkujawa #endif 1083 1.1 rkujawa } 1084