[U-Boot] [PATCH v2 0/5] mmc: omap_hsmmc: Add support for ADMA

This series enables the ADMA present in some OMAP SOCs. On a DRA7 the performances when reading from the eMMC go from 18MB/s to 43MB/s. Also while were at it, fix some incorrect bit operations
This series applies on top of the series that enables HS200 and UHS mode "mmc: Add support for HS200 and UHS modes" but should be easy to use on top of u-boot/master (just remove special handling of the tuning).
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57).
Cheers,
Jean-Jacques
changes since v1: * added a timeout to terminate the DMA transfer if it takes too long * changed omap_hsmmc_adma_desc() and omap_hsmmc_prepare_adma_table(() to not return any value (void) * removed wrong comment about cache handling
Jean-Jacques Hiblot (2): Revert "omap_hsmmc: update struct hsmmc to accommodate omap3 from DT" omap: Update the base address of the MMC controllers
Kishon Vijay Abraham I (3): mmc: omap_hsmmc: Add support for DMA (ADMA2) mmc: omap_hsmmc: Enable Auto command (CMD12) enable mmc: omap_hsmmc: Fix incorrect bit operations for disabling a bit
arch/arm/include/asm/arch-am33xx/mmc_host_def.h | 4 +- arch/arm/include/asm/arch-omap4/mmc_host_def.h | 6 +- arch/arm/include/asm/arch-omap5/mmc_host_def.h | 6 +- arch/arm/include/asm/omap_mmc.h | 19 +- arch/arm/mach-keystone/include/mach/mmc_host_def.h | 4 +- drivers/mmc/omap_hsmmc.c | 251 +++++++++++++++++---- 6 files changed, 238 insertions(+), 52 deletions(-)

This reverts commit 46831c1a4cda75d92f7ad18d4e2b1eb196c62b2f. This reserved area at the beginning of struct hsmm, will be used later to support ADMA
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com --- arch/arm/include/asm/omap_mmc.h | 3 +++ drivers/mmc/omap_hsmmc.c | 35 ++++------------------------------- 2 files changed, 7 insertions(+), 31 deletions(-)
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h index fd33408..297e6a7 100644 --- a/arch/arm/include/asm/omap_mmc.h +++ b/arch/arm/include/asm/omap_mmc.h @@ -28,6 +28,9 @@ #include <mmc.h>
struct hsmmc { +#ifdef CONFIG_DM_MMC + unsigned char res0[0x100]; +#endif unsigned char res1[0x10]; unsigned int sysconfig; /* 0x10 */ unsigned int sysstatus; /* 0x14 */ diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index efa4389..9f38687 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -56,10 +56,6 @@ DECLARE_GLOBAL_DATA_PTR; #define SYSCTL_SRC (1 << 25) #define SYSCTL_SRD (1 << 26)
-struct omap2_mmc_platform_config { - u32 reg_offset; -}; - struct omap_hsmmc_data { struct hsmmc *base_addr; #if !CONFIG_IS_ENABLED(DM_MMC) @@ -802,15 +798,13 @@ static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev) { struct omap_hsmmc_plat *plat = dev_get_platdata(dev); struct mmc_config *cfg = &plat->cfg; - struct omap2_mmc_platform_config *data = - (struct omap2_mmc_platform_config *)dev_get_driver_data(dev); const void *fdt = gd->fdt_blob; int node = dev_of_offset(dev); int val;
plat->base_addr = map_physmem(devfdt_get_addr(dev), sizeof(struct hsmmc *), - MAP_NOCACHE) + data->reg_offset; + MAP_NOCACHE);
cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS; val = fdtdec_get_int(fdt, node, "bus-width", -1); @@ -886,31 +880,10 @@ static int omap_hsmmc_probe(struct udevice *dev) }
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) -static const struct omap2_mmc_platform_config omap3_mmc_pdata = { - .reg_offset = 0, -}; - -static const struct omap2_mmc_platform_config am33xx_mmc_pdata = { - .reg_offset = 0x100, -}; - -static const struct omap2_mmc_platform_config omap4_mmc_pdata = { - .reg_offset = 0x100, -}; - static const struct udevice_id omap_hsmmc_ids[] = { - { - .compatible = "ti,omap3-hsmmc", - .data = (ulong)&omap3_mmc_pdata - }, - { - .compatible = "ti,omap4-hsmmc", - .data = (ulong)&omap4_mmc_pdata - }, - { - .compatible = "ti,am33xx-hsmmc", - .data = (ulong)&am33xx_mmc_pdata - }, + { .compatible = "ti,omap3-hsmmc" }, + { .compatible = "ti,omap4-hsmmc" }, + { .compatible = "ti,am33xx-hsmmc" }, { } }; #endif

