diff mbox

[U-Boot,3/5] mmc: sh_sdhi: Add 64-bit access to sd_buf support

Message ID 20170513135118.8134-3-marek.vasut+renesas@gmail.com
State Accepted
Commit 5eada1dbd0b6c568c3130c567d276dddf4f716bf
Delegated to: Jaehoon Chung
Headers show

Commit Message

Marek Vasut May 13, 2017, 1:51 p.m. UTC
From: Kouei Abe <kouei.abe.cp@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@renesas.com>
Cc: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
---
 arch/arm/mach-rmobile/include/mach/sh_sdhi.h |  8 +++--
 drivers/mmc/sh_sdhi.c                        | 53 ++++++++++++++++++++++------
 2 files changed, 48 insertions(+), 13 deletions(-)

Comments

Nobuhiro Iwamatsu May 13, 2017, 9:46 p.m. UTC | #1
Hi!

2017-05-13 22:51 GMT+09:00 Marek Vasut <marek.vasut@gmail.com>:
> From: Kouei Abe <kouei.abe.cp@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@renesas.com>
> Cc: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
> Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>

Reviewed-by: Nobuhiro Iwamatsu <iwamatsu@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@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
>
Jaehoon Chung May 25, 2017, 1:43 p.m. UTC | #2
On 05/13/2017 10:51 PM, Marek Vasut wrote:
> From: Kouei Abe <kouei.abe.cp@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@renesas.com>
> Cc: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
> Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

> ---
>  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@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;
>
Jaehoon Chung June 1, 2017, 3:50 a.m. UTC | #3
Hi

On 05/13/2017 10:51 PM, Marek Vasut wrote:
> From: Kouei Abe <kouei.abe.cp@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.

  aarch64:  +   r8a7795_salvator-x
+board/renesas/salvator-x/salvator-x.c: In function 'board_mmc_init':
+board/renesas/salvator-x/salvator-x.c:196:7: error: 'SH_SDHI_QUIRK_64BIT_BUF' undeclared (first use in this function)
+       SH_SDHI_QUIRK_64BIT_BUF);
+       ^~~~~~~~~~~~~~~~~~~~~~~
+board/renesas/salvator-x/salvator-x.c:196:7: note: each undeclared identifier is reported only once for each function it appears in
+make[2]: *** [board/renesas/salvator-x/salvator-x.o] Error 1
+make[1]: *** [board/renesas/salvator-x] Error 2
+make[1]: *** wait: No child processes.  Stop.
+make: *** [sub-make] Error 2

Could you fix this?

Best Regards,
Jaehoon Chung

> 
> Signed-off-by: Kouei Abe <kouei.abe.cp@renesas.com>
> Cc: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
> Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Reviewed-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
> Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
> ---
>  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@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;
>
diff mbox

Patch

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@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;