Home | History | Annotate | Line # | Download | only in dev
      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