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;
 


Reply via email to