MLK-14938-18 sata: Add i.MX8 SATA support
authorYe Li <ye.li@nxp.com>
Mon, 27 Mar 2017 09:35:42 +0000 (17:35 +0800)
committerJason Liu <jason.hui.liu@nxp.com>
Thu, 2 Nov 2017 18:36:50 +0000 (02:36 +0800)
- 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 <hongxing.zhu@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
drivers/block/Makefile
drivers/block/ahci.c
drivers/block/sata_imx.c [new file with mode: 0644]
scripts/config_whitelist.txt

index a72feec..899dc9e 100644 (file)
@@ -23,6 +23,7 @@ obj-$(CONFIG_MX51_PATA) += mxc_ata.o
 obj-$(CONFIG_PATA_BFIN) += pata_bfin.o
 obj-$(CONFIG_SATA_CEVA) += sata_ceva.o
 obj-$(CONFIG_SATA_DWC) += sata_dwc.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
index 3fa14a7..7a53b64 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) Freescale Semiconductor, Inc. 2006.
+ * Copyright 2017 NXP
  * Author: Jason Jin<Jason.jin@freescale.com>
  *         Zhang Wei<wei.zhang@freescale.com>
  *
 #include <linux/ctype.h>
 #include <ahci.h>
 
+#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(u8 port);
 
 struct ahci_probe_ent *probe_ent = NULL;
@@ -186,6 +197,16 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
 
        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. */
@@ -265,6 +286,11 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
                ret = ahci_link_up(probe_ent, 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/block/sata_imx.c b/drivers/block/sata_imx.c
new file mode 100644 (file)
index 0000000..4ed2ebb
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <asm/imx-common/sci/sci.h>
+#include <ahci.h>
+#include <scsi.h>
+#include <imx8_hsio.h>
+
+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;
+}
index 27d1421..67c0a6a 100644 (file)
@@ -2644,6 +2644,7 @@ CONFIG_SATA1
 CONFIG_SATA2
 CONFIG_SATAPWR
 CONFIG_SATA_DWC
+CONFIG_SATA_IMX
 CONFIG_SATA_MV
 CONFIG_SATA_SIL
 CONFIG_SATA_SIL3114