This enables the necessary clocks, in AHB0 and in PLL6_CFG. This is done
for sun7i only since I don't have access to any other sunxi platforms
with sata included.

The bulk of the code is taken from the Linux ahci sunxi platform driver
patches, adjusted for u-boot.

This adds the "PORT_DMA" tweaks to the core driver, under a suitable
ifdef.

This option is enabled for Cubieboard, Cubieboard2, Cubietruck and
Olinuxino Micro based on contents of Linux DTS files, including SATA
power pin config taken from the DTS. All build tested, but runtime
tested on cubietruck (FEL) only.

Signed-off-by: Ian Campbell <i...@hellion.org.uk>
---
v3:

    Drop unused register definitions

v2:

    make AHCI configurable per board, enabled for cubieboard,
    cubieboard2, cubietruck and Olinuxino Micro.
---
 arch/arm/cpu/armv7/sunxi/clock.c |  4 +++
 boards.cfg                       | 18 +++++-----
 drivers/block/Makefile           |  1 +
 drivers/block/ahci.c             | 15 +++++++-
 drivers/block/ahci_sunxi.c       | 77 ++++++++++++++++++++++++++++++++++++++++
 include/ahci.h                   |  9 +++++
 include/configs/sunxi-common.h   | 12 +++++++
 7 files changed, 126 insertions(+), 10 deletions(-)
 create mode 100644 drivers/block/ahci_sunxi.c

diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c
index 06bc283..2cc274b 100644
--- a/arch/arm/cpu/armv7/sunxi/clock.c
+++ b/arch/arm/cpu/armv7/sunxi/clock.c
@@ -51,6 +51,10 @@ static void clock_init_safe(void)
 #ifdef CONFIG_SUN7I
        writel(0x1 << 6 | readl(&ccm->ahb_gate0), &ccm->ahb_gate0);
        writel(0x1 << 31 | readl(&ccm->pll6_cfg), &ccm->pll6_cfg);
+#ifdef CONFIG_SCSI_AHCI_SUNXI
+       writel(0x1 << 25 |readl(&ccm->ahb_gate0), &ccm->ahb_gate0);
+       writel(0x1 << 14 | readl(&ccm->pll6_cfg), &ccm->pll6_cfg);
+#endif
 #endif
 }
 #endif
diff --git a/boards.cfg b/boards.cfg
index 100acc8..987bc54 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -354,8 +354,8 @@ Active  arm         armv7          sunxi       -            
   sunxi
 Active  arm         armv7          sunxi       -               sunxi           
    A13-OLinuXinoM                       
sun5i:A13_OLINUXINOM,SPL,NO_AXP,STATUSLED=201,CONS_INDEX=2                      
                                                  -
 Active  arm         armv7          sunxi       -               sunxi           
    A13-OLinuXinoM_FEL                   
sun5i:A13_OLINUXINOM,SPL_FEL,NO_AXP,STATUSLED=201,CONS_INDEX=2                  
                                                  -
 Active  arm         armv7          sunxi       -               sunxi           
    A13_MID                              sun5i:A13_MID,SPL,CONS_INDEX=2         
                                                                                
           -
-Active  arm         armv7          sunxi       -               sunxi           
    A20-OLinuXino_MICRO                  
sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL,SUNXI_EMAC                 
                                                  -
-Active  arm         armv7          sunxi       -               sunxi           
    A20-OLinuXino_MICRO_FEL              
sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL_FEL,SUNXI_EMAC             
                                                  -
+Active  arm         armv7          sunxi       -               sunxi           
    A20-OLinuXino_MICRO                  
sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPB(8)
                                                                   -
+Active  arm         armv7          sunxi       -               sunxi           
    A20-OLinuXino_MICRO_FEL              
sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL_FEL,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPB(8)
                                                               -
 Active  arm         armv7          sunxi       -               sunxi           
    Auxtek-T003                          
sun5i:AUXTEK_T003,SPL,AXP152_POWER,STATUSLED=34                                 
                                                  -
 Active  arm         armv7          sunxi       -               sunxi           
    Auxtek-T004                          
sun5i:AUXTEK_T004,SPL,AXP152_POWER,STATUSLED=34                                 
                                                  -
 Active  arm         armv7          sunxi       -               sunxi           
    ba10_tv_box                          sun4i:BA10_TV_BOX,SPL,SUNXI_EMAC       
                                                                                
           -
@@ -363,13 +363,13 @@ Active  arm         armv7          sunxi       -          
     sunxi
 Active  arm         armv7          sunxi       -               sunxi           
    Coby_MID8042                         sun4i:COBY_MID8042,SPL                 
                                                                                
           -
 Active  arm         armv7          sunxi       -               sunxi           
    Coby_MID9742                         sun4i:COBY_MID9742,SPL                 
                                                                                
           -
 Active  arm         armv7          sunxi       -               sunxi           
    Colombus                             sun6i:COLOMBUS                         
                                                                                
           -
-Active  arm         armv7          sunxi       -               sunxi           
    Cubieboard                           
sun4i:CUBIEBOARD,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245                    
                                                  -
-Active  arm         armv7          sunxi       -               sunxi           
    Cubieboard2                          
sun7i:CUBIEBOARD2,SPL,SUNXI_GMAC,STATUSLED=244,STATUSLED1=245,FAST_MBUS         
                                                  -
-Active  arm         armv7          sunxi       -               sunxi           
    Cubieboard2_FEL                      
sun7i:CUBIEBOARD2,SPL_FEL,SUNXI_GMAC,STATUSLED=244,STATUSLED1=245,FAST_MBUS     
                                                  -
-Active  arm         armv7          sunxi       -               sunxi           
    Cubietruck                           
sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII,STATUSLED=245,STATUSLED1=244,STATUSLED2=235,STATUSLED3=231,FAST_MBUS
                        -
-Active  arm         armv7          sunxi       -               sunxi           
    Cubietruck_FEL                       
sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII,STATUSLED=245,STATUSLED1=244,STATUSLED2=235,STATUSLED3=231,FAST_MBUS
                    -
-Active  arm         armv7          sunxi       -               sunxi           
    Cubieboard_512                       
sun4i:CUBIEBOARD_512,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245                
                                                  -
-Active  arm         armv7          sunxi       -               sunxi           
    Cubieboard_FEL                       
sun4i:CUBIEBOARD,SPL_FEL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245                
                                                  -
+Active  arm         armv7          sunxi       -               sunxi           
    Cubieboard                           
sun4i:CUBIEBOARD,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245,AHCI,SATAPWR=SUNXI_GPB(8)
                                            -
+Active  arm         armv7          sunxi       -               sunxi           
    Cubieboard2                          
sun7i:CUBIEBOARD2,SPL,SUNXI_GMAC,STATUSLED=244,STATUSLED1=245,FAST_MBUS,AHCI,SATAPWR=SUNXI_GPB(8)
                                 -
+Active  arm         armv7          sunxi       -               sunxi           
    Cubieboard2_FEL                      
sun7i:CUBIEBOARD2,SPL_FEL,SUNXI_GMAC,STATUSLED=244,STATUSLED1=245,FAST_MBUS,AHCI,SATAPWR=SUNXI_GPB(8)
                             -
+Active  arm         armv7          sunxi       -               sunxi           
    Cubietruck                           
sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII,STATUSLED=245,STATUSLED1=244,STATUSLED2=235,STATUSLED3=231,FAST_MBUS,AHCI,SATAPWR=SUNXI_GPH(12)
 -
+Active  arm         armv7          sunxi       -               sunxi           
    Cubietruck_FEL                       
sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII,STATUSLED=245,STATUSLED1=244,STATUSLED2=235,STATUSLED3=231,FAST_MBUS,AHCI,SATAPWR=SUNXI_GPH(12)
 -
+Active  arm         armv7          sunxi       -               sunxi           
    Cubieboard_512                       
sun4i:CUBIEBOARD_512,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245,AHCI,SATAPWR=SUNXI_GPB(8)
                                        -
+Active  arm         armv7          sunxi       -               sunxi           
    Cubieboard_FEL                       
sun4i:CUBIEBOARD,SPL_FEL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245,AHCI,SATAPWR=SUNXI_GPB(8)
                                        -
 Active  arm         armv7          sunxi       -               sunxi           
    DNS_M82                              sun4i:DNS_M82,SPL                      
                                                                                
           -
 Active  arm         armv7          sunxi       -               sunxi           
    EOMA68_A10                           
sun4i:EOMA68_A10,SPL,MMC_SUNXI_SLOT=3,SUNXI_EMAC                                
                                                  -
 Active  arm         armv7          sunxi       -               sunxi           
    EOMA68_A10_FEL                       
sun4i:EOMA68_A10,SPL_FEL,MMC_SUNXI_SLOT=3,SUNXI_EMAC                            
                                                  -
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 4e94378..e77188b 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -6,6 +6,7 @@
 #
 
 obj-$(CONFIG_SCSI_AHCI) += ahci.o
+obj-$(CONFIG_SCSI_AHCI_SUNXI) += ahci_sunxi.o
 obj-$(CONFIG_ATA_PIIX) += ata_piix.o
 obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
 obj-$(CONFIG_FSL_SATA) += fsl_sata.o
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index 90a0719..32be726 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -213,6 +213,13 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
                        msleep(500);
                }
 
+#ifdef CONFIG_SCSI_AHCI_SUNXI
+               tmp = readl(port_mmio + PORT_DMA);
+               tmp &= ~PORT_DMA_SETUP_MASK;
+               tmp |= PORT_DMA_SETUP_INIT;
+               writel_with_flush(tmp, port_mmio + PORT_DMA);
+#endif
+
                /* Add the spinup command to whatever mode bits may
                 * already be on in the command register.
                 */
@@ -490,7 +497,7 @@ static int ahci_port_start(u8 port)
        struct ahci_ioports *pp = &(probe_ent->port[port]);
        volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
        u32 port_status;
-       u32 mem;
+       u32 mem, tmp;
 
        debug("Enter start port: %d\n", port);
        port_status = readl(port_mmio + PORT_SCR_STAT);
@@ -540,6 +547,12 @@ static int ahci_port_start(u8 port)
 
        writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR);
 
+#ifdef CONFIG_SCSI_AHCI_SUNXI
+       tmp = readl(port_mmio + PORT_DMA);
+       tmp &= ~PORT_DMA_SETUP_MASK;
+        tmp |= PORT_DMA_SETUP_INIT;
+       writel_with_flush(tmp, port_mmio + PORT_DMA);
+#endif
        writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
                          PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
                          PORT_CMD_START, port_mmio + PORT_CMD);
diff --git a/drivers/block/ahci_sunxi.c b/drivers/block/ahci_sunxi.c
new file mode 100644
index 0000000..6bffc76
--- /dev/null
+++ b/drivers/block/ahci_sunxi.c
@@ -0,0 +1,77 @@
+#include <common.h>
+#include <ahci.h>
+#include <scsi.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+
+#define AHCI_PHYCS0R 0x00c0
+#define AHCI_PHYCS1R 0x00c4
+#define AHCI_PHYCS2R 0x00c8
+#define AHCI_RWCR    0x00fc
+
+#define BIT(x) (1<<x)
+static u32 sunxi_getbits(u8 *reg, u8 mask, u8 shift)
+{
+       return (readl(reg) >> shift) & mask;
+}
+
+static int sunxi_ahci_phy_init(u32 base)
+{
+       u8 *reg_base = (u8 *)base;
+       u32 reg_val;
+       int timeout;
+
+       /* This magic is from the original code */
+       writel(0, reg_base + AHCI_RWCR);
+       mdelay(5);
+
+       setbits_le32(reg_base + AHCI_PHYCS1R, BIT(19));
+       clrsetbits_le32(reg_base + AHCI_PHYCS0R,
+                       (0x7 << 24),
+                       (0x5 << 24) | BIT(23) | BIT(18));
+       clrsetbits_le32(reg_base + AHCI_PHYCS1R,
+                       (0x3 << 16) | (0x1f << 8) | (0x3 << 6),
+                       (0x2 << 16) | (0x6 << 8) | (0x2 << 6));
+       setbits_le32(reg_base + AHCI_PHYCS1R, BIT(28) | BIT(15));
+       clrbits_le32(reg_base + AHCI_PHYCS1R, BIT(19));
+       clrsetbits_le32(reg_base + AHCI_PHYCS0R,
+                       (0x7 << 20), (0x3 << 20));
+       clrsetbits_le32(reg_base + AHCI_PHYCS2R,
+                       (0x1f << 5), (0x19 << 5));
+       mdelay(5);
+
+       setbits_le32(reg_base + AHCI_PHYCS0R, (0x1 << 19));
+
+       timeout = 0x100000;
+       do {
+               reg_val = sunxi_getbits(reg_base + AHCI_PHYCS0R, 0x7, 28);
+       } while (--timeout && (reg_val != 0x2));
+       if (!timeout)
+               printf("PHY power up failed.\n");
+
+       setbits_le32(reg_base + AHCI_PHYCS2R, (0x1 << 24));
+
+       timeout = 0x100000;
+       do {
+               reg_val = sunxi_getbits(reg_base + AHCI_PHYCS2R, 0x1, 24);
+       } while (--timeout && reg_val);
+       if (!timeout)
+               printf("PHY calibration failed.\n");
+       mdelay(15);
+
+       writel(0x7, reg_base + AHCI_RWCR);
+
+       return 0;
+}
+
+void scsi_init(void)
+{
+       printf("SUNXI SCSI INIT\n");
+#ifdef CONFIG_SATAPWR
+       gpio_direction_output(CONFIG_SATAPWR, 1);
+#endif
+
+       sunxi_ahci_phy_init(SUNXI_SATA_BASE);
+
+       ahci_init(SUNXI_SATA_BASE);
+}
diff --git a/include/ahci.h b/include/ahci.h
index 90e8509..c94689c 100644
--- a/include/ahci.h
+++ b/include/ahci.h
@@ -58,6 +58,15 @@
 #define PORT_SCR_ERR           0x30 /* SATA phy register: SError */
 #define PORT_SCR_ACT           0x34 /* SATA phy register: SActive */
 
+#ifdef CONFIG_SCSI_AHCI_SUNXI
+#define PORT_DMA               0x70 /* SUNXI specific "DMA register" */
+
+#define PORT_DMA_SETUP_OFFSET 8 /* dma setup offset */
+#define PORT_DMA_SETUP_MASK   (0xff << PORT_DMA_SETUP_OFFSET) /* dma mask */
+#define PORT_DMA_SETUP_INIT   (0x44 << PORT_DMA_SETUP_OFFSET)
+#endif
+
+
 /* PORT_IRQ_{STAT,MASK} bits */
 #define PORT_IRQ_COLD_PRES     (1 << 31) /* cold presence detect */
 #define PORT_IRQ_TF_ERR                (1 << 30) /* task file error */
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index d46a43f..be4c6b5 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -88,6 +88,18 @@
 #define CONFIG_SYS_NAND_BASE            0x00
 #endif
 
+#ifdef CONFIG_AHCI
+#define CONFIG_LIBATA
+#define CONFIG_SCSI_AHCI
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SCSI_AHCI_SUNXI
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID    1
+#define CONFIG_SYS_SCSI_MAX_LUN                1
+#define CONFIG_SYS_SCSI_MAX_DEVICE     (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
+                       CONFIG_SYS_SCSI_MAX_LUN)
+#define CONFIG_CMD_SCSI
+#endif
+
 #define CONFIG_CMD_MEMORY
 #define CONFIG_CMD_SETEXPR
 
-- 
1.8.5.3

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to