diff mbox series

[RFC] ahci: imx: add the imx6qp ahci sata support

Message ID 1521424938-18254-1-git-send-email-hongxing.zhu@nxp.com
State Not Applicable
Delegated to: David Miller
Headers show
Series [RFC] ahci: imx: add the imx6qp ahci sata support | expand

Commit Message

Richard Zhu March 19, 2018, 2:02 a.m. UTC
- Regarding to imx6q ahci sata, imx6qp ahci sata
has the reset mechanism. Add the imx6qp ahci sata
support in this commit.
- Use the specific reset callback for imx53 sata,
and use the default ahci_ops.softreset for the others.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
---
 Documentation/devicetree/bindings/ata/imx-sata.txt |  1 +
 drivers/ata/ahci_imx.c                             | 36 +++++++++++++++++++---
 include/linux/mfd/syscon/imx6q-iomuxc-gpr.h        |  2 ++
 3 files changed, 35 insertions(+), 4 deletions(-)

Comments

Tejun Heo March 19, 2018, 2:35 p.m. UTC | #1
On Mon, Mar 19, 2018 at 10:02:18AM +0800, Richard Zhu wrote:
> - Regarding to imx6q ahci sata, imx6qp ahci sata
> has the reset mechanism. Add the imx6qp ahci sata
> support in this commit.
> - Use the specific reset callback for imx53 sata,
> and use the default ahci_ops.softreset for the others.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>

Applied to libata/for-4.17.

Thanks.
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/ata/imx-sata.txt b/Documentation/devicetree/bindings/ata/imx-sata.txt
index a3d1471..781f887 100644
--- a/Documentation/devicetree/bindings/ata/imx-sata.txt
+++ b/Documentation/devicetree/bindings/ata/imx-sata.txt
@@ -7,6 +7,7 @@  Required properties:
 - compatible : should be one of the following:
    - "fsl,imx53-ahci" for i.MX53 SATA controller
    - "fsl,imx6q-ahci" for i.MX6Q SATA controller
+   - "fsl,imx6qp-ahci" for i.MX6QP SATA controller
 - interrupts : interrupt mapping for SATA IRQ
 - reg : registers mapping
 - clocks : list of clock specifiers, must contain an entry for each
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index a58bcc0..577458f 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -58,6 +58,7 @@  enum {
 enum ahci_imx_type {
 	AHCI_IMX53,
 	AHCI_IMX6Q,
+	AHCI_IMX6QP,
 };
 
 struct imx_ahci_priv {
@@ -188,11 +189,26 @@  static int imx_phy_reg_read(u16 *val, void __iomem *mmio)
 
 static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
 {
+	struct imx_ahci_priv *imxpriv = hpriv->plat_data;
 	void __iomem *mmio = hpriv->mmio;
 	int timeout = 10;
 	u16 val;
 	int ret;
 
+	if (imxpriv->type == AHCI_IMX6QP) {
+		/* 6qp adds the sata reset mechanism, use it for 6qp sata */
+		regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
+				   IMX6Q_GPR5_SATA_SW_PD, 0);
+
+		regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
+				   IMX6Q_GPR5_SATA_SW_RST, 0);
+		udelay(50);
+		regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
+				   IMX6Q_GPR5_SATA_SW_RST,
+				   IMX6Q_GPR5_SATA_SW_RST);
+		return 0;
+	}
+
 	/* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */
 	ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio);
 	if (ret)
@@ -408,7 +424,7 @@  static int imx_sata_enable(struct ahci_host_priv *hpriv)
 	if (ret < 0)
 		goto disable_regulator;
 
-	if (imxpriv->type == AHCI_IMX6Q) {
+	if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
 		/*
 		 * set PHY Paremeters, two steps to configure the GPR13,
 		 * one write for rest of parameters, mask of first write
@@ -459,10 +475,21 @@  static void imx_sata_disable(struct ahci_host_priv *hpriv)
 	if (imxpriv->no_device)
 		return;
 
-	if (imxpriv->type == AHCI_IMX6Q) {
+	switch (imxpriv->type) {
+	case AHCI_IMX6QP:
+		regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
+				   IMX6Q_GPR5_SATA_SW_PD,
+				   IMX6Q_GPR5_SATA_SW_PD);
 		regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
 				   IMX6Q_GPR13_SATA_MPLL_CLK_EN,
 				   !IMX6Q_GPR13_SATA_MPLL_CLK_EN);
+		break;
+
+	case AHCI_IMX6Q:
+		regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
+				   IMX6Q_GPR13_SATA_MPLL_CLK_EN,
+				   !IMX6Q_GPR13_SATA_MPLL_CLK_EN);
+		break;
 	}
 
 	clk_disable_unprepare(imxpriv->sata_ref_clk);
@@ -513,7 +540,7 @@  static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
 
 	if (imxpriv->type == AHCI_IMX53)
 		ret = ahci_pmp_retry_srst_ops.softreset(link, class, deadline);
-	else if (imxpriv->type == AHCI_IMX6Q)
+	else
 		ret = ahci_ops.softreset(link, class, deadline);
 
 	return ret;
@@ -536,6 +563,7 @@  static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
 static const struct of_device_id imx_ahci_of_match[] = {
 	{ .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
 	{ .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
+	{ .compatible = "fsl,imx6qp-ahci", .data = (void *)AHCI_IMX6QP },
 	{},
 };
 MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
@@ -743,7 +771,7 @@  static int imx_ahci_probe(struct platform_device *pdev)
 		return PTR_ERR(imxpriv->ahb_clk);
 	}
 
-	if (imxpriv->type == AHCI_IMX6Q) {
+	if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
 		u32 reg_value;
 
 		imxpriv->gpr = syscon_regmap_lookup_by_compatible(
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
index c8e0164..e06f5f7 100644
--- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
+++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
@@ -243,6 +243,8 @@ 
 #define IMX6Q_GPR4_IPU_RD_CACHE_CTL		BIT(0)
 
 #define IMX6Q_GPR5_L2_CLK_STOP			BIT(8)
+#define IMX6Q_GPR5_SATA_SW_PD			BIT(10)
+#define IMX6Q_GPR5_SATA_SW_RST			BIT(11)
 
 #define IMX6Q_GPR6_IPU1_ID00_WR_QOS_MASK	(0xf << 0)
 #define IMX6Q_GPR6_IPU1_ID01_WR_QOS_MASK	(0xf << 4)