On Thu, Dec 31, 2020 at 3:47 AM Bin Meng <bmeng...@gmail.com> wrote: > > From: Bin Meng <bin.m...@windriver.com> > > For a multiple block write operation, each block begins with a multi > write start token. Unlike the SD mode that the multiple block write > ends when receiving a STOP_TRAN command (CMD12), a special stop tran > tocken is used to signal the card. > > Emulating this by manually sending a CMD12 to the SD card core, to > bring it out of the receiving data state. > > Signed-off-by: Bin Meng <bin.m...@windriver.com>
Acked-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > > hw/sd/ssi-sd.c | 26 ++++++++++++++++++++++++-- > 1 file changed, 24 insertions(+), 2 deletions(-) > > diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c > index 21a96e91f0..6cf5d749c7 100644 > --- a/hw/sd/ssi-sd.c > +++ b/hw/sd/ssi-sd.c > @@ -99,6 +99,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(ssi_sd_state, SSI_SD) > static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val) > { > ssi_sd_state *s = SSI_SD(dev); > + SDRequest request; > + uint8_t longresp[16]; > > /* Special case: allow CMD12 (STOP TRANSMISSION) while reading data. */ > if (s->mode == SSI_SD_DATA_READ && val == 0x4c) { > @@ -115,9 +117,31 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, > uint32_t val) > return SSI_DUMMY; > break; > case SSI_TOKEN_SINGLE: > + case SSI_TOKEN_MULTI_WRITE: > DPRINTF("Start write block\n"); > s->mode = SSI_SD_DATA_WRITE; > return SSI_DUMMY; > + case SSI_TOKEN_STOP_TRAN: > + DPRINTF("Stop multiple write\n"); > + > + /* manually issue cmd12 to stop the transfer */ > + request.cmd = 12; > + request.arg = 0; > + s->arglen = sdbus_do_command(&s->sdbus, &request, longresp); > + if (s->arglen <= 0) { > + s->arglen = 1; > + /* a zero value indicates the card is busy */ > + s->response[0] = 0; > + DPRINTF("SD card busy\n"); > + } else { > + s->arglen = 1; > + /* a non-zero value indicates the card is ready */ > + s->response[0] = SSI_DUMMY; > + } > + > + s->mode = SSI_SD_RESPONSE; > + s->response_pos = 0; > + return SSI_DUMMY; > } > > s->cmd = val & 0x3f; > @@ -126,8 +150,6 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, > uint32_t val) > return SSI_DUMMY; > case SSI_SD_CMDARG: > if (s->arglen == 4) { > - SDRequest request; > - uint8_t longresp[16]; > /* FIXME: Check CRC. */ > request.cmd = s->cmd; > request.arg = ldl_be_p(s->cmdarg); > -- > 2.25.1 > >