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:
Sam Protsenko 2024-08-07 22:14:12 -05:00 committed by Minkyu Kang
parent 454fda956c
commit 0252924ac6

View file

@ -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) {