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