[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v8 05/14] sdhci: implement UHS-I voltage switch
From: |
Alistair Francis |
Subject: |
Re: [Qemu-devel] [PATCH v8 05/14] sdhci: implement UHS-I voltage switch |
Date: |
Tue, 23 Jan 2018 14:39:15 -0800 |
On Mon, Jan 22, 2018 at 7:06 PM, Philippe Mathieu-Daudé <address@hidden> wrote:
> [based on a patch from Alistair Francis <address@hidden>
> from qemu/xilinx tag xilinx-v2015.2]
> Signed-off-by: Philippe Mathieu-Daudé <address@hidden>
Reviewed-by: Alistair Francis <address@hidden>
Alistair
> ---
> include/hw/sd/sd.h | 16 ++++++++++++++++
> include/hw/sd/sdhci.h | 1 +
> hw/sd/core.c | 13 +++++++++++++
> hw/sd/sd.c | 13 +++++++++++++
> hw/sd/sdhci.c | 12 +++++++++++-
> hw/sd/trace-events | 1 +
> 6 files changed, 55 insertions(+), 1 deletion(-)
>
> diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
> index 96caefe373..f086679493 100644
> --- a/include/hw/sd/sd.h
> +++ b/include/hw/sd/sd.h
> @@ -55,6 +55,20 @@
> #define AKE_SEQ_ERROR (1 << 3)
> #define OCR_CCS_BITN 30
>
> +typedef enum {
> + SD_VOLTAGE_0_4V = 400, /* currently not supported */
> + SD_VOLTAGE_1_8V = 1800,
> + SD_VOLTAGE_3_0V = 3000,
> + SD_VOLTAGE_3_3V = 3300,
> +} sd_voltage_mv_t;
> +
> +typedef enum {
> + UHS_NOT_SUPPORTED = 0,
> + UHS_I = 1,
> + UHS_II = 2, /* currently not supported */
> + UHS_III = 3, /* currently not supported */
> +} sd_uhs_mode_t;
> +
> typedef enum {
> sd_none = -1,
> sd_bc = 0, /* broadcast -- no response */
> @@ -88,6 +102,7 @@ typedef struct {
> void (*write_data)(SDState *sd, uint8_t value);
> uint8_t (*read_data)(SDState *sd);
> bool (*data_ready)(SDState *sd);
> + void (*set_voltage)(SDState *sd, uint16_t millivolts);
> void (*enable)(SDState *sd, bool enable);
> bool (*get_inserted)(SDState *sd);
> bool (*get_readonly)(SDState *sd);
> @@ -134,6 +149,7 @@ void sd_enable(SDState *sd, bool enable);
> /* Functions to be used by qdevified callers (working via
> * an SDBus rather than directly with SDState)
> */
> +void sdbus_set_voltage(SDBus *sdbus, uint16_t millivolts);
> int sdbus_do_command(SDBus *sd, SDRequest *req, uint8_t *response);
> void sdbus_write_data(SDBus *sd, uint8_t value);
> uint8_t sdbus_read_data(SDBus *sd);
> diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
> index 0fff941a98..06e3784e54 100644
> --- a/include/hw/sd/sdhci.h
> +++ b/include/hw/sd/sdhci.h
> @@ -93,6 +93,7 @@ typedef struct SDHCIState {
> /* Configurable properties */
> bool pending_insert_quirk; /* Quirk for Raspberry Pi card insert int */
> uint8_t sd_spec_version;
> + uint8_t uhs_mode;
> } SDHCIState;
>
> #define TYPE_PCI_SDHCI "sdhci-pci"
> diff --git a/hw/sd/core.c b/hw/sd/core.c
> index 498284f109..6d198ea775 100644
> --- a/hw/sd/core.c
> +++ b/hw/sd/core.c
> @@ -41,6 +41,19 @@ static SDState *get_card(SDBus *sdbus)
> return SD_CARD(kid->child);
> }
>
> +void sdbus_set_voltage(SDBus *sdbus, uint16_t millivolts)
> +{
> + SDState *card = get_card(sdbus);
> +
> + trace_sdbus_set_voltage(sdbus_name(sdbus), millivolts);
> + if (card) {
> + SDCardClass *sc = SD_CARD_GET_CLASS(card);
> +
> + assert(sc->set_voltage);
> + sc->set_voltage(card, millivolts);
> + }
> +}
> +
> int sdbus_do_command(SDBus *sdbus, SDRequest *req, uint8_t *response)
> {
> SDState *card = get_card(sdbus);
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 35347a5bbc..609b2da14f 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -128,6 +128,18 @@ struct SDState {
> bool enable;
> };
>
> +static void sd_set_voltage(SDState *sd, uint16_t millivolts)
> +{
> + switch (millivolts) {
> + case 3001 ... 3600: /* SD_VOLTAGE_3_3V */
> + case 2001 ... 3000: /* SD_VOLTAGE_3_0V */
> + break;
> + default:
> + qemu_log_mask(LOG_GUEST_ERROR, "SD card voltage not supported:
> %.3fV",
> + millivolts / 1000.f);
> + }
> +}
> +
> static void sd_set_mode(SDState *sd)
> {
> switch (sd->state) {
> @@ -1925,6 +1937,7 @@ static void sd_class_init(ObjectClass *klass, void
> *data)
> dc->reset = sd_reset;
> dc->bus_type = TYPE_SD_BUS;
>
> + sc->set_voltage = sd_set_voltage;
> sc->do_command = sd_do_command;
> sc->write_data = sd_write_data;
> sc->read_data = sd_read_data;
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index b7e69fbc22..aec6ca4d14 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -1255,7 +1255,16 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val,
> unsigned size)
> sdhci_update_irq(s);
> break;
> case SDHC_ACMD12ERRSTS:
> - MASKED_WRITE(s->acmd12errsts, mask, value);
> + MASKED_WRITE(s->acmd12errsts, mask, value & UINT16_MAX);
> + if (s->uhs_mode >= UHS_I) {
> + MASKED_WRITE(s->hostctl2, mask >> 16, value >> 16);
> +
> + if (FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, V18_ENA)) {
> + sdbus_set_voltage(&s->sdbus, SD_VOLTAGE_1_8V);
> + } else {
> + sdbus_set_voltage(&s->sdbus, SD_VOLTAGE_3_3V);
> + }
> + }
> break;
>
> case SDHC_CAPAB:
> @@ -1310,6 +1319,7 @@ static void sdhci_init_readonly_registers(SDHCIState
> *s, Error **errp)
>
> #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), \
> \
> /* Capabilities registers provide information on supported
> * features of this specific host controller implementation */ \
> diff --git a/hw/sd/trace-events b/hw/sd/trace-events
> index ea2746c8b7..84d2f398b1 100644
> --- a/hw/sd/trace-events
> +++ b/hw/sd/trace-events
> @@ -4,6 +4,7 @@
> sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg, uint8_t crc)
> "@%s CMD%02d arg 0x%08x crc 0x%02x"
> sdbus_read(const char *bus_name, uint8_t value) "@%s value 0x%02x"
> sdbus_write(const char *bus_name, uint8_t value) "@%s value 0x%02x"
> +sdbus_set_voltage(const char *bus_name, uint16_t millivolts) "@%s %u (mV)"
>
> # hw/sd/sdhci.c
> sdhci_set_inserted(const char *level) "card state changed: %s"
> --
> 2.15.1
>
>
- [Qemu-devel] [PATCH v8 00/14] SDHCI: add tuning sequence for UHS-I cards (part 3), Philippe Mathieu-Daudé, 2018/01/22
- [Qemu-devel] [PATCH v8 01/14] sdhci: add support for v3 capabilities, Philippe Mathieu-Daudé, 2018/01/22
- [Qemu-devel] [PATCH v8 02/14] sdhci: rename the hostctl1 register, Philippe Mathieu-Daudé, 2018/01/22
- [Qemu-devel] [PATCH v8 03/14] sdhci: implement the Host Control 2 register (tuning sequence), Philippe Mathieu-Daudé, 2018/01/22
- [Qemu-devel] [PATCH v8 04/14] sdbus: add trace events, Philippe Mathieu-Daudé, 2018/01/22
- [Qemu-devel] [PATCH v8 05/14] sdhci: implement UHS-I voltage switch, Philippe Mathieu-Daudé, 2018/01/22
- Re: [Qemu-devel] [PATCH v8 05/14] sdhci: implement UHS-I voltage switch,
Alistair Francis <=
- [Qemu-devel] [PATCH v8 06/14] sdhci: implement CMD/DAT[] fields in the Present State register, Philippe Mathieu-Daudé, 2018/01/22
- [Qemu-devel] [PATCH v8 07/14] hw/arm/bcm2835_peripherals: implement SDHCI Spec. v3, Philippe Mathieu-Daudé, 2018/01/22
- [Qemu-devel] [PATCH v8 08/14] hw/arm/bcm2835_peripherals: change maximum block size to 1kB, Philippe Mathieu-Daudé, 2018/01/22
- [Qemu-devel] [PATCH v8 09/14] hw/arm/fsl-imx6: implement SDHCI Spec. v3, Philippe Mathieu-Daudé, 2018/01/22
- [Qemu-devel] [PATCH v8 10/14] hw/arm/xilinx_zynqmp: fix the capabilities/spec version to match the datasheet, Philippe Mathieu-Daudé, 2018/01/22