From 79ed61e9f076f3382fa67a7f2418dd94e290cbff Mon Sep 17 00:00:00 2001 From: Yuantian Tang Date: Fri, 13 Jul 2018 17:25:30 +0800 Subject: [PATCH] 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 Reviewed-by: Michal Simek Tested-by: Michal Simek (with and without CONFIG_OF_LIVE on zynqmp zcu102) Reviewed-by: York Sun --- drivers/ata/sata_ceva.c | 87 +++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 35 deletions(-) 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 #include #include -#include - #include /* 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 */ - tmp = PPCFG_TTA | PPCFG_PSS_EN | PPCFG_ESDF_EN; - writel(tmp, mmio + AHCI_VEND_PPCFG); - /* Rx Watermark setting */ + 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, base + AHCI_VEND_PPCFG); tmp = PTC_RX_WM_VAL | PTC_RSVD; - writel(tmp, mmio + AHCI_VEND_PTC); - - /* 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); + writel(tmp, base + AHCI_VEND_PTC); + break; + + 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 @@ static int sata_ceva_probe(struct udevice *dev) { 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 @@ static int sata_ceva_ofdata_to_platdata(struct udevice *dev) { 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; }