diff options
| author | Ashok Reddy Soma <ashok.reddy.soma@xilinx.com> | 2021-07-09 05:53:41 -0600 | 
|---|---|---|
| committer | Michal Simek <michal.simek@xilinx.com> | 2021-07-26 09:18:45 +0200 | 
| commit | ee9ae005dc4cbd0a9a792c0b78385055f18b9a8a (patch) | |
| tree | 22f3679579c0e6465eb7f9c9889d2111799c17e6 | |
| parent | affcba728b90428f38e6ea6b945935146c8f3dcb (diff) | |
mmc: zynq_sdhci: Use Mask writes for Tap delays
Restrict tap_delay value to the allowed size(8bits for itap and 6 bits
for otap) before writing to the tap delay register.
Clear ITAP and OTAP delay bits before updating with the new tap value
for Versal platform.
Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
| -rw-r--r-- | drivers/mmc/zynq_sdhci.c | 58 | 
1 files changed, 31 insertions, 27 deletions
| diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index f65a87a4e14..bf638e96758 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -19,11 +19,13 @@  #include <sdhci.h>  #include <zynqmp_tap_delay.h> -#define SDHCI_ARASAN_ITAPDLY_REGISTER   0xF0F8 -#define SDHCI_ARASAN_OTAPDLY_REGISTER   0xF0FC -#define SDHCI_ITAPDLY_CHGWIN            0x200 -#define SDHCI_ITAPDLY_ENABLE            0x100 -#define SDHCI_OTAPDLY_ENABLE            0x40 +#define SDHCI_ARASAN_ITAPDLY_REGISTER	0xF0F8 +#define SDHCI_ARASAN_ITAPDLY_SEL_MASK	GENMASK(7, 0) +#define SDHCI_ARASAN_OTAPDLY_REGISTER	0xF0FC +#define SDHCI_ARASAN_OTAPDLY_SEL_MASK	GENMASK(5, 0) +#define SDHCI_ITAPDLY_CHGWIN		BIT(9) +#define SDHCI_ITAPDLY_ENABLE		BIT(8) +#define SDHCI_OTAPDLY_ENABLE		BIT(6)  #define SDHCI_TUNING_LOOP_COUNT		40  #define MMC_BANK2			0x2 @@ -297,6 +299,7 @@ static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host,  	struct mmc *mmc = (struct mmc *)host->mmc;  	u8 tap_delay, tap_max = 0;  	int timing = mode2timing[mmc->selected_mode]; +	u32 regval;  	/*  	 * This is applicable for SDHCI_SPEC_300 and above @@ -329,16 +332,16 @@ static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host,  	tap_delay = (degrees * tap_max) / 360; +	/* Limit output tap_delay value to 6 bits */ +	tap_delay &= SDHCI_ARASAN_OTAPDLY_SEL_MASK; +  	/* Set the Clock Phase */ -	if (tap_delay) { -		u32 regval; - -		regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER); -		regval |= SDHCI_OTAPDLY_ENABLE; -		sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); -		regval |= tap_delay; -		sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); -	} +	regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER); +	regval |= SDHCI_OTAPDLY_ENABLE; +	sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); +	regval &= ~SDHCI_ARASAN_OTAPDLY_SEL_MASK; +	regval |= tap_delay; +	sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);  	return 0;  } @@ -358,6 +361,7 @@ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host,  	struct mmc *mmc = (struct mmc *)host->mmc;  	u8 tap_delay, tap_max = 0;  	int timing = mode2timing[mmc->selected_mode]; +	u32 regval;  	/*  	 * This is applicable for SDHCI_SPEC_300 and above @@ -390,20 +394,20 @@ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host,  	tap_delay = (degrees * tap_max) / 360; +	/* Limit input tap_delay value to 8 bits */ +	tap_delay &= SDHCI_ARASAN_ITAPDLY_SEL_MASK; +  	/* Set the Clock Phase */ -	if (tap_delay) { -		u32 regval; - -		regval = sdhci_readl(host, SDHCI_ARASAN_ITAPDLY_REGISTER); -		regval |= SDHCI_ITAPDLY_CHGWIN; -		sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); -		regval |= SDHCI_ITAPDLY_ENABLE; -		sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); -		regval |= tap_delay; -		sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); -		regval &= ~SDHCI_ITAPDLY_CHGWIN; -		sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); -	} +	regval = sdhci_readl(host, SDHCI_ARASAN_ITAPDLY_REGISTER); +	regval |= SDHCI_ITAPDLY_CHGWIN; +	sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); +	regval |= SDHCI_ITAPDLY_ENABLE; +	sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); +	regval &= ~SDHCI_ARASAN_ITAPDLY_SEL_MASK; +	regval |= tap_delay; +	sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); +	regval &= ~SDHCI_ITAPDLY_CHGWIN; +	sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);  	return 0;  } | 
