mmc: sh_sdhi: Add 64-bit access to sd_buf support
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> Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
This commit is contained in:
parent
3ebc62c987
commit
5eada1dbd0
@ -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 */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user