public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support
@ 2014-05-02 13:55 Balaji T K
  2014-05-12 13:21 ` Balaji T K
  2014-05-12 13:28 ` Tom Rini
  0 siblings, 2 replies; 7+ messages in thread
From: Balaji T K @ 2014-05-02 13:55 UTC (permalink / raw)
  To: u-boot

MMC instance 1 and 2 is capable of ADMA in omap4, omap5.
Add support for ADMA and enable ADMA for read/write to
improve mmc throughput.

Signed-off-by: Balaji T K <balajitk@ti.com>
---
 arch/arm/include/asm/omap_mmc.h |   14 +++
 drivers/mmc/omap_hsmmc.c        |  163 +++++++++++++++++++++++++++++++++++++---
 include/configs/omap5_uevm.h    |    2 
 3 files changed, 169 insertions(+), 10 deletions(-)

Index: u-boot_denx/arch/arm/include/asm/omap_mmc.h
===================================================================
--- u-boot_denx.orig/arch/arm/include/asm/omap_mmc.h	2014-05-02 19:02:39.042727752 +0530
+++ u-boot_denx/arch/arm/include/asm/omap_mmc.h	2014-05-02 19:18:00.783780277 +0530
@@ -47,6 +47,9 @@ struct hsmmc {
 	unsigned int ie;		/* 0x134 */
 	unsigned char res4[0x8];
 	unsigned int capa;		/* 0x140 */
+	unsigned char res5[0x10];
+	unsigned int adma_es;		/* 0x154 */
+	unsigned int adma_sal;		/* 0x158 */
 };
 
 /*
@@ -68,9 +71,11 @@ struct hsmmc {
 #define WPP_ACTIVEHIGH			(0x0 << 8)
 #define RESERVED_MASK			(0x3 << 9)
 #define CTPL_MMC_SD			(0x0 << 11)
+#define DMA_MNS_ADMA_MODE		(0x1 << 20)
 #define BLEN_512BYTESLEN		(0x200 << 0)
 #define NBLK_STPCNT			(0x0 << 16)
 #define DE_DISABLE			(0x0 << 0)
+#define DE_ENABLE			(0x1 << 0)
 #define BCE_DISABLE			(0x0 << 1)
 #define BCE_ENABLE			(0x1 << 1)
 #define ACEN_DISABLE			(0x0 << 2)
@@ -103,6 +108,7 @@ struct hsmmc {
 #define DTW_1_BITMODE			(0x0 << 1)
 #define DTW_4_BITMODE			(0x1 << 1)
 #define DTW_8_BITMODE                   (0x1 << 5) /* CON[DW8]*/
+#define DMAS				(0x2 << 3)
 #define SDBP_PWROFF			(0x0 << 8)
 #define SDBP_PWRON			(0x1 << 8)
 #define SDVS_1V8			(0x5 << 9)
