[U-Boot] [PATCH 3/5] mmc: sh_sdhi: Add 64-bit access to sd_buf support
Nobuhiro Iwamatsu
iwamatsu at nigauri.org
Sat May 13 21:46:48 UTC 2017
Hi!
2017-05-13 22:51 GMT+09:00 Marek Vasut <marek.vasut at gmail.com>:
> From: Kouei Abe <kouei.abe.cp at renesas.com>
>
> Renesas SDHI SD/MMC driver has 16-bit width bus access to SD_BUF.
> This adds 64-bit width bus access to SD_BUF.
>
> Signed-off-by: Kouei Abe <kouei.abe.cp at renesas.com>
> Cc: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx at renesas.com>
> Cc: Nobuhiro Iwamatsu <iwamatsu at nigauri.org>
> Cc: Jaehoon Chung <jh80.chung at samsung.com>
Reviewed-by: Nobuhiro Iwamatsu <iwamatsu at nigauri.org>
> ---
> arch/arm/mach-rmobile/include/mach/sh_sdhi.h | 8 +++--
> drivers/mmc/sh_sdhi.c | 53 ++++++++++++++++++++++------
> 2 files changed, 48 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm/mach-rmobile/include/mach/sh_sdhi.h b/arch/arm/mach-rmobile/include/mach/sh_sdhi.h
> index 057bf3f8bb..a5ea45b707 100644
> --- a/arch/arm/mach-rmobile/include/mach/sh_sdhi.h
> +++ b/arch/arm/mach-rmobile/include/mach/sh_sdhi.h
> @@ -1,9 +1,9 @@
> /*
> * drivers/mmc/sh-sdhi.h
> *
> - * SD/MMC driver for Reneas rmobile ARM SoCs
> + * SD/MMC driver for Renesas rmobile ARM SoCs
> *
> - * Copyright (C) 2013-2014 Renesas Electronics Corporation
> + * Copyright (C) 2013-2017 Renesas Electronics Corporation
> * Copyright (C) 2008-2009 Renesas Solutions Corp.
> *
> * SPDX-License-Identifier: GPL-2.0
> @@ -162,7 +162,9 @@
> #define CLKDEV_INIT 400000 /* 100 - 400 KHz */
>
> /* For quirk */
> -#define SH_SDHI_QUIRK_16BIT_BUF (1)
> +#define SH_SDHI_QUIRK_16BIT_BUF BIT(0)
> +#define SH_SDHI_QUIRK_64BIT_BUF BIT(1)
> +
> int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks);
>
> #endif /* _SH_SDHI_H */
> diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c
> index 7f0b4c2603..d1dd0f0fc3 100644
> --- a/drivers/mmc/sh_sdhi.c
> +++ b/drivers/mmc/sh_sdhi.c
> @@ -3,7 +3,7 @@
> *
> * SD/MMC driver for Renesas rmobile ARM SoCs.
> *
> - * Copyright (C) 2011,2013-2014 Renesas Electronics Corporation
> + * Copyright (C) 2011,2013-2017 Renesas Electronics Corporation
> * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj at renesas.com>
> * Copyright (C) 2008-2009 Renesas Solutions Corp.
> *
> @@ -29,6 +29,17 @@ struct sh_sdhi_host {
> unsigned char sd_error;
> unsigned char detect_waiting;
> };
> +
> +static inline void sh_sdhi_writeq(struct sh_sdhi_host *host, int reg, u64 val)
> +{
> + writeq(val, host->addr + (reg << host->bus_shift));
> +}
> +
> +static inline u64 sh_sdhi_readq(struct sh_sdhi_host *host, int reg)
> +{
> + return readq(host->addr + (reg << host->bus_shift));
> +}
> +
> static inline void sh_sdhi_writew(struct sh_sdhi_host *host, int reg, u16 val)
> {
> writew(val, host->addr + (reg << host->bus_shift));
> @@ -261,6 +272,7 @@ static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data)
> long time;
> unsigned short blocksize, i;
> unsigned short *p = (unsigned short *)data->dest;
> + u64 *q = (u64 *)data->dest;
>
> if ((unsigned long)p & 0x00000001) {
> debug(DRIVER_NAME": %s: The data pointer is unaligned.",
> @@ -281,8 +293,12 @@ static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data)
>
> host->wait_int = 0;
> blocksize = sh_sdhi_readw(host, SDHI_SIZE);
> - for (i = 0; i < blocksize / 2; i++)
> - *p++ = sh_sdhi_readw(host, SDHI_BUF0);
> + if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
> + for (i = 0; i < blocksize / 8; i++)
> + *q++ = sh_sdhi_readq(host, SDHI_BUF0);
> + else
> + for (i = 0; i < blocksize / 2; i++)
> + *p++ = sh_sdhi_readw(host, SDHI_BUF0);
>
> time = sh_sdhi_wait_interrupt_flag(host);
> if (time == 0 || host->sd_error != 0)
> @@ -297,6 +313,7 @@ static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data)
> long time;
> unsigned short blocksize, i, sec;
> unsigned short *p = (unsigned short *)data->dest;
> + u64 *q = (u64 *)data->dest;
>
> if ((unsigned long)p & 0x00000001) {
> debug(DRIVER_NAME": %s: The data pointer is unaligned.",
> @@ -319,8 +336,12 @@ static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data)
>
> host->wait_int = 0;
> blocksize = sh_sdhi_readw(host, SDHI_SIZE);
> - for (i = 0; i < blocksize / 2; i++)
> - *p++ = sh_sdhi_readw(host, SDHI_BUF0);
> + if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
> + for (i = 0; i < blocksize / 8; i++)
> + *q++ = sh_sdhi_readq(host, SDHI_BUF0);
> + else
> + for (i = 0; i < blocksize / 2; i++)
> + *p++ = sh_sdhi_readw(host, SDHI_BUF0);
> }
>
> return 0;
> @@ -332,6 +353,7 @@ static int sh_sdhi_single_write(struct sh_sdhi_host *host,
> long time;
> unsigned short blocksize, i;
> const unsigned short *p = (const unsigned short *)data->src;
> + const u64 *q = (const u64 *)data->src;
>
> if ((unsigned long)p & 0x00000001) {
> debug(DRIVER_NAME": %s: The data pointer is unaligned.",
> @@ -356,8 +378,12 @@ static int sh_sdhi_single_write(struct sh_sdhi_host *host,
>
> host->wait_int = 0;
> blocksize = sh_sdhi_readw(host, SDHI_SIZE);
> - for (i = 0; i < blocksize / 2; i++)
> - sh_sdhi_writew(host, SDHI_BUF0, *p++);
> + if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
> + for (i = 0; i < blocksize / 8; i++)
> + sh_sdhi_writeq(host, SDHI_BUF0, *q++);
> + else
> + for (i = 0; i < blocksize / 2; i++)
> + sh_sdhi_writew(host, SDHI_BUF0, *p++);
>
> time = sh_sdhi_wait_interrupt_flag(host);
> if (time == 0 || host->sd_error != 0)
> @@ -372,6 +398,7 @@ static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data)
> long time;
> unsigned short i, sec, blocksize;
> const unsigned short *p = (const unsigned short *)data->src;
> + const u64 *q = (const u64 *)data->src;
>
> debug("%s: blocks = %d, blocksize = %d\n",
> __func__, data->blocks, data->blocksize);
> @@ -388,8 +415,12 @@ static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data)
>
> host->wait_int = 0;
> blocksize = sh_sdhi_readw(host, SDHI_SIZE);
> - for (i = 0; i < blocksize / 2; i++)
> - sh_sdhi_writew(host, SDHI_BUF0, *p++);
> + if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
> + for (i = 0; i < blocksize / 8; i++)
> + sh_sdhi_writeq(host, SDHI_BUF0, *q++);
> + else
> + for (i = 0; i < blocksize / 2; i++)
> + sh_sdhi_writew(host, SDHI_BUF0, *p++);
> }
>
> return 0;
> @@ -687,7 +718,9 @@ int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks)
> host->addr = addr;
> host->quirks = quirks;
>
> - if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
> + if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
> + host->bus_shift = 2;
> + else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
> host->bus_shift = 1;
>
> return ret;
> --
> 2.11.0
>
--
Nobuhiro Iwamatsu
iwamatsu at {nigauri.org / debian.org}
GPG ID: 40AD1FA6
More information about the U-Boot
mailing list