On Thu, Sep 21, 2017 at 04:51:32PM +0200, Jean-Jacques Hiblot wrote:
This reverts commit 46831c1a4cda75d92f7ad18d4e2b1eb196c62b2f. This reserved area at the beginning of struct hsmm, will be used later to support ADMA
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Reviewed-by: Tom Rini trini@konsulko.com

On 09/24/2017 11:39 PM, Tom Rini wrote:
On Thu, Sep 21, 2017 at 04:51:32PM +0200, Jean-Jacques Hiblot wrote:
This reverts commit 46831c1a4cda75d92f7ad18d4e2b1eb196c62b2f. This reserved area at the beginning of struct hsmm, will be used later to support ADMA
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Reviewed-by: Tom Rini trini@konsulko.com
Thanks for reviewed-by tag. I will pick this series[1/5~5/5] into u-boot-mmc.
Best Regards, Jaehoon Chung

On Thu, Sep 21, 2017 at 04:51:32PM +0200, Jean-Jacques Hiblot wrote:
This reverts commit 46831c1a4cda75d92f7ad18d4e2b1eb196c62b2f. This reserved area at the beginning of struct hsmm, will be used later to support ADMA
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com Reviewed-by: Tom Rini trini@konsulko.com
Applied to u-boot/master, thanks!

