All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v5 13/21] mmc: dw_mmc: support fifo mode in dwc mmc driver
Date: Fri, 13 Nov 2015 11:13:35 -0700	[thread overview]
Message-ID: <CAPnjgZ2rnT1_RPa8Or86D+uwTRP4HaWMQzVo-COB5FDzP2C6ig@mail.gmail.com> (raw)
In-Reply-To: <1447151098-2628-14-git-send-email-hl@rock-chips.com>

+Pantelis (mmc maintainer)

Hi Lin,

On 10 November 2015 at 03:24, Lin Huang <hl@rock-chips.com> wrote:
> some soc(rk3036 etc) use dw_mmc but do not have internal dma,
> so we implement fifo mode to read and write data.
>
> Signed-off-by: Lin Huang <hl@rock-chips.com>
> ---
>  drivers/mmc/dw_mmc.c | 81 +++++++++++++++++++++++++++++++++++++++++++---------
>  include/dwmmc.h      |  5 ++++
>  2 files changed, 72 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> index 26d34ae..18be055 100644
> --- a/drivers/mmc/dw_mmc.c
> +++ b/drivers/mmc/dw_mmc.c
> @@ -118,6 +118,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>         u32 mask, ctrl;
>         ulong start = get_timer(0);
>         struct bounce_buffer bbstate;
> +       unsigned int fifo_len, fifo_depth, size;
> +       unsigned int *buf = NULL;
>
>         while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
>                 if (get_timer(start) > timeout) {
> @@ -129,17 +131,28 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>         dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
>
>         if (data) {
> -               if (data->flags == MMC_DATA_READ) {
> -                       bounce_buffer_start(&bbstate, (void*)data->dest,
> -                                           data->blocksize *
> -                                           data->blocks, GEN_BB_WRITE);
> +               if (host->fifo_mode) {
> +                       if (data->flags == MMC_DATA_READ)
> +                               buf = (unsigned int *)data->dest;
> +                       else
> +                               buf = (unsigned int *)data->src;
> +                       dwmci_writel(host, DWMCI_BLKSIZ, data->blocksize);
> +                       dwmci_writel(host, DWMCI_BYTCNT,
> +                                    data->blocksize * data->blocks);
> +                       dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
>                 } else {
> -                       bounce_buffer_start(&bbstate, (void*)data->src,
> -                                           data->blocksize *
> -                                           data->blocks, GEN_BB_READ);
> +                       if (data->flags == MMC_DATA_READ) {
> +                               bounce_buffer_start(&bbstate, (void*)data->dest,
> +                                               data->blocksize *
> +                                               data->blocks, GEN_BB_WRITE);
> +                       } else {
> +                               bounce_buffer_start(&bbstate, (void*)data->src,
> +                                               data->blocksize *
> +                                               data->blocks, GEN_BB_READ);
> +                       }
> +                       dwmci_prepare_data(host, data, cur_idmac,
> +                                          bbstate.bounce_buffer);
>                 }
> -               dwmci_prepare_data(host, data, cur_idmac,
> -                                  bbstate.bounce_buffer);
>         }
>
>         dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
> @@ -215,6 +228,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>         if (data) {
>                 start = get_timer(0);
>                 timeout = 240000;
> +               size = data->blocksize * data->blocks / 4;
>                 for (;;) {
>                         mask = dwmci_readl(host, DWMCI_RINTSTS);
>                         /* Error during data transfer. */
> @@ -224,6 +238,44 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>                                 break;
>                         }
>

This looks too long to me. Can you first add a patch to move
everything inside the 'if (data)' block to a separate static function?

> +                       /* only fifo mode need it */
> +                       if (data->flags == MMC_DATA_READ && host->fifo_mode) {

I think both of these blocks should be in the same 'if (host->fifo_mode)'

In fact, can it be 'if (host->fifo_mode && size)' ?

> +                               if ((dwmci_readl(host, DWMCI_RINTSTS) &&
> +                                    DWMCI_INTMSK_RXDR) && size) {
> +                                       fifo_len = dwmci_readl(host,
> +                                                              DWMCI_STATUS);
> +                                       fifo_len = (fifo_len >> DWMCI_FIFO_SHIFT)
> +                                                   & DWMCI_FIFO_MASK;
> +                                       for (i = 0; i < fifo_len; i++)
> +                                               *buf++ = dwmci_readl(host,
> +                                                               DWMCI_DATA);
> +                                       dwmci_writel(host, DWMCI_RINTSTS,
> +                                                    DWMCI_INTMSK_RXDR);
> +                                       size = size > fifo_len ?
> +                                                       (size - fifo_len) : 0;

Then the above line can be common at the end of the if ()/

> +                               }
> +                       } else if (data->flags == MMC_DATA_WRITE &&
> +                                  host->fifo_mode) {
> +                               fifo_depth = (((host->fifoth_val &
> +                                               RX_WMARK_MASK) >>
> +                                               RX_WMARK_SHIFT) + 1) * 2;
> +                               if ((dwmci_readl(host, DWMCI_RINTSTS) &&
> +                                    DWMCI_INTMSK_TXDR) && size) {
> +                                       fifo_len = dwmci_readl(host,
> +                                                       DWMCI_STATUS);
> +                                       fifo_len = fifo_depth -
> +                                               ((fifo_len >> DWMCI_FIFO_SHIFT)
> +                                               & DWMCI_FIFO_MASK);
> +                                       for (i = 0; i < fifo_len; i++)
> +                                               dwmci_writel(host, DWMCI_DATA,
> +                                                            *buf++);
> +                                       dwmci_writel(host, DWMCI_RINTSTS,
> +                                                    DWMCI_INTMSK_TXDR);
> +                                       size = size > fifo_len ?
> +                                                       (size - fifo_len) : 0;
> +                               }
> +                       }
> +
>                         /* Data arrived correctly. */
>                         if (mask & DWMCI_INTMSK_DTO) {
>                                 ret = 0;
> @@ -241,11 +293,12 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>
>                 dwmci_writel(host, DWMCI_RINTSTS, mask);
>
> -               ctrl = dwmci_readl(host, DWMCI_CTRL);
> -               ctrl &= ~(DWMCI_DMA_EN);
> -               dwmci_writel(host, DWMCI_CTRL, ctrl);
> -
> -               bounce_buffer_stop(&bbstate);
> +               if (!host->fifo_mode) {
> +                       ctrl = dwmci_readl(host, DWMCI_CTRL);
> +                       ctrl &= ~(DWMCI_DMA_EN);
> +                       dwmci_writel(host, DWMCI_CTRL, ctrl);
> +                       bounce_buffer_stop(&bbstate);
> +               }
>         }
>
>         udelay(100);
> diff --git a/include/dwmmc.h b/include/dwmmc.h
> index 25cf42c..8d26e5e 100644
> --- a/include/dwmmc.h
> +++ b/include/dwmmc.h
> @@ -105,6 +105,8 @@
>
>  /* Status Register */
>  #define DWMCI_BUSY             (1 << 9)
> +#define DWMCI_FIFO_MASK                0x1ff
> +#define DWMCI_FIFO_SHIFT       17
>
>  /* FIFOTH Register */
>  #define MSIZE(x)               ((x) << 28)
> @@ -180,6 +182,9 @@ struct dwmci_host {
>         unsigned int (*get_mmc_clk)(struct dwmci_host *host, uint freq);
>
>         struct mmc_config cfg;
> +
> +       /* use fifo mode to read and write data */
> +       u32 fifo_mode;

Can this be bool?

>  };
>
>  struct dwmci_idmac {
> --
> 1.9.1
>

Regards,
Simon

  reply	other threads:[~2015-11-13 18:13 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-10 10:24 [U-Boot] [PATCH v5 00/21] Bring up rk3036 uboot Lin Huang
2015-11-10 10:24 ` [U-Boot] [PATCH v5 01/21] rockchip: add timer driver Lin Huang
2015-11-12  2:04   ` Ben Chan
2015-11-12  2:49     ` hl
2015-11-10 10:24 ` [U-Boot] [PATCH v5 02/21] rockchip: move SYS_MALLOC_F_LEN to rk3288 own Kconfig Lin Huang
2015-11-10 10:24 ` [U-Boot] [PATCH v5 03/21] rockchip: rename board-spl.c to rk3288-board-spl.c Lin Huang
2015-11-10 10:24 ` [U-Boot] [PATCH v5 04/21] rockchip: add config decide whether to build common.c Lin Huang
2015-11-10 10:24 ` [U-Boot] [PATCH v5 05/21] dm: core: Add SPL Kconfig for REGMAP and SYSCON Lin Huang
2015-11-13 18:13   ` Simon Glass
2015-11-10 10:24 ` [U-Boot] [PATCH v5 06/21] rockchip: serial driver support rk3036 Lin Huang
2015-11-10 10:24 ` [U-Boot] [PATCH v5 07/21] rockchip: Bring in RK3036 device tree file includes and bindings Lin Huang
2015-11-10 10:24 ` [U-Boot] [PATCH v5 08/21] rockchip: rk3036: Add clock driver Lin Huang
2015-11-10 10:24 ` [U-Boot] [PATCH v5 09/21] rockchip: rk3036: Add header files for GRF Lin Huang
2015-11-12  2:23   ` Ben Chan
2015-11-10 10:24 ` [U-Boot] [PATCH v5 10/21] rockchip: rk3036: Add Soc reset driver Lin Huang
2015-11-10 10:24 ` [U-Boot] [PATCH v5 11/21] rockchip: rk3036: Add a simple syscon driver Lin Huang
2015-11-10 10:24 ` [U-Boot] [PATCH v5 12/21] rockchip: rk3036: Add pinctrl driver Lin Huang
2015-11-13 23:54   ` Ariel D'Alessandro
2015-11-16  2:12     ` hl
2015-11-10 10:24 ` [U-Boot] [PATCH v5 13/21] mmc: dw_mmc: support fifo mode in dwc mmc driver Lin Huang
2015-11-13 18:13   ` Simon Glass [this message]
2015-11-10 10:24 ` [U-Boot] [PATCH v5 14/21] rockchip: mmc: get the fifo mode and fifo depth property from dts Lin Huang
2015-11-13 18:13   ` Simon Glass
2015-11-10 10:24 ` [U-Boot] [PATCH v5 15/21] rockchip: add early uart driver Lin Huang
2015-11-13 18:13   ` Simon Glass
2015-11-10 10:24 ` [U-Boot] [PATCH v5 16/21] rockchip: add rk3036 sdram driver Lin Huang
2015-11-12  8:35   ` Ben Chan
2015-11-13 18:13   ` Simon Glass
2015-11-10 10:24 ` [U-Boot] [PATCH v5 17/21] rockchip: rk3036: Add core Soc start-up code Lin Huang
2015-11-13 18:13   ` Simon Glass
2015-11-10 10:24 ` [U-Boot] [PATCH v5 18/21] rockchip: Add basic support for evb-rk3036 board Lin Huang
2015-11-13 18:13   ` Simon Glass
2015-11-10 10:24 ` [U-Boot] [PATCH v5 19/21] rockchip: Add max init size & chip tag configs Lin Huang
2015-11-13 18:13   ` Simon Glass
2015-11-10 10:24 ` [U-Boot] [PATCH v5 20/21] rockchip: Add support for rk's second level loader Lin Huang
2015-11-10 10:24 ` [U-Boot] [PATCH v5 21/21] rockchip: doc: show packet rk3036 uboot image Lin Huang
2015-11-13 18:13   ` Simon Glass
2015-11-13 18:14 ` [U-Boot] [PATCH v5 00/21] Bring up rk3036 uboot Simon Glass
2015-11-16  0:58   ` hl
2015-11-28  0:21     ` Simon Glass
2015-11-28  2:34       ` Naoki FUKAUMI
2015-11-28  2:46         ` Naoki FUKAUMI
2015-11-30  8:12       ` Sjoerd Simons
2015-11-30  8:24         ` Stefan Roese
2015-11-30  8:39           ` Sjoerd Simons
2015-11-30  8:46             ` Stefan Roese
2015-11-30 23:17         ` Simon Glass
2015-12-01  7:48           ` Sjoerd Simons
2015-12-01 20:02             ` Simon Glass

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=CAPnjgZ2rnT1_RPa8Or86D+uwTRP4HaWMQzVo-COB5FDzP2C6ig@mail.gmail.com \
    --to=sjg@chromium.org \
    --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.