diff options
author | Bin Meng <bin.meng@windriver.com> | 2021-01-23 18:39:54 +0800 |
---|---|---|
committer | Philippe Mathieu-Daudé <f4bug@amsat.org> | 2021-01-24 18:53:20 +0100 |
commit | 281c5c95b259a0d9809977c9f407d4654c3a79aa (patch) | |
tree | d80ad0f068e2dcac1acf73d6f9c6632ddd3ec034 /hw/sd/ssi-sd.c | |
parent | e93c65a6c64fa18b0c61fb9338d364cbea32b6ef (diff) | |
download | qemu-281c5c95b259a0d9809977c9f407d4654c3a79aa.zip qemu-281c5c95b259a0d9809977c9f407d4654c3a79aa.tar.gz qemu-281c5c95b259a0d9809977c9f407d4654c3a79aa.tar.bz2 |
hw/sd: ssi-sd: Fix incorrect card response sequence
Per the "Physical Layer Specification Version 8.00" chapter 7.5.1,
"Command/Response", there is a minimum 8 clock cycles (Ncr) before
the card response shows up on the data out line. However current
implementation jumps directly to the sending response state after
all 6 bytes command is received, which is a spec violation.
Add a new state PREP_RESP in the ssi-sd state machine to handle it.
Fixes: 775616c3ae8c ("Partial SD card SPI mode support")
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Tested-by: Pragnesh Patel <pragnesh.patel@sifive.com>
Reviewed-by: Pragnesh Patel <pragnesh.patel@sifive.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20210123104016.17485-4-bmeng.cn@gmail.com>
[PMD: Change VMState version id 2 -> 3]
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Diffstat (limited to 'hw/sd/ssi-sd.c')
-rw-r--r-- | hw/sd/ssi-sd.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c index 9a75e00..d976467 100644 --- a/hw/sd/ssi-sd.c +++ b/hw/sd/ssi-sd.c @@ -36,6 +36,7 @@ do { fprintf(stderr, "ssi_sd: error: " fmt , ## __VA_ARGS__);} while (0) typedef enum { SSI_SD_CMD = 0, SSI_SD_CMDARG, + SSI_SD_PREP_RESP, SSI_SD_RESPONSE, SSI_SD_DATA_START, SSI_SD_DATA_READ, @@ -163,12 +164,16 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val) s->response[1] = status; DPRINTF("Card status 0x%02x\n", status); } - s->mode = SSI_SD_RESPONSE; + s->mode = SSI_SD_PREP_RESP; s->response_pos = 0; } else { s->cmdarg[s->arglen++] = val; } return 0xff; + case SSI_SD_PREP_RESP: + DPRINTF("Prepare card response (Ncr)\n"); + s->mode = SSI_SD_RESPONSE; + return 0xff; case SSI_SD_RESPONSE: if (s->stopping) { s->stopping = 0; @@ -224,8 +229,8 @@ static int ssi_sd_post_load(void *opaque, int version_id) static const VMStateDescription vmstate_ssi_sd = { .name = "ssi_sd", - .version_id = 2, - .minimum_version_id = 2, + .version_id = 3, + .minimum_version_id = 3, .post_load = ssi_sd_post_load, .fields = (VMStateField []) { VMSTATE_UINT32(mode, ssi_sd_state), |