+ Adrian, Russell On 22 December 2015 at 04:24, Peter Guo <peter.guo@xxxxxxxxxxxxxx> 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html