Commit c206ca62ec4e3a04af24c668d2394b81142b6ec4

Authored by Ye Li
1 parent 7a3ac31ccd

MLK-22293-2 ata: Add iMX AHCI driver

Add new iMX AHCI driver which is ported from kernel and support
imx6q/qp/imx8qm.
The new driver adapt to SCSI through common AHCI interfaces in ahci.c
So after enabling it, we will use SCSI commands to access the SATA
disk device.

Signed-off-by: Ye Li <ye.li@nxp.com>

Showing 3 changed files with 866 additions and 0 deletions Side-by-side Diff

... ... @@ -59,6 +59,15 @@
59 59 Enable this driver to support Sata devices through
60 60 Synopsys DWC AHCI module.
61 61  
  62 +config IMX_AHCI
  63 + bool "Enable IMX AHCI driver support"
  64 + select SCSI_AHCI
  65 + depends on AHCI
  66 + depends on DM_SCSI
  67 + help
  68 + Enable this driver to support Sata devices through
  69 + i.MX AHCI module.
  70 +
62 71 config DWC_AHSATA
63 72 bool "Enable DWC AHSATA driver support"
64 73 select LIBATA
drivers/ata/Makefile
... ... @@ -13,6 +13,7 @@
13 13 obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o
14 14 obj-$(CONFIG_SATA) += sata.o
15 15 obj-$(CONFIG_SATA_CEVA) += sata_ceva.o
  16 +obj-$(CONFIG_IMX_AHCI) += imx_ahci.o
16 17 obj-$(CONFIG_SATA_MV) += sata_mv.o
17 18 obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
18 19 obj-$(CONFIG_SATA_SIL) += sata_sil.o
drivers/ata/imx_ahci.c
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +/*
  3 + * Copyright 2019 NXP
  4 + */
  5 +
  6 +#include <common.h>
  7 +#include <dm.h>
  8 +#include <ahci.h>
  9 +#include <scsi.h>
  10 +#include <sata.h>
  11 +#include <asm/io.h>
  12 +#if CONFIG_IS_ENABLED(CLK)
  13 +#include <clk.h>
  14 +#else
  15 +#include <asm/arch/clock.h>
  16 +#include <asm/arch/sys_proto.h>
  17 +#endif
  18 +#include <asm/arch-mx6/iomux.h>
  19 +#include <syscon.h>
  20 +#include <regmap.h>
  21 +#include <asm-generic/gpio.h>
  22 +
  23 +enum {
  24 + /* Timer 1-ms Register */
  25 + IMX_TIMER1MS = 0x00e0,
  26 + /* Port0 PHY Control Register */
  27 + IMX_P0PHYCR = 0x0178,
  28 + IMX_P0PHYCR_TEST_PDDQ = 1 << 20,
  29 + IMX_P0PHYCR_CR_READ = 1 << 19,
  30 + IMX_P0PHYCR_CR_WRITE = 1 << 18,
  31 + IMX_P0PHYCR_CR_CAP_DATA = 1 << 17,
  32 + IMX_P0PHYCR_CR_CAP_ADDR = 1 << 16,
  33 + /* Port0 PHY Status Register */
  34 + IMX_P0PHYSR = 0x017c,
  35 + IMX_P0PHYSR_CR_ACK = 1 << 18,
  36 + IMX_P0PHYSR_CR_DATA_OUT = 0xffff << 0,
  37 + /* Lane0 Output Status Register */
  38 + IMX_LANE0_OUT_STAT = 0x2003,
  39 + IMX_LANE0_OUT_STAT_RX_PLL_STATE = 1 << 1,
  40 + /* Clock Reset Register */
  41 + IMX_CLOCK_RESET = 0x7f3f,
  42 + IMX_CLOCK_RESET_RESET = 1 << 0,
  43 + /* IMX8QM HSIO AHCI definitions */
  44 + IMX8QM_SATA_PHY_REG03_RX_IMPED_RATIO = 0x03,
  45 + IMX8QM_SATA_PHY_REG09_TX_IMPED_RATIO = 0x09,
  46 + IMX8QM_SATA_PHY_REG10_TX_POST_CURSOR_RATIO = 0x0a,
  47 + IMX8QM_SATA_PHY_GEN1_TX_POST_CURSOR_RATIO = 0x15,
  48 + IMX8QM_SATA_PHY_IMPED_RATIO_85OHM = 0x6c,
  49 + IMX8QM_SATA_PHY_REG22_TX_POST_CURSOR_RATIO = 0x16,
  50 + IMX8QM_SATA_PHY_GEN2_TX_POST_CURSOR_RATIO = 0x00,
  51 + IMX8QM_SATA_PHY_REG24_TX_AMP_RATIO_MARGIN0 = 0x18,
  52 + IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN0 = 0x64,
  53 + IMX8QM_SATA_PHY_REG25_TX_AMP_RATIO_MARGIN1 = 0x19,
  54 + IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN1 = 0x70,
  55 + IMX8QM_SATA_PHY_REG26_TX_AMP_RATIO_MARGIN2 = 0x1a,
  56 + IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN2 = 0x69,
  57 + IMX8QM_SATA_PHY_REG48_PMA_STATUS = 0x30,
  58 + IMX8QM_SATA_PHY_REG48_PMA_RDY = BIT(7),
  59 + IMX8QM_SATA_PHY_REG128_UPDATE_SETTING = 0x80,
  60 + IMX8QM_SATA_PHY_UPDATE_SETTING = 0x01,
  61 + IMX8QM_LPCG_PHYX2_OFFSET = 0x00000,
  62 + IMX8QM_CSR_PHYX2_OFFSET = 0x90000,
  63 + IMX8QM_CSR_PHYX1_OFFSET = 0xa0000,
  64 + IMX8QM_CSR_PHYX_STTS0_OFFSET = 0x4,
  65 + IMX8QM_CSR_PCIEA_OFFSET = 0xb0000,
  66 + IMX8QM_CSR_PCIEB_OFFSET = 0xc0000,
  67 + IMX8QM_CSR_SATA_OFFSET = 0xd0000,
  68 + IMX8QM_CSR_PCIE_CTRL2_OFFSET = 0x8,
  69 + IMX8QM_CSR_MISC_OFFSET = 0xe0000,
  70 + /* IMX8QM SATA specific control registers */
  71 + IMX8QM_SATA_PPCFG_OFFSET = 0xa8,
  72 + IMX8QM_SATA_PPCFG_FORCE_PHY_RDY = BIT(20),
  73 + IMX8QM_SATA_PPCFG_BIST_PATTERN_MASK = 0x7 << 21,
  74 + IMX8QM_SATA_PPCFG_BIST_PATTERN_OFFSET = 21,
  75 + IMX8QM_SATA_PPCFG_BIST_PATTERN_EN = BIT(24),
  76 + IMX8QM_SATA_PPCFG_BIST_PATTERN_NOALIGNS = BIT(26),
  77 + IMX8QM_SATA_PP2CFG_OFFSET = 0xac,
  78 + IMX8QM_SATA_PP2CFG_COMINIT_NEGATE_MIN = 0x28 << 24,
  79 + IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP = 0x18 << 16,
  80 + IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP_MAX = 0x2b << 8,
  81 + IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP_MIN = 0x1b << 0,
  82 + IMX8QM_SATA_PP3CFG_OFFSET = 0xb0,
  83 + IMX8QM_SATA_PP3CFG_COMWAKE_NEGATE_MIN = 0x0e << 24,
  84 + IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP = 0x08 << 16,
  85 + IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP_MAX = 0x0f << 8,
  86 + IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP_MIN = 0x01 << 0,
  87 +
  88 + IMX8QM_LPCG_PHYX2_PCLK0_MASK = (0x3 << 16),
  89 + IMX8QM_LPCG_PHYX2_PCLK1_MASK = (0x3 << 20),
  90 + IMX8QM_PHY_APB_RSTN_0 = BIT(0),
  91 + IMX8QM_PHY_MODE_SATA = BIT(19),
  92 + IMX8QM_PHY_MODE_MASK = (0xf << 17),
  93 + IMX8QM_PHY_PIPE_RSTN_0 = BIT(24),
  94 + IMX8QM_PHY_PIPE_RSTN_OVERRIDE_0 = BIT(25),
  95 + IMX8QM_PHY_PIPE_RSTN_1 = BIT(26),
  96 + IMX8QM_PHY_PIPE_RSTN_OVERRIDE_1 = BIT(27),
  97 + IMX8QM_STTS0_LANE0_TX_PLL_LOCK = BIT(4),
  98 + IMX8QM_MISC_IOB_RXENA = BIT(0),
  99 + IMX8QM_MISC_IOB_TXENA = BIT(1),
  100 + IMX8QM_MISC_PHYX1_EPCS_SEL = BIT(12),
  101 + IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_1 = BIT(24),
  102 + IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_0 = BIT(25),
  103 + IMX8QM_MISC_CLKREQN_IN_OVERRIDE_1 = BIT(28),
  104 + IMX8QM_MISC_CLKREQN_IN_OVERRIDE_0 = BIT(29),
  105 + IMX8QM_SATA_CTRL_RESET_N = BIT(12),
  106 + IMX8QM_SATA_CTRL_EPCS_PHYRESET_N = BIT(7),
  107 + IMX8QM_SATA_CTRL_EPCS_TXDEEMP_SEL = BIT(6),
  108 + IMX8QM_SATA_CTRL_EPCS_TXDEEMP = BIT(5),
  109 + IMX8QM_CTRL_BUTTON_RST_N = BIT(21),
  110 + IMX8QM_CTRL_POWER_UP_RST_N = BIT(23),
  111 + IMX8QM_CTRL_LTSSM_ENABLE = BIT(4),
  112 +};
  113 +
  114 +enum ahci_imx_type {
  115 + AHCI_IMX6Q,
  116 + AHCI_IMX6QP,
  117 + AHCI_IMX8QM,
  118 +};
  119 +
  120 +struct imx_ahci_priv {
  121 +#if CONFIG_IS_ENABLED(CLK)
  122 + struct clk sata_clk;
  123 + struct clk sata_ref_clk;
  124 + struct clk ahb_clk;
  125 + struct clk epcs_tx_clk;
  126 + struct clk epcs_rx_clk;
  127 + struct clk phy_apbclk;
  128 + struct clk phy_pclk0;
  129 + struct clk phy_pclk1;
  130 +#endif
  131 + enum ahci_imx_type type;
  132 + void __iomem *phy_base;
  133 + void __iomem *mmio;
  134 + struct regmap *gpr;
  135 + struct gpio_desc clkreq_gpio;
  136 + u32 phy_params;
  137 + u32 imped_ratio;
  138 + u32 ext_osc;
  139 +};
  140 +
  141 +static int imx_phy_crbit_assert(void __iomem *mmio, u32 bit, bool assert)
  142 +{
  143 + int timeout = 10;
  144 + u32 crval;
  145 + u32 srval;
  146 +
  147 + /* Assert or deassert the bit */
  148 + crval = readl(mmio + IMX_P0PHYCR);
  149 + if (assert)
  150 + crval |= bit;
  151 + else
  152 + crval &= ~bit;
  153 + writel(crval, mmio + IMX_P0PHYCR);
  154 +
  155 + /* Wait for the cr_ack signal */
  156 + do {
  157 + srval = readl(mmio + IMX_P0PHYSR);
  158 + if ((assert ? srval : ~srval) & IMX_P0PHYSR_CR_ACK)
  159 + break;
  160 + udelay(100);
  161 + } while (--timeout);
  162 +
  163 + return timeout ? 0 : -ETIMEDOUT;
  164 +}
  165 +
  166 +static int imx_phy_reg_addressing(u16 addr, void __iomem *mmio)
  167 +{
  168 + u32 crval = addr;
  169 + int ret;
  170 +
  171 + /* Supply the address on cr_data_in */
  172 + writel(crval, mmio + IMX_P0PHYCR);
  173 +
  174 + /* Assert the cr_cap_addr signal */
  175 + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, true);
  176 + if (ret)
  177 + return ret;
  178 +
  179 + /* Deassert cr_cap_addr */
  180 + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, false);
  181 + if (ret)
  182 + return ret;
  183 +
  184 + return 0;
  185 +}
  186 +
  187 +static int imx_phy_reg_write(u16 val, void __iomem *mmio)
  188 +{
  189 + u32 crval = val;
  190 + int ret;
  191 +
  192 + /* Supply the data on cr_data_in */
  193 + writel(crval, mmio + IMX_P0PHYCR);
  194 +
  195 + /* Assert the cr_cap_data signal */
  196 + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, true);
  197 + if (ret)
  198 + return ret;
  199 +
  200 + /* Deassert cr_cap_data */
  201 + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, false);
  202 + if (ret)
  203 + return ret;
  204 +
  205 + if (val & IMX_CLOCK_RESET_RESET) {
  206 + /*
  207 + * In case we're resetting the phy, it's unable to acknowledge,
  208 + * so we return immediately here.
  209 + */
  210 + crval |= IMX_P0PHYCR_CR_WRITE;
  211 + writel(crval, mmio + IMX_P0PHYCR);
  212 + goto out;
  213 + }
  214 +
  215 + /* Assert the cr_write signal */
  216 + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, true);
  217 + if (ret)
  218 + return ret;
  219 +
  220 + /* Deassert cr_write */
  221 + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, false);
  222 + if (ret)
  223 + return ret;
  224 +
  225 +out:
  226 + return 0;
  227 +}
  228 +
  229 +static int imx_phy_reg_read(u16 *val, void __iomem *mmio)
  230 +{
  231 + int ret;
  232 +
  233 + /* Assert the cr_read signal */
  234 + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, true);
  235 + if (ret)
  236 + return ret;
  237 +
  238 + /* Capture the data from cr_data_out[] */
  239 + *val = readl(mmio + IMX_P0PHYSR) & IMX_P0PHYSR_CR_DATA_OUT;
  240 +
  241 + /* Deassert cr_read */
  242 + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, false);
  243 + if (ret)
  244 + return ret;
  245 +
  246 + return 0;
  247 +}
  248 +
  249 +static int imx_sata_phy_reset(struct imx_ahci_priv *priv)
  250 +{
  251 + void __iomem *mmio = priv->mmio;
  252 + int timeout = 10;
  253 + u16 val;
  254 + int ret;
  255 +
  256 + /* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */
  257 + ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio);
  258 + if (ret)
  259 + return ret;
  260 + ret = imx_phy_reg_write(IMX_CLOCK_RESET_RESET, mmio);
  261 + if (ret)
  262 + return ret;
  263 +
  264 + /* Wait for PHY RX_PLL to be stable */
  265 + do {
  266 + udelay(100);
  267 + ret = imx_phy_reg_addressing(IMX_LANE0_OUT_STAT, mmio);
  268 + if (ret)
  269 + return ret;
  270 + ret = imx_phy_reg_read(&val, mmio);
  271 + if (ret)
  272 + return ret;
  273 + if (val & IMX_LANE0_OUT_STAT_RX_PLL_STATE)
  274 + break;
  275 + } while (--timeout);
  276 +
  277 + return timeout ? 0 : -ETIMEDOUT;
  278 +}
  279 +
  280 +static int imx8_sata_enable(struct udevice *dev)
  281 +{
  282 + u32 val, reg;
  283 + int i, ret;
  284 + struct imx_ahci_priv *imxpriv = dev_get_priv(dev);
  285 +
  286 +#if CONFIG_IS_ENABLED(CLK)
  287 + /* configure the hsio for sata */
  288 + ret = clk_enable(&imxpriv->phy_pclk0);
  289 + if (ret < 0) {
  290 + dev_err(dev, "can't enable phy pclk0.\n");
  291 + return ret;
  292 + }
  293 + ret = clk_enable(&imxpriv->phy_pclk1);
  294 + if (ret < 0) {
  295 + dev_err(dev, "can't enable phy pclk1.\n");
  296 + goto disable_phy_pclk0;
  297 + }
  298 + ret = clk_enable(&imxpriv->epcs_tx_clk);
  299 + if (ret < 0) {
  300 + dev_err(dev, "can't enable epcs tx clk.\n");
  301 + goto disable_phy_pclk1;
  302 + }
  303 + ret = clk_enable(&imxpriv->epcs_rx_clk);
  304 + if (ret < 0) {
  305 + dev_err(dev, "can't enable epcs rx clk.\n");
  306 + goto disable_epcs_tx_clk;
  307 + }
  308 + ret = clk_enable(&imxpriv->phy_apbclk);
  309 + if (ret < 0) {
  310 + dev_err(dev, "can't enable phy pclk1.\n");
  311 + goto disable_epcs_rx_clk;
  312 + }
  313 +#endif
  314 +
  315 + /* Configure PHYx2 PIPE_RSTN */
  316 + regmap_read(imxpriv->gpr, IMX8QM_CSR_PCIEA_OFFSET
  317 + + IMX8QM_CSR_PCIE_CTRL2_OFFSET, &val);
  318 + if ((val & IMX8QM_CTRL_LTSSM_ENABLE) == 0) {
  319 + /* PCIEA of HSIO is down too */
  320 + regmap_update_bits(imxpriv->gpr,
  321 + IMX8QM_CSR_PHYX2_OFFSET,
  322 + IMX8QM_PHY_PIPE_RSTN_0
  323 + | IMX8QM_PHY_PIPE_RSTN_OVERRIDE_0,
  324 + IMX8QM_PHY_PIPE_RSTN_0
  325 + | IMX8QM_PHY_PIPE_RSTN_OVERRIDE_0);
  326 + }
  327 + regmap_read(imxpriv->gpr, IMX8QM_CSR_PCIEB_OFFSET
  328 + + IMX8QM_CSR_PCIE_CTRL2_OFFSET, &reg);
  329 + if ((reg & IMX8QM_CTRL_LTSSM_ENABLE) == 0) {
  330 + /* PCIEB of HSIO is down */
  331 + regmap_update_bits(imxpriv->gpr,
  332 + IMX8QM_CSR_PHYX2_OFFSET,
  333 + IMX8QM_PHY_PIPE_RSTN_1
  334 + | IMX8QM_PHY_PIPE_RSTN_OVERRIDE_1,
  335 + IMX8QM_PHY_PIPE_RSTN_1
  336 + | IMX8QM_PHY_PIPE_RSTN_OVERRIDE_1);
  337 + }
  338 +
  339 + /* set PWR_RST and BT_RST of csr_pciea */
  340 + val = IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL2_OFFSET;
  341 + regmap_update_bits(imxpriv->gpr,
  342 + val,
  343 + IMX8QM_CTRL_BUTTON_RST_N,
  344 + IMX8QM_CTRL_BUTTON_RST_N);
  345 + regmap_update_bits(imxpriv->gpr,
  346 + val,
  347 + IMX8QM_CTRL_POWER_UP_RST_N,
  348 + IMX8QM_CTRL_POWER_UP_RST_N);
  349 +
  350 + /* PHYX1_MODE to SATA */
  351 + regmap_update_bits(imxpriv->gpr,
  352 + IMX8QM_CSR_PHYX1_OFFSET,
  353 + IMX8QM_PHY_MODE_MASK,
  354 + IMX8QM_PHY_MODE_SATA);
  355 +
  356 + if (imxpriv->ext_osc) {
  357 + dev_info(dev, "external osc is used.\n");
  358 + /*
  359 + * bit0 rx ena 1, bit1 tx ena 0
  360 + * bit12 PHY_X1_EPCS_SEL 1.
  361 + */
  362 + regmap_update_bits(imxpriv->gpr,
  363 + IMX8QM_CSR_MISC_OFFSET,
  364 + IMX8QM_MISC_IOB_RXENA,
  365 + IMX8QM_MISC_IOB_RXENA);
  366 + regmap_update_bits(imxpriv->gpr,
  367 + IMX8QM_CSR_MISC_OFFSET,
  368 + IMX8QM_MISC_IOB_TXENA,
  369 + 0);
  370 + } else {
  371 + dev_info(dev, "internal pll is used.\n");
  372 + regmap_update_bits(imxpriv->gpr,
  373 + IMX8QM_CSR_MISC_OFFSET,
  374 + IMX8QM_MISC_IOB_RXENA,
  375 + 0);
  376 + regmap_update_bits(imxpriv->gpr,
  377 + IMX8QM_CSR_MISC_OFFSET,
  378 + IMX8QM_MISC_IOB_TXENA,
  379 + IMX8QM_MISC_IOB_TXENA);
  380 +
  381 + }
  382 + regmap_update_bits(imxpriv->gpr,
  383 + IMX8QM_CSR_MISC_OFFSET,
  384 + IMX8QM_MISC_PHYX1_EPCS_SEL,
  385 + IMX8QM_MISC_PHYX1_EPCS_SEL);
  386 + /*
  387 + * It is possible, for PCIe and SATA are sharing
  388 + * the same clock source, HPLL or external oscillator.
  389 + * When PCIe is in low power modes (L1.X or L2 etc),
  390 + * the clock source can be turned off. In this case,
  391 + * if this clock source is required to be toggling by
  392 + * SATA, then SATA functions will be abnormal.
  393 + */
  394 + regmap_update_bits(imxpriv->gpr,
  395 + IMX8QM_CSR_MISC_OFFSET,
  396 + IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_1
  397 + | IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_0
  398 + | IMX8QM_MISC_CLKREQN_IN_OVERRIDE_1
  399 + | IMX8QM_MISC_CLKREQN_IN_OVERRIDE_0,
  400 + IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_1
  401 + | IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_0
  402 + | IMX8QM_MISC_CLKREQN_IN_OVERRIDE_1
  403 + | IMX8QM_MISC_CLKREQN_IN_OVERRIDE_0);
  404 +
  405 + /* clear PHY RST, then set it */
  406 + regmap_update_bits(imxpriv->gpr,
  407 + IMX8QM_CSR_SATA_OFFSET,
  408 + IMX8QM_SATA_CTRL_EPCS_PHYRESET_N,
  409 + 0);
  410 +
  411 + regmap_update_bits(imxpriv->gpr,
  412 + IMX8QM_CSR_SATA_OFFSET,
  413 + IMX8QM_SATA_CTRL_EPCS_PHYRESET_N,
  414 + IMX8QM_SATA_CTRL_EPCS_PHYRESET_N);
  415 + regmap_update_bits(imxpriv->gpr,
  416 + IMX8QM_CSR_SATA_OFFSET,
  417 + IMX8QM_SATA_CTRL_EPCS_TXDEEMP,
  418 + IMX8QM_SATA_CTRL_EPCS_TXDEEMP);
  419 + regmap_update_bits(imxpriv->gpr,
  420 + IMX8QM_CSR_SATA_OFFSET,
  421 + IMX8QM_SATA_CTRL_EPCS_TXDEEMP_SEL,
  422 + IMX8QM_SATA_CTRL_EPCS_TXDEEMP_SEL);
  423 +
  424 + /* CTRL RST: SET -> delay 1 us -> CLEAR -> SET */
  425 + regmap_update_bits(imxpriv->gpr,
  426 + IMX8QM_CSR_SATA_OFFSET,
  427 + IMX8QM_SATA_CTRL_RESET_N,
  428 + IMX8QM_SATA_CTRL_RESET_N);
  429 + udelay(1);
  430 + regmap_update_bits(imxpriv->gpr,
  431 + IMX8QM_CSR_SATA_OFFSET,
  432 + IMX8QM_SATA_CTRL_RESET_N,
  433 + 0);
  434 + regmap_update_bits(imxpriv->gpr,
  435 + IMX8QM_CSR_SATA_OFFSET,
  436 + IMX8QM_SATA_CTRL_RESET_N,
  437 + IMX8QM_SATA_CTRL_RESET_N);
  438 +
  439 + /* APB reset */
  440 + regmap_update_bits(imxpriv->gpr,
  441 + IMX8QM_CSR_PHYX1_OFFSET,
  442 + IMX8QM_PHY_APB_RSTN_0,
  443 + IMX8QM_PHY_APB_RSTN_0);
  444 +
  445 + for (i = 0; i < 100; i++) {
  446 + reg = IMX8QM_CSR_PHYX1_OFFSET
  447 + + IMX8QM_CSR_PHYX_STTS0_OFFSET;
  448 + regmap_read(imxpriv->gpr, reg, &val);
  449 + val &= IMX8QM_STTS0_LANE0_TX_PLL_LOCK;
  450 + if (val == IMX8QM_STTS0_LANE0_TX_PLL_LOCK)
  451 + break;
  452 + udelay(1);
  453 + }
  454 +
  455 + if (val != IMX8QM_STTS0_LANE0_TX_PLL_LOCK) {
  456 + dev_err(dev, "TX PLL of the PHY is not locked\n");
  457 + ret = -ENODEV;
  458 + } else {
  459 + for (i = 0; i < 1000; i++) {
  460 + reg = readb(imxpriv->phy_base +
  461 + IMX8QM_SATA_PHY_REG48_PMA_STATUS);
  462 + if (reg & IMX8QM_SATA_PHY_REG48_PMA_RDY)
  463 + break;
  464 + udelay(10);
  465 + }
  466 + if ((reg & IMX8QM_SATA_PHY_REG48_PMA_RDY) == 0) {
  467 + dev_err(dev, "Calibration is NOT finished.\n");
  468 + ret = -ENODEV;
  469 + goto err_out;
  470 + }
  471 +
  472 + writeb(imxpriv->imped_ratio, imxpriv->phy_base
  473 + + IMX8QM_SATA_PHY_REG03_RX_IMPED_RATIO);
  474 + writeb(imxpriv->imped_ratio, imxpriv->phy_base
  475 + + IMX8QM_SATA_PHY_REG09_TX_IMPED_RATIO);
  476 + reg = readb(imxpriv->phy_base
  477 + + IMX8QM_SATA_PHY_REG03_RX_IMPED_RATIO);
  478 + if (unlikely(reg != imxpriv->imped_ratio))
  479 + dev_info(dev, "Can't set PHY RX impedance ratio.\n");
  480 + reg = readb(imxpriv->phy_base
  481 + + IMX8QM_SATA_PHY_REG09_TX_IMPED_RATIO);
  482 + if (unlikely(reg != imxpriv->imped_ratio))
  483 + dev_info(dev, "Can't set PHY TX impedance ratio.\n");
  484 +
  485 + /* Configure the tx_amplitude to pass the tests. */
  486 + writeb(IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN0, imxpriv->phy_base +
  487 + IMX8QM_SATA_PHY_REG24_TX_AMP_RATIO_MARGIN0);
  488 + writeb(IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN1, imxpriv->phy_base +
  489 + IMX8QM_SATA_PHY_REG25_TX_AMP_RATIO_MARGIN1);
  490 + writeb(IMX8QM_SATA_PHY_TX_AMP_RATIO_MARGIN2, imxpriv->phy_base +
  491 + IMX8QM_SATA_PHY_REG26_TX_AMP_RATIO_MARGIN2);
  492 +
  493 + /* Adjust the OOB COMINIT/COMWAKE to pass the tests. */
  494 + writeb(IMX8QM_SATA_PHY_GEN1_TX_POST_CURSOR_RATIO,
  495 + imxpriv->phy_base +
  496 + IMX8QM_SATA_PHY_REG10_TX_POST_CURSOR_RATIO);
  497 + writeb(IMX8QM_SATA_PHY_GEN2_TX_POST_CURSOR_RATIO,
  498 + imxpriv->phy_base +
  499 + IMX8QM_SATA_PHY_REG22_TX_POST_CURSOR_RATIO);
  500 +
  501 + writeb(IMX8QM_SATA_PHY_UPDATE_SETTING, imxpriv->phy_base +
  502 + IMX8QM_SATA_PHY_REG128_UPDATE_SETTING);
  503 +
  504 + reg = IMX8QM_SATA_PP2CFG_COMINIT_NEGATE_MIN |
  505 + IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP |
  506 + IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP_MAX |
  507 + IMX8QM_SATA_PP2CFG_COMINT_BURST_GAP_MIN;
  508 + writel(reg, imxpriv->mmio + IMX8QM_SATA_PP2CFG_OFFSET);
  509 + reg = IMX8QM_SATA_PP3CFG_COMWAKE_NEGATE_MIN |
  510 + IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP |
  511 + IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP_MAX |
  512 + IMX8QM_SATA_PP3CFG_COMWAKE_BURST_GAP_MIN;
  513 + writel(reg, imxpriv->mmio + IMX8QM_SATA_PP3CFG_OFFSET);
  514 +
  515 + udelay(100);
  516 +
  517 + /*
  518 + * To reduce the power consumption, gate off
  519 + * the PHY clks
  520 + */
  521 +#if CONFIG_IS_ENABLED(CLK)
  522 + clk_disable(&imxpriv->phy_apbclk);
  523 + clk_disable(&imxpriv->phy_pclk1);
  524 + clk_disable(&imxpriv->phy_pclk0);
  525 +#endif
  526 + return ret;
  527 + }
  528 +
  529 +err_out:
  530 +#if CONFIG_IS_ENABLED(CLK)
  531 + clk_disable(&imxpriv->phy_apbclk);
  532 +disable_epcs_rx_clk:
  533 + clk_disable(&imxpriv->epcs_rx_clk);
  534 +disable_epcs_tx_clk:
  535 + clk_disable(&imxpriv->epcs_tx_clk);
  536 +disable_phy_pclk1:
  537 + clk_disable(&imxpriv->phy_pclk1);
  538 +disable_phy_pclk0:
  539 + clk_disable(&imxpriv->phy_pclk0);
  540 +#endif
  541 + return ret;
  542 +}
  543 +
  544 +static int imx8_sata_probe(struct udevice *dev, struct imx_ahci_priv *imxpriv)
  545 +{
  546 + int ret = 0;
  547 + fdt_addr_t addr;
  548 +
  549 + if (dev_read_u32u(dev, "ext_osc", &imxpriv->ext_osc)) {
  550 + dev_info(dev, "ext_osc is not specified.\n");
  551 + /* Use the external osc as ref clk defaultly. */
  552 + imxpriv->ext_osc = 1;
  553 + }
  554 +
  555 + if (dev_read_u32u(dev, "fsl,phy-imp", &imxpriv->imped_ratio)) {
  556 + /*
  557 + * Regarding to the differnet Hw designs,
  558 + * Set the impedance ratio to 0x6c when 85OHM is used.
  559 + * Keep it to default value 0x80, when 100OHM is used.
  560 + */
  561 + dev_info(dev, "phy impedance ratio is not specified.\n");
  562 + imxpriv->imped_ratio = IMX8QM_SATA_PHY_IMPED_RATIO_85OHM;
  563 + }
  564 +
  565 + addr = dev_read_addr_name(dev, "phy");
  566 + if (addr == FDT_ADDR_T_NONE){
  567 + dev_err(dev, "no phy space\n");
  568 + return -ENOMEM;
  569 + }
  570 +
  571 + imxpriv->phy_base = (void __iomem *)addr;
  572 +
  573 + imxpriv->gpr =
  574 + syscon_regmap_lookup_by_phandle(dev, "hsio");
  575 + if (IS_ERR(imxpriv->gpr)) {
  576 + dev_err(dev, "unable to find gpr registers\n");
  577 + return PTR_ERR(imxpriv->gpr);
  578 + }
  579 +
  580 +#if CONFIG_IS_ENABLED(CLK)
  581 + ret = clk_get_by_name(dev, "epcs_tx", &imxpriv->epcs_tx_clk);
  582 + if (ret) {
  583 + dev_err(dev, "can't get sata_epcs tx clock.\n");
  584 + return ret;
  585 + }
  586 +
  587 + ret = clk_get_by_name(dev, "epcs_rx", &imxpriv->epcs_rx_clk);
  588 + if (ret) {
  589 + dev_err(dev, "can't get sata_epcs rx clock.\n");
  590 + return ret;
  591 + }
  592 +
  593 + ret = clk_get_by_name(dev, "phy_pclk0", &imxpriv->phy_pclk0);
  594 + if (ret) {
  595 + dev_err(dev, "can't get sata_phy_pclk0 clock.\n");
  596 + return ret;
  597 + }
  598 +
  599 + ret = clk_get_by_name(dev, "phy_pclk1", &imxpriv->phy_pclk1);
  600 + if (ret) {
  601 + dev_err(dev, "can't get sata_phy_pclk1 clock.\n");
  602 + return ret;
  603 + }
  604 +
  605 + ret = clk_get_by_name(dev, "phy_apbclk", &imxpriv->phy_apbclk);
  606 + if (ret) {
  607 + dev_err(dev, "can't get sata_phy_apbclk clock.\n");
  608 + return ret;
  609 + }
  610 +#endif
  611 +
  612 + /* Fetch GPIO, then enable the external OSC */
  613 + ret = gpio_request_by_name(dev, "clkreq-gpio", 0, &imxpriv->clkreq_gpio,
  614 + (GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE));
  615 + if (ret) {
  616 + dev_err(dev, "%d unable to get clkreq.\n", ret);
  617 + return ret;
  618 + }
  619 +
  620 + return 0;
  621 +}
  622 +
  623 +
  624 +static int imx_sata_enable(struct udevice *dev)
  625 +{
  626 + struct imx_ahci_priv *imxpriv = dev_get_priv(dev);
  627 + int ret = 0;
  628 +
  629 + if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
  630 + /*
  631 + * set PHY Paremeters, two steps to configure the GPR13,
  632 + * one write for rest of parameters, mask of first write
  633 + * is 0x07ffffff, and the other one write for setting
  634 + * the mpll_clk_en.
  635 + */
  636 + regmap_update_bits(imxpriv->gpr, 0x34,
  637 + IOMUXC_GPR13_SATA_MASK,
  638 + imxpriv->phy_params);
  639 + regmap_update_bits(imxpriv->gpr, 0x34,
  640 + IOMUXC_GPR13_SATA_PHY_1_MASK,
  641 + IOMUXC_GPR13_SATA_PHY_1_SLOW);
  642 +
  643 + udelay(200);
  644 + }
  645 +
  646 + if (imxpriv->type == AHCI_IMX6Q) {
  647 + ret = imx_sata_phy_reset(imxpriv);
  648 + } else if (imxpriv->type == AHCI_IMX6QP) {
  649 + /* 6qp adds the sata reset mechanism, use it for 6qp sata */
  650 + regmap_update_bits(imxpriv->gpr, 0x14,
  651 + BIT(10), 0);
  652 +
  653 + regmap_update_bits(imxpriv->gpr, 0x14,
  654 + BIT(11), 0);
  655 + udelay(50);
  656 + regmap_update_bits(imxpriv->gpr, 0x14,
  657 + BIT(11), BIT(11));
  658 + } else if (imxpriv->type == AHCI_IMX8QM) {
  659 + ret = imx8_sata_enable(dev);
  660 + }
  661 +
  662 + if (ret) {
  663 + dev_err(dev, "failed to reset phy: %d\n", ret);
  664 + return ret;
  665 + }
  666 +
  667 + udelay(2000);
  668 +
  669 + return 0;
  670 +}
  671 +
  672 +static void imx_sata_disable(struct udevice *dev)
  673 +{
  674 + struct imx_ahci_priv *imxpriv = dev_get_priv(dev);
  675 +
  676 + if (imxpriv->type == AHCI_IMX6QP)
  677 + regmap_update_bits(imxpriv->gpr, 0x14,
  678 + BIT(10), BIT(10));
  679 +
  680 + if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
  681 + regmap_update_bits(imxpriv->gpr, 0x34,
  682 + IOMUXC_GPR13_SATA_PHY_1_MASK,
  683 + 0);
  684 + }
  685 +
  686 + if (imxpriv->type == AHCI_IMX8QM) {
  687 +#if CONFIG_IS_ENABLED(CLK)
  688 + clk_disable(&imxpriv->epcs_rx_clk);
  689 + clk_disable(&imxpriv->epcs_tx_clk);
  690 +#endif
  691 + }
  692 +}
  693 +
  694 +
  695 +static int imx_ahci_bind(struct udevice *dev)
  696 +{
  697 + struct udevice *scsi_dev;
  698 +
  699 + return ahci_bind_scsi(dev, &scsi_dev);
  700 +}
  701 +
  702 +static int imx_ahci_probe(struct udevice *dev)
  703 +{
  704 + int ret = 0;
  705 + struct imx_ahci_priv *priv = dev_get_priv(dev);
  706 + fdt_addr_t addr;
  707 + unsigned int reg_val;
  708 +
  709 + priv->type = (enum ahci_imx_type)dev_get_driver_data(dev);
  710 +
  711 +#if CONFIG_IS_ENABLED(CLK)
  712 + ret = clk_get_by_name(dev, "sata", &priv->sata_clk);
  713 + if (ret) {
  714 + printf("Failed to get sata clk\n");
  715 + return ret;
  716 + }
  717 +
  718 + ret = clk_get_by_name(dev, "sata_ref", &priv->sata_ref_clk);
  719 + if (ret) {
  720 + printf("Failed to get sata_ref clk\n");
  721 + return ret;
  722 + }
  723 +#endif
  724 +
  725 + addr = dev_read_addr(dev);
  726 + if (addr == FDT_ADDR_T_NONE) {
  727 + dev_err(dev, "no mmio space\n");
  728 + return -EINVAL;
  729 + }
  730 +
  731 + priv->mmio = (void __iomem *)addr;
  732 +
  733 + if (priv->type == AHCI_IMX6Q || priv->type == AHCI_IMX6QP) {
  734 + priv->gpr = syscon_regmap_lookup_by_phandle(dev, "gpr");
  735 + if (IS_ERR(priv->gpr)) {
  736 + dev_err(dev,
  737 + "failed to find fsl,imx6q-iomux-gpr regmap\n");
  738 + return PTR_ERR(priv->gpr);
  739 + }
  740 +
  741 + priv->phy_params =
  742 + IOMUXC_GPR13_SATA_PHY_7_SATA2M |
  743 + (3 << IOMUXC_GPR13_SATA_PHY_6_SHIFT) |
  744 + IOMUXC_GPR13_SATA_SPEED_3G |
  745 + IOMUXC_GPR13_SATA_PHY_2_TX_1P025V |
  746 + IOMUXC_GPR13_SATA_PHY_3_TXBOOST_3P33_DB |
  747 + IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_9_16 |
  748 + IOMUXC_GPR13_SATA_PHY_8_RXEQ_3P0DB |
  749 + IOMUXC_GPR13_SATA_SATA_PHY_5_SS_DISABLED;
  750 + } else if (priv->type == AHCI_IMX8QM) {
  751 + ret = imx8_sata_probe(dev, priv);
  752 + if (ret)
  753 + return ret;
  754 + }
  755 +
  756 +#if CONFIG_IS_ENABLED(CLK)
  757 + ret = clk_enable(&priv->sata_clk);
  758 + if (ret)
  759 + return ret;
  760 +
  761 + ret = clk_enable(&priv->sata_ref_clk);
  762 + if (ret)
  763 + return ret;
  764 +#else
  765 + enable_sata_clock();
  766 +#endif
  767 +
  768 + ret = imx_sata_enable(dev);
  769 + if (ret)
  770 + goto disable_clk;
  771 +
  772 + /*
  773 + * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
  774 + * and IP vendor specific register IMX_TIMER1MS.
  775 + * Configure CAP_SSS (support stagered spin up).
  776 + * Implement the port0.
  777 + * Get the ahb clock rate, and configure the TIMER1MS register.
  778 + */
  779 + reg_val = readl(priv->mmio + HOST_CAP);
  780 + if (!(reg_val & (1 << 27))) {
  781 + reg_val |= (1 << 27);
  782 + writel(reg_val, priv->mmio + HOST_CAP);
  783 + }
  784 + reg_val = readl(priv->mmio + HOST_PORTS_IMPL);
  785 + if (!(reg_val & 0x1)) {
  786 + reg_val |= 0x1;
  787 + writel(reg_val, priv->mmio + HOST_PORTS_IMPL);
  788 + }
  789 +
  790 +#if CONFIG_IS_ENABLED(CLK)
  791 + ret = clk_get_by_name(dev, "ahb", &priv->ahb_clk);
  792 + if (ret) {
  793 + dev_info(dev, "no ahb clock.\n");
  794 + } else {
  795 + /*
  796 + * AHB clock is only used to configure the vendor specified
  797 + * TIMER1MS register. Set it if the AHB clock is defined.
  798 + */
  799 + reg_val = clk_get_rate(&priv->ahb_clk) / 1000;
  800 + writel(reg_val, priv->mmio + IMX_TIMER1MS);
  801 + }
  802 +#else
  803 + reg_val = mxc_get_clock(MXC_AHB_CLK) / 1000;
  804 + writel(reg_val, priv->mmio + IMX_TIMER1MS);
  805 +#endif
  806 +
  807 + ret = ahci_probe_scsi(dev, (ulong)priv->mmio);
  808 + if (ret)
  809 + goto disable_sata;
  810 +
  811 + return ret;
  812 +
  813 +disable_sata:
  814 + imx_sata_disable(dev);
  815 +disable_clk:
  816 +#if CONFIG_IS_ENABLED(CLK)
  817 + clk_disable(&priv->sata_ref_clk);
  818 + clk_disable(&priv->sata_clk);
  819 +#else
  820 + disable_sata_clock();
  821 +#endif
  822 + return ret;
  823 +}
  824 +
  825 +static int imx_ahci_remove(struct udevice *dev)
  826 +{
  827 + imx_sata_disable(dev);
  828 +
  829 +#if CONFIG_IS_ENABLED(CLK)
  830 + struct imx_ahci_priv *priv = dev_get_priv(dev);
  831 + clk_disable(&priv->sata_ref_clk);
  832 + clk_disable(&priv->sata_clk);
  833 +#else
  834 + disable_sata_clock();
  835 +#endif
  836 +
  837 + return 0;
  838 +}
  839 +
  840 +
  841 +static const struct udevice_id imx_ahci_ids[] = {
  842 + { .compatible = "fsl,imx6q-ahci", .data = (ulong)AHCI_IMX6Q },
  843 + { .compatible = "fsl,imx6qp-ahci", .data = (ulong)AHCI_IMX6QP },
  844 + { .compatible = "fsl,imx8qm-ahci", .data = (ulong)AHCI_IMX8QM },
  845 + { }
  846 +};
  847 +
  848 +U_BOOT_DRIVER(imx_ahci) = {
  849 + .name = "imx_ahci",
  850 + .id = UCLASS_AHCI,
  851 + .of_match = imx_ahci_ids,
  852 + .bind = imx_ahci_bind,
  853 + .probe = imx_ahci_probe,
  854 + .remove = imx_ahci_remove,
  855 + .priv_auto_alloc_size = sizeof(struct imx_ahci_priv),
  856 +};