mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
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>
This commit is contained in:
parent
8095508a9d
commit
3b2d81766f
3 changed files with 27 additions and 1 deletions
|
@ -75,6 +75,7 @@
|
||||||
#define SDHC_CMD_INHIBIT 0x00000001
|
#define SDHC_CMD_INHIBIT 0x00000001
|
||||||
#define SDHC_DATA_INHIBIT 0x00000002
|
#define SDHC_DATA_INHIBIT 0x00000002
|
||||||
#define SDHC_DAT_LINE_ACTIVE 0x00000004
|
#define SDHC_DAT_LINE_ACTIVE 0x00000004
|
||||||
|
#define SDHC_IMX_CLOCK_GATE_OFF 0x00000080
|
||||||
#define SDHC_DOING_WRITE 0x00000100
|
#define SDHC_DOING_WRITE 0x00000100
|
||||||
#define SDHC_DOING_READ 0x00000200
|
#define SDHC_DOING_READ 0x00000200
|
||||||
#define SDHC_SPACE_AVAILABLE 0x00000400
|
#define SDHC_SPACE_AVAILABLE 0x00000400
|
||||||
|
@ -289,7 +290,10 @@ extern const VMStateDescription sdhci_vmstate;
|
||||||
|
|
||||||
|
|
||||||
#define ESDHC_MIX_CTRL 0x48
|
#define ESDHC_MIX_CTRL 0x48
|
||||||
|
|
||||||
#define ESDHC_VENDOR_SPEC 0xc0
|
#define ESDHC_VENDOR_SPEC 0xc0
|
||||||
|
#define ESDHC_IMX_FRC_SDCLK_ON (1 << 8)
|
||||||
|
|
||||||
#define ESDHC_DLL_CTRL 0x60
|
#define ESDHC_DLL_CTRL 0x60
|
||||||
|
|
||||||
#define ESDHC_TUNING_CTRL 0xcc
|
#define ESDHC_TUNING_CTRL 0xcc
|
||||||
|
@ -326,6 +330,7 @@ extern const VMStateDescription sdhci_vmstate;
|
||||||
#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \
|
#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \
|
||||||
DEFINE_PROP_UINT8("sd-spec-version", _state, sd_spec_version, 2), \
|
DEFINE_PROP_UINT8("sd-spec-version", _state, sd_spec_version, 2), \
|
||||||
DEFINE_PROP_UINT8("uhs", _state, uhs_mode, UHS_NOT_SUPPORTED), \
|
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
|
/* Capabilities registers provide information on supported
|
||||||
* features of this specific host controller implementation */ \
|
* features of this specific host controller implementation */ \
|
||||||
|
|
|
@ -1569,11 +1569,13 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ESDHC_VENDOR_SPEC:
|
||||||
|
ret = s->vendor_spec;
|
||||||
|
break;
|
||||||
case ESDHC_DLL_CTRL:
|
case ESDHC_DLL_CTRL:
|
||||||
case ESDHC_TUNE_CTRL_STATUS:
|
case ESDHC_TUNE_CTRL_STATUS:
|
||||||
case ESDHC_UNDOCUMENTED_REG27:
|
case ESDHC_UNDOCUMENTED_REG27:
|
||||||
case ESDHC_TUNING_CTRL:
|
case ESDHC_TUNING_CTRL:
|
||||||
case ESDHC_VENDOR_SPEC:
|
|
||||||
case ESDHC_MIX_CTRL:
|
case ESDHC_MIX_CTRL:
|
||||||
case ESDHC_WTMK_LVL:
|
case ESDHC_WTMK_LVL:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -1596,7 +1598,21 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
|
||||||
case ESDHC_UNDOCUMENTED_REG27:
|
case ESDHC_UNDOCUMENTED_REG27:
|
||||||
case ESDHC_TUNING_CTRL:
|
case ESDHC_TUNING_CTRL:
|
||||||
case ESDHC_WTMK_LVL:
|
case ESDHC_WTMK_LVL:
|
||||||
|
break;
|
||||||
|
|
||||||
case ESDHC_VENDOR_SPEC:
|
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;
|
break;
|
||||||
|
|
||||||
case SDHC_HOSTCTL:
|
case SDHC_HOSTCTL:
|
||||||
|
|
|
@ -74,6 +74,7 @@ typedef struct SDHCIState {
|
||||||
uint16_t acmd12errsts; /* Auto CMD12 error status register */
|
uint16_t acmd12errsts; /* Auto CMD12 error status register */
|
||||||
uint16_t hostctl2; /* Host Control 2 */
|
uint16_t hostctl2; /* Host Control 2 */
|
||||||
uint64_t admasysaddr; /* ADMA System Address Register */
|
uint64_t admasysaddr; /* ADMA System Address Register */
|
||||||
|
uint16_t vendor_spec; /* Vendor specific register */
|
||||||
|
|
||||||
/* Read-only registers */
|
/* Read-only registers */
|
||||||
uint64_t capareg; /* Capabilities Register */
|
uint64_t capareg; /* Capabilities Register */
|
||||||
|
@ -96,8 +97,12 @@ typedef struct SDHCIState {
|
||||||
uint32_t quirks;
|
uint32_t quirks;
|
||||||
uint8_t sd_spec_version;
|
uint8_t sd_spec_version;
|
||||||
uint8_t uhs_mode;
|
uint8_t uhs_mode;
|
||||||
|
uint8_t vendor; /* For vendor specific functionality */
|
||||||
} SDHCIState;
|
} SDHCIState;
|
||||||
|
|
||||||
|
#define SDHCI_VENDOR_NONE 0
|
||||||
|
#define SDHCI_VENDOR_IMX 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Controller does not provide transfer-complete interrupt when not
|
* Controller does not provide transfer-complete interrupt when not
|
||||||
* busy.
|
* busy.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue