Commit 83812d4d636d98afdcb617a3aeab7b037e884aa1

Authored by Ye Li
1 parent 99c90ff2de

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 <hongxing.zhu@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>

Showing 4 changed files with 96 additions and 0 deletions Side-by-side Diff

... ... @@ -79,6 +79,12 @@
79 79 Enable this driver to support the SATA controller found in
80 80 some Marvell SoCs, running in IDE compatibility mode using PIO.
81 81  
  82 +config SATA_IMX
  83 + bool "Enable SATA driver support for i.MX8QM"
  84 + select LIBATA
  85 + help
  86 + Enable this driver to support the SATA controller found in i.MX8QM SoCs.
  87 +
82 88 config SATA_MV
83 89 bool "Enable Marvell SATA controller driver support"
84 90 select LIBATA
drivers/ata/Makefile
... ... @@ -15,6 +15,7 @@
15 15 obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o
16 16 obj-$(CONFIG_SATA) += sata.o
17 17 obj-$(CONFIG_SATA_CEVA) += sata_ceva.o
  18 +obj-$(CONFIG_SATA_IMX) += sata_imx.o
18 19 obj-$(CONFIG_SATA_MV) += sata_mv.o
19 20 obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
20 21 obj-$(CONFIG_SATA_SIL) += sata_sil.o
... ... @@ -27,6 +27,16 @@
27 27 #include <dm/device-internal.h>
28 28 #include <dm/lists.h>
29 29  
  30 +#ifdef CONFIG_SCSI_AHCI_PLAT
  31 +#ifdef CONFIG_FSL_HSIO
  32 +#define HW_PP2C 0xAC
  33 +#define HW_PP3C 0xB0
  34 +#define HW_PP4C 0xB4
  35 +#define HW_PP5C 0xB8
  36 +#define HW_PAXIC 0xC0
  37 +#endif
  38 +#endif
  39 +
30 40 static int ata_io_flush(struct ahci_uc_priv *uc_priv, u8 port);
31 41  
32 42 #ifndef CONFIG_DM_SCSI
... ... @@ -192,6 +202,16 @@
192 202  
193 203 debug("ahci_host_init: start\n");
194 204  
  205 +#ifdef CONFIG_SCSI_AHCI_PLAT
  206 +#ifdef CONFIG_FSL_HSIO
  207 + writel((1 << 28) | (1 << 24) | readl(mmio + HW_PAXIC), mmio + HW_PAXIC);
  208 + writel(0x2718461C, mmio + HW_PP2C);
  209 + writel(0x0D081907, mmio + HW_PP3C);
  210 + writel(0x06000815, mmio + HW_PP4C);
  211 + writel(0x800C96A4, mmio + HW_PP5C);
  212 +#endif
  213 +#endif
  214 +
195 215 cap_save = readl(mmio + HOST_CAP);
196 216 cap_save &= ((1 << 28) | (1 << 17));
197 217 cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */
... ... @@ -271,6 +291,11 @@
271 291 ret = ahci_link_up(uc_priv, i);
272 292 if (ret) {
273 293 printf("SATA link %d timeout.\n", i);
  294 +#ifdef CONFIG_SCSI_AHCI_PLAT
  295 +#ifdef CONFIG_FSL_HSIO
  296 + return -ENODEV;
  297 +#endif
  298 +#endif
274 299 continue;
275 300 } else {
276 301 debug("SATA link ok.\n");
drivers/ata/sata_imx.c
  1 +/*
  2 + * Copyright 2017 NXP
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +#include <common.h>
  7 +#include <linux/errno.h>
  8 +#include <asm/io.h>
  9 +#include <asm/mach-imx/sci/sci.h>
  10 +#include <ahci.h>
  11 +#include <scsi.h>
  12 +#include <imx8_hsio.h>
  13 +
  14 +int sata_init(void)
  15 +{
  16 + int ret;
  17 + u32 val, i = 0;
  18 +
  19 + printf("start sata init\n");
  20 + writel(0x22222222, GPR_LPCG_PHYX2APB_0_APB);
  21 + writel(0x22222222, GPR_LPCG_PHYX1_APB);
  22 +
  23 + setbits_le32(0x5F130008, BIT(21));
  24 + setbits_le32(0x5F130008, BIT(23));
  25 +
  26 + /* PHY_MODE to SATA100Mhz ref clk */
  27 + setbits_le32(HW_PHYX1_CTRL0_ADDR, BIT(19));
  28 +
  29 + /*
  30 + * bit 0 rx ena, bit 1 tx ena, bit 11 fast_init,
  31 + * bit12 PHY_X1_EPCS_SEL 1.
  32 + */
  33 + setbits_le32(HW_MISC_CTRL0_ADDR, HW_MISC_CTRL0_IOB_RXENA
  34 + | HW_MISC_CTRL0_PHY_X1_EPCS_SEL);
  35 +
  36 + clrbits_le32(HW_SATA_CTRL0_ADDR, HW_SATA_CTRL0_PHY_RESET);
  37 + setbits_le32(HW_SATA_CTRL0_ADDR, HW_SATA_CTRL0_PHY_RESET);
  38 + setbits_le32(HW_SATA_CTRL0_ADDR, HW_SATA_CTRL0_RESET);
  39 + udelay(1);
  40 + clrbits_le32(HW_SATA_CTRL0_ADDR, HW_SATA_CTRL0_RESET);
  41 + setbits_le32(HW_SATA_CTRL0_ADDR, HW_SATA_CTRL0_RESET);
  42 +
  43 + setbits_le32(HW_PHYX1_CTRL0_ADDR, HW_PHYX1_CTRL0_APB_RSTN);
  44 +
  45 + for (i = 0; i < 100; i++) {
  46 + val = readl(HW_PHYX1_STTS0_ADDR);
  47 + val &= HW_PHYX1_STTS0_LANE0_TX_PLL_LOCK;
  48 + if (val == HW_PHYX1_STTS0_LANE0_TX_PLL_LOCK)
  49 + break;
  50 + udelay(1);
  51 + }
  52 +
  53 + if (val != HW_PHYX1_STTS0_LANE0_TX_PLL_LOCK) {
  54 + printf("TX PLL is not locked.\n");
  55 + return -ENODEV;
  56 + }
  57 +
  58 + ret = ahci_init((void __iomem *)AHCI_BASE_ADDR);
  59 + if (ret)
  60 + return ret;
  61 + scsi_scan(1);
  62 +
  63 + return 0;
  64 +}