From 9f538d64a8f7b216751f722e9c9ab4dc3af598ce Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 16 Apr 2018 20:11:30 -0700 Subject: [PATCH] MLK-14938-18 sata: Add i.MX8 SATA support - some delay is required between SATA_CTRL0 RST SET and CLR. Otherwise, sata phy link would be down. - specific the ahci modification by imx8qm platform. Signed-off-by: Richard Zhu Signed-off-by: Ye Li (cherry picked from commit 83812d4d636d98afdcb617a3aeab7b037e884aa1) --- drivers/ata/Kconfig | 6 ++++ drivers/ata/Makefile | 1 + drivers/ata/ahci.c | 25 +++++++++++++++++ drivers/ata/sata_imx.c | 64 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 drivers/ata/sata_imx.c diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 49a056e941..cc610092ac 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -79,6 +79,12 @@ config MVSATA_IDE Enable this driver to support the SATA controller found in some Marvell SoCs, running in IDE compatibility mode using PIO. +config SATA_IMX + bool "Enable SATA driver support for i.MX8QM" + select LIBATA + help + Enable this driver to support the SATA controller found in i.MX8QM SoCs. + config SATA_MV bool "Enable Marvell SATA controller driver support" select LIBATA diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 10bed53bb3..8fa3037153 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_LIBATA) += libata.o obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o obj-$(CONFIG_SATA) += sata.o obj-$(CONFIG_SATA_CEVA) += sata_ceva.o +obj-$(CONFIG_SATA_IMX) += sata_imx.o obj-$(CONFIG_SATA_MV) += sata_mv.o obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o obj-$(CONFIG_SATA_SIL) += sata_sil.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5fafb63aeb..b7ea379d69 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -26,6 +26,16 @@ #include #include +#ifdef CONFIG_SCSI_AHCI_PLAT +#ifdef CONFIG_FSL_HSIO +#define HW_PP2C 0xAC +#define HW_PP3C 0xB0 +#define HW_PP4C 0xB4 +#define HW_PP5C 0xB8 +#define HW_PAXIC 0xC0 +#endif +#endif + static int ata_io_flush(struct ahci_uc_priv *uc_priv, u8 port); #ifndef CONFIG_DM_SCSI @@ -191,6 +201,16 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) debug("ahci_host_init: start\n"); +#ifdef CONFIG_SCSI_AHCI_PLAT +#ifdef CONFIG_FSL_HSIO + writel((1 << 28) | (1 << 24) | readl(mmio + HW_PAXIC), mmio + HW_PAXIC); + writel(0x2718461C, mmio + HW_PP2C); + writel(0x0D081907, mmio + HW_PP3C); + writel(0x06000815, mmio + HW_PP4C); + writel(0x800C96A4, mmio + HW_PP5C); +#endif +#endif + cap_save = readl(mmio + HOST_CAP); cap_save &= ((1 << 28) | (1 << 17)); cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */ @@ -272,6 +292,11 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) ret = ahci_link_up(uc_priv, i); if (ret) { printf("SATA link %d timeout.\n", i); +#ifdef CONFIG_SCSI_AHCI_PLAT +#ifdef CONFIG_FSL_HSIO + return -ENODEV; +#endif +#endif continue; } else { debug("SATA link ok.\n"); diff --git a/drivers/ata/sata_imx.c b/drivers/ata/sata_imx.c new file mode 100644 index 0000000000..e713335e81 --- /dev/null +++ b/drivers/ata/sata_imx.c @@ -0,0 +1,64 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include +#include +#include + +int sata_init(void) +{ + int ret; + u32 val, i = 0; + + printf("start sata init\n"); + writel(0x22222222, GPR_LPCG_PHYX2APB_0_APB); + writel(0x22222222, GPR_LPCG_PHYX1_APB); + + setbits_le32(0x5F130008, BIT(21)); + setbits_le32(0x5F130008, BIT(23)); + + /* PHY_MODE to SATA100Mhz ref clk */ + setbits_le32(HW_PHYX1_CTRL0_ADDR, BIT(19)); + + /* + * bit 0 rx ena, bit 1 tx ena, bit 11 fast_init, + * bit12 PHY_X1_EPCS_SEL 1. + */ + setbits_le32(HW_MISC_CTRL0_ADDR, HW_MISC_CTRL0_IOB_RXENA + | HW_MISC_CTRL0_PHY_X1_EPCS_SEL); + + clrbits_le32(HW_SATA_CTRL0_ADDR, HW_SATA_CTRL0_PHY_RESET); + setbits_le32(HW_SATA_CTRL0_ADDR, HW_SATA_CTRL0_PHY_RESET); + setbits_le32(HW_SATA_CTRL0_ADDR, HW_SATA_CTRL0_RESET); + udelay(1); + clrbits_le32(HW_SATA_CTRL0_ADDR, HW_SATA_CTRL0_RESET); + setbits_le32(HW_SATA_CTRL0_ADDR, HW_SATA_CTRL0_RESET); + + setbits_le32(HW_PHYX1_CTRL0_ADDR, HW_PHYX1_CTRL0_APB_RSTN); + + for (i = 0; i < 100; i++) { + val = readl(HW_PHYX1_STTS0_ADDR); + val &= HW_PHYX1_STTS0_LANE0_TX_PLL_LOCK; + if (val == HW_PHYX1_STTS0_LANE0_TX_PLL_LOCK) + break; + udelay(1); + } + + if (val != HW_PHYX1_STTS0_LANE0_TX_PLL_LOCK) { + printf("TX PLL is not locked.\n"); + return -ENODEV; + } + + ret = ahci_init((void __iomem *)AHCI_BASE_ADDR); + if (ret) + return ret; + scsi_scan(1); + + return 0; +} -- 2.17.1