diff mbox

[U-Boot,v2] mmc/dwmmc: use bounce buffer for data exchange between CPU and MMC controller

Message ID 1388057347-13899-1-git-send-email-abrodkin@synopsys.com
State Accepted
Delegated to: Pantelis Antoniou
Headers show

Commit Message

Alexey Brodkin Dec. 26, 2013, 11:29 a.m. UTC
Bounce buffer implementation takes care of proper data buffer alignemt
and correct flush/invalidation of data cache at once so we no longer
depend on input data variety and make sure CPU and MMC controller deal
with expected data in case of enabled data cache.

Bounce buffer requires to add its definition (CONFIG_BOUNCE_BUFFER) in
board configuration, otherwise corresponding library won't be compiled
and linker will fail to build resulting executable.

Difference since v1 - fixed compile-time warning with type casting to
"void *":

Comments

Jaehoon Chung Dec. 27, 2013, 4:33 a.m. UTC | #1
Hi, Alexey.

Acked-by: Jaehoon Chung <jh80.chung@samsung.com>
Tested-by: Jaehoon Chung <jh80.chung@samsung.com>

With Exynos4 board.

Best Regards,
Jaehoon Chung

On 12/26/2013 08:29 PM, Alexey Brodkin wrote:
> Bounce buffer implementation takes care of proper data buffer alignemt
> and correct flush/invalidation of data cache at once so we no longer
> depend on input data variety and make sure CPU and MMC controller deal
> with expected data in case of enabled data cache.
> 
> Bounce buffer requires to add its definition (CONFIG_BOUNCE_BUFFER) in
> board configuration, otherwise corresponding library won't be compiled
> and linker will fail to build resulting executable.
> 
> Difference since v1 - fixed compile-time warning with type casting to
> "void *":
> ====
> passing argument 2 of ‘bounce_buffer_start’ discards ‘const’ qualifier
> from pointer target type
> ====
> 
> Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
> 
> Cc: Mischa Jonker <mjonker@synopsys.com>
> Cc: Alim Akhtar <alim.akhtar@samsung.com>
> Cc: Rajeshwari Shinde <rajeshwari.s@samsung.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Amar <amarendra.xt@samsung.com>
> Cc: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Minkyu Kang <mk7.kang@samsung.com>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
> Cc: Andy Fleming <afleming@gmail.com>
> ---
>  drivers/mmc/dw_mmc.c            | 32 ++++++++++++++++++++++----------
>  include/configs/arndale.h       |  1 +
>  include/configs/exynos5250-dt.h |  1 +
>  3 files changed, 24 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> index 19d9b0b..1e34f36 100644
> --- a/drivers/mmc/dw_mmc.c
> +++ b/drivers/mmc/dw_mmc.c
> @@ -6,6 +6,7 @@
>   * SPDX-License-Identifier:	GPL-2.0+
>   */
>  
> +#include <bouncebuf.h>
>  #include <common.h>
>  #include <malloc.h>
>  #include <mmc.h>
> @@ -41,11 +42,13 @@ static void dwmci_set_idma_desc(struct dwmci_idmac *idmac,
>  }
>  
>  static void dwmci_prepare_data(struct dwmci_host *host,
> -		struct mmc_data *data, struct dwmci_idmac *cur_idmac)
> +			       struct mmc_data *data,
> +			       struct dwmci_idmac *cur_idmac,
> +			       void *bounce_buffer)
>  {
>  	unsigned long ctrl;
>  	unsigned int i = 0, flags, cnt, blk_cnt;
> -	ulong data_start, data_end, start_addr;
> +	ulong data_start, data_end;
>  
>  
>  	blk_cnt = data->blocks;
> @@ -55,11 +58,6 @@ static void dwmci_prepare_data(struct dwmci_host *host,
>  	data_start = (ulong)cur_idmac;
>  	dwmci_writel(host, DWMCI_DBADDR, (unsigned int)cur_idmac);
>  
> -	if (data->flags == MMC_DATA_READ)
> -		start_addr = (unsigned int)data->dest;
> -	else
> -		start_addr = (unsigned int)data->src;
> -
>  	do {
>  		flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ;
>  		flags |= (i == 0) ? DWMCI_IDMAC_FS : 0;
> @@ -70,7 +68,7 @@ static void dwmci_prepare_data(struct dwmci_host *host,
>  			cnt = data->blocksize * 8;
>  
>  		dwmci_set_idma_desc(cur_idmac, flags, cnt,
> -				start_addr + (i * PAGE_SIZE));
> +				    (u32)bounce_buffer + (i * PAGE_SIZE));
>  
>  		if (blk_cnt <= 8)
>  			break;
> @@ -117,6 +115,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>  	u32 retry = 10000;
>  	u32 mask, ctrl;
>  	ulong start = get_timer(0);
> +	struct bounce_buffer bbstate;
>  
>  	while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
>  		if (get_timer(start) > timeout) {
> @@ -127,8 +126,19 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>  
>  	dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
>  
> -	if (data)
> -		dwmci_prepare_data(host, data, cur_idmac);
> +	if (data) {
> +		if (data->flags == MMC_DATA_READ) {
> +			bounce_buffer_start(&bbstate, (void*)data->dest,
> +					    data->blocksize *
> +					    data->blocks, GEN_BB_WRITE);
> +		} else {
> +			bounce_buffer_start(&bbstate, (void*)data->src,
> +					    data->blocksize *
> +					    data->blocks, GEN_BB_READ);
> +		}
> +		dwmci_prepare_data(host, data, cur_idmac,
> +				   bbstate.bounce_buffer);
> +	}
>  
>  	dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
>  
> @@ -204,6 +214,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>  		ctrl = dwmci_readl(host, DWMCI_CTRL);
>  		ctrl &= ~(DWMCI_DMA_EN);
>  		dwmci_writel(host, DWMCI_CTRL, ctrl);
> +
> +		bounce_buffer_stop(&bbstate);
>  	}
>  
>  	udelay(100);
> diff --git a/include/configs/arndale.h b/include/configs/arndale.h
> index a3cb56b..3d29caf 100644
> --- a/include/configs/arndale.h
> +++ b/include/configs/arndale.h
> @@ -85,6 +85,7 @@
>  #define CONFIG_DWMMC
>  #define CONFIG_EXYNOS_DWMMC
>  #define CONFIG_SUPPORT_EMMC_BOOT
> +#define CONFIG_BOUNCE_BUFFER
>  
>  
>  #define CONFIG_BOARD_EARLY_INIT_F
> diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
> index 8fb904c..b39bafc 100644
> --- a/include/configs/exynos5250-dt.h
> +++ b/include/configs/exynos5250-dt.h
> @@ -102,6 +102,7 @@
>  #define CONFIG_DWMMC
>  #define CONFIG_EXYNOS_DWMMC
>  #define CONFIG_SUPPORT_EMMC_BOOT
> +#define CONFIG_BOUNCE_BUFFER
>  
>  
>  #define CONFIG_BOARD_EARLY_INIT_F
>
Pantelis Antoniou Jan. 9, 2014, 9:26 a.m. UTC | #2
Hi Alexey,

Looks fine and I'll apply with a small edit to the commit message to
remove the UTF8 characters.

On Dec 26, 2013, at 1:29 PM, Alexey Brodkin wrote:

> Bounce buffer implementation takes care of proper data buffer alignemt
> and correct flush/invalidation of data cache at once so we no longer
> depend on input data variety and make sure CPU and MMC controller deal
> with expected data in case of enabled data cache.
> 
> Bounce buffer requires to add its definition (CONFIG_BOUNCE_BUFFER) in
> board configuration, otherwise corresponding library won't be compiled
> and linker will fail to build resulting executable.
> 
> Difference since v1 - fixed compile-time warning with type casting to
> "void *":
> ====
> passing argument 2 of ‘bounce_buffer_start’ discards ‘const’ qualifier
> from pointer target type
> ====
> 

>    ====
>     passing argument 2 of <E2><80><98>bounce_buffer_start<E2><80><99> discards <E2><80><98>const<E2><80><99> qualifier
>     from pointer target type
>     ====
>  


> Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
> 
> Cc: Mischa Jonker <mjonker@synopsys.com>
> Cc: Alim Akhtar <alim.akhtar@samsung.com>
> Cc: Rajeshwari Shinde <rajeshwari.s@samsung.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Amar <amarendra.xt@samsung.com>
> Cc: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Minkyu Kang <mk7.kang@samsung.com>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
> Cc: Andy Fleming <afleming@gmail.com>
> ---
> drivers/mmc/dw_mmc.c            | 32 ++++++++++++++++++++++----------
> include/configs/arndale.h       |  1 +
> include/configs/exynos5250-dt.h |  1 +
> 3 files changed, 24 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> index 19d9b0b..1e34f36 100644
> --- a/drivers/mmc/dw_mmc.c
> +++ b/drivers/mmc/dw_mmc.c
> @@ -6,6 +6,7 @@
>  * SPDX-License-Identifier:	GPL-2.0+
>  */
> 
> +#include <bouncebuf.h>
> #include <common.h>
> #include <malloc.h>
> #include <mmc.h>
> @@ -41,11 +42,13 @@ static void dwmci_set_idma_desc(struct dwmci_idmac *idmac,
> }
> 
> static void dwmci_prepare_data(struct dwmci_host *host,
> -		struct mmc_data *data, struct dwmci_idmac *cur_idmac)
> +			       struct mmc_data *data,
> +			       struct dwmci_idmac *cur_idmac,
> +			       void *bounce_buffer)
> {
> 	unsigned long ctrl;
> 	unsigned int i = 0, flags, cnt, blk_cnt;
> -	ulong data_start, data_end, start_addr;
> +	ulong data_start, data_end;
> 
> 
> 	blk_cnt = data->blocks;
> @@ -55,11 +58,6 @@ static void dwmci_prepare_data(struct dwmci_host *host,
> 	data_start = (ulong)cur_idmac;
> 	dwmci_writel(host, DWMCI_DBADDR, (unsigned int)cur_idmac);
> 
> -	if (data->flags == MMC_DATA_READ)
> -		start_addr = (unsigned int)data->dest;
> -	else
> -		start_addr = (unsigned int)data->src;
> -
> 	do {
> 		flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ;
> 		flags |= (i == 0) ? DWMCI_IDMAC_FS : 0;
> @@ -70,7 +68,7 @@ static void dwmci_prepare_data(struct dwmci_host *host,
> 			cnt = data->blocksize * 8;
> 
> 		dwmci_set_idma_desc(cur_idmac, flags, cnt,
> -				start_addr + (i * PAGE_SIZE));
> +				    (u32)bounce_buffer + (i * PAGE_SIZE));
> 
> 		if (blk_cnt <= 8)
> 			break;
> @@ -117,6 +115,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
> 	u32 retry = 10000;
> 	u32 mask, ctrl;
> 	ulong start = get_timer(0);
> +	struct bounce_buffer bbstate;
> 
> 	while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
> 		if (get_timer(start) > timeout) {
> @@ -127,8 +126,19 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
> 
> 	dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
> 
> -	if (data)
> -		dwmci_prepare_data(host, data, cur_idmac);
> +	if (data) {
> +		if (data->flags == MMC_DATA_READ) {
> +			bounce_buffer_start(&bbstate, (void*)data->dest,
> +					    data->blocksize *
> +					    data->blocks, GEN_BB_WRITE);
> +		} else {
> +			bounce_buffer_start(&bbstate, (void*)data->src,
> +					    data->blocksize *
> +					    data->blocks, GEN_BB_READ);
> +		}
> +		dwmci_prepare_data(host, data, cur_idmac,
> +				   bbstate.bounce_buffer);
> +	}
> 
> 	dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
> 
> @@ -204,6 +214,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
> 		ctrl = dwmci_readl(host, DWMCI_CTRL);
> 		ctrl &= ~(DWMCI_DMA_EN);
> 		dwmci_writel(host, DWMCI_CTRL, ctrl);
> +
> +		bounce_buffer_stop(&bbstate);
> 	}
> 
> 	udelay(100);
> diff --git a/include/configs/arndale.h b/include/configs/arndale.h
> index a3cb56b..3d29caf 100644
> --- a/include/configs/arndale.h
> +++ b/include/configs/arndale.h
> @@ -85,6 +85,7 @@
> #define CONFIG_DWMMC
> #define CONFIG_EXYNOS_DWMMC
> #define CONFIG_SUPPORT_EMMC_BOOT
> +#define CONFIG_BOUNCE_BUFFER
> 
> 
> #define CONFIG_BOARD_EARLY_INIT_F
> diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
> index 8fb904c..b39bafc 100644
> --- a/include/configs/exynos5250-dt.h
> +++ b/include/configs/exynos5250-dt.h
> @@ -102,6 +102,7 @@
> #define CONFIG_DWMMC
> #define CONFIG_EXYNOS_DWMMC
> #define CONFIG_SUPPORT_EMMC_BOOT
> +#define CONFIG_BOUNCE_BUFFER
> 
> 
> #define CONFIG_BOARD_EARLY_INIT_F
> -- 
> 1.8.4.2
> 

Thanks

Acked-by: Pantelis Antoniou <panto@antoniou-consulting.com>
diff mbox

Patch

====
passing argument 2 of ‘bounce_buffer_start’ discards ‘const’ qualifier
from pointer target type
====

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>

Cc: Mischa Jonker <mjonker@synopsys.com>
Cc: Alim Akhtar <alim.akhtar@samsung.com>
Cc: Rajeshwari Shinde <rajeshwari.s@samsung.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Amar <amarendra.xt@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Minkyu Kang <mk7.kang@samsung.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
Cc: Andy Fleming <afleming@gmail.com>
---
 drivers/mmc/dw_mmc.c            | 32 ++++++++++++++++++++++----------
 include/configs/arndale.h       |  1 +
 include/configs/exynos5250-dt.h |  1 +
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 19d9b0b..1e34f36 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -6,6 +6,7 @@ 
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <bouncebuf.h>
 #include <common.h>
 #include <malloc.h>
 #include <mmc.h>
@@ -41,11 +42,13 @@  static void dwmci_set_idma_desc(struct dwmci_idmac *idmac,
 }
 
 static void dwmci_prepare_data(struct dwmci_host *host,
-		struct mmc_data *data, struct dwmci_idmac *cur_idmac)
+			       struct mmc_data *data,
+			       struct dwmci_idmac *cur_idmac,
+			       void *bounce_buffer)
 {
 	unsigned long ctrl;
 	unsigned int i = 0, flags, cnt, blk_cnt;
-	ulong data_start, data_end, start_addr;
+	ulong data_start, data_end;
 
 
 	blk_cnt = data->blocks;
@@ -55,11 +58,6 @@  static void dwmci_prepare_data(struct dwmci_host *host,
 	data_start = (ulong)cur_idmac;
 	dwmci_writel(host, DWMCI_DBADDR, (unsigned int)cur_idmac);
 
-	if (data->flags == MMC_DATA_READ)
-		start_addr = (unsigned int)data->dest;
-	else
-		start_addr = (unsigned int)data->src;
-
 	do {
 		flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ;
 		flags |= (i == 0) ? DWMCI_IDMAC_FS : 0;
@@ -70,7 +68,7 @@  static void dwmci_prepare_data(struct dwmci_host *host,
 			cnt = data->blocksize * 8;
 
 		dwmci_set_idma_desc(cur_idmac, flags, cnt,
-				start_addr + (i * PAGE_SIZE));
+				    (u32)bounce_buffer + (i * PAGE_SIZE));
 
 		if (blk_cnt <= 8)
 			break;
@@ -117,6 +115,7 @@  static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 	u32 retry = 10000;
 	u32 mask, ctrl;
 	ulong start = get_timer(0);
+	struct bounce_buffer bbstate;
 
 	while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
 		if (get_timer(start) > timeout) {
@@ -127,8 +126,19 @@  static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 
 	dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
 
-	if (data)
-		dwmci_prepare_data(host, data, cur_idmac);
+	if (data) {
+		if (data->flags == MMC_DATA_READ) {
+			bounce_buffer_start(&bbstate, (void*)data->dest,
+					    data->blocksize *
+					    data->blocks, GEN_BB_WRITE);
+		} else {
+			bounce_buffer_start(&bbstate, (void*)data->src,
+					    data->blocksize *
+					    data->blocks, GEN_BB_READ);
+		}
+		dwmci_prepare_data(host, data, cur_idmac,
+				   bbstate.bounce_buffer);
+	}
 
 	dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
 
@@ -204,6 +214,8 @@  static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 		ctrl = dwmci_readl(host, DWMCI_CTRL);
 		ctrl &= ~(DWMCI_DMA_EN);
 		dwmci_writel(host, DWMCI_CTRL, ctrl);
+
+		bounce_buffer_stop(&bbstate);
 	}
 
 	udelay(100);
diff --git a/include/configs/arndale.h b/include/configs/arndale.h
index a3cb56b..3d29caf 100644
--- a/include/configs/arndale.h
+++ b/include/configs/arndale.h
@@ -85,6 +85,7 @@ 
 #define CONFIG_DWMMC
 #define CONFIG_EXYNOS_DWMMC
 #define CONFIG_SUPPORT_EMMC_BOOT
+#define CONFIG_BOUNCE_BUFFER
 
 
 #define CONFIG_BOARD_EARLY_INIT_F
diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
index 8fb904c..b39bafc 100644
--- a/include/configs/exynos5250-dt.h
+++ b/include/configs/exynos5250-dt.h
@@ -102,6 +102,7 @@ 
 #define CONFIG_DWMMC
 #define CONFIG_EXYNOS_DWMMC
 #define CONFIG_SUPPORT_EMMC_BOOT
+#define CONFIG_BOUNCE_BUFFER
 
 
 #define CONFIG_BOARD_EARLY_INIT_F