[U-Boot] [PATCH 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 20MB/s to 40MB/s. Also while were at it, fix some incorrect bit operations
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57). This series applies on u-boot-mmc/hs200-ufs-testing although it could be modified to apply on u-boot/master.
JJ
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 | 234 +++++++++++++++++---- 6 files changed, 222 insertions(+), 51 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 f6eb51e..ba019b0 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 bb10caa..2c1e429 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; #ifndef CONFIG_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

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 ba019b0..2b489a4 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 11 July 2017 at 10:20, Jean-Jacques Hiblot jjhiblot@ti.com 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
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(-)
Reviewed-by: Simon Glass sjg@chromium.org

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 | 186 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h index 2b489a4..206badb 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 2c1e429..3419dc5 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,10 +72,37 @@ 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 +#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, @@ -242,6 +270,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 +302,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 +355,123 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) } } } + +#ifndef CONFIG_OMAP34XX +static int 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; + + return 0; +} + +static int 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)); + return 0; +} + +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); + + /* TODO: This shouldn't be required for read. However I don't seem + * to get valid data without this. + */ + 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 + #ifndef CONFIG_DM_MMC static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) @@ -332,6 +482,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 +557,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); @@ -441,6 +601,28 @@ 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)) { + if (mmc_stat & IE_ADMAE) { + omap_hsmmc_dma_cleanup(mmc); + return -1; + } + + do { + mmc_stat = readl(&mmc_base->stat); + if (mmc_stat & TC_MASK) { + writel(readl(&mmc_base->stat) | TC_MASK, + &mmc_base->stat); + break; + } + } 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);

Hi JJ,
On 07/12/2017 01:20 AM, 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.
There is a conflict...but if you're ok, i will apply after fixing it.. If you don't want it, let me know, plz.
Best Regards, Jaehoon Chung
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 | 186 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h index 2b489a4..206badb 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 2c1e429..3419dc5 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,10 +72,37 @@ 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 +#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, @@ -242,6 +270,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 +302,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 +355,123 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) } } }
+#ifndef CONFIG_OMAP34XX +static int 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;
- return 0;
+}
+static int 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));
- return 0;
+}
+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);
- /* TODO: This shouldn't be required for read. However I don't seem
* to get valid data without this.
*/
- 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
#ifndef CONFIG_DM_MMC static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) @@ -332,6 +482,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 +557,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); @@ -441,6 +601,28 @@ 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)) {
if (mmc_stat & IE_ADMAE) {
omap_hsmmc_dma_cleanup(mmc);
return -1;
}
do {
mmc_stat = readl(&mmc_base->stat);
if (mmc_stat & TC_MASK) {
writel(readl(&mmc_base->stat) | TC_MASK,
&mmc_base->stat);
break;
}
} 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);

Hi JJ
On 07/12/2017 01:20 AM, 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
Sorry..i added the some comment at below.
arch/arm/include/asm/omap_mmc.h | 12 ++- drivers/mmc/omap_hsmmc.c | 186 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h index 2b489a4..206badb 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 2c1e429..3419dc5 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,10 +72,37 @@ 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 +#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, @@ -242,6 +270,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 +302,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 +355,123 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) } } }
+#ifndef CONFIG_OMAP34XX +static int omap_hsmmc_adma_desc(struct mmc *mmc, char *buf, u16 len, bool end)
Can be void..?
+{
- 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;
- return 0;
+}
+static int omap_hsmmc_prepare_adma_table(struct mmc *mmc, struct mmc_data *data)
Ditto.
+{
- 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));
- return 0;
+}
+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);
- /* TODO: This shouldn't be required for read. However I don't seem
* to get valid data without this.
TODO? not FIXME?
*/
- 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
#ifndef CONFIG_DM_MMC static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) @@ -332,6 +482,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 +557,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); @@ -441,6 +601,28 @@ 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)) {
if (mmc_stat & IE_ADMAE) {
omap_hsmmc_dma_cleanup(mmc);
return -1;
Use the valid error number.
}
do {
mmc_stat = readl(&mmc_base->stat);
if (mmc_stat & TC_MASK) {
writel(readl(&mmc_base->stat) | TC_MASK,
&mmc_base->stat);
break;
}
} while (1);
Can you add the timeout? There is a potential infinte loop.
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 28/07/2017 14:46, Jaehoon Chung wrote:
Hi JJ
On 07/12/2017 01:20 AM, 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
Sorry..i added the some comment at below.
arch/arm/include/asm/omap_mmc.h | 12 ++- drivers/mmc/omap_hsmmc.c | 186 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h index 2b489a4..206badb 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 2c1e429..3419dc5 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,10 +72,37 @@ 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
+#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, @@ -242,6 +270,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 +302,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 +355,123 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) } } }
+#ifndef CONFIG_OMAP34XX +static int omap_hsmmc_adma_desc(struct mmc *mmc, char *buf, u16 len, bool end)
Can be void..?
yes indeed. I'll fix that.
+{
- 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;
- return 0;
+}
+static int omap_hsmmc_prepare_adma_table(struct mmc *mmc, struct mmc_data *data)
Ditto.
+{
- 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));
- return 0;
+}
+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);
- /* TODO: This shouldn't be required for read. However I don't seem
* to get valid data without this.
TODO? not FIXME?
Actually the comment should be removed. It's required for read as well (at least the cache invalidation part is required). I'll remove the comment in v2
*/
- 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
- #ifndef CONFIG_DM_MMC static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
@@ -332,6 +482,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 +557,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); @@ -441,6 +601,28 @@ 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)) {
if (mmc_stat & IE_ADMAE) {
omap_hsmmc_dma_cleanup(mmc);
return -1;
Use the valid error number.
}
do {
mmc_stat = readl(&mmc_base->stat);
if (mmc_stat & TC_MASK) {
writel(readl(&mmc_base->stat) | TC_MASK,
&mmc_base->stat);
break;
}
} while (1);
Can you add the timeout? There is a potential infinte loop.
ok
Thanks for the review
JJ
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);

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 3419dc5..3ee81bb 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -490,6 +490,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) { @@ -546,7 +550,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);

Hi,
On 07/12/2017 01:20 AM, 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
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 3419dc5..3ee81bb 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -490,6 +490,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;
Just i wonder that there is no side-effect..I'm not sure that all omap SoCs can be supported Auto command12.
Best Regards, Jaehoon Chung
- start = get_timer(0); while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) { if (get_timer(0) - start > MAX_RETRY_MS) {
@@ -546,7 +550,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 28/07/2017 14:49, Jaehoon Chung wrote:
Hi,
On 07/12/2017 01:20 AM, 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
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 3419dc5..3ee81bb 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -490,6 +490,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;
Just i wonder that there is no side-effect..I'm not sure that all omap SoCs can be supported Auto command12.
AFAIK it's supported.
Kishon,
can you confirm ?
JJ
Best Regards, Jaehoon Chung
- start = get_timer(0); while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) { if (get_timer(0) - start > MAX_RETRY_MS) {
@@ -546,7 +550,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);

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 206badb..964bc5c 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 3ee81bb..28865c0 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -287,7 +287,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); @@ -540,7 +540,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; @@ -794,7 +795,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 Tue, Jul 11, 2017 at 06:20:09PM +0200, 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 20MB/s to 40MB/s. Also while were at it, fix some incorrect bit operations
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57). This series applies on u-boot-mmc/hs200-ufs-testing although it could be modified to apply on u-boot/master.
What hardware have you runtime tested this on? If you haven't done omap3, I can do some run-time testing there. Thanks!

On Wed, Jul 12, 2017 at 12:30 PM, Tom Rini trini@konsulko.com wrote:
On Tue, Jul 11, 2017 at 06:20:09PM +0200, 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 20MB/s to 40MB/s. Also while were at it, fix some incorrect bit operations
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57). This series applies on u-boot-mmc/hs200-ufs-testing although it could be modified to apply on u-boot/master.
What hardware have you runtime tested this on? If you haven't done omap3, I can do some run-time testing there. Thanks!
Currently, whatever is checked into trunk is breaking my omap3630 board, but 2017.07 is working, so I have only a couple days worth of bisects to address. If you think any of these patches will help, I'll do those first. If not, I'm going to do some bisecting in the next few days to see if I can determine what happened, then I can test those patches on OMAP3630.
adam
-- Tom

On 12/07/2017 19:30, Tom Rini wrote:
On Tue, Jul 11, 2017 at 06:20:09PM +0200, 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 20MB/s to 40MB/s. Also while were at it, fix some incorrect bit operations
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57). This series applies on u-boot-mmc/hs200-ufs-testing although it could be modified to apply on u-boot/master.
What hardware have you runtime tested this on? If you haven't done omap3, I can do some run-time testing there. Thanks!
I haven't been able to test on omap3. I did BBB, am437x SK, AM57X evm and DRA7 evm.
JJ

On Thu, Jul 13, 2017 at 2:22 AM, Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 12/07/2017 19:30, Tom Rini wrote:
On Tue, Jul 11, 2017 at 06:20:09PM +0200, 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 20MB/s to 40MB/s. Also while were at it, fix some incorrect bit operations
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57). This series applies on u-boot-mmc/hs200-ufs-testing although it could be modified to apply on u-boot/master.
What hardware have you runtime tested this on? If you haven't done omap3, I can do some run-time testing there. Thanks!
I haven't been able to test on omap3. I did BBB, am437x SK, AM57X evm and DRA7 evm.
I had to fix some other SPL issues first and once I was able to do that, I applied this 5-patch series and tested on DM3730 booting with SPL using Device Tree in U-boot. (I might still be the only OMAP3 board which enables CONFIG_OF_CONTROL=y).
The only compile concern I found was:
CC drivers/usb/gadget/f_fastboot.o drivers/mmc/omap_hsmmc.c: In function ‘omap_hsmmc_send_cmd’: drivers/mmc/omap_hsmmc.c:486:14: warning: unused variable ‘mmc’ [-Wunused-variable] struct mmc *mmc = upriv->mmc; ^~~ LD board/logicpd/omap3som/built-in.o CC lib/smbios.o
However, my board booted correctly via SD card.
adam
JJ

On 14/07/2017 15:18, Adam Ford wrote:
On Thu, Jul 13, 2017 at 2:22 AM, Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 12/07/2017 19:30, Tom Rini wrote:
On Tue, Jul 11, 2017 at 06:20:09PM +0200, 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 20MB/s to 40MB/s. Also while were at it, fix some incorrect bit operations
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57). This series applies on u-boot-mmc/hs200-ufs-testing although it could be modified to apply on u-boot/master.
What hardware have you runtime tested this on? If you haven't done omap3, I can do some run-time testing there. Thanks!
I haven't been able to test on omap3. I did BBB, am437x SK, AM57X evm and DRA7 evm.
I had to fix some other SPL issues first and once I was able to do that, I applied this 5-patch series and tested on DM3730 booting with SPL using Device Tree in U-boot. (I might still be the only OMAP3 board which enables CONFIG_OF_CONTROL=y).
The only compile concern I found was:
CC drivers/usb/gadget/f_fastboot.o drivers/mmc/omap_hsmmc.c: In function ‘omap_hsmmc_send_cmd’: drivers/mmc/omap_hsmmc.c:486:14: warning: unused variable ‘mmc’ [-Wunused-variable] struct mmc *mmc = upriv->mmc; ^~~ LD board/logicpd/omap3som/built-in.o CC lib/smbios.o
However, my board booted correctly via SD card.
Thanks for testing. I'll fix the warning in the next version
JJ
adam
JJ

On Mon, Jul 17, 2017 at 3:29 PM, Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 14/07/2017 15:18, Adam Ford wrote:
On Thu, Jul 13, 2017 at 2:22 AM, Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 12/07/2017 19:30, Tom Rini wrote:
On Tue, Jul 11, 2017 at 06:20:09PM +0200, 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 20MB/s to 40MB/s. Also while were at it, fix some incorrect bit operations
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57). This series applies on u-boot-mmc/hs200-ufs-testing although it could be modified to apply on u-boot/master.
What hardware have you runtime tested this on? If you haven't done omap3, I can do some run-time testing there. Thanks!
I haven't been able to test on omap3. I did BBB, am437x SK, AM57X evm and DRA7 evm.
I had to fix some other SPL issues first and once I was able to do that, I applied this 5-patch series and tested on DM3730 booting with SPL using Device Tree in U-boot. (I might still be the only OMAP3 board which enables CONFIG_OF_CONTROL=y).
The only compile concern I found was:
CC drivers/usb/gadget/f_fastboot.o drivers/mmc/omap_hsmmc.c: In function ‘omap_hsmmc_send_cmd’: drivers/mmc/omap_hsmmc.c:486:14: warning: unused variable ‘mmc’ [-Wunused-variable] struct mmc *mmc = upriv->mmc; ^~~ LD board/logicpd/omap3som/built-in.o CC lib/smbios.o
However, my board booted correctly via SD card.
Thanks for testing. I'll fix the warning in the next version
no problem. For what it's worth, someone from TI asked me not to use the #ifdef to set the base address offsets. I originally did your way, and it was rejected. You might want to make sure that everyone at TI is on board.
adam
JJ
adam
JJ

On 17/07/2017 23:39, Adam Ford wrote:
On Mon, Jul 17, 2017 at 3:29 PM, Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 14/07/2017 15:18, Adam Ford wrote:
On Thu, Jul 13, 2017 at 2:22 AM, Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 12/07/2017 19:30, Tom Rini wrote:
On Tue, Jul 11, 2017 at 06:20:09PM +0200, 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 20MB/s to 40MB/s. Also while were at it, fix some incorrect bit operations
This is the first series of 3 which wille enable HS200 and UHS on the omap5 platforms (dra7 and am57). This series applies on u-boot-mmc/hs200-ufs-testing although it could be modified to apply on u-boot/master.
What hardware have you runtime tested this on? If you haven't done omap3, I can do some run-time testing there. Thanks!
I haven't been able to test on omap3. I did BBB, am437x SK, AM57X evm and DRA7 evm.
I had to fix some other SPL issues first and once I was able to do that, I applied this 5-patch series and tested on DM3730 booting with SPL using Device Tree in U-boot. (I might still be the only OMAP3 board which enables CONFIG_OF_CONTROL=y).
The only compile concern I found was:
CC drivers/usb/gadget/f_fastboot.o drivers/mmc/omap_hsmmc.c: In function ‘omap_hsmmc_send_cmd’: drivers/mmc/omap_hsmmc.c:486:14: warning: unused variable ‘mmc’ [-Wunused-variable] struct mmc *mmc = upriv->mmc; ^~~ LD board/logicpd/omap3som/built-in.o CC lib/smbios.o
However, my board booted correctly via SD card.
Thanks for testing. I'll fix the warning in the next version
no problem. For what it's worth, someone from TI asked me not to use the #ifdef to set the base address offsets. I originally did your way, and it was rejected. You might want to make sure that everyone at TI is on board.
I understand how it feels. But it's a bit more than just changing the base address. There are actually new registers defined in this area, that do not exist on omap3. JJ
adam
JJ
adam
JJ
participants (5)
-
Adam Ford
-
Jaehoon Chung
-
Jean-Jacques Hiblot
-
Simon Glass
-
Tom Rini