scsi: ceva: add ls1012a soc support

Make the code structure more general so that more socs can be
added easily and also remove speed limitation restriction.
Add the ls1012a sata support as well.

Signed-off-by: Tang Yuantian <andy.tang@nxp.com>
Reviewed-by: Michal Simek <michal.simek@xilinx.com>
Tested-by: Michal Simek <michal.simek@xilinx.com>
	(with and without CONFIG_OF_LIVE on zynqmp zcu102)
Reviewed-by: York Sun <york.sun@nxp.com>
diff --git a/drivers/ata/sata_ceva.c b/drivers/ata/sata_ceva.c
index a7d45e8..047cff7 100644
--- a/drivers/ata/sata_ceva.c
+++ b/drivers/ata/sata_ceva.c
@@ -7,8 +7,6 @@
 #include <dm.h>
 #include <ahci.h>
 #include <scsi.h>
-#include <asm/arch/hardware.h>
-
 #include <asm/io.h>
 
 /* Vendor Specific Register Offsets */
@@ -18,6 +16,7 @@
 #define AHCI_VEND_PP3C  0xB0
 #define AHCI_VEND_PP4C  0xB4
 #define AHCI_VEND_PP5C  0xB8
+#define AHCI_VEND_AXICC 0xBc
 #define AHCI_VEND_PAXIC 0xC0
 #define AHCI_VEND_PTC   0xC8
 
@@ -72,45 +71,57 @@
 #define DRV_NAME	"ahci-ceva"
 #define CEVA_FLAG_BROKEN_GEN2	1
 
+/* flag bit definition */
+#define FLAG_COHERENT	1
+
+/* register config value */
+#define CEVA_PHY1_CFG	0xa003fffe
+#define CEVA_PHY2_CFG	0x28184d1f
+#define CEVA_PHY3_CFG	0x0e081509
+#define CEVA_TRANS_CFG	0x08000029
+#define CEVA_AXICC_CFG	0x3fffffff
+
+/* ecc addr-val pair */
+#define ECC_DIS_ADDR_CH2	0x80000000
+#define ECC_DIS_VAL_CH2	0x20140520
+
+enum ceva_soc {
+	CEVA_1V84,
+	CEVA_LS1012A,
+};
+
 struct ceva_sata_priv {
 	ulong base;
+	enum ceva_soc soc;
+	ulong flag;
 };
 
-static int ceva_init_sata(ulong mmio)
+static int ceva_init_sata(struct ceva_sata_priv *priv)
 {
+	ulong base = priv->base;
 	ulong tmp;
-	int i;
 
-	/*
-	 * AXI Data bus width to 64
-	 * Set Mem Addr Read, Write ID for data transfers
-	 * Transfer limit to 72 DWord
-	 */
-	tmp = PAXIC_ADBW_BW64 | PAXIC_MAWIDD | PAXIC_MARIDD | PAXIC_OTL;
-	writel(tmp, mmio + AHCI_VEND_PAXIC);
-
-	/* Set AHCI Enable */
-	tmp = readl(mmio + HOST_CTL);
-	tmp |= HOST_AHCI_EN;
-	writel(tmp, mmio + HOST_CTL);
-
-	for (i = 0; i < NR_PORTS; i++) {
-		/* TPSS TPRS scalars, CISE and Port Addr */
-		tmp = PCFG_TPSS_VAL | PCFG_TPRS_VAL | (PCFG_PAD_VAL + i);
-		writel(tmp, mmio + AHCI_VEND_PCFG);
-
-		/* Port Phy Cfg register enables */
+	switch (priv->soc) {
+	case CEVA_1V84:
+		tmp = PAXIC_ADBW_BW64 | PAXIC_MAWIDD | PAXIC_MARIDD | PAXIC_OTL;
+		writel(tmp, base + AHCI_VEND_PAXIC);
+		tmp = PCFG_TPSS_VAL | PCFG_TPRS_VAL | PCFG_PAD_VAL;
+		writel(tmp, base + AHCI_VEND_PCFG);
 		tmp = PPCFG_TTA | PPCFG_PSS_EN | PPCFG_ESDF_EN;
-		writel(tmp, mmio + AHCI_VEND_PPCFG);
-
-		/* Rx Watermark setting  */
+		writel(tmp, base + AHCI_VEND_PPCFG);
 		tmp = PTC_RX_WM_VAL | PTC_RSVD;
-		writel(tmp, mmio + AHCI_VEND_PTC);
+		writel(tmp, base + AHCI_VEND_PTC);
+		break;
 
-		/* Default to Gen 2 Speed and Gen 1 if Gen2 is broken */
-		tmp = PORT_SCTL_SPD_GEN3 | PORT_SCTL_IPM;
-		writel(tmp, mmio + PORT_SCR_CTL + PORT_BASE + PORT_OFFSET * i);
+	case CEVA_LS1012A:
+		writel(ECC_DIS_ADDR_CH2, ECC_DIS_VAL_CH2);
+		writel(CEVA_PHY1_CFG, base + AHCI_VEND_PPCFG);
+		writel(CEVA_TRANS_CFG, base + AHCI_VEND_PTC);
+		if (priv->flag & FLAG_COHERENT)
+			writel(CEVA_AXICC_CFG, base + AHCI_VEND_AXICC);
+		break;
 	}
+
 	return 0;
 }
 
@@ -125,13 +136,14 @@
 {
 	struct ceva_sata_priv *priv = dev_get_priv(dev);
 
-	ceva_init_sata(priv->base);
+	ceva_init_sata(priv);
 
 	return ahci_probe_scsi(dev, priv->base);
 }
 
 static const struct udevice_id sata_ceva_ids[] = {
-	{ .compatible = "ceva,ahci-1v84" },
+	{ .compatible = "ceva,ahci-1v84", .data = CEVA_1V84 },
+	{ .compatible = "fsl,ls1012a-ahci", .data = CEVA_LS1012A },
 	{ }
 };
 
@@ -139,10 +151,15 @@
 {
 	struct ceva_sata_priv *priv = dev_get_priv(dev);
 
-	priv->base = devfdt_get_addr(dev);
+	if (dev_read_bool(dev, "dma-coherent"))
+		priv->flag |= FLAG_COHERENT;
+
+	priv->base = dev_read_addr(dev);
 	if (priv->base == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
+	priv->soc = dev_get_driver_data(dev);
+
 	return 0;
 }