diff mbox

[U-Boot] ls2085a: esdhc: flush D-cache before 'mmc read'

Message ID 1435112008-2841-1-git-send-email-yangbo.lu@freescale.com
State Changes Requested, archived
Delegated to: Pantelis Antoniou
Headers show

Commit Message

Yangbo Lu June 24, 2015, 2:13 a.m. UTC
It needs to flush D-cache before 'mmc read' so that
we can see the right data in DDR. And fix parameter
for invalidate_dcache_range() after 'mmc read'.

Signed-off-by: Yangbo Lu <yangbo.lu@freescale.com>
Cc: York Sun <yorksun@freescale.com>
---
 drivers/mmc/fsl_esdhc.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

Comments

Pantelis Antoniou Aug. 12, 2015, 7:19 a.m. UTC | #1
Hi Yangbo,

> On Jun 24, 2015, at 05:13 , Yangbo Lu <yangbo.lu@freescale.com> wrote:
> 
> It needs to flush D-cache before 'mmc read' so that
> we can see the right data in DDR. And fix parameter
> for invalidate_dcache_range() after 'mmc read'.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@freescale.com>
> Cc: York Sun <yorksun@freescale.com>
> ---
> drivers/mmc/fsl_esdhc.c | 21 +++++++++++++++------
> 1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
> index c4719e6..3ca25bd 100644
> --- a/drivers/mmc/fsl_esdhc.c
> +++ b/drivers/mmc/fsl_esdhc.c
> @@ -192,6 +192,17 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
> 	wml_value = data->blocksize/4;
> 
> 	if (data->flags & MMC_DATA_READ) {
> +#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
> +#ifdef CONFIG_LS2085A
> +		/*
> +		 * It's temporary for ls2085a so that
> +		 * we can see right data in DDR
> +		 */
> +		flush_dcache_range((ulong)data->dest,
> +				   (ulong)data->dest+data->blocks
> +					 *data->blocksize);
> +#endif
> +#endif
> 		if (wml_value > WML_RD_WML_MAX)
> 			wml_value = WML_RD_WML_MAX_VAL;
> 

This looks like not board/soc specific, more like whether a non-coherent architecture.

Please rework as a configuration option that’s suited for that kind of architectures.

It looks like you’re only doing this for reads? What about writes?

> @@ -278,14 +289,9 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
> static void check_and_invalidate_dcache_range
> 	(struct mmc_cmd *cmd,
> 	 struct mmc_data *data) {
> -#ifdef CONFIG_LS2085A
> -	unsigned start = 0;
> -#else
> -	unsigned start = (unsigned)data->dest ;
> -#endif
> +	unsigned start, end;
> 	unsigned size = roundup(ARCH_DMA_MINALIGN,
> 				data->blocks*data->blocksize);
> -	unsigned end = start+size ;
> #ifdef CONFIG_LS2085A
> 	dma_addr_t addr;
> 
> @@ -294,7 +300,10 @@ static void check_and_invalidate_dcache_range
> 		printf("Error found for upper 32 bits\n");
> 	else
> 		start = lower_32_bits(addr);
> +#else
> +	start = (unsigned)data->dest;
> #endif
> +	end = start + size;
> 	invalidate_dcache_range(start, end);
> }
> #endif
> -- 
> 2.1.0.27.g96db324
> 

Regards

— Pantelis
Yangbo Lu Aug. 12, 2015, 8:09 a.m. UTC | #2
Hi Pantelis,


> Hi Yangbo,

> 

> > On Jun 24, 2015, at 05:13 , Yangbo Lu <yangbo.lu@freescale.com> wrote:

> >

> > It needs to flush D-cache before 'mmc read' so that we can see the

> > right data in DDR. And fix parameter for invalidate_dcache_range()

> > after 'mmc read'.

> >

> > Signed-off-by: Yangbo Lu <yangbo.lu@freescale.com>

> > Cc: York Sun <yorksun@freescale.com>

> > ---

> > drivers/mmc/fsl_esdhc.c | 21 +++++++++++++++------

> > 1 file changed, 15 insertions(+), 6 deletions(-)

> >

> > diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index

> > c4719e6..3ca25bd 100644

> > --- a/drivers/mmc/fsl_esdhc.c

> > +++ b/drivers/mmc/fsl_esdhc.c

> > @@ -192,6 +192,17 @@ static int esdhc_setup_data(struct mmc *mmc,

> struct mmc_data *data)

> > 	wml_value = data->blocksize/4;

> >

> > 	if (data->flags & MMC_DATA_READ) {

> > +#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO

> > +#ifdef CONFIG_LS2085A

> > +		/*

> > +		 * It's temporary for ls2085a so that

> > +		 * we can see right data in DDR

> > +		 */

> > +		flush_dcache_range((ulong)data->dest,

> > +				   (ulong)data->dest+data->blocks

> > +					 *data->blocksize);

> > +#endif

> > +#endif

> > 		if (wml_value > WML_RD_WML_MAX)

> > 			wml_value = WML_RD_WML_MAX_VAL;

> >

> 

> This looks like not board/soc specific, more like whether a non-coherent

> architecture.

> 

> Please rework as a configuration option that’s suited for that kind of

> architectures.

> 

> It looks like you’re only doing this for reads? What about writes?


The LS2085A platform exists cache coherency issue now. mmc writing is normal while mmc reading should use this workaround to work fine.
When cache coherency bug is fixed, this code would be removed.
Do I still need to rework as a configuration option?
Thanks a lot.

-Yangbo Lu


> 

> > @@ -278,14 +289,9 @@ static int esdhc_setup_data(struct mmc *mmc,

> > struct mmc_data *data) static void check_and_invalidate_dcache_range

> > 	(struct mmc_cmd *cmd,

> > 	 struct mmc_data *data) {

> > -#ifdef CONFIG_LS2085A

> > -	unsigned start = 0;

> > -#else

> > -	unsigned start = (unsigned)data->dest ;

> > -#endif

> > +	unsigned start, end;

> > 	unsigned size = roundup(ARCH_DMA_MINALIGN,

> > 				data->blocks*data->blocksize);

> > -	unsigned end = start+size ;

> > #ifdef CONFIG_LS2085A

> > 	dma_addr_t addr;

> >

> > @@ -294,7 +300,10 @@ static void check_and_invalidate_dcache_range

> > 		printf("Error found for upper 32 bits\n");

> > 	else

> > 		start = lower_32_bits(addr);

> > +#else

> > +	start = (unsigned)data->dest;

> > #endif

> > +	end = start + size;

> > 	invalidate_dcache_range(start, end);

> > }

> > #endif

> > --

> > 2.1.0.27.g96db324

> >

> 

> Regards

> 

> — Pantelis
diff mbox

Patch

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index c4719e6..3ca25bd 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -192,6 +192,17 @@  static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
 	wml_value = data->blocksize/4;
 
 	if (data->flags & MMC_DATA_READ) {
+#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
+#ifdef CONFIG_LS2085A
+		/*
+		 * It's temporary for ls2085a so that
+		 * we can see right data in DDR
+		 */
+		flush_dcache_range((ulong)data->dest,
+				   (ulong)data->dest+data->blocks
+					 *data->blocksize);
+#endif
+#endif
 		if (wml_value > WML_RD_WML_MAX)
 			wml_value = WML_RD_WML_MAX_VAL;
 
@@ -278,14 +289,9 @@  static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
 static void check_and_invalidate_dcache_range
 	(struct mmc_cmd *cmd,
 	 struct mmc_data *data) {
-#ifdef CONFIG_LS2085A
-	unsigned start = 0;
-#else
-	unsigned start = (unsigned)data->dest ;
-#endif
+	unsigned start, end;
 	unsigned size = roundup(ARCH_DMA_MINALIGN,
 				data->blocks*data->blocksize);
-	unsigned end = start+size ;
 #ifdef CONFIG_LS2085A
 	dma_addr_t addr;
 
@@ -294,7 +300,10 @@  static void check_and_invalidate_dcache_range
 		printf("Error found for upper 32 bits\n");
 	else
 		start = lower_32_bits(addr);
+#else
+	start = (unsigned)data->dest;
 #endif
+	end = start + size;
 	invalidate_dcache_range(start, end);
 }
 #endif