Skip to content
Snippets Groups Projects
Commit 0c3fb03f authored by Philippe Mathieu-Daudé's avatar Philippe Mathieu-Daudé Committed by Peter Maydell
Browse files

sdcard: Add the Tuning Command (CMD19)


From the "Physical Layer Simplified Specification Version 3.01":

  A known data block ("Tuning block") can be used to tune sampling
  point for tuning required hosts. [...]
  This procedure gives the system optimal timing for each specific
  host and card combination and compensates for static delays in
  the timing budget including process, voltage and different PCB
  loads and skews. [...]
  Data block, carried by DAT[3:0], contains a pattern for tuning
  sampling position to receive data on the CMD and DAT[3:0] line.

[based on a patch from Alistair Francis <alistair.francis@xilinx.com>
 from qemu/xilinx tag xilinx-v2015.2]
Signed-off-by: default avatarPhilippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: default avatarAlistair Francis <alistair.francis@xilinx.com>
Message-id: 20180309153654.13518-5-f4bug@amsat.org
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 75a96f5e
No related branches found
No related tags found
No related merge requests found
......@@ -1169,6 +1169,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
break;
case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */
if (sd->state == sd_transfer_state) {
sd->state = sd_sendingdata_state;
sd->data_offset = 0;
return sd_r1;
}
break;
case 23: /* CMD23: SET_BLOCK_COUNT */
switch (sd->state) {
case sd_transfer_state:
......@@ -1893,6 +1901,20 @@ void sd_write_data(SDState *sd, uint8_t value)
}
}
#define SD_TUNING_BLOCK_SIZE 64
static const uint8_t sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
/* See: Physical Layer Simplified Specification Version 3.01, Table 4-2 */
0xff, 0x0f, 0xff, 0x00, 0x0f, 0xfc, 0xc3, 0xcc,
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
};
uint8_t sd_read_data(SDState *sd)
{
/* TODO: Append CRCs */
......@@ -1972,6 +1994,13 @@ uint8_t sd_read_data(SDState *sd)
}
break;
case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */
if (sd->data_offset >= SD_TUNING_BLOCK_SIZE - 1) {
sd->state = sd_transfer_state;
}
ret = sd_tuning_block_pattern[sd->data_offset++];
break;
case 22: /* ACMD22: SEND_NUM_WR_BLOCKS */
ret = sd->data[sd->data_offset ++];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment