SDHCI controller present in PXA1928 has few differences as far as register map is concerned. For example, PXAxxx PXA1928 ====== ======= SDCLK_DELAY field 0x10A 0x114 SDCLK_DELAY mask 0x1F 0x3FF SDCLK_DELAY shift 9 8 SDCLK_SEL shift 8 2 (SEL1) So in order to support multi-platform, use sdhci_pxa_regdata structure as a variant data according to platform. Note that, there are some more differences, which would be added as and when respective feature gets added to the driver. Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath@xxxxxxxxxx> --- drivers/mmc/host/sdhci-pxav3.c | 62 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 6d4bad4..aecae04 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -42,9 +42,6 @@ #define PXAV3_RPM_DELAY_MS 50 #define SD_CLOCK_BURST_SIZE_SETUP 0x10A -#define SDCLK_SEL 0x100 -#define SDCLK_DELAY_SHIFT 9 -#define SDCLK_DELAY_MASK 0x1f #define SD_CFG_FIFO_PARAM 0x100 #define SDCFG_GEN_PAD_CLK_ON BIT(6) @@ -58,11 +55,25 @@ #define SDCE_MISC_INT BIT(2) #define SDCE_MISC_INT_EN BIT(1) +#define SD_RX_CFG_REG 0x114 + /* IO Power control */ #define IO_PWR_AKEY_ASFAR 0xbaba #define IO_PWR_AKEY_ASSAR 0xeb10 #define IO_PWR_MMC1_PAD_1V8 BIT(2) +struct sdhci_pxa_data { + u32 sdclk_delay_reg; + u32 sdclk_delay_mask; + u8 sdclk_delay_shift; + u8 sdclk_sel_mask; + u8 sdclk_sel_shift; + /* + * We have few more differences, add them along with their + * respective feature support + */ +}; + struct sdhci_pxa { struct clk *clk_core; struct clk *clk_io; @@ -70,6 +81,24 @@ struct sdhci_pxa { void __iomem *sdio3_conf_reg; void __iomem *io_pwr_reg; void __iomem *io_pwr_lock_reg; + struct sdhci_pxa_data *data; +}; + +static struct sdhci_pxa_data pxav3_data_v1 = { + .sdclk_delay_reg = SD_CLOCK_BURST_SIZE_SETUP, + .sdclk_delay_mask = 0x1F, + .sdclk_delay_shift = 9, + .sdclk_sel_mask = 0x1, + .sdclk_sel_shift = 8, +}; + +static struct sdhci_pxa_data pxav3_data_v2 = { + .sdclk_delay_reg = SD_RX_CFG_REG, + .sdclk_delay_mask = 0x3FF, + .sdclk_delay_shift = 8, + /* Only set SDCLK_SEL1, as driver uses default value of SDCLK_SEL0 */ + .sdclk_sel_mask = 0x3, + .sdclk_sel_shift = 2, /* SDCLK_SEL1 */ }; /* @@ -183,6 +212,8 @@ static void pxav3_reset(struct sdhci_host *host, u8 mask) { struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc)); struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_pxa *pxa = pltfm_host->priv; sdhci_reset(host, mask); @@ -193,12 +224,14 @@ static void pxav3_reset(struct sdhci_host *host, u8 mask) */ if (pdata && 0 != pdata->clk_delay_cycles) { u16 tmp; - - tmp = readw(host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP); - tmp |= (pdata->clk_delay_cycles & SDCLK_DELAY_MASK) - << SDCLK_DELAY_SHIFT; - tmp |= SDCLK_SEL; - writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP); + struct sdhci_pxa_data *data = pxa->data; + + tmp = readw(host->ioaddr + data->sdclk_delay_reg); + tmp |= (pdata->clk_delay_cycles & data->sdclk_delay_mask) + << data->sdclk_delay_shift; + tmp &= ~(data->sdclk_sel_mask << data->sdclk_sel_shift); + tmp |= 1 << data->sdclk_sel_shift; + writew(tmp, host->ioaddr + data->sdclk_delay_reg); } } } @@ -363,10 +396,16 @@ static struct sdhci_pltfm_data sdhci_pxav3_pdata = { #ifdef CONFIG_OF static const struct of_device_id sdhci_pxav3_of_match[] = { { - .compatible = "mrvl,pxav3-mmc", + .compatible = "mrvl,pxav3-mmc", + .data = (void *)&pxav3_data_v1, + }, + { + .compatible = "marvell,armada-380-sdhci", + .data = (void *)&pxav3_data_v1, }, { - .compatible = "marvell,armada-380-sdhci", + .compatible = "marvell,pxav3-1928-sdhci", + .data = (void *)&pxav3_data_v2, }, {}, }; @@ -470,6 +509,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) goto err_of_parse; sdhci_get_of_property(pdev); pdata = pxav3_get_mmc_pdata(dev); + pxa->data = (struct sdhci_pxa_data *)match->data; pdev->dev.platform_data = pdata; } else if (pdata) { /* on-chip device */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html