Align the base address defined in header files with the base address used in the DTS. This will facilitate the introduction of the DMA support.
Of all HSMMC users, only omap3 doesn't have the 0x100 reserved region at the top. This region will be used to determine if the controller supports DMA transfers
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com --- arch/arm/include/asm/arch-am33xx/mmc_host_def.h | 4 ++-- arch/arm/include/asm/arch-omap4/mmc_host_def.h | 6 +++--- arch/arm/include/asm/arch-omap5/mmc_host_def.h | 6 +++--- arch/arm/include/asm/omap_mmc.h | 2 +- arch/arm/mach-keystone/include/mach/mmc_host_def.h | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/arm/include/asm/arch-am33xx/mmc_host_def.h b/arch/arm/include/asm/arch-am33xx/mmc_host_def.h index 724e252..5a2ea8f 100644 --- a/arch/arm/include/asm/arch-am33xx/mmc_host_def.h +++ b/arch/arm/include/asm/arch-am33xx/mmc_host_def.h @@ -21,8 +21,8 @@ /* * OMAP HSMMC register definitions */ -#define OMAP_HSMMC1_BASE 0x48060100 -#define OMAP_HSMMC2_BASE 0x481D8100 +#define OMAP_HSMMC1_BASE 0x48060000 +#define OMAP_HSMMC2_BASE 0x481D8000
#if defined(CONFIG_TI814X) #undef MMC_CLOCK_REFERENCE diff --git a/arch/arm/include/asm/arch-omap4/mmc_host_def.h b/arch/arm/include/asm/arch-omap4/mmc_host_def.h index 9c8ccb6..d067799 100644 --- a/arch/arm/include/asm/arch-omap4/mmc_host_def.h +++ b/arch/arm/include/asm/arch-omap4/mmc_host_def.h @@ -31,8 +31,8 @@ * OMAP HSMMC register definitions */
-#define OMAP_HSMMC1_BASE 0x4809C100 -#define OMAP_HSMMC2_BASE 0x480B4100 -#define OMAP_HSMMC3_BASE 0x480AD100 +#define OMAP_HSMMC1_BASE 0x4809C000 +#define OMAP_HSMMC2_BASE 0x480B4000 +#define OMAP_HSMMC3_BASE 0x480AD000
#endif /* MMC_HOST_DEF_H */ diff --git a/arch/arm/include/asm/arch-omap5/mmc_host_def.h b/arch/arm/include/asm/arch-omap5/mmc_host_def.h index 9c8ccb6..d067799 100644 --- a/arch/arm/include/asm/arch-omap5/mmc_host_def.h +++ b/arch/arm/include/asm/arch-omap5/mmc_host_def.h @@ -31,8 +31,8 @@ * OMAP HSMMC register definitions */
-#define OMAP_HSMMC1_BASE 0x4809C100 -#define OMAP_HSMMC2_BASE 0x480B4100 -#define OMAP_HSMMC3_BASE 0x480AD100 +#define OMAP_HSMMC1_BASE 0x4809C000 +#define OMAP_HSMMC2_BASE 0x480B4000 +#define OMAP_HSMMC3_BASE 0x480AD000
#endif /* MMC_HOST_DEF_H */ diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h index 297e6a7..77278a3 100644 --- a/arch/arm/include/asm/omap_mmc.h +++ b/arch/arm/include/asm/omap_mmc.h @@ -28,7 +28,7 @@ #include <mmc.h>
struct hsmmc { -#ifdef CONFIG_DM_MMC +#ifndef CONFIG_OMAP34XX unsigned char res0[0x100]; #endif unsigned char res1[0x10]; diff --git a/arch/arm/mach-keystone/include/mach/mmc_host_def.h b/arch/arm/mach-keystone/include/mach/mmc_host_def.h index a5050ac..b8eed7d 100644 --- a/arch/arm/mach-keystone/include/mach/mmc_host_def.h +++ b/arch/arm/mach-keystone/include/mach/mmc_host_def.h @@ -16,7 +16,7 @@ * OMAP HSMMC register definitions */
-#define OMAP_HSMMC1_BASE 0x23000100 -#define OMAP_HSMMC2_BASE 0x23100100 +#define OMAP_HSMMC1_BASE 0x23000000 +#define OMAP_HSMMC2_BASE 0x23100000
#endif /* K2G_MMC_HOST_DEF_H */

On Thu, Sep 21, 2017 at 04:51:33PM +0200, Jean-Jacques Hiblot wrote:
Align the base address defined in header files with the base address used in the DTS. This will facilitate the introduction of the DMA support.
Of all HSMMC users, only omap3 doesn't have the 0x100 reserved region at the top. This region will be used to determine if the controller supports DMA transfers
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Reviewed-by: Tom Rini trini@konsulko.com

On Thu, Sep 21, 2017 at 04:51:33PM +0200, Jean-Jacques Hiblot wrote:
Align the base address defined in header files with the base address used in the DTS. This will facilitate the introduction of the DMA support.
Of all HSMMC users, only omap3 doesn't have the 0x100 reserved region at the top. This region will be used to determine if the controller supports DMA transfers
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com Reviewed-by: Tom Rini trini@konsulko.com
Applied to u-boot/master, thanks!

From: Kishon Vijay Abraham I kishon@ti.com
The omap hsmmc host controller can have the ADMA2 feature. It brings better read and write throughput. On most SOC, the capability is read from the hl_hwinfo register. On OMAP3, DMA support is compiled out.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com --- arch/arm/include/asm/omap_mmc.h | 12 ++- drivers/mmc/omap_hsmmc.c | 203 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 211 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h index 77278a3..128cd81 100644 --- a/arch/arm/include/asm/omap_mmc.h +++ b/arch/arm/include/asm/omap_mmc.h @@ -29,7 +29,10 @@
struct hsmmc { #ifndef CONFIG_OMAP34XX - unsigned char res0[0x100]; + unsigned int hl_rev; + unsigned int hl_hwinfo; + unsigned int hl_sysconfig; + unsigned char res0[0xf4]; #endif unsigned char res1[0x10]; unsigned int sysconfig; /* 0x10 */ @@ -52,6 +55,9 @@ struct hsmmc { unsigned int ie; /* 0x134 */ unsigned char res4[0x8]; unsigned int capa; /* 0x140 */ + unsigned char res5[0x10]; + unsigned int admaes; /* 0x154 */ + unsigned int admasal; /* 0x158 */ };
struct omap_hsmmc_plat { @@ -64,6 +70,7 @@ struct omap_hsmmc_plat { /* * OMAP HS MMC Bit definitions */ +#define MADMA_EN (0x1 << 0) #define MMC_SOFTRESET (0x1 << 1) #define RESETDONE (0x1 << 0) #define NOOPENDRAIN (0x0 << 0) @@ -80,6 +87,7 @@ struct omap_hsmmc_plat { #define WPP_ACTIVEHIGH (0x0 << 8) #define RESERVED_MASK (0x3 << 9) #define CTPL_MMC_SD (0x0 << 11) +#define DMA_MASTER (0x1 << 20) #define BLEN_512BYTESLEN (0x200 << 0) #define NBLK_STPCNT (0x0 << 16) #define DE_DISABLE (0x0 << 0) @@ -119,6 +127,7 @@ struct omap_hsmmc_plat { #define SDBP_PWRON (0x1 << 8) #define SDVS_1V8 (0x5 << 9) #define SDVS_3V0 (0x6 << 9) +#define DMA_SELECT (0x2 << 3) #define ICE_MASK (0x1 << 0) #define ICE_STOP (0x0 << 0) #define ICS_MASK (0x1 << 1) @@ -148,6 +157,7 @@ struct omap_hsmmc_plat { #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)
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 9f38687..3cac6ea 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -25,6 +25,7 @@ #include <config.h> #include <common.h> #include <malloc.h> +#include <memalign.h> #include <mmc.h> #include <part.h> #include <i2c.h> @@ -71,11 +72,45 @@ struct omap_hsmmc_data { int wp_gpio; #endif #endif + u8 controller_flags; +#ifndef CONFIG_OMAP34XX + struct omap_hsmmc_adma_desc *adma_desc_table; + uint desc_slot; +#endif +}; + +#ifndef CONFIG_OMAP34XX +struct omap_hsmmc_adma_desc { + u8 attr; + u8 reserved; + u16 len; + u32 addr; };
+#define ADMA_MAX_LEN 63488 + +/* Decriptor table defines */ +#define ADMA_DESC_ATTR_VALID BIT(0) +#define ADMA_DESC_ATTR_END BIT(1) +#define ADMA_DESC_ATTR_INT BIT(2) +#define ADMA_DESC_ATTR_ACT1 BIT(4) +#define ADMA_DESC_ATTR_ACT2 BIT(5) + +#define ADMA_DESC_TRANSFER_DATA ADMA_DESC_ATTR_ACT2 +#define ADMA_DESC_LINK_DESC (ADMA_DESC_ATTR_ACT1 | ADMA_DESC_ATTR_ACT2) +#endif + /* If we fail after 1 second wait, something is really bad */ #define MAX_RETRY_MS 1000
+/* DMA transfers can take a long time if a lot a data is transfered. + * The timeout must take in account the amount of data. Let's assume + * that the time will never exceed 333 ms per MB (in other word we assume + * that the bandwidth is always above 3MB/s). + */ +#define DMA_TIMEOUT_PER_MB 333 +#define OMAP_HSMMC_USE_ADMA BIT(2) + static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size); static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, unsigned int siz); @@ -242,6 +277,11 @@ static int omap_hsmmc_init_setup(struct mmc *mmc) return -ETIMEDOUT; } } +#ifndef CONFIG_OMAP34XX + reg_val = readl(&mmc_base->hl_hwinfo); + if (reg_val & MADMA_EN) + priv->controller_flags |= OMAP_HSMMC_USE_ADMA; +#endif writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl); writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP, &mmc_base->capa); @@ -269,8 +309,8 @@ static int omap_hsmmc_init_setup(struct mmc *mmc) 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); + IE_CEB | IE_CCRC | IE_ADMAE | IE_CTO | IE_BRR | IE_BWR | IE_TC | + IE_CC, &mmc_base->ie);
mmc_init_stream(mmc_base);
@@ -322,6 +362,118 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) } } } + +#ifndef CONFIG_OMAP34XX +static void omap_hsmmc_adma_desc(struct mmc *mmc, char *buf, u16 len, bool end) +{ + struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); + struct omap_hsmmc_adma_desc *desc; + u8 attr; + + desc = &priv->adma_desc_table[priv->desc_slot]; + + attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA; + if (!end) + priv->desc_slot++; + else + attr |= ADMA_DESC_ATTR_END; + + desc->len = len; + desc->addr = (u32)buf; + desc->reserved = 0; + desc->attr = attr; +} + +static void omap_hsmmc_prepare_adma_table(struct mmc *mmc, + struct mmc_data *data) +{ + uint total_len = data->blocksize * data->blocks; + uint desc_count = DIV_ROUND_UP(total_len, ADMA_MAX_LEN); + struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); + int i = desc_count; + char *buf; + + priv->desc_slot = 0; + priv->adma_desc_table = (struct omap_hsmmc_adma_desc *) + memalign(ARCH_DMA_MINALIGN, desc_count * + sizeof(struct omap_hsmmc_adma_desc)); + + if (data->flags & MMC_DATA_READ) + buf = data->dest; + else + buf = (char *)data->src; + + while (--i) { + omap_hsmmc_adma_desc(mmc, buf, ADMA_MAX_LEN, false); + buf += ADMA_MAX_LEN; + total_len -= ADMA_MAX_LEN; + } + + omap_hsmmc_adma_desc(mmc, buf, total_len, true); + + flush_dcache_range((long)priv->adma_desc_table, + (long)priv->adma_desc_table + + ROUND(desc_count * + sizeof(struct omap_hsmmc_adma_desc), + ARCH_DMA_MINALIGN)); +} + +static void omap_hsmmc_prepare_data(struct mmc *mmc, struct mmc_data *data) +{ + struct hsmmc *mmc_base; + struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); + u32 val; + char *buf; + + mmc_base = priv->base_addr; + omap_hsmmc_prepare_adma_table(mmc, data); + + if (data->flags & MMC_DATA_READ) + buf = data->dest; + else + buf = (char *)data->src; + + val = readl(&mmc_base->hctl); + val |= DMA_SELECT; + writel(val, &mmc_base->hctl); + + val = readl(&mmc_base->con); + val |= DMA_MASTER; + writel(val, &mmc_base->con); + + writel((u32)priv->adma_desc_table, &mmc_base->admasal); + + flush_dcache_range((u32)buf, + (u32)buf + + ROUND(data->blocksize * data->blocks, + ARCH_DMA_MINALIGN)); +} + +static void omap_hsmmc_dma_cleanup(struct mmc *mmc) +{ + struct hsmmc *mmc_base; + struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); + u32 val; + + mmc_base = priv->base_addr; + + val = readl(&mmc_base->con); + val &= ~DMA_MASTER; + writel(val, &mmc_base->con); + + val = readl(&mmc_base->hctl); + val &= ~DMA_SELECT; + writel(val, &mmc_base->hctl); + + kfree(priv->adma_desc_table); +} +#else +#define omap_hsmmc_adma_desc +#define omap_hsmmc_prepare_adma_table +#define omap_hsmmc_prepare_data +#define omap_hsmmc_dma_cleanup +#endif + #if !CONFIG_IS_ENABLED(DM_MMC) static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) @@ -332,6 +484,8 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { struct omap_hsmmc_data *priv = dev_get_priv(dev); + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct mmc *mmc = upriv->mmc; #endif struct hsmmc *mmc_base; unsigned int flags, mmc_stat; @@ -405,6 +559,14 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, flags |= (DP_DATA | DDIR_READ); else flags |= (DP_DATA | DDIR_WRITE); + +#ifndef CONFIG_OMAP34XX + if ((priv->controller_flags & OMAP_HSMMC_USE_ADMA) && + !mmc_is_tuning_cmd(cmd->cmdidx)) { + omap_hsmmc_prepare_data(mmc, data); + flags |= DE_ENABLE; + } +#endif }
writel(cmd->cmdarg, &mmc_base->arg); @@ -414,7 +576,7 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, start = get_timer(0); do { mmc_stat = readl(&mmc_base->stat); - if (get_timer(0) - start > MAX_RETRY_MS) { + if (get_timer(start) > MAX_RETRY_MS) { printf("%s : timeout: No status update\n", __func__); return -ETIMEDOUT; } @@ -441,6 +603,41 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, } }
+#ifndef CONFIG_OMAP34XX + if ((priv->controller_flags & OMAP_HSMMC_USE_ADMA) && data && + !mmc_is_tuning_cmd(cmd->cmdidx)) { + u32 sz_mb, timeout; + + if (mmc_stat & IE_ADMAE) { + omap_hsmmc_dma_cleanup(mmc); + return -EIO; + } + + sz_mb = DIV_ROUND_UP(data->blocksize * data->blocks, 1 << 20); + timeout = sz_mb * DMA_TIMEOUT_PER_MB; + if (timeout < MAX_RETRY_MS) + timeout = MAX_RETRY_MS; + + start = get_timer(0); + do { + mmc_stat = readl(&mmc_base->stat); + if (mmc_stat & TC_MASK) { + writel(readl(&mmc_base->stat) | TC_MASK, + &mmc_base->stat); + break; + } + if (get_timer(start) > timeout) { + printf("%s : DMA timeout: No status update\n", + __func__); + return -ETIMEDOUT; + } + } while (1); + + omap_hsmmc_dma_cleanup(mmc); + return 0; + } +#endif + if (data && (data->flags & MMC_DATA_READ)) { mmc_read_data(mmc_base, data->dest, data->blocksize * data->blocks);

On Thu, Sep 21, 2017 at 04:51:34PM +0200, Jean-Jacques Hiblot wrote:
From: Kishon Vijay Abraham I kishon@ti.com
The omap hsmmc host controller can have the ADMA2 feature. It brings better read and write throughput. On most SOC, the capability is read from the hl_hwinfo register. On OMAP3, DMA support is compiled out.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Reviewed-by: Tom Rini trini@konsulko.com

On Thu, Sep 21, 2017 at 04:51:34PM +0200, Jean-Jacques Hiblot wrote:
From: Kishon Vijay Abraham I kishon@ti.com
The omap hsmmc host controller can have the ADMA2 feature. It brings better read and write throughput. On most SOC, the capability is read from the hl_hwinfo register. On OMAP3, DMA support is compiled out.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com Reviewed-by: Tom Rini trini@konsulko.com
Applied to u-boot/master, thanks!

From: Kishon Vijay Abraham I kishon@ti.com
Instead of sending STOP TRANSMISSION command from MMC core, enable the auto command feature so that the Host Controller issues CMD12 automatically when last block transfer is completed.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com --- drivers/mmc/omap_hsmmc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 3cac6ea..fcda0e2 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -492,6 +492,10 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, ulong start;
mmc_base = priv->base_addr; + + if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) + return 0; + start = get_timer(0); while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) { if (get_timer(0) - start > MAX_RETRY_MS) { @@ -548,7 +552,7 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, if (data) { if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) || (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) { - flags |= (MSBS_MULTIBLK | BCE_ENABLE); + flags |= (MSBS_MULTIBLK | BCE_ENABLE | ACEN_ENABLE); data->blocksize = 512; writel(data->blocksize | (data->blocks << 16), &mmc_base->blk);

On Thu, Sep 21, 2017 at 04:51:35PM +0200, Jean-Jacques Hiblot wrote:
From: Kishon Vijay Abraham I kishon@ti.com
Instead of sending STOP TRANSMISSION command from MMC core, enable the auto command feature so that the Host Controller issues CMD12 automatically when last block transfer is completed.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Reviewed-by: Tom Rini trini@konsulko.com

On Thu, Sep 21, 2017 at 04:51:35PM +0200, Jean-Jacques Hiblot wrote:
From: Kishon Vijay Abraham I kishon@ti.com
Instead of sending STOP TRANSMISSION command from MMC core, enable the auto command feature so that the Host Controller issues CMD12 automatically when last block transfer is completed.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com Reviewed-by: Tom Rini trini@konsulko.com
Applied to u-boot/master, thanks!

From: Kishon Vijay Abraham I kishon@ti.com
omap_hsmmc driver uses "|" in a couple of places for disabling a bit. While it's okay to use it in "mmc_reg_out" (since mmc_reg_out has a _mask_ argument to take care of resetting a bit), it's incorrectly used for resetting flags in "omap_hsmmc_send_cmd".
Fix it here by using "&= ~()" to reset a bit.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com --- arch/arm/include/asm/omap_mmc.h | 6 ++---- drivers/mmc/omap_hsmmc.c | 7 ++++--- 2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h index 128cd81..bf9de9b 100644 --- a/arch/arm/include/asm/omap_mmc.h +++ b/arch/arm/include/asm/omap_mmc.h @@ -90,10 +90,9 @@ struct omap_hsmmc_plat { #define DMA_MASTER (0x1 << 20) #define BLEN_512BYTESLEN (0x200 << 0) #define NBLK_STPCNT (0x0 << 16) -#define DE_DISABLE (0x0 << 0) -#define BCE_DISABLE (0x0 << 1) +#define DE_ENABLE (0x1 << 0) #define BCE_ENABLE (0x1 << 1) -#define ACEN_DISABLE (0x0 << 2) +#define ACEN_ENABLE (0x1 << 2) #define DDIR_OFFSET (4) #define DDIR_MASK (0x1 << 4) #define DDIR_WRITE (0x0 << 4) @@ -134,7 +133,6 @@ struct omap_hsmmc_plat { #define ICS_NOTREADY (0x0 << 1) #define ICE_OSCILLATE (0x1 << 0) #define CEN_MASK (0x1 << 2) -#define CEN_DISABLE (0x0 << 2) #define CEN_ENABLE (0x1 << 2) #define CLKD_OFFSET (6) #define CLKD_MASK (0x3FF << 6) diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index fcda0e2..1c3d1a5 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -294,7 +294,7 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
dsor = 240; mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK), - (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); + (ICE_STOP | DTO_15THDTO)); mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK, (dsor << CLKD_OFFSET) | ICE_OSCILLATE); start = get_timer(0); @@ -542,7 +542,8 @@ static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
/* enable default flags */ flags = flags | (CMD_TYPE_NORMAL | CICE_NOCHECK | CCCE_NOCHECK | - MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | DE_DISABLE); + MSBS_SGLEBLK); + flags &= ~(ACEN_ENABLE | BCE_ENABLE | DE_ENABLE);
if (cmd->resp_type & MMC_RSP_CRC) flags |= CCCE_CHECK; @@ -809,7 +810,7 @@ static int omap_hsmmc_set_ios(struct udevice *dev) }
mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK), - (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); + (ICE_STOP | DTO_15THDTO));
mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK, (dsor << CLKD_OFFSET) | ICE_OSCILLATE);

On Thu, Sep 21, 2017 at 04:51:36PM +0200, Jean-Jacques Hiblot wrote:
From: Kishon Vijay Abraham I kishon@ti.com
omap_hsmmc driver uses "|" in a couple of places for disabling a bit. While it's okay to use it in "mmc_reg_out" (since mmc_reg_out has a _mask_ argument to take care of resetting a bit), it's incorrectly used for resetting flags in "omap_hsmmc_send_cmd".
Fix it here by using "&= ~()" to reset a bit.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Reviewed-by: Tom Rini trini@konsulko.com

On Thu, Sep 21, 2017 at 04:51:36PM +0200, Jean-Jacques Hiblot wrote:
From: Kishon Vijay Abraham I kishon@ti.com
omap_hsmmc driver uses "|" in a couple of places for disabling a bit. While it's okay to use it in "mmc_reg_out" (since mmc_reg_out has a _mask_ argument to take care of resetting a bit), it's incorrectly used for resetting flags in "omap_hsmmc_send_cmd".
Fix it here by using "&= ~()" to reset a bit.
Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com Reviewed-by: Tom Rini trini@konsulko.com
Applied to u-boot/master, thanks!

On 09/21/2017 11:51 PM, Jean-Jacques Hiblot wrote:
This series enables the ADMA present in some OMAP SOCs. On a DRA7 the performances when reading from the eMMC go from 18MB/s to 43MB/s. Also while were at it, fix some incorrect bit operations
This series applies on top of the series that enables HS200 and UHS mode "mmc: Add support for HS200 and UHS modes" but should be easy to use on top of u-boot/master (just remove special handling of the tuning).
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57).
I didn't have omap board...Can someone check this patchset with omap? Then it's more clearly.
Best Regards, Jaehoon Chung
Cheers,
Jean-Jacques
changes since v1:
- added a timeout to terminate the DMA transfer if it takes too long
- changed omap_hsmmc_adma_desc() and omap_hsmmc_prepare_adma_table(() to not return any value (void)
- removed wrong comment about cache handling
Jean-Jacques Hiblot (2): Revert "omap_hsmmc: update struct hsmmc to accommodate omap3 from DT" omap: Update the base address of the MMC controllers
Kishon Vijay Abraham I (3): mmc: omap_hsmmc: Add support for DMA (ADMA2) mmc: omap_hsmmc: Enable Auto command (CMD12) enable mmc: omap_hsmmc: Fix incorrect bit operations for disabling a bit
arch/arm/include/asm/arch-am33xx/mmc_host_def.h | 4 +- arch/arm/include/asm/arch-omap4/mmc_host_def.h | 6 +- arch/arm/include/asm/arch-omap5/mmc_host_def.h | 6 +- arch/arm/include/asm/omap_mmc.h | 19 +- arch/arm/mach-keystone/include/mach/mmc_host_def.h | 4 +- drivers/mmc/omap_hsmmc.c | 251 +++++++++++++++++---- 6 files changed, 238 insertions(+), 52 deletions(-)

Hi,
On 22 September 2017 at 08:20, Jaehoon Chung jh80.chung@samsung.com wrote:
On 09/21/2017 11:51 PM, Jean-Jacques Hiblot wrote:
This series enables the ADMA present in some OMAP SOCs. On a DRA7 the performances when reading from the eMMC go from 18MB/s to 43MB/s. Also while were at it, fix some incorrect bit operations
This series applies on top of the series that enables HS200 and UHS mode "mmc: Add support for HS200 and UHS modes" but should be easy to use on top of u-boot/master (just remove special handling of the tuning).
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57).
I didn't have omap board...Can someone check this patchset with omap? Then it's more clearly.
Possibly, but it should not hold up the series being applied IMO. People tend to test mainline and it's good to apply these sorts of things during the merge window so that problems are found during the RC period.
Regards, Simon

