[U-Boot] [PATCH] mmc: omap_hsmmc: add adma support

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

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;
if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) || (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) { flags |= (MSBS_MULTIBLK | BCE_ENABLE);writel(ie_val, &mmc_base->ie);
@@ -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

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!

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.

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?

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 ?

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.
participants (2)
-
Balaji T K
-
Tom Rini