mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-04-11 16:37:45 -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 cmdr = __reg_orf(SDMMC_CMDR, CPSMEN(1), CMDINDEX(cmd->command));
|
||||
uint32_t cmd_wait = WAIT_CMD;
|
||||
uint32_t dctrl = 0, dtimer = 0, dlenr = 0;
|
||||
|
||||
void *buff_addr = cmd->buffer;
|
||||
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__);
|
||||
|
||||
/* Set block size */
|
||||
uint32_t dctrl = 0;
|
||||
uint32_t dblocksize = find_first_set_bit(cmd->block_len);
|
||||
if (dblocksize > 14 || (cmd->block_len & (cmd->block_len - 1)))
|
||||
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));
|
||||
|
||||
/* Use a 10 second timeout (DTIMER is in units of bus clocks) */
|
||||
reg_varl(ctl->regs, SDMMC_DTIMER) = 10 * ctl->bus_freq;
|
||||
reg_varl(ctl->regs, SDMMC_DLENR) = buff_size;
|
||||
|
||||
/* DCTRL must be written last */
|
||||
reg_varl(ctl->regs, SDMMC_DCTRL) = dctrl;
|
||||
dtimer = 10 * ctl->bus_freq;
|
||||
dlenr = buff_size;
|
||||
|
||||
/* Enable data phase */
|
||||
reg_vwritef(cmdr, SDMMC_CMDR, CMDTRANS(1));
|
||||
|
|
@ -356,16 +353,17 @@ int stm32h7_sdmmc_submit_command(void *controller,
|
|||
{
|
||||
/* Disable data transfer */
|
||||
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 */
|
||||
if (cmd->flags & SDMMC_RESP_BUSY)
|
||||
reg_varl(ctl->regs, SDMMC_DTIMER) = 1 * ctl->bus_freq;
|
||||
else
|
||||
reg_varl(ctl->regs, SDMMC_DTIMER) = 0;
|
||||
dtimer = 1 * ctl->bus_freq;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
* this is needed to stop the DPSM in case of an error in
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue