On Thu, Feb 20, 2014 at 8:48 AM, Ian Campbell <i...@hellion.org.uk> wrote: > 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> > --- > 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 | 95 > ++++++++++++++++++++++++++++++++++++++++ > include/ahci.h | 9 ++++ > include/configs/sunxi-common.h | 12 +++++ > 7 files changed, 144 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..2ae742d > --- /dev/null > +++ b/drivers/block/ahci_sunxi.c > @@ -0,0 +1,95 @@ > +#include <common.h> > +#include <ahci.h> > +#include <scsi.h> > +#include <asm/io.h> > +#include <asm/gpio.h> > + > +#define AHCI_BISTAFR 0x00a0 > +#define AHCI_BISTCR 0x00a4 > +#define AHCI_BISTFCTR 0x00a8 > +#define AHCI_BISTSR 0x00ac > +#define AHCI_BISTDECR 0x00b0 > +#define AHCI_DIAGNR0 0x00b4 > +#define AHCI_DIAGNR1 0x00b8 > +#define AHCI_OOBR 0x00bc > +#define AHCI_PHYCS0R 0x00c0 > +#define AHCI_PHYCS1R 0x00c4 > +#define AHCI_PHYCS2R 0x00c8 > +#define AHCI_TIMER1MS 0x00e0 > +#define AHCI_GPARAM1R 0x00e8 > +#define AHCI_GPARAM2R 0x00ec > +#define AHCI_PPARAMR 0x00f0 > +#define AHCI_TESTR 0x00f4 > +#define AHCI_VERSIONR 0x00f8 > +#define AHCI_IDR 0x00fc > +#define AHCI_RWCR 0x00fc > +#define AHCI_P0DMACR 0x0170 > +#define AHCI_P0PHYCR 0x0178 > +#define AHCI_P0PHYSR 0x017c
These registers are not sunxi specific, but part of a certain vendor's IP found in several SOCs. I can't tell you who, but it shouldn't be too hard to figure out. > + > +#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); > + I would guess this code or something very similar already exists in u-boot. Rob _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot