From: Andre Przywara Date: Fri, 12 Apr 2019 10:58:54 +0000 (+0530) Subject: sunxi: update SATA driver to always use DM_SCSI X-Git-Tag: v2019.07-rc1~18^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f8c8669760610b2949d8d9ccaeef8231a44d4205;p=platform%2Fkernel%2Fu-boot.git 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 --- diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile index 4d6258d932..c4e13f8c38 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 9b03013667..0000000000 --- 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 7ebee75c0a..4be5c63f09 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 10bed53bb3..a69edb10f7 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 0000000000..77b932aa03 --- /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 b01d1c3c84..bc30994029 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 fa98efc24c..d42219095a 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