+ Adrian, Russell
On 22 December 2015 at 04:24, Peter Guo <[email protected]> wrote:
> Hi Ulf & Alex,
>
> Below is the complete analysis of this issue.
>
> The basic flow of send command is as below:
> (1) Upper layer prepare the command parameter;
> (2) Call sdhci_send_command, and sdhci_send_command will call
> sdhci_set_transfer_mode to set Host Register 0xC;
> (3) Call sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags),
> SDHCI_COMMAND) to send command;
>
> For Linux kernel mainstream (without any quirk), MMC case:
> (1) It will call mmc_get_ext_csd and this is an DMA transfer, then DMA
> enable bit will be set to 1 (0xC[0]=1'b1).
> (2) Then next Command is mmc_switch(cmd6) which is none-data command, the
> driver will keep DMA enable bit to 1; this will let our Host failed to
> execute the CMD06.
>
> According to SD Host Spec(SD Host Controller Specification verson 4.1 page
> 41):
> Bit0 of Transfer Mode Register(0x0C) is DMA Enable bit, this bit set to 1
> means a DMA operation shall begin when Host Driver writes to the upper byte
> of Command Register(0x0F).
>
> The DMA enable bit should be set to zero for this none-data command(CMD6).
> Our host follow the spec. so I think it should be the sdhci driver’s issue
> (sdhci_set_transfer_mode).
>
>
> So We tried SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD to fix above
> issue.
This quirk seems a bit strange. It looks like a generic problem being
solved by the wrong approach. Although, my knowledge of sdhci HW is
limited so I might be wrong.
Why doesn't sdhci *always* reset the related registers when the
command or data transfer gets *completed*? Instead as currently,
delaying that until the *next* request is started and via using
SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD?
>
> But it encounter new problem as Alex reported for tuning command as tuning
> command flow in sdhci_execute_tuning function is:
> (1). cmd.data = NULL;
> (2). sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
> (3). sdhci_send_command(host, &cmd);
> As data is null, this quirk will set 0x0C[0:15] to ALL zero before send
> tuning command including SDHCI_TRNS_READ, and the tuning command will failed.
I see.
Sdhci's sdhci_execute_tuning() function must be converted to use
mmc_send_tuning().
This means the regular request path will be maintained and thus no
special treatment should be needed.
Nevertheless, if my suggestions around changing sdhci's default
behaviour instead of using
SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD, perhaps you don't need
to fix sdhci_execute_tuning() to solve the error here!?
>
> So, can we commit one patch as below to fix this DMA enable bit for non-data
> command bug if you cannot accept add new QUIRK?
Nope, no new quirks.
> Code should like below(sdhci_set_transfer_mode):
> if (data == NULL) {
> if (host->quirks2 &
>
> SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD) {
> sdhci_writew(host, 0x0,
> SDHCI_TRANSFER_MODE);
> } else {
> /* clear Auto CMD settings for no data CMDs */
> mode = sdhci_readw(host,
> SDHCI_TRANSFER_MODE);
> sdhci_writew(host, mode &
> ~(SDHCI_TRNS_AUTO_CMD12 | SDHCI_TRNS_DMA /*Clear DMA enable bit also for
> no data CMDs*/
>
> SDHCI_TRNS_AUTO_CMD23), SDHCI_TRANSFER_MODE);
> }
> return;
> }
Thanks for the suggested solution, although I think this looks like
yet another hacky workaround for a generic problem.
Before I further consider that change, can you please look into my
suggestions above and see if any of those can simplify the solution?
[...]
Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html