Lx2160a is a new introduced soc which supports ATA3.0

Signed-off-by: Peng Ma <peng...@nxp.com>
---
changed for V6:
        - Add ecc_initialized to ensure set sata bit once of
        ECC error register
        - Recovery AHCI_LS2088A platform

 drivers/ata/ahci_qoriq.c |   52 +++++++++++++++++++++++++++++++---------------
 1 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c
index ce59253..08dbb86 100644
--- a/drivers/ata/ahci_qoriq.c
+++ b/drivers/ata/ahci_qoriq.c
@@ -58,6 +58,7 @@ enum ahci_qoriq_type {
        AHCI_LS1046A,
        AHCI_LS1088A,
        AHCI_LS2088A,
+       AHCI_LX2160A,
 };
 
 struct ahci_qoriq_priv {
@@ -67,6 +68,8 @@ struct ahci_qoriq_priv {
        bool is_dmacoherent;
 };
 
+static bool ecc_initialized;
+
 static const struct of_device_id ahci_qoriq_of_match[] = {
        { .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A},
        { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
@@ -74,6 +77,7 @@ struct ahci_qoriq_priv {
        { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
        { .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A},
        { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
+       { .compatible = "fsl,lx2160a-ahci", .data = (void *)AHCI_LX2160A},
        {},
 };
 MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
@@ -165,9 +169,10 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv 
*hpriv)
 
        switch (qpriv->type) {
        case AHCI_LS1021A:
-               if (!qpriv->ecc_addr)
+               if (!(qpriv->ecc_addr || ecc_initialized))
                        return -EINVAL;
-               writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
+               else if (qpriv->ecc_addr && !ecc_initialized)
+                       writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
                writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
                writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2);
                writel(LS1021A_PORT_PHY3, reg_base + PORT_PHY3);
@@ -180,10 +185,12 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv 
*hpriv)
                break;
 
        case AHCI_LS1043A:
-               if (!qpriv->ecc_addr)
+               if (!(qpriv->ecc_addr || ecc_initialized))
                        return -EINVAL;
-               writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
-                               qpriv->ecc_addr);
+               else if (qpriv->ecc_addr && !ecc_initialized)
+                       writel(readl(qpriv->ecc_addr) |
+                              ECC_DIS_ARMV8_CH2,
+                              qpriv->ecc_addr);
                writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
                writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
                writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
@@ -202,10 +209,12 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv 
*hpriv)
                break;
 
        case AHCI_LS1046A:
-               if (!qpriv->ecc_addr)
+               if (!(qpriv->ecc_addr || ecc_initialized))
                        return -EINVAL;
-               writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
-                               qpriv->ecc_addr);
+               else if (qpriv->ecc_addr && !ecc_initialized)
+                       writel(readl(qpriv->ecc_addr) |
+                              ECC_DIS_ARMV8_CH2,
+                              qpriv->ecc_addr);
                writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
                writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
                writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
@@ -215,10 +224,13 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv 
*hpriv)
                break;
 
        case AHCI_LS1088A:
-               if (!qpriv->ecc_addr)
+       case AHCI_LX2160A:
+               if (!(qpriv->ecc_addr || ecc_initialized))
                        return -EINVAL;
-               writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A,
-                      qpriv->ecc_addr);
+               else if (qpriv->ecc_addr && !ecc_initialized)
+                       writel(readl(qpriv->ecc_addr) |
+                              ECC_DIS_LS1088A,
+                              qpriv->ecc_addr);
                writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
                writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
                writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
@@ -237,6 +249,7 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
                break;
        }
 
+       ecc_initialized = true;
        return 0;
 }
 
@@ -264,13 +277,18 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
 
        qoriq_priv->type = (enum ahci_qoriq_type)of_id->data;
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-                       "sata-ecc");
-       if (res) {
-               qoriq_priv->ecc_addr = devm_ioremap_resource(dev, res);
-               if (IS_ERR(qoriq_priv->ecc_addr))
-                       return PTR_ERR(qoriq_priv->ecc_addr);
+       if (unlikely(!ecc_initialized)) {
+               res = platform_get_resource_byname(pdev,
+                                                  IORESOURCE_MEM,
+                                                  "sata-ecc");
+               if (res) {
+                       qoriq_priv->ecc_addr =
+                               devm_ioremap_resource(dev, res);
+                       if (IS_ERR(qoriq_priv->ecc_addr))
+                               return PTR_ERR(qoriq_priv->ecc_addr);
+               }
        }
+
        qoriq_priv->is_dmacoherent = of_dma_is_coherent(np);
 
        rc = ahci_platform_enable_resources(hpriv);
-- 
1.7.1

Reply via email to