mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-20 20:04:46 +00:00
mmc: dw_mmc: Extract FIFO data transfer into a separate routine
FIFO data transfer is implemented as quite a massive chunk of code. Extract it into a dedicated function to make dwmci_data_transfer() easier to read and reduce the indentation level of the code. No functional change. Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org> Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
This commit is contained in:
parent
454fda956c
commit
0252924ac6
1 changed files with 53 additions and 54 deletions
|
@ -139,25 +139,67 @@ static unsigned int dwmci_get_timeout(struct mmc *mmc, const unsigned int size)
|
||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
|
static int dwmci_data_transfer_fifo(struct dwmci_host *host,
|
||||||
|
struct mmc_data *data, u32 mask)
|
||||||
{
|
{
|
||||||
struct mmc *mmc = host->mmc;
|
const u32 fifo_depth = (((host->fifoth_val & RX_WMARK_MASK) >>
|
||||||
|
RX_WMARK_SHIFT) + 1) * 2;
|
||||||
|
const u32 int_rx = mask & (DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO);
|
||||||
|
const u32 int_tx = mask & DWMCI_INTMSK_TXDR;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u32 timeout, mask, size, i, len = 0;
|
u32 len = 0, size, i;
|
||||||
u32 *buf = NULL;
|
u32 *buf;
|
||||||
ulong start = get_timer(0);
|
|
||||||
u32 fifo_depth = (((host->fifoth_val & RX_WMARK_MASK) >>
|
size = (data->blocksize * data->blocks) / 4;
|
||||||
RX_WMARK_SHIFT) + 1) * 2;
|
if (!host->fifo_mode || !size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
size = data->blocksize * data->blocks;
|
|
||||||
if (data->flags == MMC_DATA_READ)
|
if (data->flags == MMC_DATA_READ)
|
||||||
buf = (unsigned int *)data->dest;
|
buf = (unsigned int *)data->dest;
|
||||||
else
|
else
|
||||||
buf = (unsigned int *)data->src;
|
buf = (unsigned int *)data->src;
|
||||||
|
|
||||||
timeout = dwmci_get_timeout(mmc, size);
|
if (data->flags == MMC_DATA_READ && int_rx) {
|
||||||
|
dwmci_writel(host, DWMCI_RINTSTS, int_rx);
|
||||||
|
while (size) {
|
||||||
|
ret = dwmci_fifo_ready(host, DWMCI_FIFO_EMPTY, &len);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
size /= 4;
|
len = (len >> DWMCI_FIFO_SHIFT) & DWMCI_FIFO_MASK;
|
||||||
|
len = min(size, len);
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
*buf++ = dwmci_readl(host, DWMCI_DATA);
|
||||||
|
size = size > len ? (size - len) : 0;
|
||||||
|
}
|
||||||
|
} else if (data->flags == MMC_DATA_WRITE && int_tx) {
|
||||||
|
while (size) {
|
||||||
|
ret = dwmci_fifo_ready(host, DWMCI_FIFO_FULL, &len);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
len = fifo_depth - ((len >> DWMCI_FIFO_SHIFT) &
|
||||||
|
DWMCI_FIFO_MASK);
|
||||||
|
len = min(size, len);
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
dwmci_writel(host, DWMCI_DATA, *buf++);
|
||||||
|
size = size > len ? (size - len) : 0;
|
||||||
|
}
|
||||||
|
dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_TXDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
|
||||||
|
{
|
||||||
|
struct mmc *mmc = host->mmc;
|
||||||
|
int ret = 0;
|
||||||
|
u32 timeout, mask, size;
|
||||||
|
ulong start = get_timer(0);
|
||||||
|
|
||||||
|
size = data->blocksize * data->blocks;
|
||||||
|
timeout = dwmci_get_timeout(mmc, size);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
mask = dwmci_readl(host, DWMCI_RINTSTS);
|
mask = dwmci_readl(host, DWMCI_RINTSTS);
|
||||||
|
@ -168,50 +210,7 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (host->fifo_mode && size) {
|
ret = dwmci_data_transfer_fifo(host, data, mask);
|
||||||
len = 0;
|
|
||||||
if (data->flags == MMC_DATA_READ &&
|
|
||||||
(mask & (DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO))) {
|
|
||||||
dwmci_writel(host, DWMCI_RINTSTS,
|
|
||||||
mask & (DWMCI_INTMSK_RXDR |
|
|
||||||
DWMCI_INTMSK_DTO));
|
|
||||||
while (size) {
|
|
||||||
ret = dwmci_fifo_ready(host,
|
|
||||||
DWMCI_FIFO_EMPTY,
|
|
||||||
&len);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
len = (len >> DWMCI_FIFO_SHIFT) &
|
|
||||||
DWMCI_FIFO_MASK;
|
|
||||||
len = min(size, len);
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
*buf++ =
|
|
||||||
dwmci_readl(host, DWMCI_DATA);
|
|
||||||
size = size > len ? (size - len) : 0;
|
|
||||||
}
|
|
||||||
} else if (data->flags == MMC_DATA_WRITE &&
|
|
||||||
(mask & DWMCI_INTMSK_TXDR)) {
|
|
||||||
while (size) {
|
|
||||||
ret = dwmci_fifo_ready(host,
|
|
||||||
DWMCI_FIFO_FULL,
|
|
||||||
&len);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
len = fifo_depth - ((len >>
|
|
||||||
DWMCI_FIFO_SHIFT) &
|
|
||||||
DWMCI_FIFO_MASK);
|
|
||||||
len = min(size, len);
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
dwmci_writel(host, DWMCI_DATA,
|
|
||||||
*buf++);
|
|
||||||
size = size > len ? (size - len) : 0;
|
|
||||||
}
|
|
||||||
dwmci_writel(host, DWMCI_RINTSTS,
|
|
||||||
DWMCI_INTMSK_TXDR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Data arrived correctly. */
|
/* Data arrived correctly. */
|
||||||
if (mask & DWMCI_INTMSK_DTO) {
|
if (mask & DWMCI_INTMSK_DTO) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue