Here are the changes needed to make SATA drives available on the Cubieboard A10. It consists of a DMA workaround and fiddling with some register assignments. I’ve successfully built the RAMDISK kernel via an external drive using this driver patch, so it’s been through what I’m hoping is a valid smoke test.
This patch was based off work done by others. Let me know what needs changing. ? lib/csu/obj Index: sys/arch/armv7/sunxi/sxiahci.c =================================================================== RCS file: /cvs/src/sys/arch/armv7/sunxi/sxiahci.c,v retrieving revision 1.6 diff -u -p -u -r1.6 sxiahci.c --- sys/arch/armv7/sunxi/sxiahci.c 14 Apr 2014 04:42:22 -0000 1.6 +++ sys/arch/armv7/sunxi/sxiahci.c 25 Nov 2014 01:52:57 -0000 @@ -1,6 +1,7 @@ /* $OpenBSD */ /* * Copyright (c) 2013 Patrick Wildt <patr...@blueri.se> + * Copyright (c) 2013,2014 Artturi Alm * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -75,18 +76,15 @@ sxiahci_attach(struct device *parent, st struct armv7_attach_args *aa = args; struct sxiahci_softc *sxisc = (struct sxiahci_softc *)self; struct ahci_softc *sc = &sxisc->sc; - bus_space_tag_t iot; - bus_space_handle_t ioh; uint32_t timo; - sc->sc_iot = iot = aa->aa_iot; + sc->sc_iot = aa->aa_iot; sc->sc_ios = aa->aa_dev->mem[0].size; sc->sc_dmat = aa->aa_dmat; if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, - aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) + sc->sc_ios, 0, &sc->sc_ioh)) panic("sxiahci_attach: bus_space_map failed!"); - ioh = sc->sc_ioh; /* enable clock */ sxiccmu_enablemodule(CCMU_AHCI); @@ -99,13 +97,13 @@ sxiahci_attach(struct device *parent, st SXISET4(sc, SXIAHCI_PHYCS1, 1 << 19); delay(10); - SXICMS4(sc, SXIAHCI_PHYCS0, 1 << 25, - 1 << 23 | 1 << 24 | 1 << 18 | 1 << 26); + SXICMS4(sc, SXIAHCI_PHYCS0, 7 << 24, + 1 << 23 | 5 << 24 | 1 << 18); delay(10); SXICMS4(sc, SXIAHCI_PHYCS1, - 1 << 16 | 1 << 12 | 1 << 11 | 1 << 8 | 1 << 6, - 1 << 17 | 1 << 10 | 1 << 9 | 1 << 7); + 3 << 16 | 0x1f << 8 | 3 << 6, + 2 << 16 | 0x06 << 8 | 2 << 6); delay(10); SXISET4(sc, SXIAHCI_PHYCS1, 1 << 28 | 1 << 15); @@ -114,18 +112,15 @@ sxiahci_attach(struct device *parent, st SXICLR4(sc, SXIAHCI_PHYCS1, 1 << 19); delay(10); - SXICMS4(sc, SXIAHCI_PHYCS0, 1 << 21 | 1 << 20, 1 << 22); - delay(10); - - SXICMS4(sc, SXIAHCI_PHYCS2, 1 << 7 | 1 << 6, - 1 << 9 | 1 << 8 | 1 << 5); + SXICMS4(sc, SXIAHCI_PHYCS0, 0x07 << 20, 0x03 << 20); + SXICMS4(sc, SXIAHCI_PHYCS2, 0x1f << 5, 0x19 << 5); delay(5000); SXISET4(sc, SXIAHCI_PHYCS0, 1 << 19); delay(20); timo = SXIAHCI_TIMEOUT; - while ((SXIREAD4(sc, SXIAHCI_PHYCS0) >> 28 & 3) != 2 && --timo) + while ((SXIREAD4(sc, SXIAHCI_PHYCS0) >> 28 & 7) != 2 && --timo) delay(10); if (!timo) { printf(": AHCI phy power up failed.\n"); @@ -158,7 +153,7 @@ sxiahci_attach(struct device *parent, st SXIWRITE4(sc, SXIAHCI_PI, 1); SXICLR4(sc, SXIAHCI_CAP, AHCI_REG_CAP_SPM); - sc->sc_flags |= AHCI_F_NO_PMP; /* XXX enough? */ + sc->sc_flags |= AHCI_F_NO_PMP | AHCI_F_SUNXI_QUIRK; if (ahci_attach(sc) != 0) { /* error printed by ahci_attach */ goto irq; Index: sys/dev/ic/ahci.c =================================================================== RCS file: /cvs/src/sys/dev/ic/ahci.c,v retrieving revision 1.16 diff -u -p -u -r1.16 ahci.c --- sys/dev/ic/ahci.c 13 Jul 2014 23:10:23 -0000 1.16 +++ sys/dev/ic/ahci.c 25 Nov 2014 01:54:18 -0000 @@ -836,6 +836,14 @@ ahci_port_start(struct ahci_port *ap, in { u_int32_t r; + if (ap->ap_sc->sc_flags & AHCI_F_SUNXI_QUIRK) { + /* Setup DMA */ + r = ahci_pread(ap, AHCI_PREG_SUNXI_DMA); + r &= ~AHCI_PREG_SUNXI_DMA_MASK; + r |= AHCI_PREG_SUNXI_DMA_INIT; /* XXX if fre_only? */ + ahci_pwrite(ap, AHCI_PREG_SUNXI_DMA, r); + } + /* XXX FBS: possibly turn FBS on here */ /* Turn on FRE (and ST) */ Index: sys/dev/ic/ahcireg.h =================================================================== RCS file: /cvs/src/sys/dev/ic/ahcireg.h,v retrieving revision 1.3 diff -u -p -u -r1.3 ahcireg.h --- sys/dev/ic/ahcireg.h 14 Apr 2014 04:42:22 -0000 1.3 +++ sys/dev/ic/ahcireg.h 25 Nov 2014 01:54:32 -0000 @@ -228,6 +228,10 @@ #define AHCI_PREG_FBS_DEC (1<<1) /* Device Error Clear */ #define AHCI_PREG_FBS_EN (1<<0) /* Enable */ +#define AHCI_PREG_SUNXI_DMA 0x70 /* Vendor Spec Port DMA for armv7/sunxi */ +#define AHCI_PREG_SUNXI_DMA_MASK (0xff<<8) +#define AHCI_PREG_SUNXI_DMA_INIT (0x44<<8) + struct ahci_cmd_hdr { u_int16_t flags; #define AHCI_CMD_LIST_FLAG_CFL 0x001f /* Command FIS Length */ Index: sys/dev/ic/ahcivar.h =================================================================== RCS file: /cvs/src/sys/dev/ic/ahcivar.h,v retrieving revision 1.8 diff -u -p -u -r1.8 ahcivar.h --- sys/dev/ic/ahcivar.h 14 Apr 2014 04:42:22 -0000 1.8 +++ sys/dev/ic/ahcivar.h 25 Nov 2014 01:54:32 -0000 @@ -123,6 +123,7 @@ struct ahci_softc { #define AHCI_F_IPMS_PROBE (1<<1) /* IPMS on failed PMP probe */ #define AHCI_F_NO_PMP (1<<2) /* ignore PMP capability */ #define AHCI_F_NO_MSI (1<<3) /* disable MSI */ +#define AHCI_F_SUNXI_QUIRK (1<<4) /* quirk for armv7/sunxi */ u_int sc_ncmds;