From 33685372cf7dc8687c15e426b3a11281d4efce47 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Mon, 15 Apr 2019 16:42:16 +0530 Subject: clk: sunxi: r40: Fix GMAC reset reg offset GMAC reset reg offset added by below commit seems to assume it as EMAC but R40 indeed using GMAC. "clk: sunxi: Implement EMAC, GMAC clocks, resets" (sha1: 68620c9698f109c1f001f80d282138a5c67cabef) So, fix by updating the reg offset for RST_BUS_GMAC. Signed-off-by: Jagan Teki --- drivers/clk/sunxi/clk_r40.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/sunxi/clk_r40.c b/drivers/clk/sunxi/clk_r40.c index 30beac98bb8..44abc4f536d 100644 --- a/drivers/clk/sunxi/clk_r40.c +++ b/drivers/clk/sunxi/clk_r40.c @@ -62,7 +62,6 @@ static struct ccu_reset r40_resets[] = { [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)), [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)), [RST_BUS_MMC3] = RESET(0x2c0, BIT(11)), - [RST_BUS_GMAC] = RESET(0x2c0, BIT(17)), [RST_BUS_SPI0] = RESET(0x2c0, BIT(20)), [RST_BUS_SPI1] = RESET(0x2c0, BIT(21)), [RST_BUS_SPI2] = RESET(0x2c0, BIT(22)), @@ -75,6 +74,8 @@ static struct ccu_reset r40_resets[] = { [RST_BUS_OHCI1] = RESET(0x2c0, BIT(30)), [RST_BUS_OHCI2] = RESET(0x2c0, BIT(31)), + [RST_BUS_GMAC] = RESET(0x2c4, BIT(17)), + [RST_BUS_UART0] = RESET(0x2d8, BIT(16)), [RST_BUS_UART1] = RESET(0x2d8, BIT(17)), [RST_BUS_UART2] = RESET(0x2d8, BIT(18)), -- cgit v1.3.1 From 0ed8eaf1de2074c40d9a2d4d3d829fd6acee1597 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Thu, 28 Feb 2019 00:26:50 +0530 Subject: net: sunxi_emac: Add CLK support Add CLk support for sunxi_emac to enable AHB_EMAC clock via CLK framework. Cc: Joe Hershberger Signed-off-by: Jagan Teki Acked-by: Joe Hershberger --- drivers/net/sunxi_emac.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c index 8dbd3c50c11..9a5f7fd3c7b 100644 --- a/drivers/net/sunxi_emac.c +++ b/drivers/net/sunxi_emac.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -157,6 +158,7 @@ struct sunxi_sramc_regs { struct emac_eth_dev { struct emac_regs *regs; + struct clk clk; struct mii_dev *bus; struct phy_device *phydev; int link_printed; @@ -500,14 +502,12 @@ static int _sunxi_emac_eth_send(struct emac_eth_dev *priv, void *packet, return 0; } -static void sunxi_emac_board_setup(struct emac_eth_dev *priv) +static int sunxi_emac_board_setup(struct emac_eth_dev *priv) { - struct sunxi_ccm_reg *const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; struct sunxi_sramc_regs *sram = (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; struct emac_regs *regs = priv->regs; - int pin; + int pin, ret; /* Map SRAM to EMAC */ setbits_le32(&sram->ctrl1, 0x5 << 2); @@ -517,10 +517,16 @@ static void sunxi_emac_board_setup(struct emac_eth_dev *priv) sunxi_gpio_set_cfgpin(pin, SUNXI_GPA_EMAC); /* Set up clock gating */ - setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC); + ret = clk_enable(&priv->clk); + if (ret) { + dev_err(dev, "failed to enable emac clock\n"); + return ret; + } /* Set MII clock */ clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); + + return 0; } static int sunxi_emac_eth_start(struct udevice *dev) @@ -557,9 +563,19 @@ static int sunxi_emac_eth_probe(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct emac_eth_dev *priv = dev_get_priv(dev); + int ret; priv->regs = (struct emac_regs *)pdata->iobase; - sunxi_emac_board_setup(priv); + + ret = clk_get_by_index(dev, 0, &priv->clk); + if (ret) { + dev_err(dev, "failed to get emac clock\n"); + return ret; + } + + ret = sunxi_emac_board_setup(priv); + if (ret) + return ret; return sunxi_emac_init_phy(priv, dev); } -- cgit v1.3.1 From 695f6043c9d84df6feeaca46661123c9f570397d Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Thu, 28 Feb 2019 00:26:51 +0530 Subject: net: sun8i_emac: Retrieve GMAC clock via 'syscon' phandle Unlike other Allwinner SoC's R40 GMAC clock control register is locate in CCU, but rest located via syscon itself. Since the phandle property for current code look for 'syscon' and it will grab the respective ccu or syscon base address based on DT property defined in respective SoC dtsi. So, use the existing 'syscon' code even for R40 for retrieving GMAC clock via CCU and update the register directly in sun8i_emac_set_syscon instead of writing it separately using ccm base. Cc: Joe Hershberger Cc: Lothar Felten Signed-off-by: Jagan Teki --- drivers/net/sun8i_emac.c | 55 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index c9798445c7d..a7fb7ac4055 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -285,10 +285,18 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata, int ret; u32 reg; - reg = readl(priv->sysctl_reg + 0x30); + if (priv->variant == R40_GMAC) { + /* Select RGMII for R40 */ + reg = readl(priv->sysctl_reg + 0x164); + reg |= CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII | + CCM_GMAC_CTRL_GPIT_RGMII | + CCM_GMAC_CTRL_TX_CLK_DELAY(CONFIG_GMAC_TX_DELAY); - if (priv->variant == R40_GMAC) + writel(reg, priv->sysctl_reg + 0x164); return 0; + } + + reg = readl(priv->sysctl_reg + 0x30); if (priv->variant == H3_EMAC) { ret = sun8i_emac_set_syscon_ephy(priv, ®); @@ -662,13 +670,6 @@ static void sun8i_emac_board_setup(struct emac_eth_dev *priv) /* De-assert EMAC */ setbits_le32(&ccm->ahb_gate1, BIT(AHB_GATE_OFFSET_GMAC)); - - /* Select RGMII for R40 */ - setbits_le32(&ccm->gmac_clk_cfg, - CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII | - CCM_GMAC_CTRL_GPIT_RGMII); - setbits_le32(&ccm->gmac_clk_cfg, - CCM_GMAC_CTRL_TX_CLK_DELAY(CONFIG_GMAC_TX_DELAY)); } else { /* Set clock gating for emac */ setbits_le32(&ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_GMAC)); @@ -850,25 +851,23 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev) return -EINVAL; } - if (priv->variant != R40_GMAC) { - offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "syscon"); - if (offset < 0) { - debug("%s: cannot find syscon node\n", __func__); - return -EINVAL; - } - reg = fdt_getprop(gd->fdt_blob, offset, "reg", NULL); - if (!reg) { - debug("%s: cannot find reg property in syscon node\n", - __func__); - return -EINVAL; - } - priv->sysctl_reg = fdt_translate_address((void *)gd->fdt_blob, - offset, reg); - if (priv->sysctl_reg == FDT_ADDR_T_NONE) { - debug("%s: Cannot find syscon base address\n", - __func__); - return -EINVAL; - } + offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "syscon"); + if (offset < 0) { + debug("%s: cannot find syscon node\n", __func__); + return -EINVAL; + } + + reg = fdt_getprop(gd->fdt_blob, offset, "reg", NULL); + if (!reg) { + debug("%s: cannot find reg property in syscon node\n", + __func__); + return -EINVAL; + } + priv->sysctl_reg = fdt_translate_address((void *)gd->fdt_blob, + offset, reg); + if (priv->sysctl_reg == FDT_ADDR_T_NONE) { + debug("%s: Cannot find syscon base address\n", __func__); + return -EINVAL; } pdata->phy_interface = -1; -- cgit v1.3.1 From d3a2c0586e01741e3763d67713f0e55746c46971 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Thu, 28 Feb 2019 00:26:58 +0530 Subject: net: sun8i_emac: Add CLK and RESET support Add CLK and RESET support for sun8i_emac driver to enable TX clock and reset pins via CLK and RESET framework. Cc: Joe Hershberger Cc: Lothar Felten Signed-off-by: Jagan Teki Acked-by: Joe Hershberger --- drivers/net/sun8i_emac.c | 57 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index a7fb7ac4055..98bd7a58232 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -14,12 +14,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #ifdef CONFIG_DM_GPIO #include @@ -135,6 +137,8 @@ struct emac_eth_dev { phys_addr_t sysctl_reg; struct phy_device *phydev; struct mii_dev *bus; + struct clk tx_clk; + struct reset_ctl tx_rst; #ifdef CONFIG_DM_GPIO struct gpio_desc reset_gpio; #endif @@ -647,9 +651,24 @@ static int sun8i_eth_write_hwaddr(struct udevice *dev) return _sun8i_write_hwaddr(priv, pdata->enetaddr); } -static void sun8i_emac_board_setup(struct emac_eth_dev *priv) +static int sun8i_emac_board_setup(struct emac_eth_dev *priv) { struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + int ret; + + ret = clk_enable(&priv->tx_clk); + if (ret) { + dev_err(dev, "failed to enable TX clock\n"); + return ret; + } + + if (reset_valid(&priv->tx_rst)) { + ret = reset_deassert(&priv->tx_rst); + if (ret) { + dev_err(dev, "failed to deassert TX reset\n"); + goto err_tx_clk; + } + } if (priv->variant == H3_EMAC) { /* Only H3/H5 have clock controls for internal EPHY */ @@ -664,19 +683,11 @@ static void sun8i_emac_board_setup(struct emac_eth_dev *priv) } } - if (priv->variant == R40_GMAC) { - /* Set clock gating for emac */ - setbits_le32(&ccm->ahb_reset1_cfg, BIT(AHB_RESET_OFFSET_GMAC)); - - /* De-assert EMAC */ - setbits_le32(&ccm->ahb_gate1, BIT(AHB_GATE_OFFSET_GMAC)); - } else { - /* Set clock gating for emac */ - setbits_le32(&ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_GMAC)); + return 0; - /* De-assert EMAC */ - setbits_le32(&ccm->ahb_reset0_cfg, BIT(AHB_RESET_OFFSET_GMAC)); - } +err_tx_clk: + clk_disable(&priv->tx_clk); + return ret; } #if defined(CONFIG_DM_GPIO) @@ -803,10 +814,14 @@ static int sun8i_emac_eth_probe(struct udevice *dev) struct sun8i_eth_pdata *sun8i_pdata = dev_get_platdata(dev); struct eth_pdata *pdata = &sun8i_pdata->eth_pdata; struct emac_eth_dev *priv = dev_get_priv(dev); + int ret; priv->mac_reg = (void *)pdata->iobase; - sun8i_emac_board_setup(priv); + ret = sun8i_emac_board_setup(priv); + if (ret) + return ret; + sun8i_emac_set_syscon(sun8i_pdata, priv); sun8i_mdio_init(dev->name, dev); @@ -835,8 +850,8 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev) int offset = 0; #ifdef CONFIG_DM_GPIO int reset_flags = GPIOD_IS_OUT; - int ret = 0; #endif + int ret; pdata->iobase = devfdt_get_addr(dev); if (pdata->iobase == FDT_ADDR_T_NONE) { @@ -851,6 +866,18 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev) return -EINVAL; } + ret = clk_get_by_name(dev, "stmmaceth", &priv->tx_clk); + if (ret) { + dev_err(dev, "failed to get TX clock\n"); + return ret; + } + + ret = reset_get_by_name(dev, "stmmaceth", &priv->tx_rst); + if (ret && ret != -ENOENT) { + dev_err(dev, "failed to get TX reset\n"); + return ret; + } + offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "syscon"); if (offset < 0) { debug("%s: cannot find syscon node\n", __func__); -- cgit v1.3.1 From f8c8669760610b2949d8d9ccaeef8231a44d4205 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 12 Apr 2019 16:28:54 +0530 Subject: sunxi: update SATA driver to always use DM_SCSI It seems like the Allwinner SATA driver is already quite capable of using the driver model, so we can force this on all boards and can remove support for a non-DM_SCSI build. This removes the warning about boards with SATA ports not being DM_SCSI compliant. It also takes the opportunity to move the driver out of the board/sunxi directory to join its siblings in drivers/ata, and to make it a proper Kconfig citizen. The board defconfigs stay untouched. Signed-off-by: Andre Przywara Reviewed-by: Simon Glass Reviewed-by: Jagan Teki [jagan: select DM_SCSI separately] Signed-off-by: Jagan Teki --- board/sunxi/Makefile | 3 - board/sunxi/ahci.c | 135 ----------------------------------------- drivers/ata/Kconfig | 8 +++ drivers/ata/Makefile | 1 + drivers/ata/ahci_sunxi.c | 125 ++++++++++++++++++++++++++++++++++++++ include/configs/sunxi-common.h | 6 -- scripts/config_whitelist.txt | 1 - 7 files changed, 134 insertions(+), 145 deletions(-) delete mode 100644 board/sunxi/ahci.c create mode 100644 drivers/ata/ahci_sunxi.c (limited to 'drivers') diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile index 4d6258d9324..c4e13f8c38d 100644 --- a/board/sunxi/Makefile +++ b/board/sunxi/Makefile @@ -8,9 +8,6 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. obj-y += board.o obj-$(CONFIG_SUN7I_GMAC) += gmac.o -ifndef CONFIG_SPL_BUILD -obj-$(CONFIG_SUNXI_AHCI) += ahci.o -endif obj-$(CONFIG_MACH_SUN4I) += dram_sun4i_auto.o obj-$(CONFIG_MACH_SUN5I) += dram_sun5i_auto.o obj-$(CONFIG_MACH_SUN7I) += dram_sun5i_auto.o diff --git a/board/sunxi/ahci.c b/board/sunxi/ahci.c deleted file mode 100644 index 9b030136672..00000000000 --- a/board/sunxi/ahci.c +++ /dev/null @@ -1,135 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define AHCI_PHYCS0R 0x00c0 -#define AHCI_PHYCS1R 0x00c4 -#define AHCI_PHYCS2R 0x00c8 -#define AHCI_RWCR 0x00fc - -/* This magic PHY initialisation was taken from the Allwinner releases - * and Linux driver, but is completely undocumented. - */ -static int sunxi_ahci_phy_init(u8 *reg_base) -{ - u32 reg_val; - int timeout; - - writel(0, reg_base + AHCI_RWCR); - mdelay(5); - - setbits_le32(reg_base + AHCI_PHYCS1R, 0x1 << 19); - clrsetbits_le32(reg_base + AHCI_PHYCS0R, - (0x7 << 24), - (0x5 << 24) | (0x1 << 23) | (0x1 << 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, (0x1 << 28) | (0x1 << 15)); - clrbits_le32(reg_base + AHCI_PHYCS1R, (0x1 << 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 = 250; /* Power up takes approx 50 us */ - for (;;) { - reg_val = readl(reg_base + AHCI_PHYCS0R) & (0x7 << 28); - if (reg_val == (0x2 << 28)) - break; - if (--timeout == 0) { - printf("AHCI PHY power up failed.\n"); - return -EIO; - } - udelay(1); - }; - - setbits_le32(reg_base + AHCI_PHYCS2R, (0x1 << 24)); - - timeout = 100; /* Calibration takes approx 10 us */ - for (;;) { - reg_val = readl(reg_base + AHCI_PHYCS2R) & (0x1 << 24); - if (reg_val == 0x0) - break; - if (--timeout == 0) { - printf("AHCI PHY calibration failed.\n"); - return -EIO; - } - udelay(1); - } - - mdelay(15); - - writel(0x7, reg_base + AHCI_RWCR); - - return 0; -} - -#ifndef CONFIG_DM_SCSI -void scsi_init(void) -{ - if (sunxi_ahci_phy_init((u8 *)SUNXI_SATA_BASE) < 0) - return; - - ahci_init((void __iomem *)SUNXI_SATA_BASE); -} -#else -static int sunxi_sata_probe(struct udevice *dev) -{ - ulong base; - u8 *reg; - int ret; - - base = dev_read_addr(dev); - if (base == FDT_ADDR_T_NONE) { - debug("%s: Failed to find address (err=%d\n)", __func__, ret); - return -EINVAL; - } - reg = (u8 *)base; - ret = sunxi_ahci_phy_init(reg); - if (ret) { - debug("%s: Failed to init phy (err=%d\n)", __func__, ret); - return ret; - } - ret = ahci_probe_scsi(dev, base); - if (ret) { - debug("%s: Failed to probe (err=%d\n)", __func__, ret); - return ret; - } - - return 0; -} - -static int sunxi_sata_bind(struct udevice *dev) -{ - struct udevice *scsi_dev; - int ret; - - ret = ahci_bind_scsi(dev, &scsi_dev); - if (ret) { - debug("%s: Failed to bind (err=%d\n)", __func__, ret); - return ret; - } - - return 0; -} - -static const struct udevice_id sunxi_ahci_ids[] = { - { .compatible = "allwinner,sun4i-a10-ahci" }, - { .compatible = "allwinner,sun8i-r40-ahci" }, - { } -}; - -U_BOOT_DRIVER(ahci_sunxi_drv) = { - .name = "ahci_sunxi", - .id = UCLASS_AHCI, - .of_match = sunxi_ahci_ids, - .bind = sunxi_sata_bind, - .probe = sunxi_sata_probe, -}; -#endif diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 7ebee75c0a5..4be5c63f09a 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -101,6 +101,14 @@ config SATA_SIL3114 help Enable this driver to support the SIL3114 SATA controllers. +config SUNXI_AHCI + bool "Enable Allwinner SATA driver support" + depends on AHCI + default y if ARCH_SUNXI + help + Enable this driver to support the SATA controllers found in the + Allwinner A10, A20 and R40 SoCs. + config AHCI_MVEBU bool "Marvell EBU AHCI SATA support" depends on ARCH_MVEBU diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 10bed53bb3f..a69edb10f7a 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -18,3 +18,4 @@ obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o obj-$(CONFIG_SATA_SIL) += sata_sil.o obj-$(CONFIG_SANDBOX) += sata_sandbox.o obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o +obj-$(CONFIG_SUNXI_AHCI) += ahci_sunxi.o diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c new file mode 100644 index 00000000000..77b932aa039 --- /dev/null +++ b/drivers/ata/ahci_sunxi.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include +#include + +#define AHCI_PHYCS0R 0x00c0 +#define AHCI_PHYCS1R 0x00c4 +#define AHCI_PHYCS2R 0x00c8 +#define AHCI_RWCR 0x00fc + +/* This magic PHY initialisation was taken from the Allwinner releases + * and Linux driver, but is completely undocumented. + */ +static int sunxi_ahci_phy_init(u8 *reg_base) +{ + u32 reg_val; + int timeout; + + writel(0, reg_base + AHCI_RWCR); + mdelay(5); + + setbits_le32(reg_base + AHCI_PHYCS1R, 0x1 << 19); + clrsetbits_le32(reg_base + AHCI_PHYCS0R, + (0x7 << 24), + (0x5 << 24) | (0x1 << 23) | (0x1 << 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, (0x1 << 28) | (0x1 << 15)); + clrbits_le32(reg_base + AHCI_PHYCS1R, (0x1 << 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 = 250; /* Power up takes approx 50 us */ + for (;;) { + reg_val = readl(reg_base + AHCI_PHYCS0R) & (0x7 << 28); + if (reg_val == (0x2 << 28)) + break; + if (--timeout == 0) { + printf("AHCI PHY power up failed.\n"); + return -EIO; + } + udelay(1); + }; + + setbits_le32(reg_base + AHCI_PHYCS2R, (0x1 << 24)); + + timeout = 100; /* Calibration takes approx 10 us */ + for (;;) { + reg_val = readl(reg_base + AHCI_PHYCS2R) & (0x1 << 24); + if (reg_val == 0x0) + break; + if (--timeout == 0) { + printf("AHCI PHY calibration failed.\n"); + return -EIO; + } + udelay(1); + } + + mdelay(15); + + writel(0x7, reg_base + AHCI_RWCR); + + return 0; +} + +static int sunxi_sata_probe(struct udevice *dev) +{ + ulong base; + u8 *reg; + int ret; + + base = dev_read_addr(dev); + if (base == FDT_ADDR_T_NONE) { + debug("%s: Failed to find address (err=%d\n)", __func__, ret); + return -EINVAL; + } + reg = (u8 *)base; + ret = sunxi_ahci_phy_init(reg); + if (ret) { + debug("%s: Failed to init phy (err=%d\n)", __func__, ret); + return ret; + } + ret = ahci_probe_scsi(dev, base); + if (ret) { + debug("%s: Failed to probe (err=%d\n)", __func__, ret); + return ret; + } + + return 0; +} + +static int sunxi_sata_bind(struct udevice *dev) +{ + struct udevice *scsi_dev; + int ret; + + ret = ahci_bind_scsi(dev, &scsi_dev); + if (ret) { + debug("%s: Failed to bind (err=%d\n)", __func__, ret); + return ret; + } + + return 0; +} + +static const struct udevice_id sunxi_ahci_ids[] = { + { .compatible = "allwinner,sun4i-a10-ahci" }, + { .compatible = "allwinner,sun8i-r40-ahci" }, + { } +}; + +U_BOOT_DRIVER(ahci_sunxi_drv) = { + .name = "ahci_sunxi", + .id = UCLASS_AHCI, + .of_match = sunxi_ahci_ids, + .bind = sunxi_sata_bind, + .probe = sunxi_sata_probe, +}; diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index b01d1c3c843..bc309940296 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -104,13 +104,7 @@ #define PHYS_SDRAM_0_SIZE 0x80000000 /* 2 GiB */ #ifdef CONFIG_AHCI -#define CONFIG_SCSI_AHCI_PLAT -#define CONFIG_SUNXI_AHCI #define CONFIG_SYS_64BIT_LBA -#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) #endif #define CONFIG_SETUP_MEMORY_TAGS diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index fa98efc24c0..d42219095aa 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1939,7 +1939,6 @@ CONFIG_STV0991 CONFIG_STV0991_HZ CONFIG_STV0991_HZ_CLOCK CONFIG_ST_SMI -CONFIG_SUNXI_AHCI CONFIG_SUNXI_GPIO CONFIG_SUNXI_MAX_FB_SIZE CONFIG_SUPERH_ON_CHIP_R8A66597 -- cgit v1.3.1