@@ -136,12 +142,18 @@ struct hsmmc {
 #define IE_DTO				(0x01 << 20)
 #define IE_DCRC				(0x01 << 21)
 #define IE_DEB				(0x01 << 22)
+#define IE_ADMAE			(0x01 << 25)
 #define IE_CERR				(0x01 << 28)
 #define IE_BADA				(0x01 << 29)
 
+#define CAPA_ADMA_SUPPORT		(1 << 19)
 #define VS30_3V0SUP			(1 << 25)
 #define VS18_1V8SUP			(1 << 26)
 
+#define ADMA_XFER_VALID			(1 << 0)
+#define ADMA_XFER_END			(1 << 1)
+#define ADMA_XFER_DESC			(1 << 5)
+
 /* Driver definitions */
 #define MMCSD_SECTOR_SIZE		512
 #define MMC_CARD			0
@@ -151,6 +163,8 @@ struct hsmmc {
 #define CLK_INITSEQ			0
 #define CLK_400KHZ			1
 #define CLK_MISC			2
+#define DMA_TYPE_SDMA			1
+#define DMA_TYPE_ADMA			2
 
 #define RSP_TYPE_NONE	(RSP_TYPE_NORSP   | CCCE_NOCHECK | CICE_NOCHECK)
 #define MMC_CMD0	(INDEX(0)  | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE)
Index: u-boot_denx/drivers/mmc/omap_hsmmc.c
===================================================================
--- u-boot_denx.orig/drivers/mmc/omap_hsmmc.c	2014-05-02 19:02:39.066727884 +0530
+++ u-boot_denx/drivers/mmc/omap_hsmmc.c	2014-05-02 19:17:25.247585485 +0530
@@ -22,6 +22,7 @@
  * MA 02111-1307 USA
  */
 
+#include <bouncebuf.h>
 #include <config.h>
 #include <common.h>
 #include <malloc.h>
@@ -44,12 +45,30 @@
 #undef OMAP_HSMMC_USE_GPIO
 #endif
 
+#ifdef CONFIG_SPL_BUILD
+#undef CONFIG_OMAP_MMC_ADMA
+#endif
+
+#ifdef CONFIG_OMAP_MMC_ADMA
+struct adma_desc_table {
+	u16 attr;
+	u16 length;
+	u32 addr;
+};
+#define ADMA_MAX_BYTES_PER_ROW (127 * 512)
+#define ADMA_TABLE_NUM_ENTRIES 517
+#endif
+
 /* common definitions for all OMAPs */
 #define SYSCTL_SRC	(1 << 25)
 #define SYSCTL_SRD	(1 << 26)
+#define IE_MASK		(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO |\
+			 IE_CIE | IE_CEB | IE_CCRC | IE_CTO | IE_BRR |\
+			 IE_BWR | IE_TC | IE_CC)
 
 struct omap_hsmmc_data {
 	struct hsmmc *base_addr;
+	int cap_dma;
 	struct mmc_config cfg;
 #ifdef OMAP_HSMMC_USE_GPIO
 	int cd_gpio;
@@ -205,11 +224,13 @@ void mmc_init_stream(struct hsmmc *mmc_b
 static int omap_hsmmc_init_setup(struct mmc *mmc)
 {
 	struct hsmmc *mmc_base;
+	struct omap_hsmmc_data *hsmmc_data;
 	unsigned int reg_val;
 	unsigned int dsor;
 	ulong start;
 
 	mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
+	hsmmc_data = (struct omap_hsmmc_data *)mmc->priv;
 	mmc_board_init(mmc);
 
 	writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
@@ -239,6 +260,16 @@ static int omap_hsmmc_init_setup(struct
 	writel(CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | CDP_ACTIVEHIGH |
 		MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | STR_BLOCK |
 		HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN, &mmc_base->con);
+#ifdef CONFIG_OMAP_MMC_ADMA
+	if (readl(&mmc_base->capa) & CAPA_ADMA_SUPPORT) {
+		reg_val = readl(&mmc_base->con);
+		writel(reg_val | DMA_MNS_ADMA_MODE, &mmc_base->con);
+		writel(readl(&mmc_base->hctl) | DMAS, &mmc_base->hctl);
+		hsmmc_data->cap_dma = DMA_TYPE_ADMA;
+	}
+#else
+		hsmmc_data->cap_dma = 0;
+#endif
 
 	dsor = 240;
 	mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
@@ -255,10 +286,7 @@ static int omap_hsmmc_init_setup(struct
 	writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
 
 	writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl);
-
-	writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE |
-		IE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC,
-		&mmc_base->ie);
+	writel(IE_MASK, &mmc_base->ie);
 
 	mmc_init_stream(mmc_base);
 
@@ -311,14 +339,93 @@ static void mmc_reset_controller_fsm(str
 	}
 }
 
+#ifdef CONFIG_OMAP_MMC_ADMA
+static int omap_hsmmc_adma_start(struct hsmmc *mmc_base,
+	struct adma_desc_table *pdesc, struct mmc_data *data,
+	void *bounce_buffer)
+{
+	int i;
+	u32 dmaaddr;
+	ulong blocks;
+	ulong data_start, data_end;
+
+	dmaaddr = (u32) bounce_buffer;
+	blocks = data->blocks;
+	writel((u32)pdesc, &mmc_base->adma_sal);
+	data_start = (ulong) pdesc;
+
+	for (i = 0; blocks != 0; i++) {
+		pdesc->addr = dmaaddr;
+		pdesc->attr = (ADMA_XFER_DESC | ADMA_XFER_VALID);
+		if ((blocks * data->blocksize) <= ADMA_MAX_BYTES_PER_ROW) {
+			pdesc->length = data->blocksize * blocks;
+			pdesc->attr |= ADMA_XFER_END;
+			break;
+		} else {
+			pdesc->length = ADMA_MAX_BYTES_PER_ROW;
+			blocks -= (ADMA_MAX_BYTES_PER_ROW / data->blocksize);
+			dmaaddr += ADMA_MAX_BYTES_PER_ROW;
+			pdesc++;
+		}
+	}
+	data_end = (ulong) pdesc;
+	flush_dcache_range(data_start, data_end + ARCH_DMA_MINALIGN);
+
+	return 0;
+}
+
+static int omap_hsmmc_adma_wait_for_tc(struct hsmmc *mmc_base)
+{
+	unsigned mmc_stat;
+	ulong start;
+	int ret = 0;
+
+	start = get_timer(0);
+	while (1) {
+		mmc_stat = readl(&mmc_base->stat);
+
+		if (get_timer(0) - start > 10 * MAX_RETRY_MS) {
+			printf("%s: timed out waiting for status!\n",
+			       __func__);
+			ret = TIMEOUT;
+			break;
+		}
+
+		if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
+			mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
+
+		if (mmc_stat & ERRI_MASK) {
+			ret = 1;
+			break;
+		}
+
+		if (mmc_stat & TC_MASK) {
+			writel(mmc_stat | TC_MASK, &mmc_base->stat);
+			break;
+		}
+	}
+
+	return ret;
+}
+#endif
+
 static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 			struct mmc_data *data)
 {
 	struct hsmmc *mmc_base;
+	struct omap_hsmmc_data *hsmmc_data;
 	unsigned int flags, mmc_stat;
 	ulong start;
+	int dma_type = 0;
+	u32 ie_val;
+#ifdef CONFIG_OMAP_MMC_ADMA
+	struct bounce_buffer bb;
+	ALLOC_CACHE_ALIGN_BUFFER(struct adma_desc_table, adma_desc,
+				 ADMA_TABLE_NUM_ENTRIES);
+#endif
 
 	mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
+	hsmmc_data = (struct omap_hsmmc_data *)mmc->priv;
 	start = get_timer(0);
 	while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
 		if (get_timer(0) - start > MAX_RETRY_MS) {
@@ -373,6 +480,8 @@ static int omap_hsmmc_send_cmd(struct mm
 		flags |= CICE_CHECK;
 
 	if (data) {
+		ie_val = IE_MASK;
+		writel(ie_val, &mmc_base->ie);
 		if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) ||
 			 (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) {
 			flags |= (MSBS_MULTIBLK | BCE_ENABLE);
@@ -386,6 +495,29 @@ static int omap_hsmmc_send_cmd(struct mm
 			flags |= (DP_DATA | DDIR_READ);
 		else
 			flags |= (DP_DATA | DDIR_WRITE);
+
+		if (!(hsmmc_data->cap_dma & DMA_TYPE_ADMA)) {
+			dma_type = 0;
+#ifdef CONFIG_OMAP_MMC_ADMA
+		} else {
+			dma_type = DMA_TYPE_ADMA;
+			flags = flags | DE_ENABLE;
+			ie_val &= ~(IE_BRR | IE_BWR);
+			ie_val |= IE_ADMAE;
+			writel(ie_val, &mmc_base->ie);
+			if (data->flags == MMC_DATA_READ) {
+				bounce_buffer_start(&bb, (void *)data->dest,
+						    data->blocksize *
+						    data->blocks, GEN_BB_WRITE);
+			} else {
+				bounce_buffer_start(&bb, (void *)data->src,
+						    data->blocksize *
+						    data->blocks, GEN_BB_READ);
+			}
+			omap_hsmmc_adma_start(mmc_base, adma_desc, data,
+					      bb.bounce_buffer);
+#endif
+		}
 	}
 
 	writel(cmd->cmdarg, &mmc_base->arg);
@@ -422,13 +554,24 @@ static int omap_hsmmc_send_cmd(struct mm
 		}
 	}
 
-	if (data && (data->flags & MMC_DATA_READ)) {
-		mmc_read_data(mmc_base,	data->dest,
-				data->blocksize * data->blocks);
-	} else if (data && (data->flags & MMC_DATA_WRITE)) {
-		mmc_write_data(mmc_base, data->src,
-				data->blocksize * data->blocks);
+	if (!dma_type) {
+		if (data && (data->flags & MMC_DATA_READ)) {
+			mmc_read_data(mmc_base,	data->dest,
+				      data->blocksize * data->blocks);
+		} else if (data && (data->flags & MMC_DATA_WRITE)) {
+			mmc_write_data(mmc_base, data->src,
+				       data->blocksize * data->blocks);
+		}
+#ifdef CONFIG_OMAP_MMC_ADMA
+	} else {
+		omap_hsmmc_adma_wait_for_tc(mmc_base);
+#endif
 	}
+
+#ifdef CONFIG_OMAP_MMC_ADMA
+	if (dma_type)
+		bounce_buffer_stop(&bb);
+#endif
 	return 0;
 }
 
Index: u-boot_denx/include/configs/omap5_uevm.h
===================================================================
--- u-boot_denx.orig/include/configs/omap5_uevm.h	2014-05-02 19:02:39.094728037 +0530
+++ u-boot_denx/include/configs/omap5_uevm.h	2014-05-02 19:17:25.247585485 +0530
@@ -31,6 +31,8 @@
 #define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_CMD_SAVEENV
 
+#define CONFIG_BOUNCE_BUFFER
+#define CONFIG_OMAP_MMC_ADMA
 /* Enhance our eMMC support / experience. */
 #define CONFIG_CMD_GPT
 #define CONFIG_EFI_PARTITION

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support
  2014-05-02 13:55 [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support Balaji T K
@ 2014-05-12 13:21 ` Balaji T K
  2014-05-12 13:28 ` Tom Rini
  1 sibling, 0 replies; 7+ messages in thread
From: Balaji T K @ 2014-05-12 13:21 UTC (permalink / raw)
  To: u-boot

On Friday 02 May 2014 07:25 PM, Balaji T K wrote:
> MMC instance 1 and 2 is capable of ADMA in omap4, omap5.
> Add support for ADMA and enable ADMA for read/write to
> improve mmc throughput.
Hi,

Realized I need to git format-patch this patch,
Any other comments ?

>
> Signed-off-by: Balaji T K <balajitk@ti.com>
> ---
>   arch/arm/include/asm/omap_mmc.h |   14 +++
>   drivers/mmc/omap_hsmmc.c        |  163 +++++++++++++++++++++++++++++++++++++---
>   include/configs/omap5_uevm.h    |    2
>   3 files changed, 169 insertions(+), 10 deletions(-)
>
> Index: u-boot_denx/arch/arm/include/asm/omap_mmc.h
> ===================================================================
> --- u-boot_denx.orig/arch/arm/include/asm/omap_mmc.h	2014-05-02 19:02:39.042727752 +0530
> +++ u-boot_denx/arch/arm/include/asm/omap_mmc.h	2014-05-02 19:18:00.783780277 +0530
> @@ -47,6 +47,9 @@ struct hsmmc {
>   	unsigned int ie;		/* 0x134 */
>   	unsigned char res4[0x8];
>   	unsigned int capa;		/* 0x140 */
> +	unsigned char res5[0x10];
> +	unsigned int adma_es;		/* 0x154 */
> +	unsigned int adma_sal;		/* 0x158 */
>   };
>
>   /*
> @@ -68,9 +71,11 @@ struct hsmmc {
>   #define WPP_ACTIVEHIGH			(0x0 << 8)
>   #define RESERVED_MASK			(0x3 << 9)
>   #define CTPL_MMC_SD			(0x0 << 11)
> +#define DMA_MNS_ADMA_MODE		(0x1 << 20)
>   #define BLEN_512BYTESLEN		(0x200 << 0)
>   #define NBLK_STPCNT			(0x0 << 16)
>   #define DE_DISABLE			(0x0 << 0)
> +#define DE_ENABLE			(0x1 << 0)
>   #define BCE_DISABLE			(0x0 << 1)
>   #define BCE_ENABLE			(0x1 << 1)
>   #define ACEN_DISABLE			(0x0 << 2)
> @@ -103,6 +108,7 @@ struct hsmmc {
>   #define DTW_1_BITMODE			(0x0 << 1)
>   #define DTW_4_BITMODE			(0x1 << 1)
>   #define DTW_8_BITMODE                   (0x1 << 5) /* CON[DW8]*/
> +#define DMAS				(0x2 << 3)
>   #define SDBP_PWROFF			(0x0 << 8)
>   #define SDBP_PWRON			(0x1 << 8)
>   #define SDVS_1V8			(0x5 << 9)
> @@ -136,12 +142,18 @@ struct hsmmc {
>   #define IE_DTO				(0x01 << 20)
>   #define IE_DCRC				(0x01 << 21)
>   #define IE_DEB				(0x01 << 22)
> +#define IE_ADMAE			(0x01 << 25)
>   #define IE_CERR				(0x01 << 28)
>   #define IE_BADA				(0x01 << 29)
>
> +#define CAPA_ADMA_SUPPORT		(1 << 19)
>   #define VS30_3V0SUP			(1 << 25)
>   #define VS18_1V8SUP			(1 << 26)
>
> +#define ADMA_XFER_VALID			(1 << 0)
> +#define ADMA_XFER_END			(1 << 1)
> +#define ADMA_XFER_DESC			(1 << 5)
> +
>   /* Driver definitions */
>   #define MMCSD_SECTOR_SIZE		512
>   #define MMC_CARD			0
> @@ -151,6 +163,8 @@ struct hsmmc {
>   #define CLK_INITSEQ			0
>   #define CLK_400KHZ			1
>   #define CLK_MISC			2
> +#define DMA_TYPE_SDMA			1
> +#define DMA_TYPE_ADMA			2
>
>   #define RSP_TYPE_NONE	(RSP_TYPE_NORSP   | CCCE_NOCHECK | CICE_NOCHECK)
>   #define MMC_CMD0	(INDEX(0)  | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE)
> Index: u-boot_denx/drivers/mmc/omap_hsmmc.c
> ===================================================================
> --- u-boot_denx.orig/drivers/mmc/omap_hsmmc.c	2014-05-02 19:02:39.066727884 +0530
> +++ u-boot_denx/drivers/mmc/omap_hsmmc.c	2014-05-02 19:17:25.247585485 +0530
> @@ -22,6 +22,7 @@
>    * MA 02111-1307 USA
>    */
>
> +#include <bouncebuf.h>
>   #include <config.h>
>   #include <common.h>
>   #include <malloc.h>
> @@ -44,12 +45,30 @@
>   #undef OMAP_HSMMC_USE_GPIO
>   #endif
>
> +#ifdef CONFIG_SPL_BUILD
> +#undef CONFIG_OMAP_MMC_ADMA
> +#endif
> +
> +#ifdef CONFIG_OMAP_MMC_ADMA
> +struct adma_desc_table {
> +	u16 attr;
> +	u16 length;
> +	u32 addr;
> +};
> +#define ADMA_MAX_BYTES_PER_ROW (127 * 512)
> +#define ADMA_TABLE_NUM_ENTRIES 517
> +#endif
> +
>   /* common definitions for all OMAPs */
>   #define SYSCTL_SRC	(1 << 25)
>   #define SYSCTL_SRD	(1 << 26)
> +#define IE_MASK		(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO |\
> +			 IE_CIE | IE_CEB | IE_CCRC | IE_CTO | IE_BRR |\
> +			 IE_BWR | IE_TC | IE_CC)
>
>   struct omap_hsmmc_data {
>   	struct hsmmc *base_addr;
> +	int cap_dma;
>   	struct mmc_config cfg;
>   #ifdef OMAP_HSMMC_USE_GPIO
>   	int cd_gpio;
> @@ -205,11 +224,13 @@ void mmc_init_stream(struct hsmmc *mmc_b
>   static int omap_hsmmc_init_setup(struct mmc *mmc)
>   {
>   	struct hsmmc *mmc_base;
> +	struct omap_hsmmc_data *hsmmc_data;
>   	unsigned int reg_val;
>   	unsigned int dsor;
>   	ulong start;
>
>   	mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
> +	hsmmc_data = (struct omap_hsmmc_data *)mmc->priv;
>   	mmc_board_init(mmc);
>
>   	writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
> @@ -239,6 +260,16 @@ static int omap_hsmmc_init_setup(struct
>   	writel(CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | CDP_ACTIVEHIGH |
>   		MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | STR_BLOCK |
>   		HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN, &mmc_base->con);
> +#ifdef CONFIG_OMAP_MMC_ADMA
> +	if (readl(&mmc_base->capa) & CAPA_ADMA_SUPPORT) {
> +		reg_val = readl(&mmc_base->con);
> +		writel(reg_val | DMA_MNS_ADMA_MODE, &mmc_base->con);
> +		writel(readl(&mmc_base->hctl) | DMAS, &mmc_base->hctl);
> +		hsmmc_data->cap_dma = DMA_TYPE_ADMA;
> +	}
> +#else
> +		hsmmc_data->cap_dma = 0;
> +#endif
>
>   	dsor = 240;
>   	mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
> @@ -255,10 +286,7 @@ static int omap_hsmmc_init_setup(struct
>   	writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
>
>   	writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl);
> -
> -	writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE |
> -		IE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC,
> -		&mmc_base->ie);
> +	writel(IE_MASK, &mmc_base->ie);
>
>   	mmc_init_stream(mmc_base);
>
> @@ -311,14 +339,93 @@ static void mmc_reset_controller_fsm(str
>   	}
>   }
>
> +#ifdef CONFIG_OMAP_MMC_ADMA
> +static int omap_hsmmc_adma_start(struct hsmmc *mmc_base,
> +	struct adma_desc_table *pdesc, struct mmc_data *data,
> +	void *bounce_buffer)
> +{
> +	int i;
> +	u32 dmaaddr;
> +	ulong blocks;
> +	ulong data_start, data_end;
> +
> +	dmaaddr = (u32) bounce_buffer;
> +	blocks = data->blocks;
> +	writel((u32)pdesc, &mmc_base->adma_sal);
> +	data_start = (ulong) pdesc;
> +
> +	for (i = 0; blocks != 0; i++) {
> +		pdesc->addr = dmaaddr;
> +		pdesc->attr = (ADMA_XFER_DESC | ADMA_XFER_VALID);
> +		if ((blocks * data->blocksize) <= ADMA_MAX_BYTES_PER_ROW) {
> +			pdesc->length = data->blocksize * blocks;
> +			pdesc->attr |= ADMA_XFER_END;
> +			break;
> +		} else {
> +			pdesc->length = ADMA_MAX_BYTES_PER_ROW;
> +			blocks -= (ADMA_MAX_BYTES_PER_ROW / data->blocksize);
> +			dmaaddr += ADMA_MAX_BYTES_PER_ROW;
> +			pdesc++;
> +		}
> +	}
> +	data_end = (ulong) pdesc;
> +	flush_dcache_range(data_start, data_end + ARCH_DMA_MINALIGN);
> +
> +	return 0;
> +}
> +
> +static int omap_hsmmc_adma_wait_for_tc(struct hsmmc *mmc_base)
> +{
> +	unsigned mmc_stat;
> +	ulong start;
> +	int ret = 0;
> +
> +	start = get_timer(0);
> +	while (1) {
> +		mmc_stat = readl(&mmc_base->stat);
> +
> +		if (get_timer(0) - start > 10 * MAX_RETRY_MS) {
> +			printf("%s: timed out waiting for status!\n",
> +			       __func__);
> +			ret = TIMEOUT;
> +			break;
> +		}
> +
> +		if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
> +			mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
> +
> +		if (mmc_stat & ERRI_MASK) {
> +			ret = 1;
> +			break;
> +		}
> +
> +		if (mmc_stat & TC_MASK) {
> +			writel(mmc_stat | TC_MASK, &mmc_base->stat);
> +			break;
> +		}
> +	}
> +
> +	return ret;
> +}
> +#endif
> +
>   static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>   			struct mmc_data *data)
>   {
>   	struct hsmmc *mmc_base;
> +	struct omap_hsmmc_data *hsmmc_data;
>   	unsigned int flags, mmc_stat;
>   	ulong start;
> +	int dma_type = 0;
> +	u32 ie_val;
> +#ifdef CONFIG_OMAP_MMC_ADMA
> +	struct bounce_buffer bb;
> +	ALLOC_CACHE_ALIGN_BUFFER(struct adma_desc_table, adma_desc,
> +				 ADMA_TABLE_NUM_ENTRIES);
> +#endif
>
>   	mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
> +	hsmmc_data = (struct omap_hsmmc_data *)mmc->priv;
>   	start = get_timer(0);
>   	while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
>   		if (get_timer(0) - start > MAX_RETRY_MS) {
> @@ -373,6 +480,8 @@ static int omap_hsmmc_send_cmd(struct mm
>   		flags |= CICE_CHECK;
>
>   	if (data) {
> +		ie_val = IE_MASK;
> +		writel(ie_val, &mmc_base->ie);
>   		if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) ||
>   			 (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) {
>   			flags |= (MSBS_MULTIBLK | BCE_ENABLE);
> @@ -386,6 +495,29 @@ static int omap_hsmmc_send_cmd(struct mm
>   			flags |= (DP_DATA | DDIR_READ);
>   		else
>   			flags |= (DP_DATA | DDIR_WRITE);
> +
> +		if (!(hsmmc_data->cap_dma & DMA_TYPE_ADMA)) {
> +			dma_type = 0;
> +#ifdef CONFIG_OMAP_MMC_ADMA
> +		} else {
> +			dma_type = DMA_TYPE_ADMA;
> +			flags = flags | DE_ENABLE;
> +			ie_val &= ~(IE_BRR | IE_BWR);
> +			ie_val |= IE_ADMAE;
> +			writel(ie_val, &mmc_base->ie);
> +			if (data->flags == MMC_DATA_READ) {
> +				bounce_buffer_start(&bb, (void *)data->dest,
> +						    data->blocksize *
> +						    data->blocks, GEN_BB_WRITE);
> +			} else {
> +				bounce_buffer_start(&bb, (void *)data->src,
> +						    data->blocksize *
> +						    data->blocks, GEN_BB_READ);
> +			}
> +			omap_hsmmc_adma_start(mmc_base, adma_desc, data,
> +					      bb.bounce_buffer);
> +#endif
> +		}
>   	}
>
>   	writel(cmd->cmdarg, &mmc_base->arg);
> @@ -422,13 +554,24 @@ static int omap_hsmmc_send_cmd(struct mm
>   		}
>   	}
>
> -	if (data && (data->flags & MMC_DATA_READ)) {
> -		mmc_read_data(mmc_base,	data->dest,
> -				data->blocksize * data->blocks);
> -	} else if (data && (data->flags & MMC_DATA_WRITE)) {
> -		mmc_write_data(mmc_base, data->src,
> -				data->blocksize * data->blocks);
> +	if (!dma_type) {
> +		if (data && (data->flags & MMC_DATA_READ)) {
> +			mmc_read_data(mmc_base,	data->dest,
> +				      data->blocksize * data->blocks);
> +		} else if (data && (data->flags & MMC_DATA_WRITE)) {
> +			mmc_write_data(mmc_base, data->src,
> +				       data->blocksize * data->blocks);
> +		}
> +#ifdef CONFIG_OMAP_MMC_ADMA
> +	} else {
> +		omap_hsmmc_adma_wait_for_tc(mmc_base);
> +#endif
>   	}
> +
> +#ifdef CONFIG_OMAP_MMC_ADMA
> +	if (dma_type)
> +		bounce_buffer_stop(&bb);
> +#endif
>   	return 0;
>   }
>
> Index: u-boot_denx/include/configs/omap5_uevm.h
> ===================================================================
> --- u-boot_denx.orig/include/configs/omap5_uevm.h	2014-05-02 19:02:39.094728037 +0530
> +++ u-boot_denx/include/configs/omap5_uevm.h	2014-05-02 19:17:25.247585485 +0530
> @@ -31,6 +31,8 @@
>   #define CONFIG_SYS_REDUNDAND_ENVIRONMENT
>   #define CONFIG_CMD_SAVEENV
>
> +#define CONFIG_BOUNCE_BUFFER
> +#define CONFIG_OMAP_MMC_ADMA
>   /* Enhance our eMMC support / experience. */
>   #define CONFIG_CMD_GPT
>   #define CONFIG_EFI_PARTITION
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support
  2014-05-02 13:55 [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support Balaji T K
  2014-05-12 13:21 ` Balaji T K
@ 2014-05-12 13:28 ` Tom Rini
  2014-05-12 13:42   ` Balaji T K
  1 sibling, 1 reply; 7+ messages in thread
From: Tom Rini @ 2014-05-12 13:28 UTC (permalink / raw)
  To: u-boot

On Fri, May 02, 2014 at 07:25:20PM +0530, Balaji T K wrote:

> MMC instance 1 and 2 is capable of ADMA in omap4, omap5.
> Add support for ADMA and enable ADMA for read/write to
> improve mmc throughput.
[snip]
> @@ -44,12 +45,30 @@
>  #undef OMAP_HSMMC_USE_GPIO
>  #endif
>  
> +#ifdef CONFIG_SPL_BUILD
> +#undef CONFIG_OMAP_MMC_ADMA
> +#endif

Why?  Especially since a number of the folks interested in this for
performance want it for SPL OS mode.  Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140512/70cccf78/attachment.pgp>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support
  2014-05-12 13:28 ` Tom Rini
@ 2014-05-12 13:42   ` Balaji T K
  2014-05-12 14:50     ` Tom Rini
  0 siblings, 1 reply; 7+ messages in thread
From: Balaji T K @ 2014-05-12 13:42 UTC (permalink / raw)
  To: u-boot

On Monday 12 May 2014 06:58 PM, Tom Rini wrote:
> On Fri, May 02, 2014 at 07:25:20PM +0530, Balaji T K wrote:
>
>> MMC instance 1 and 2 is capable of ADMA in omap4, omap5.
>> Add support for ADMA and enable ADMA for read/write to
>> improve mmc throughput.
> [snip]
>> @@ -44,12 +45,30 @@
>>   #undef OMAP_HSMMC_USE_GPIO
>>   #endif
>>
>> +#ifdef CONFIG_SPL_BUILD
>> +#undef CONFIG_OMAP_MMC_ADMA
>> +#endif
>
> Why?  Especially since a number of the folks interested in this for
> performance want it for SPL OS mode.  Thanks!

Because in SoCs like OMAP4/5 mmc1/2 adma doesn't have access to sram.
So can't have descriptor or src / destination buffers (allocated on stack)
given by mmc core on sram.

Thanks and Regards,
Balaji T K.

>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support
  2014-05-12 13:42   ` Balaji T K
@ 2014-05-12 14:50     ` Tom Rini
  2014-05-15 14:15       ` Balaji T K
  0 siblings, 1 reply; 7+ messages in thread
From: Tom Rini @ 2014-05-12 14:50 UTC (permalink / raw)
  To: u-boot

On Mon, May 12, 2014 at 07:12:44PM +0530, Balaji T K wrote:
> On Monday 12 May 2014 06:58 PM, Tom Rini wrote:
> >On Fri, May 02, 2014 at 07:25:20PM +0530, Balaji T K wrote:
> >
> >>MMC instance 1 and 2 is capable of ADMA in omap4, omap5.
> >>Add support for ADMA and enable ADMA for read/write to
> >>improve mmc throughput.
> >[snip]
> >>@@ -44,12 +45,30 @@
> >>  #undef OMAP_HSMMC_USE_GPIO
> >>  #endif
> >>
> >>+#ifdef CONFIG_SPL_BUILD
> >>+#undef CONFIG_OMAP_MMC_ADMA
> >>+#endif
> >
> >Why?  Especially since a number of the folks interested in this for
> >performance want it for SPL OS mode.  Thanks!
> 
> Because in SoCs like OMAP4/5 mmc1/2 adma doesn't have access to sram.
> So can't have descriptor or src / destination buffers (allocated on stack)
> given by mmc core on sram.

And we can't malloc them?

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140512/cebe71ce/attachment.pgp>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support
  2014-05-12 14:50     ` Tom Rini
@ 2014-05-15 14:15       ` Balaji T K
  2014-05-15 17:55         ` Tom Rini
  0 siblings, 1 reply; 7+ messages in thread
From: Balaji T K @ 2014-05-15 14:15 UTC (permalink / raw)
  To: u-boot

On Monday 12 May 2014 08:20 PM, Tom Rini wrote:
> On Mon, May 12, 2014 at 07:12:44PM +0530, Balaji T K wrote:
>> On Monday 12 May 2014 06:58 PM, Tom Rini wrote:
>>> On Fri, May 02, 2014 at 07:25:20PM +0530, Balaji T K wrote:
>>>
>>>> MMC instance 1 and 2 is capable of ADMA in omap4, omap5.
>>>> Add support for ADMA and enable ADMA for read/write to
>>>> improve mmc throughput.
>>> [snip]
>>>> @@ -44,12 +45,30 @@
>>>>   #undef OMAP_HSMMC_USE_GPIO
>>>>   #endif
>>>>
>>>> +#ifdef CONFIG_SPL_BUILD
>>>> +#undef CONFIG_OMAP_MMC_ADMA
>>>> +#endif
>>>
>>> Why?  Especially since a number of the folks interested in this for
>>> performance want it for SPL OS mode.  Thanks!
>>
>> Because in SoCs like OMAP4/5 mmc1/2 adma doesn't have access to sram.
>> So can't have descriptor or src / destination buffers (allocated on stack)
>> given by mmc core on sram.
>
> And we can't malloc them?
>

For descriptor yes, but for src / dest, I doubt since
it would be difficult to force the upper (fs, mmc..) layers for controller limitation
and some ARCH might require the buffers to be cache aligned

Does malloc return buffers aligned to cache boundary ?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support
  2014-05-15 14:15       ` Balaji T K
@ 2014-05-15 17:55         ` Tom Rini
  0 siblings, 0 replies; 7+ messages in thread
From: Tom Rini @ 2014-05-15 17:55 UTC (permalink / raw)
  To: u-boot

On Thu, May 15, 2014 at 07:45:28PM +0530, Balaji T K wrote:
> On Monday 12 May 2014 08:20 PM, Tom Rini wrote:
> >On Mon, May 12, 2014 at 07:12:44PM +0530, Balaji T K wrote:
> >>On Monday 12 May 2014 06:58 PM, Tom Rini wrote:
> >>>On Fri, May 02, 2014 at 07:25:20PM +0530, Balaji T K wrote:
> >>>
> >>>>MMC instance 1 and 2 is capable of ADMA in omap4, omap5.
> >>>>Add support for ADMA and enable ADMA for read/write to
> >>>>improve mmc throughput.
> >>>[snip]
> >>>>@@ -44,12 +45,30 @@
> >>>>  #undef OMAP_HSMMC_USE_GPIO
> >>>>  #endif
> >>>>
> >>>>+#ifdef CONFIG_SPL_BUILD
> >>>>+#undef CONFIG_OMAP_MMC_ADMA
> >>>>+#endif
> >>>
> >>>Why?  Especially since a number of the folks interested in this for
> >>>performance want it for SPL OS mode.  Thanks!
> >>
> >>Because in SoCs like OMAP4/5 mmc1/2 adma doesn't have access to sram.
> >>So can't have descriptor or src / destination buffers (allocated on stack)
> >>given by mmc core on sram.
> >
> >And we can't malloc them?
> >
> 
> For descriptor yes, but for src / dest, I doubt since
> it would be difficult to force the upper (fs, mmc..) layers for controller limitation
> and some ARCH might require the buffers to be cache aligned
> 
> Does malloc return buffers aligned to cache boundary ?

Yes, with memalign which upper layers should also be using for such
cases.  FWIW, the ADMA patches I see in the omapzoom tree I'm fairly
certain do SPL (since that's a focus of theirs) but incorrectly don't
bother ensuring alignment with memalign.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140515/06551b04/attachment.pgp>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-05-15 17:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-02 13:55 [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support Balaji T K
2014-05-12 13:21 ` Balaji T K
2014-05-12 13:28 ` Tom Rini
2014-05-12 13:42   ` Balaji T K
2014-05-12 14:50     ` Tom Rini
2014-05-15 14:15       ` Balaji T K
2014-05-15 17:55         ` Tom Rini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox