aboutsummaryrefslogtreecommitdiff
path: root/hw/sd
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2020-06-16 10:32:29 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-06-16 10:32:29 +0100
commit3b2d81766fd9c957a9fcfe997ff3d692e9981c98 (patch)
tree7a39f667574e7112973e2a8f3c8fe6c15fb5f5c6 /hw/sd
parent8095508a9d8af3d83365becf45ef2a58ba3d488a (diff)
downloadqemu-3b2d81766fd9c957a9fcfe997ff3d692e9981c98.zip
qemu-3b2d81766fd9c957a9fcfe997ff3d692e9981c98.tar.gz
qemu-3b2d81766fd9c957a9fcfe997ff3d692e9981c98.tar.bz2
sd: sdhci: Implement basic vendor specific register support
The Linux kernel's IMX code now uses vendor specific commands. This results in endless warnings when booting the Linux kernel. sdhci-esdhc-imx 2194000.usdhc: esdhc_wait_for_card_clock_gate_off: card clock still not gate off in 100us!. Implement support for the vendor specific command implemented in IMX hardware to be able to avoid this warning. Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Message-id: 20200603145258.195920-2-linux@roeck-us.net Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/sd')
-rw-r--r--hw/sd/sdhci-internal.h5
-rw-r--r--hw/sd/sdhci.c18
2 files changed, 22 insertions, 1 deletions
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index e7c8a52..e8c753d 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -75,6 +75,7 @@
#define SDHC_CMD_INHIBIT 0x00000001
#define SDHC_DATA_INHIBIT 0x00000002
#define SDHC_DAT_LINE_ACTIVE 0x00000004
+#define SDHC_IMX_CLOCK_GATE_OFF 0x00000080
#define SDHC_DOING_WRITE 0x00000100
#define SDHC_DOING_READ 0x00000200
#define SDHC_SPACE_AVAILABLE 0x00000400
@@ -289,7 +290,10 @@ extern const VMStateDescription sdhci_vmstate;
#define ESDHC_MIX_CTRL 0x48
+
#define ESDHC_VENDOR_SPEC 0xc0
+#define ESDHC_IMX_FRC_SDCLK_ON (1 << 8)
+
#define ESDHC_DLL_CTRL 0x60
#define ESDHC_TUNING_CTRL 0xcc
@@ -326,6 +330,7 @@ extern const VMStateDescription sdhci_vmstate;
#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \
DEFINE_PROP_UINT8("sd-spec-version", _state, sd_spec_version, 2), \
DEFINE_PROP_UINT8("uhs", _state, uhs_mode, UHS_NOT_SUPPORTED), \
+ DEFINE_PROP_UINT8("vendor", _state, vendor, SDHCI_VENDOR_NONE), \
\
/* Capabilities registers provide information on supported
* features of this specific host controller implementation */ \
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 1b75d7b..eb2be65 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1569,11 +1569,13 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
}
break;
+ case ESDHC_VENDOR_SPEC:
+ ret = s->vendor_spec;
+ break;
case ESDHC_DLL_CTRL:
case ESDHC_TUNE_CTRL_STATUS:
case ESDHC_UNDOCUMENTED_REG27:
case ESDHC_TUNING_CTRL:
- case ESDHC_VENDOR_SPEC:
case ESDHC_MIX_CTRL:
case ESDHC_WTMK_LVL:
ret = 0;
@@ -1596,7 +1598,21 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
case ESDHC_UNDOCUMENTED_REG27:
case ESDHC_TUNING_CTRL:
case ESDHC_WTMK_LVL:
+ break;
+
case ESDHC_VENDOR_SPEC:
+ s->vendor_spec = value;
+ switch (s->vendor) {
+ case SDHCI_VENDOR_IMX:
+ if (value & ESDHC_IMX_FRC_SDCLK_ON) {
+ s->prnsts &= ~SDHC_IMX_CLOCK_GATE_OFF;
+ } else {
+ s->prnsts |= SDHC_IMX_CLOCK_GATE_OFF;
+ }
+ break;
+ default:
+ break;
+ }
break;
case SDHC_HOSTCTL: