From: Balaji T K <balajitk@ti.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support
Date: Mon, 12 May 2014 18:51:11 +0530 [thread overview]
Message-ID: <5370CAC7.80304@ti.com> (raw)
In-Reply-To: <1399038920-19023-1-git-send-email-balajitk@ti.com>
On Friday 02 May 2014 07:25 PM, Balaji T K wrote:
> MMC instance 1 and 2 is capable of ADMA in omap4, omap5.
> Add support for ADMA and enable ADMA for read/write to
> improve mmc throughput.
Hi,
Realized I need to git format-patch this patch,
Any other comments ?
>
> Signed-off-by: Balaji T K <balajitk@ti.com>
> ---
> arch/arm/include/asm/omap_mmc.h | 14 +++
> drivers/mmc/omap_hsmmc.c | 163 +++++++++++++++++++++++++++++++++++++---
> include/configs/omap5_uevm.h | 2
> 3 files changed, 169 insertions(+), 10 deletions(-)
>
> Index: u-boot_denx/arch/arm/include/asm/omap_mmc.h
> ===================================================================
> --- u-boot_denx.orig/arch/arm/include/asm/omap_mmc.h 2014-05-02 19:02:39.042727752 +0530
> +++ u-boot_denx/arch/arm/include/asm/omap_mmc.h 2014-05-02 19:18:00.783780277 +0530
> @@ -47,6 +47,9 @@ struct hsmmc {
> unsigned int ie; /* 0x134 */
> unsigned char res4[0x8];
> unsigned int capa; /* 0x140 */
> + unsigned char res5[0x10];
> + unsigned int adma_es; /* 0x154 */
> + unsigned int adma_sal; /* 0x158 */
> };
>
> /*
> @@ -68,9 +71,11 @@ struct hsmmc {
> #define WPP_ACTIVEHIGH (0x0 << 8)
> #define RESERVED_MASK (0x3 << 9)
> #define CTPL_MMC_SD (0x0 << 11)
> +#define DMA_MNS_ADMA_MODE (0x1 << 20)
> #define BLEN_512BYTESLEN (0x200 << 0)
> #define NBLK_STPCNT (0x0 << 16)
> #define DE_DISABLE (0x0 << 0)
> +#define DE_ENABLE (0x1 << 0)
> #define BCE_DISABLE (0x0 << 1)
> #define BCE_ENABLE (0x1 << 1)
> #define ACEN_DISABLE (0x0 << 2)
> @@ -103,6 +108,7 @@ struct hsmmc {
> #define DTW_1_BITMODE (0x0 << 1)
> #define DTW_4_BITMODE (0x1 << 1)
> #define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/
> +#define DMAS (0x2 << 3)
> #define SDBP_PWROFF (0x0 << 8)
> #define SDBP_PWRON (0x1 << 8)
> #define SDVS_1V8 (0x5 << 9)
> @@ -136,12 +142,18 @@ struct hsmmc {
> #define IE_DTO (0x01 << 20)
> #define IE_DCRC (0x01 << 21)
> #define IE_DEB (0x01 << 22)
> +#define IE_ADMAE (0x01 << 25)
> #define IE_CERR (0x01 << 28)
> #define IE_BADA (0x01 << 29)
>
> +#define CAPA_ADMA_SUPPORT (1 << 19)
> #define VS30_3V0SUP (1 << 25)
> #define VS18_1V8SUP (1 << 26)
>
> +#define ADMA_XFER_VALID (1 << 0)
> +#define ADMA_XFER_END (1 << 1)
> +#define ADMA_XFER_DESC (1 << 5)
> +
> /* Driver definitions */
> #define MMCSD_SECTOR_SIZE 512
> #define MMC_CARD 0
> @@ -151,6 +163,8 @@ struct hsmmc {
> #define CLK_INITSEQ 0
> #define CLK_400KHZ 1
> #define CLK_MISC 2
> +#define DMA_TYPE_SDMA 1
> +#define DMA_TYPE_ADMA 2
>
> #define RSP_TYPE_NONE (RSP_TYPE_NORSP | CCCE_NOCHECK | CICE_NOCHECK)
> #define MMC_CMD0 (INDEX(0) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE)
> Index: u-boot_denx/drivers/mmc/omap_hsmmc.c
> ===================================================================
> --- u-boot_denx.orig/drivers/mmc/omap_hsmmc.c 2014-05-02 19:02:39.066727884 +0530
> +++ u-boot_denx/drivers/mmc/omap_hsmmc.c 2014-05-02 19:17:25.247585485 +0530
> @@ -22,6 +22,7 @@
> * MA 02111-1307 USA
> */
>
> +#include <bouncebuf.h>
> #include <config.h>
> #include <common.h>
> #include <malloc.h>
> @@ -44,12 +45,30 @@
> #undef OMAP_HSMMC_USE_GPIO
> #endif
>
> +#ifdef CONFIG_SPL_BUILD
> +#undef CONFIG_OMAP_MMC_ADMA
> +#endif
> +
> +#ifdef CONFIG_OMAP_MMC_ADMA
> +struct adma_desc_table {
> + u16 attr;
> + u16 length;
> + u32 addr;
> +};
> +#define ADMA_MAX_BYTES_PER_ROW (127 * 512)
> +#define ADMA_TABLE_NUM_ENTRIES 517
> +#endif
> +
> /* common definitions for all OMAPs */
> #define SYSCTL_SRC (1 << 25)
> #define SYSCTL_SRD (1 << 26)
> +#define IE_MASK (IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO |\
> + IE_CIE | IE_CEB | IE_CCRC | IE_CTO | IE_BRR |\
> + IE_BWR | IE_TC | IE_CC)
>
> struct omap_hsmmc_data {
> struct hsmmc *base_addr;
> + int cap_dma;
> struct mmc_config cfg;
> #ifdef OMAP_HSMMC_USE_GPIO
> int cd_gpio;
> @@ -205,11 +224,13 @@ void mmc_init_stream(struct hsmmc *mmc_b
> static int omap_hsmmc_init_setup(struct mmc *mmc)
> {
> struct hsmmc *mmc_base;
> + struct omap_hsmmc_data *hsmmc_data;
> unsigned int reg_val;
> unsigned int dsor;
> ulong start;
>
> mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
> + hsmmc_data = (struct omap_hsmmc_data *)mmc->priv;
> mmc_board_init(mmc);
>
> writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
> @@ -239,6 +260,16 @@ static int omap_hsmmc_init_setup(struct
> writel(CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | CDP_ACTIVEHIGH |
> MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | STR_BLOCK |
> HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN, &mmc_base->con);
> +#ifdef CONFIG_OMAP_MMC_ADMA
> + if (readl(&mmc_base->capa) & CAPA_ADMA_SUPPORT) {
> + reg_val = readl(&mmc_base->con);
> + writel(reg_val | DMA_MNS_ADMA_MODE, &mmc_base->con);
> + writel(readl(&mmc_base->hctl) | DMAS, &mmc_base->hctl);
> + hsmmc_data->cap_dma = DMA_TYPE_ADMA;
> + }
> +#else
> + hsmmc_data->cap_dma = 0;
> +#endif
>
> dsor = 240;
> mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
> @@ -255,10 +286,7 @@ static int omap_hsmmc_init_setup(struct
> writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
>
> writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl);
> -
> - writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE |
> - IE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC,
> - &mmc_base->ie);
> + writel(IE_MASK, &mmc_base->ie);
>
> mmc_init_stream(mmc_base);
>
> @@ -311,14 +339,93 @@ static void mmc_reset_controller_fsm(str
> }
> }
>
> +#ifdef CONFIG_OMAP_MMC_ADMA
> +static int omap_hsmmc_adma_start(struct hsmmc *mmc_base,
> + struct adma_desc_table *pdesc, struct mmc_data *data,
> + void *bounce_buffer)
> +{
> + int i;
> + u32 dmaaddr;
> + ulong blocks;
> + ulong data_start, data_end;
> +
> + dmaaddr = (u32) bounce_buffer;
> + blocks = data->blocks;
> + writel((u32)pdesc, &mmc_base->adma_sal);
> + data_start = (ulong) pdesc;
> +
> + for (i = 0; blocks != 0; i++) {
> + pdesc->addr = dmaaddr;
> + pdesc->attr = (ADMA_XFER_DESC | ADMA_XFER_VALID);
> + if ((blocks * data->blocksize) <= ADMA_MAX_BYTES_PER_ROW) {
> + pdesc->length = data->blocksize * blocks;
> + pdesc->attr |= ADMA_XFER_END;
> + break;
> + } else {
> + pdesc->length = ADMA_MAX_BYTES_PER_ROW;
> + blocks -= (ADMA_MAX_BYTES_PER_ROW / data->blocksize);
> + dmaaddr += ADMA_MAX_BYTES_PER_ROW;
> + pdesc++;
> + }
> + }
> + data_end = (ulong) pdesc;
> + flush_dcache_range(data_start, data_end + ARCH_DMA_MINALIGN);
> +
> + return 0;
> +}
> +
> +static int omap_hsmmc_adma_wait_for_tc(struct hsmmc *mmc_base)
> +{
> + unsigned mmc_stat;
> + ulong start;
> + int ret = 0;
> +
> + start = get_timer(0);
> + while (1) {
> + mmc_stat = readl(&mmc_base->stat);
> +
> + if (get_timer(0) - start > 10 * MAX_RETRY_MS) {
> + printf("%s: timed out waiting for status!\n",
> + __func__);
> + ret = TIMEOUT;
> + break;
> + }
> +
> + if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
> + mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
> +
> + if (mmc_stat & ERRI_MASK) {
> + ret = 1;
> + break;
> + }
> +
> + if (mmc_stat & TC_MASK) {
> + writel(mmc_stat | TC_MASK, &mmc_base->stat);
> + break;
> + }
> + }
> +
> + return ret;
> +}
> +#endif
> +
> static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
> struct mmc_data *data)
> {
> struct hsmmc *mmc_base;
> + struct omap_hsmmc_data *hsmmc_data;
> unsigned int flags, mmc_stat;
> ulong start;
> + int dma_type = 0;
> + u32 ie_val;
> +#ifdef CONFIG_OMAP_MMC_ADMA
> + struct bounce_buffer bb;
> + ALLOC_CACHE_ALIGN_BUFFER(struct adma_desc_table, adma_desc,
> + ADMA_TABLE_NUM_ENTRIES);
> +#endif
>
> mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
> + hsmmc_data = (struct omap_hsmmc_data *)mmc->priv;
> start = get_timer(0);
> while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
> if (get_timer(0) - start > MAX_RETRY_MS) {
> @@ -373,6 +480,8 @@ static int omap_hsmmc_send_cmd(struct mm
> flags |= CICE_CHECK;
>
> if (data) {
> + ie_val = IE_MASK;
> + writel(ie_val, &mmc_base->ie);
> if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) ||
> (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) {
> flags |= (MSBS_MULTIBLK | BCE_ENABLE);
> @@ -386,6 +495,29 @@ static int omap_hsmmc_send_cmd(struct mm
> flags |= (DP_DATA | DDIR_READ);
> else
> flags |= (DP_DATA | DDIR_WRITE);
> +
> + if (!(hsmmc_data->cap_dma & DMA_TYPE_ADMA)) {
> + dma_type = 0;
> +#ifdef CONFIG_OMAP_MMC_ADMA
> + } else {
> + dma_type = DMA_TYPE_ADMA;
> + flags = flags | DE_ENABLE;
> + ie_val &= ~(IE_BRR | IE_BWR);
> + ie_val |= IE_ADMAE;
> + writel(ie_val, &mmc_base->ie);
> + if (data->flags == MMC_DATA_READ) {
> + bounce_buffer_start(&bb, (void *)data->dest,
> + data->blocksize *
> + data->blocks, GEN_BB_WRITE);
> + } else {
> + bounce_buffer_start(&bb, (void *)data->src,
> + data->blocksize *
> + data->blocks, GEN_BB_READ);
> + }
> + omap_hsmmc_adma_start(mmc_base, adma_desc, data,
> + bb.bounce_buffer);
> +#endif
> + }
> }
>
> writel(cmd->cmdarg, &mmc_base->arg);
> @@ -422,13 +554,24 @@ static int omap_hsmmc_send_cmd(struct mm
> }
> }
>
> - if (data && (data->flags & MMC_DATA_READ)) {
> - mmc_read_data(mmc_base, data->dest,
> - data->blocksize * data->blocks);
> - } else if (data && (data->flags & MMC_DATA_WRITE)) {
> - mmc_write_data(mmc_base, data->src,
> - data->blocksize * data->blocks);
> + if (!dma_type) {
> + if (data && (data->flags & MMC_DATA_READ)) {
> + mmc_read_data(mmc_base, data->dest,
> + data->blocksize * data->blocks);
> + } else if (data && (data->flags & MMC_DATA_WRITE)) {
> + mmc_write_data(mmc_base, data->src,
> + data->blocksize * data->blocks);
> + }
> +#ifdef CONFIG_OMAP_MMC_ADMA
> + } else {
> + omap_hsmmc_adma_wait_for_tc(mmc_base);
> +#endif
> }
> +
> +#ifdef CONFIG_OMAP_MMC_ADMA
> + if (dma_type)
> + bounce_buffer_stop(&bb);
> +#endif
> return 0;
> }
>
> Index: u-boot_denx/include/configs/omap5_uevm.h
> ===================================================================
> --- u-boot_denx.orig/include/configs/omap5_uevm.h 2014-05-02 19:02:39.094728037 +0530
> +++ u-boot_denx/include/configs/omap5_uevm.h 2014-05-02 19:17:25.247585485 +0530
> @@ -31,6 +31,8 @@
> #define CONFIG_SYS_REDUNDAND_ENVIRONMENT
> #define CONFIG_CMD_SAVEENV
>
> +#define CONFIG_BOUNCE_BUFFER
> +#define CONFIG_OMAP_MMC_ADMA
> /* Enhance our eMMC support / experience. */
> #define CONFIG_CMD_GPT
> #define CONFIG_EFI_PARTITION
>
next prev parent reply other threads:[~2014-05-12 13:21 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-02 13:55 [U-Boot] [PATCH] mmc: omap_hsmmc: add adma support Balaji T K
2014-05-12 13:21 ` Balaji T K [this message]
2014-05-12 13:28 ` Tom Rini
2014-05-12 13:42 ` Balaji T K
2014-05-12 14:50 ` Tom Rini
2014-05-15 14:15 ` Balaji T K
2014-05-15 17:55 ` Tom Rini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5370CAC7.80304@ti.com \
--to=balajitk@ti.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.