Merge branch 'for-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
[sfrench/cifs-2.6.git] / drivers / ata / ahci_qoriq.c
index 9884c8c6e93447fac77e2b74a322b526eaae26f7..85d833289f28f85de9aa98efe52a05a921cdc3bd 100644 (file)
 #define LS1021A_AXICC_ADDR     0xC0
 
 #define SATA_ECC_DISABLE       0x00020000
-#define LS1046A_SATA_ECC_DIS   0x80000000
+#define ECC_DIS_ARMV8_CH2      0x80000000
 
 enum ahci_qoriq_type {
        AHCI_LS1021A,
        AHCI_LS1043A,
        AHCI_LS2080A,
        AHCI_LS1046A,
+       AHCI_LS2088A,
 };
 
 struct ahci_qoriq_priv {
        struct ccsr_ahci *reg_base;
        enum ahci_qoriq_type type;
        void __iomem *ecc_addr;
+       bool is_dmacoherent;
 };
 
 static const struct of_device_id ahci_qoriq_of_match[] = {
@@ -66,6 +68,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = {
        { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
        { .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A},
        { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
+       { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
        {},
 };
 MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
@@ -157,6 +160,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
 
        switch (qpriv->type) {
        case AHCI_LS1021A:
+               if (!qpriv->ecc_addr)
+                       return -EINVAL;
                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);
@@ -164,26 +169,43 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
                writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4);
                writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5);
                writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
-               writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR);
+               if (qpriv->is_dmacoherent)
+                       writel(AHCI_PORT_AXICC_CFG,
+                                       reg_base + LS1021A_AXICC_ADDR);
                break;
 
        case AHCI_LS1043A:
+               if (!qpriv->ecc_addr)
+                       return -EINVAL;
+               writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr);
                writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
                writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
-               writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+               if (qpriv->is_dmacoherent)
+                       writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
                break;
 
        case AHCI_LS2080A:
                writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
                writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
-               writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+               if (qpriv->is_dmacoherent)
+                       writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
                break;
 
        case AHCI_LS1046A:
-               writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr);
+               if (!qpriv->ecc_addr)
+                       return -EINVAL;
+               writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr);
                writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
                writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
-               writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+               if (qpriv->is_dmacoherent)
+                       writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
+               break;
+
+       case AHCI_LS2088A:
+               writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
+               writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
+               if (qpriv->is_dmacoherent)
+                       writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
                break;
        }
 
@@ -221,6 +243,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
                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);
        if (rc)