mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
stm32h7: sdmmc: write DCTRL after DTIMER/DLENR for non-data commands
According to RM0433 the DCTRL register needs to be written after DLENR and DTIMER. This is respected for data transfer commands but not for non-data commands. Nothing bad seems to be happening because of this, but it seems wise to rectify the issue. Change-Id: I55d8f2c1994bff747e5978847fda57445f001b02
This commit is contained in:
parent
65bf8d4192
commit
55183c0b2a
1 changed files with 9 additions and 11 deletions
|
|
@ -260,6 +260,7 @@ int stm32h7_sdmmc_submit_command(void *controller,
|
||||||
uint32_t maskr = CMD_ERROR_BITS;
|
uint32_t maskr = CMD_ERROR_BITS;
|
||||||
uint32_t cmdr = __reg_orf(SDMMC_CMDR, CPSMEN(1), CMDINDEX(cmd->command));
|
uint32_t cmdr = __reg_orf(SDMMC_CMDR, CPSMEN(1), CMDINDEX(cmd->command));
|
||||||
uint32_t cmd_wait = WAIT_CMD;
|
uint32_t cmd_wait = WAIT_CMD;
|
||||||
|
uint32_t dctrl = 0, dtimer = 0, dlenr = 0;
|
||||||
|
|
||||||
void *buff_addr = cmd->buffer;
|
void *buff_addr = cmd->buffer;
|
||||||
size_t buff_size = cmd->nr_blocks * cmd->block_len;
|
size_t buff_size = cmd->nr_blocks * cmd->block_len;
|
||||||
|
|
@ -317,7 +318,6 @@ int stm32h7_sdmmc_submit_command(void *controller,
|
||||||
panicf("%s: buffer too big", __func__);
|
panicf("%s: buffer too big", __func__);
|
||||||
|
|
||||||
/* Set block size */
|
/* Set block size */
|
||||||
uint32_t dctrl = 0;
|
|
||||||
uint32_t dblocksize = find_first_set_bit(cmd->block_len);
|
uint32_t dblocksize = find_first_set_bit(cmd->block_len);
|
||||||
if (dblocksize > 14 || (cmd->block_len & (cmd->block_len - 1)))
|
if (dblocksize > 14 || (cmd->block_len & (cmd->block_len - 1)))
|
||||||
panicf("%s: incorrect block size", __func__);
|
panicf("%s: incorrect block size", __func__);
|
||||||
|
|
@ -341,11 +341,8 @@ int stm32h7_sdmmc_submit_command(void *controller,
|
||||||
reg_assignlf(ctl->regs, SDMMC_IDMACTRLR, IDMAEN(1));
|
reg_assignlf(ctl->regs, SDMMC_IDMACTRLR, IDMAEN(1));
|
||||||
|
|
||||||
/* Use a 10 second timeout (DTIMER is in units of bus clocks) */
|
/* Use a 10 second timeout (DTIMER is in units of bus clocks) */
|
||||||
reg_varl(ctl->regs, SDMMC_DTIMER) = 10 * ctl->bus_freq;
|
dtimer = 10 * ctl->bus_freq;
|
||||||
reg_varl(ctl->regs, SDMMC_DLENR) = buff_size;
|
dlenr = buff_size;
|
||||||
|
|
||||||
/* DCTRL must be written last */
|
|
||||||
reg_varl(ctl->regs, SDMMC_DCTRL) = dctrl;
|
|
||||||
|
|
||||||
/* Enable data phase */
|
/* Enable data phase */
|
||||||
reg_vwritef(cmdr, SDMMC_CMDR, CMDTRANS(1));
|
reg_vwritef(cmdr, SDMMC_CMDR, CMDTRANS(1));
|
||||||
|
|
@ -356,16 +353,17 @@ int stm32h7_sdmmc_submit_command(void *controller,
|
||||||
{
|
{
|
||||||
/* Disable data transfer */
|
/* Disable data transfer */
|
||||||
reg_assignlf(ctl->regs, SDMMC_IDMACTRLR, IDMAEN(0));
|
reg_assignlf(ctl->regs, SDMMC_IDMACTRLR, IDMAEN(0));
|
||||||
reg_varl(ctl->regs, SDMMC_DLENR) = 0;
|
|
||||||
reg_varl(ctl->regs, SDMMC_DCTRL) = 0;
|
|
||||||
|
|
||||||
/* DTIMER is the wait time for the busy signal */
|
/* DTIMER is the wait time for the busy signal */
|
||||||
if (cmd->flags & SDMMC_RESP_BUSY)
|
if (cmd->flags & SDMMC_RESP_BUSY)
|
||||||
reg_varl(ctl->regs, SDMMC_DTIMER) = 1 * ctl->bus_freq;
|
dtimer = 1 * ctl->bus_freq;
|
||||||
else
|
|
||||||
reg_varl(ctl->regs, SDMMC_DTIMER) = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set data transfer registers */
|
||||||
|
reg_varl(ctl->regs, SDMMC_DLENR) = dlenr;
|
||||||
|
reg_varl(ctl->regs, SDMMC_DTIMER) = dtimer;
|
||||||
|
reg_varl(ctl->regs, SDMMC_DCTRL) = dctrl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set CMDSTOP bit for CMD12 (stop transmission) command;
|
* Set CMDSTOP bit for CMD12 (stop transmission) command;
|
||||||
* this is needed to stop the DPSM in case of an error in
|
* this is needed to stop the DPSM in case of an error in
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue