diff options
author | Oleksandr Suvorov <oleksandr.suvorov@toradex.com> | 2020-07-06 20:17:30 +0300 |
---|---|---|
committer | Oleksandr Suvorov <oleksandr.suvorov@toradex.com> | 2020-07-06 20:24:05 +0300 |
commit | d6e1cff14875d6ce338c1f27afe0639ef0f97b79 (patch) | |
tree | 2449859b19a9e58abb0414700621a86f234d91d6 /drivers/ata | |
parent | 453fdfde79e13e27030a56c7ea787e98698b0dba (diff) | |
parent | 0347fe7527d062e1762498cb5863bcd5bde0997b (diff) |
Merge branch 'imx_4.14.98_2.3.0' into toradex_4.14-2.3.x-imx
Fix conflicts after merging changes from the latest NXP branch.
Conflicts:
arch/arm64/boot/dts/freescale/fsl-imx8qm-device.dtsi
drivers/pci/dwc/pci-imx6.c
Related-to: ELB-1306
Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ahci_imx.c | 137 |
1 files changed, 120 insertions, 17 deletions
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index e1b0fe4cef7c..16e19affc514 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -148,6 +148,12 @@ struct imx_ahci_priv { struct clk *phy_apbclk; struct clk *phy_pclk0; struct clk *phy_pclk1; + struct clk *per_clk0; + struct clk *per_clk1; + struct clk *per_clk2; + struct clk *per_clk3; + struct clk *per_clk4; + struct clk *per_clk5; void __iomem *phy_base; struct clk *sata_ext; int clkreq_gpio; @@ -484,39 +490,112 @@ static struct attribute *fsl_sata_ahci_attrs[] = { }; ATTRIBUTE_GROUPS(fsl_sata_ahci); -static int imx8_sata_enable(struct ahci_host_priv *hpriv) +static int imx8_sata_clk_enable(struct imx_ahci_priv *imxpriv) { - u32 val, reg; - int i, ret; - struct imx_ahci_priv *imxpriv = hpriv->plat_data; + int ret; struct device *dev = &imxpriv->ahci_pdev->dev; /* configure the hsio for sata */ ret = clk_prepare_enable(imxpriv->phy_pclk0); if (ret < 0) { - dev_err(dev, "can't enable phy pclk0.\n"); + dev_err(dev, "can't enable phy_pclk0.\n"); return ret; } ret = clk_prepare_enable(imxpriv->phy_pclk1); if (ret < 0) { - dev_err(dev, "can't enable phy pclk1.\n"); + dev_err(dev, "can't enable phy_pclk1.\n"); goto disable_phy_pclk0; } ret = clk_prepare_enable(imxpriv->epcs_tx_clk); if (ret < 0) { - dev_err(dev, "can't enable epcs tx clk.\n"); + dev_err(dev, "can't enable epcs_tx_clk.\n"); goto disable_phy_pclk1; } ret = clk_prepare_enable(imxpriv->epcs_rx_clk); if (ret < 0) { - dev_err(dev, "can't enable epcs rx clk.\n"); + dev_err(dev, "can't enable epcs_rx_clk.\n"); goto disable_epcs_tx_clk; } ret = clk_prepare_enable(imxpriv->phy_apbclk); if (ret < 0) { - dev_err(dev, "can't enable phy pclk1.\n"); + dev_err(dev, "can't enable phy_apbclk.\n"); goto disable_epcs_rx_clk; } + ret = clk_prepare_enable(imxpriv->per_clk0); + if (ret < 0) { + dev_err(dev, "can't enable per_clk.\n"); + goto disable_phy_apbclk; + } + ret = clk_prepare_enable(imxpriv->per_clk1); + if (ret < 0) { + dev_err(dev, "can't enable per_clk.\n"); + goto disable_per_clk0; + } + ret = clk_prepare_enable(imxpriv->per_clk2); + if (ret < 0) { + dev_err(dev, "can't enable per_clk.\n"); + goto disable_per_clk1; + } + ret = clk_prepare_enable(imxpriv->per_clk3); + if (ret < 0) { + dev_err(dev, "can't enable per_clk.\n"); + goto disable_per_clk2; + } + ret = clk_prepare_enable(imxpriv->per_clk4); + if (ret < 0) { + dev_err(dev, "can't enable per_clk.\n"); + goto disable_per_clk3; + } + ret = clk_prepare_enable(imxpriv->per_clk5); + if (ret < 0) + dev_err(dev, "can't enable per_clk.\n"); + else + return 0; + + clk_disable_unprepare(imxpriv->per_clk4); +disable_per_clk3: + clk_disable_unprepare(imxpriv->per_clk3); +disable_per_clk2: + clk_disable_unprepare(imxpriv->per_clk2); +disable_per_clk1: + clk_disable_unprepare(imxpriv->per_clk1); +disable_per_clk0: + clk_disable_unprepare(imxpriv->per_clk0); +disable_phy_apbclk: + clk_disable_unprepare(imxpriv->phy_apbclk); +disable_epcs_rx_clk: + clk_disable_unprepare(imxpriv->epcs_rx_clk); +disable_epcs_tx_clk: + clk_disable_unprepare(imxpriv->epcs_tx_clk); +disable_phy_pclk1: + clk_disable_unprepare(imxpriv->phy_pclk1); +disable_phy_pclk0: + clk_disable_unprepare(imxpriv->phy_pclk0); + return ret; +} + +static void imx8_sata_clk_disable(struct imx_ahci_priv *imxpriv) +{ + clk_disable_unprepare(imxpriv->epcs_rx_clk); + clk_disable_unprepare(imxpriv->epcs_tx_clk); + clk_disable_unprepare(imxpriv->per_clk5); + clk_disable_unprepare(imxpriv->per_clk4); + clk_disable_unprepare(imxpriv->per_clk3); + clk_disable_unprepare(imxpriv->per_clk2); + clk_disable_unprepare(imxpriv->per_clk1); + clk_disable_unprepare(imxpriv->per_clk0); +} + +static int imx8_sata_enable(struct ahci_host_priv *hpriv) +{ + u32 val, reg; + int i, ret; + struct imx_ahci_priv *imxpriv = hpriv->plat_data; + struct device *dev = &imxpriv->ahci_pdev->dev; + + ret = imx8_sata_clk_enable(imxpriv); + if (ret) + return ret; /* Configure PHYx2 PIPE_RSTN */ regmap_read(imxpriv->gpr, IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL2_OFFSET, &val); @@ -745,14 +824,9 @@ static int imx8_sata_enable(struct ahci_host_priv *hpriv) err_out: clk_disable_unprepare(imxpriv->phy_apbclk); -disable_epcs_rx_clk: - clk_disable_unprepare(imxpriv->epcs_rx_clk); -disable_epcs_tx_clk: - clk_disable_unprepare(imxpriv->epcs_tx_clk); -disable_phy_pclk1: clk_disable_unprepare(imxpriv->phy_pclk1); -disable_phy_pclk0: clk_disable_unprepare(imxpriv->phy_pclk0); + imx8_sata_clk_disable(imxpriv); return ret; } @@ -858,8 +932,7 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv) } if (imxpriv->type == AHCI_IMX8QM) { - clk_disable_unprepare(imxpriv->epcs_rx_clk); - clk_disable_unprepare(imxpriv->epcs_tx_clk); + imx8_sata_clk_disable(imxpriv); } clk_disable_unprepare(imxpriv->sata_ref_clk); @@ -1169,6 +1242,36 @@ static int imx8_sata_probe(struct device *dev, struct imx_ahci_priv *imxpriv) return PTR_ERR(imxpriv->phy_apbclk); } + imxpriv->per_clk0 = devm_clk_get(dev, "per_clk0"); + if (IS_ERR(imxpriv->per_clk0)) { + dev_err(dev, "can't get per_clk0 clock.\n"); + return PTR_ERR(imxpriv->per_clk0); + } + imxpriv->per_clk1 = devm_clk_get(dev, "per_clk1"); + if (IS_ERR(imxpriv->per_clk1)) { + dev_err(dev, "can't get per_clk1 clock.\n"); + return PTR_ERR(imxpriv->per_clk1); + } + imxpriv->per_clk2 = devm_clk_get(dev, "per_clk2"); + if (IS_ERR(imxpriv->per_clk2)) { + dev_err(dev, "can't get per_clk2 clock.\n"); + return PTR_ERR(imxpriv->per_clk2); + } + imxpriv->per_clk3 = devm_clk_get(dev, "per_clk3"); + if (IS_ERR(imxpriv->per_clk3)) { + dev_err(dev, "can't get per_clk3 clock.\n"); + return PTR_ERR(imxpriv->per_clk3); + } + imxpriv->per_clk4 = devm_clk_get(dev, "per_clk4"); + if (IS_ERR(imxpriv->per_clk4)) { + dev_err(dev, "can't get per_clk4 clock.\n"); + return PTR_ERR(imxpriv->per_clk4); + } + imxpriv->per_clk5 = devm_clk_get(dev, "per_clk5"); + if (IS_ERR(imxpriv->per_clk5)) { + dev_err(dev, "can't get per_clk5 clock.\n"); + return PTR_ERR(imxpriv->per_clk5); + } /* Fetch GPIO, then enable the external OSC */ imxpriv->clkreq_gpio = of_get_named_gpio(np, "clkreq-gpio", 0); if (gpio_is_valid(imxpriv->clkreq_gpio)) { |