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
/*
* 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;
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. */
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");
--- /dev/null
+/*
+ * 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;
+}