Hi,
On 09/25/2017 11:15 AM, Simon Glass wrote:
Hi,
On 22 September 2017 at 08:20, Jaehoon Chung jh80.chung@samsung.com wrote:
On 09/21/2017 11:51 PM, Jean-Jacques Hiblot wrote:
This series enables the ADMA present in some OMAP SOCs. On a DRA7 the performances when reading from the eMMC go from 18MB/s to 43MB/s. Also while were at it, fix some incorrect bit operations
This series applies on top of the series that enables HS200 and UHS mode "mmc: Add support for HS200 and UHS modes" but should be easy to use on top of u-boot/master (just remove special handling of the tuning).
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57).
I didn't have omap board...Can someone check this patchset with omap? Then it's more clearly.
Possibly, but it should not hold up the series being applied IMO. People tend to test mainline and it's good to apply these sorts of things during the merge window so that problems are found during the RC period.
This patch is depended on "HS200 an UHS modes" patches.. but i have replied with the some comment for them..so i will not apply this patches before applying them.
Best Regards, Jaehoon Chung
Regards, Simon

Hi Jaehoon
On 25/09/2017 07:26, Jaehoon Chung wrote:
Hi,
On 09/25/2017 11:15 AM, Simon Glass wrote:
Hi,
On 22 September 2017 at 08:20, Jaehoon Chung jh80.chung@samsung.com wrote:
On 09/21/2017 11:51 PM, Jean-Jacques Hiblot wrote:
This series enables the ADMA present in some OMAP SOCs. On a DRA7 the performances when reading from the eMMC go from 18MB/s to 43MB/s. Also while were at it, fix some incorrect bit operations
This series applies on top of the series that enables HS200 and UHS mode "mmc: Add support for HS200 and UHS modes" but should be easy to use on top of u-boot/master (just remove special handling of the tuning).
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57).
I didn't have omap board...Can someone check this patchset with omap? Then it's more clearly.
Possibly, but it should not hold up the series being applied IMO. People tend to test mainline and it's good to apply these sorts of things during the merge window so that problems are found during the RC period.
This patch is depended on "HS200 an UHS modes" patches.. but i have replied with the some comment for them..so i will not apply this patches before applying them.
Thank you for merging the "HS200 and UHS modes" series.
Will you take this series also ? and the series actually implementing the missing pieces HS200 and UHS for omap5 (mmc: omap5: Add support for UHS and HS200 modes) ?
Thanks,
Jean-Jacques
Best Regards, Jaehoon Chung
Regards, Simon

+ Adam, who authored the reverted patch for omap3.
On Friday 22 September 2017 07:50 PM, Jaehoon Chung wrote:
On 09/21/2017 11:51 PM, Jean-Jacques Hiblot wrote:
This series enables the ADMA present in some OMAP SOCs. On a DRA7 the performances when reading from the eMMC go from 18MB/s to 43MB/s. Also while were at it, fix some incorrect bit operations
This series applies on top of the series that enables HS200 and UHS mode "mmc: Add support for HS200 and UHS modes" but should be easy to use on top of u-boot/master (just remove special handling of the tuning).
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57).
I didn't have omap board...Can someone check this patchset with omap? Then it's more clearly.
Best Regards, Jaehoon Chung
Cheers,
Jean-Jacques
changes since v1:
- added a timeout to terminate the DMA transfer if it takes too long
- changed omap_hsmmc_adma_desc() and omap_hsmmc_prepare_adma_table(() to not return any value (void)
- removed wrong comment about cache handling
Jean-Jacques Hiblot (2): Revert "omap_hsmmc: update struct hsmmc to accommodate omap3 from DT" omap: Update the base address of the MMC controllers
Kishon Vijay Abraham I (3): mmc: omap_hsmmc: Add support for DMA (ADMA2) mmc: omap_hsmmc: Enable Auto command (CMD12) enable mmc: omap_hsmmc: Fix incorrect bit operations for disabling a bit
arch/arm/include/asm/arch-am33xx/mmc_host_def.h | 4 +- arch/arm/include/asm/arch-omap4/mmc_host_def.h | 6 +- arch/arm/include/asm/arch-omap5/mmc_host_def.h | 6 +- arch/arm/include/asm/omap_mmc.h | 19 +- arch/arm/mach-keystone/include/mach/mmc_host_def.h | 4 +- drivers/mmc/omap_hsmmc.c | 251 +++++++++++++++++---- 6 files changed, 238 insertions(+), 52 deletions(-)
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
participants (5)
-
Jaehoon Chung
-
Jean-Jacques Hiblot
-
Simon Glass
-
Tom Rini
-
Vignesh R