From: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
To: Alistair Francis <alistair.francis@xilinx.com>,
Peter Maydell <peter.maydell@linaro.org>,
Igor Mitsyanko <i.mitsyanko@gmail.com>
Cc: "Philippe Mathieu-Daudé" <f4bug@amsat.org>,
qemu-devel@nongnu.org,
"Edgar E . Iglesias" <edgar.iglesias@xilinx.com>,
"Prasad J Pandit" <pjp@fedoraproject.org>,
"Andrzej Zaborowski" <balrogg@gmail.com>
Subject: [Qemu-devel] [PATCH v4 18/20] sdcard: implement the UHS-I SWITCH_FUNCTION entries (Spec v3)
Date: Thu, 15 Feb 2018 19:13:23 -0300 [thread overview]
Message-ID: <20180215221325.7611-19-f4bug@amsat.org> (raw)
In-Reply-To: <20180215221325.7611-1-f4bug@amsat.org>
[based on a patch from Alistair Francis <alistair.francis@xilinx.com>
from qemu/xilinx tag xilinx-v2015.2]
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
hw/sd/sd.c | 148 +++++++++++++++++++++++++++++++++++++++++++++--------
hw/sd/trace-events | 1 +
2 files changed, 127 insertions(+), 22 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 4b0bb7992d..ada96f5574 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -124,6 +124,7 @@ struct SDState {
bool enable;
uint8_t dat_lines;
bool cmd_line;
+ bool uhs_enabled;
};
static const char *sd_state_name(enum SDCardStates state)
@@ -563,6 +564,7 @@ static void sd_reset(DeviceState *dev)
sd->expecting_acmd = false;
sd->dat_lines = 0xf;
sd->cmd_line = true;
+ sd->uhs_enabled = false;
sd->multi_blk_cnt = 0;
}
@@ -761,30 +763,132 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
return ret;
}
+/* Function Group */
+enum {
+ SD_FG_MIN = 1,
+ SD_FG_ACCESS_MODE = 1,
+ SD_FG_COMMAND_SYSTEM = 2,
+ SD_FG_DRIVER_STRENGTH = 3,
+ SD_FG_CURRENT_LIMIT = 4,
+ SD_FG_RSVD_5 = 5,
+ SD_FG_RSVD_6 = 6,
+ SD_FG_COUNT
+};
+
+/* Function name */
+#define SD_FN_COUNT 16
+
+static const char *sd_fn_grp_name[SD_FG_COUNT] = {
+ [SD_FG_ACCESS_MODE] = "ACCESS_MODE",
+ [SD_FG_COMMAND_SYSTEM] = "COMMAND_SYSTEM",
+ [SD_FG_DRIVER_STRENGTH] = "DRIVER_STRENGTH",
+ [SD_FG_CURRENT_LIMIT] = "CURRENT_LIMIT",
+ [SD_FG_RSVD_5] = "RSVD5",
+ [SD_FG_RSVD_6] = "RSVD6",
+};
+
+typedef struct sd_fn_support {
+ const char *name;
+ bool uhs_only;
+ bool unimp;
+} sd_fn_support;
+
+static const sd_fn_support *sd_fn_support_defs[SD_FG_COUNT] = {
+ [SD_FG_ACCESS_MODE] = (sd_fn_support [SD_FN_COUNT]) {
+ [0] = { .name = "default/SDR12" },
+ [1] = { .name = "high-speed/SDR25" },
+ [2] = { .name = "SDR50", .uhs_only = true },
+ [3] = { .name = "SDR104", .uhs_only = true },
+ [4] = { .name = "DDR50", .uhs_only = true },
+ },
+ [SD_FG_COMMAND_SYSTEM] = (sd_fn_support [SD_FN_COUNT]) {
+ [0] = { .name = "default" },
+ [1] = { .name = "For eC" },
+ [3] = { .name = "OTP", .unimp = true },
+ [4] = { .name = "ASSD", .unimp = true },
+ },
+ [SD_FG_DRIVER_STRENGTH] = (sd_fn_support [SD_FN_COUNT]) {
+ [0] = { .name = "default/Type B" },
+ [1] = { .name = "Type A", .uhs_only = true },
+ [2] = { .name = "Type C", .uhs_only = true },
+ [3] = { .name = "Type D", .uhs_only = true },
+ },
+ [SD_FG_CURRENT_LIMIT] = (sd_fn_support [SD_FN_COUNT]) {
+ [0] = { .name = "default/200mA" },
+ [1] = { .name = "400mA", .uhs_only = true },
+ [2] = { .name = "600mA", .uhs_only = true },
+ [3] = { .name = "800mA", .uhs_only = true },
+ },
+ [SD_FG_RSVD_5] = (sd_fn_support [SD_FN_COUNT]) {
+ [0] = { .name = "default" },
+ },
+ [SD_FG_RSVD_6] = (sd_fn_support [SD_FN_COUNT]) {
+ [0] = { .name = "default" },
+ },
+};
+
+#define SD_FN_NO_INFLUENCE (1 << 15)
+
static void sd_function_switch(SDState *sd, uint32_t arg)
{
- int i, mode, new_func;
- mode = !!(arg & 0x80000000);
-
- sd->data[0] = 0x00; /* Maximum current consumption */
- sd->data[1] = 0x01;
- sd->data[2] = 0x80; /* Supported group 6 functions */
- sd->data[3] = 0x01;
- sd->data[4] = 0x80; /* Supported group 5 functions */
- sd->data[5] = 0x01;
- sd->data[6] = 0x80; /* Supported group 4 functions */
- sd->data[7] = 0x01;
- sd->data[8] = 0x80; /* Supported group 3 functions */
- sd->data[9] = 0x01;
- sd->data[10] = 0x80; /* Supported group 2 functions */
- sd->data[11] = 0x43;
- sd->data[12] = 0x80; /* Supported group 1 functions */
- sd->data[13] = 0x03;
- for (i = 0; i < 6; i ++) {
- new_func = (arg >> (i * 4)) & 0x0f;
- if (mode && new_func != 0x0f)
- sd->function_group[i] = new_func;
- sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4);
+ int fn_grp, new_func, i;
+ uint8_t *data_p;
+ bool mode = extract32(arg, 31, 1); /* 0: check only, 1: do switch */
+
+ stw_be_p(sd->data + 0, 0x0001); /* Maximum current consumption */
+
+ data_p = &sd->data[2];
+ for (fn_grp = SD_FG_COUNT - 1; fn_grp >= SD_FG_MIN; fn_grp--) {
+ uint16_t supported_fns = SD_FN_NO_INFLUENCE;
+ for (i = 0; i < SD_FN_COUNT; ++i) {
+ const sd_fn_support *def = &sd_fn_support_defs[fn_grp][i];
+
+ if (def->name && !def->unimp &&
+ !(def->uhs_only && !sd->uhs_enabled)) {
+ supported_fns |= 1 << i;
+ }
+ }
+ stw_be_p(data_p, supported_fns);
+ data_p += 2;
+ }
+
+ assert(data_p == &sd->data[14]);
+ for (fn_grp = SD_FG_COUNT - 1; fn_grp >= SD_FG_MIN; fn_grp--) {
+ new_func = (arg >> ((fn_grp - 1) * 4)) & 0x0f;
+ if (new_func == 0xf) {
+ new_func = sd->function_group[fn_grp - 1];
+ } else {
+ const sd_fn_support *def = &sd_fn_support_defs[fn_grp][new_func];
+ if (mode) {
+ if (!def->name) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Function %d not a valid for "
+ "function group %d\n",
+ new_func, fn_grp);
+ new_func = 0xf;
+ } else if (def->unimp) {
+ qemu_log_mask(LOG_UNIMP,
+ "Function %s (fn grp %d) not implemented\n",
+ def->name, fn_grp);
+ new_func = 0xf;
+ } else if (def->uhs_only && !sd->uhs_enabled) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Function %s (fn grp %d) only "
+ "valid in UHS mode\n",
+ def->name, fn_grp);
+ new_func = 0xf;
+ } else {
+ sd->function_group[fn_grp - 1] = new_func;
+ }
+ }
+ trace_sdcard_function_select(def->name, sd_fn_grp_name[fn_grp],
+ mode);
+ }
+ if (!(fn_grp & 0x1)) { /* evens go in high nibble */
+ *data_p = new_func << 4;
+ } else { /* odds go in low nibble */
+ *(data_p++) |= new_func;
+ }
}
memset(&sd->data[17], 0, 47);
stw_be_p(sd->data + 65, sd_crc16(sd->data, 64));
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
index 2059ace61f..c106541a47 100644
--- a/hw/sd/trace-events
+++ b/hw/sd/trace-events
@@ -42,6 +42,7 @@ sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint8_t value) "%s %20s/ CMD%02d value 0x%02x"
sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, int length) "%s %20s/ CMD%02d len %d"
sdcard_set_voltage(uint16_t millivolts) "%u mV"
+sdcard_function_select(const char *fn_name, const char *grp_name, bool do_switch) "Function %s (group: %s, sw: %u)"
# hw/sd/milkymist-memcard.c
milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
--
2.16.1
next prev parent reply other threads:[~2018-02-15 22:14 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-15 22:13 [Qemu-devel] [PATCH v4 00/20] SDCard: bugfixes, support UHS-I (part 5) Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 01/20] sdcard: Don't always set the high capacity bit Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 02/20] sdcard: update the CSD CRC register regardless the CSD structure version Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 03/20] sdcard: fix the 'maximum data transfer rate' to 25MHz Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 04/20] sdcard: clean the SCR register and add few comments Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 05/20] sdcard: remove commands from unsupported old MMC specification Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 06/20] sdcard: simplify using the ldst API Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 07/20] sdcard: use the correct masked OCR in the R3 reply Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 08/20] sdcard: use the registerfields API for the CARD_STATUS register masks Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 09/20] sdcard: handle CMD54 (SDIO) Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 10/20] sdcard: handle the Security Specification commands Philippe Mathieu-Daudé
2018-02-15 22:54 ` Alistair Francis
2018-03-03 12:04 ` Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 11/20] sdcard: use a more descriptive label 'unimplemented_spi_cmd' Philippe Mathieu-Daudé
2018-02-15 22:54 ` Alistair Francis
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 12/20] sdcard: handles more commands in SPI mode Philippe Mathieu-Daudé
2018-02-15 22:47 ` Alistair Francis
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 13/20] sdcard: check the card is in correct state for APP CMD (CMD55) Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 14/20] sdcard: warn if host uses an incorrect address " Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 15/20] sdcard: simplify SEND_IF_COND (CMD8) Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 16/20] sdcard: simplify SD_SEND_OP_COND (ACMD41) Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 17/20] sdcard: add SD SEND_TUNING_BLOCK (CMD19) Philippe Mathieu-Daudé
2018-02-22 14:23 ` Peter Maydell
2018-02-15 22:13 ` Philippe Mathieu-Daudé [this message]
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 19/20] sdcard: add a 'uhs' property, update the OCR register ACCEPT_SWITCH_1V8 bit Philippe Mathieu-Daudé
2018-02-15 22:55 ` Alistair Francis
2018-02-22 14:25 ` Peter Maydell
2018-03-03 11:46 ` Philippe Mathieu-Daudé
2018-02-15 22:13 ` [Qemu-devel] [PATCH v4 20/20] sdcard: add an enum for the SD PHY Spec version Philippe Mathieu-Daudé
2018-02-22 14:26 ` Peter Maydell
2018-03-03 11:50 ` Philippe Mathieu-Daudé
2018-02-22 9:04 ` [Qemu-devel] [PATCH v4 00/20] SDCard: bugfixes, support UHS-I (part 5) Philippe Mathieu-Daudé
2018-02-22 14:31 ` Peter Maydell
2018-03-03 12:05 ` Philippe Mathieu-Daudé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180215221325.7611-19-f4bug@amsat.org \
--to=f4bug@amsat.org \
--cc=alistair.francis@xilinx.com \
--cc=balrogg@gmail.com \
--cc=edgar.iglesias@xilinx.com \
--cc=i.mitsyanko@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=pjp@fedoraproject.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).