summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBin Meng2021-01-23 11:39:59 +0100
committerPhilippe Mathieu-Daudé2021-01-24 20:11:05 +0100
commit3a67cbe619179c390908bf415159290acbe96ccd (patch)
tree48108c38315716686a9e1792b30dc951ac0e4bff
parenthw/sd: ssi-sd: Suffix a data block with CRC16 (diff)
downloadqemu-3a67cbe619179c390908bf415159290acbe96ccd.tar.gz
qemu-3a67cbe619179c390908bf415159290acbe96ccd.tar.xz
qemu-3a67cbe619179c390908bf415159290acbe96ccd.zip
hw/sd: ssi-sd: Add a state representing Nac
Per the "Physical Layer Specification Version 8.00" chapter 7.5.2, "Data Read", there is a minimum 8 clock cycles (Nac) after the card response and before data block shows up on the data out line. This applies to both single and multiple block read operations. Current implementation of single block read already satisfies the timing requirement as in the RESPONSE state after all responses are transferred the state remains unchanged. In the next 8 clock cycles it jumps to DATA_START state if data is ready. However we need an explicit state when expanding our support to multiple block read in the future. Let's add a new state PREP_DATA explicitly in the ssi-sd state machine to represent Nac. Note we don't change the single block read state machine to let it jump from RESPONSE state to DATA_START state as that effectively generates a 16 clock cycles Nac, which might not be safe. As the spec says the maximum Nac shall be calculated from several fields encoded in the CSD register, we don't want to bother updating CSD to ensure our Nac is within range to complicate things. Signed-off-by: Bin Meng <bin.meng@windriver.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-Id: <20210123104016.17485-9-bmeng.cn@gmail.com> [PMD: Change VMState version id 4 -> 5] Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
-rw-r--r--hw/sd/ssi-sd.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 08852dc8d4..1cdaf73c29 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -39,6 +39,7 @@ typedef enum {
SSI_SD_CMDARG,
SSI_SD_PREP_RESP,
SSI_SD_RESPONSE,
+ SSI_SD_PREP_DATA,
SSI_SD_DATA_START,
SSI_SD_DATA_READ,
SSI_SD_DATA_CRC16,
@@ -194,6 +195,10 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
s->mode = SSI_SD_CMD;
}
return 0xff;
+ case SSI_SD_PREP_DATA:
+ DPRINTF("Prepare data block (Nac)\n");
+ s->mode = SSI_SD_DATA_START;
+ return 0xff;
case SSI_SD_DATA_START:
DPRINTF("Start read block\n");
s->mode = SSI_SD_DATA_READ;
@@ -244,8 +249,8 @@ static int ssi_sd_post_load(void *opaque, int version_id)
static const VMStateDescription vmstate_ssi_sd = {
.name = "ssi_sd",
- .version_id = 4,
- .minimum_version_id = 4,
+ .version_id = 5,
+ .minimum_version_id = 5,
.post_load = ssi_sd_post_load,
.fields = (VMStateField []) {
VMSTATE_UINT32(mode, ssi_sd_state),