* [PATCH v3 01/12] hw/sd/sdhci: Remove need for SDHCIState::vendor field
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 02/12] hw/sd/sdhci: Introduce SDHCIClass stub Philippe Mathieu-Daudé
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
All instances of TYPE_IMX_USDHC set vendor=SDHCI_VENDOR_IMX.
No need to special-case it.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sdhci-internal.h | 1 -
include/hw/sd/sdhci.h | 4 ----
hw/arm/fsl-imx25.c | 2 --
hw/arm/fsl-imx6.c | 2 --
hw/arm/fsl-imx6ul.c | 2 --
hw/arm/fsl-imx7.c | 2 --
hw/arm/fsl-imx8mp.c | 2 --
hw/sd/sdhci.c | 14 ++++----------
8 files changed, 4 insertions(+), 25 deletions(-)
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index 9f768c418e0..9072b06bdde 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -311,7 +311,6 @@ extern const VMStateDescription sdhci_vmstate;
DEFINE_PROP_UINT8("endianness", _state, endianness, DEVICE_LITTLE_ENDIAN), \
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/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
index 38c08e28598..48247e9a20f 100644
--- a/include/hw/sd/sdhci.h
+++ b/include/hw/sd/sdhci.h
@@ -99,7 +99,6 @@ struct SDHCIState {
uint8_t endianness;
uint8_t sd_spec_version;
uint8_t uhs_mode;
- uint8_t vendor; /* For vendor specific functionality */
/*
* Write Protect pin default active low for detecting SD card
* to be protected. Set wp_inverted to invert the signal.
@@ -108,9 +107,6 @@ struct SDHCIState {
};
typedef struct SDHCIState SDHCIState;
-#define SDHCI_VENDOR_NONE 0
-#define SDHCI_VENDOR_IMX 1
-
/*
* Controller does not provide transfer-complete interrupt when not
* busy.
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 5359a6d8d3b..02214ca1a1c 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -243,8 +243,6 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
&error_abort);
object_property_set_uint(OBJECT(&s->esdhc[i]), "capareg",
IMX25_ESDHC_CAPABILITIES, &error_abort);
- object_property_set_uint(OBJECT(&s->esdhc[i]), "vendor",
- SDHCI_VENDOR_IMX, &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->esdhc[i]), errp)) {
return;
}
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index dc86338b3a5..a114dc0d63d 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -327,8 +327,6 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
&error_abort);
object_property_set_uint(OBJECT(&s->esdhc[i]), "capareg",
IMX6_ESDHC_CAPABILITIES, &error_abort);
- object_property_set_uint(OBJECT(&s->esdhc[i]), "vendor",
- SDHCI_VENDOR_IMX, &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->esdhc[i]), errp)) {
return;
}
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 34c4aa15cd0..ce8d3ef535f 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -531,8 +531,6 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
FSL_IMX6UL_USDHC2_IRQ,
};
- object_property_set_uint(OBJECT(&s->usdhc[i]), "vendor",
- SDHCI_VENDOR_IMX, &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), &error_abort);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 3374018cde0..ed1f10bca26 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -471,8 +471,6 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
FSL_IMX7_USDHC3_IRQ,
};
- object_property_set_uint(OBJECT(&s->usdhc[i]), "vendor",
- SDHCI_VENDOR_IMX, &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), &error_abort);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c
index 1ea98e14635..c3f6da63220 100644
--- a/hw/arm/fsl-imx8mp.c
+++ b/hw/arm/fsl-imx8mp.c
@@ -524,8 +524,6 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
{ fsl_imx8mp_memmap[FSL_IMX8MP_USDHC3].addr, FSL_IMX8MP_USDHC3_IRQ },
};
- object_property_set_uint(OBJECT(&s->usdhc[i]), "vendor",
- SDHCI_VENDOR_IMX, &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), errp)) {
return;
}
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 1f45a77566c..149b748cbee 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1731,16 +1731,10 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
case USDHC_VENDOR_SPEC:
s->vendor_spec = value;
- switch (s->vendor) {
- case SDHCI_VENDOR_IMX:
- if (value & USDHC_IMX_FRC_SDCLK_ON) {
- s->prnsts &= ~SDHC_IMX_CLOCK_GATE_OFF;
- } else {
- s->prnsts |= SDHC_IMX_CLOCK_GATE_OFF;
- }
- break;
- default:
- break;
+ if (value & USDHC_IMX_FRC_SDCLK_ON) {
+ s->prnsts &= ~SDHC_IMX_CLOCK_GATE_OFF;
+ } else {
+ s->prnsts |= SDHC_IMX_CLOCK_GATE_OFF;
}
break;
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 02/12] hw/sd/sdhci: Introduce SDHCIClass stub
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 01/12] hw/sd/sdhci: Remove need for SDHCIState::vendor field Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 03/12] hw/sd/sdhci: Make quirks a class property Philippe Mathieu-Daudé
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
TYPE_SYSBUS_SDHCI is a bit odd because it uses an union
to work with both SysBus / PCI parent. As this is not a
normal use, introduce SDHCIClass in its own commit.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/sd/sdhci.h | 9 +++++++++
hw/sd/sdhci.c | 1 +
2 files changed, 10 insertions(+)
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
index 48247e9a20f..c4b20db3877 100644
--- a/include/hw/sd/sdhci.h
+++ b/include/hw/sd/sdhci.h
@@ -107,6 +107,13 @@ struct SDHCIState {
};
typedef struct SDHCIState SDHCIState;
+typedef struct SDHCIClass {
+ union {
+ PCIDeviceClass pci_parent_class;
+ SysBusDeviceClass sbd_parent_class;
+ };
+} SDHCIClass;
+
/*
* Controller does not provide transfer-complete interrupt when not
* busy.
@@ -123,6 +130,8 @@ DECLARE_INSTANCE_CHECKER(SDHCIState, PCI_SDHCI,
#define TYPE_SYSBUS_SDHCI "generic-sdhci"
DECLARE_INSTANCE_CHECKER(SDHCIState, SYSBUS_SDHCI,
TYPE_SYSBUS_SDHCI)
+DECLARE_CLASS_CHECKERS(SDHCIClass, SYSBUS_SDHCI,
+ TYPE_SYSBUS_SDHCI)
#define TYPE_IMX_USDHC "imx-usdhc"
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 149b748cbee..4917a9b3632 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1960,6 +1960,7 @@ static const TypeInfo sdhci_types[] = {
.instance_size = sizeof(SDHCIState),
.instance_init = sdhci_sysbus_init,
.instance_finalize = sdhci_sysbus_finalize,
+ .class_size = sizeof(SDHCIClass),
.class_init = sdhci_sysbus_class_init,
},
{
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 03/12] hw/sd/sdhci: Make quirks a class property
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 01/12] hw/sd/sdhci: Remove need for SDHCIState::vendor field Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 02/12] hw/sd/sdhci: Introduce SDHCIClass stub Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 04/12] hw/sd/sdhci: Make I/O region size " Philippe Mathieu-Daudé
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
All TYPE_IMX_USDHC instances use the quirk:
move it to the class layer.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/sd/sdhci.h | 3 ++-
hw/sd/sdhci.c | 15 +++++++++++++--
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
index c4b20db3877..0616ce3aa59 100644
--- a/include/hw/sd/sdhci.h
+++ b/include/hw/sd/sdhci.h
@@ -95,7 +95,6 @@ struct SDHCIState {
/* Configurable properties */
bool pending_insert_quirk; /* Quirk for Raspberry Pi card insert int */
- uint32_t quirks;
uint8_t endianness;
uint8_t sd_spec_version;
uint8_t uhs_mode;
@@ -112,6 +111,8 @@ typedef struct SDHCIClass {
PCIDeviceClass pci_parent_class;
SysBusDeviceClass sbd_parent_class;
};
+
+ uint32_t quirks;
} SDHCIClass;
/*
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 4917a9b3632..2b7eb11a14a 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -345,6 +345,8 @@ static void sdhci_send_command(SDHCIState *s)
rlen = sdbus_do_command(&s->sdbus, &request, response);
if (s->cmdreg & SDHC_CMD_RESPONSE) {
+ SDHCIClass *sc = SYSBUS_SDHCI_GET_CLASS(s);
+
if (rlen == 4) {
s->rspreg[0] = ldl_be_p(response);
s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
@@ -366,7 +368,7 @@ static void sdhci_send_command(SDHCIState *s)
}
}
- if (!(s->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
+ if (!(sc->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
(s->norintstsen & SDHC_NISEN_TRSCMP) &&
(s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) {
s->norintsts |= SDHC_NIS_TRSCMP;
@@ -1886,7 +1888,15 @@ static void imx_usdhc_init(Object *obj)
SDHCIState *s = SYSBUS_SDHCI(obj);
s->io_ops = &usdhc_mmio_ops;
- s->quirks = SDHCI_QUIRK_NO_BUSY_IRQ;
+}
+
+static void imx_usdhc_class_init(ObjectClass *oc, void *data)
+{
+ SDHCIClass *sc = SYSBUS_SDHCI_CLASS(oc);
+
+ sc->quirks = SDHCI_QUIRK_NO_BUSY_IRQ;
+
+ sdhci_common_class_init(oc, data);
}
/* --- qdev Samsung s3c --- */
@@ -1967,6 +1977,7 @@ static const TypeInfo sdhci_types[] = {
.name = TYPE_IMX_USDHC,
.parent = TYPE_SYSBUS_SDHCI,
.instance_init = imx_usdhc_init,
+ .class_init = imx_usdhc_class_init,
},
{
.name = TYPE_S3C_SDHCI,
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 04/12] hw/sd/sdhci: Make I/O region size a class property
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
` (2 preceding siblings ...)
2025-03-08 19:02 ` [PATCH v3 03/12] hw/sd/sdhci: Make quirks a class property Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 05/12] hw/sd/sdhci: Enforce little endianness on PCI devices Philippe Mathieu-Daudé
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
Be ready to have SDHC implementations to cover
a wider I/O address range.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/sd/sdhci.h | 1 +
hw/sd/sdhci.c | 9 +++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
index 0616ce3aa59..2709a7a69d5 100644
--- a/include/hw/sd/sdhci.h
+++ b/include/hw/sd/sdhci.h
@@ -113,6 +113,7 @@ typedef struct SDHCIClass {
};
uint32_t quirks;
+ uint64_t iomem_size;
} SDHCIClass;
/*
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 2b7eb11a14a..59d506cafa3 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1443,6 +1443,7 @@ void sdhci_uninitfn(SDHCIState *s)
void sdhci_common_realize(SDHCIState *s, Error **errp)
{
ERRP_GUARD();
+ SDHCIClass *sc = SYSBUS_SDHCI_GET_CLASS(s);
switch (s->endianness) {
case DEVICE_LITTLE_ENDIAN:
@@ -1468,8 +1469,9 @@ void sdhci_common_realize(SDHCIState *s, Error **errp)
s->buf_maxsz = sdhci_get_fifolen(s);
s->fifo_buffer = g_malloc0(s->buf_maxsz);
- memory_region_init_io(&s->iomem, OBJECT(s), s->io_ops, s, "sdhci",
- SDHC_REGISTERS_MAP_SIZE);
+ assert(sc->iomem_size >= SDHC_REGISTERS_MAP_SIZE);
+ memory_region_init_io(&s->iomem, OBJECT(s), s->io_ops, s,
+ object_get_typename(OBJECT(s)), sc->iomem_size);
}
void sdhci_common_unrealize(SDHCIState *s)
@@ -1621,11 +1623,14 @@ static void sdhci_sysbus_unrealize(DeviceState *dev)
static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ SDHCIClass *sc = SYSBUS_SDHCI_CLASS(klass);
device_class_set_props(dc, sdhci_sysbus_properties);
dc->realize = sdhci_sysbus_realize;
dc->unrealize = sdhci_sysbus_unrealize;
+ sc->iomem_size = SDHC_REGISTERS_MAP_SIZE;
+
sdhci_common_class_init(klass, data);
}
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 05/12] hw/sd/sdhci: Enforce little endianness on PCI devices
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
` (3 preceding siblings ...)
2025-03-08 19:02 ` [PATCH v3 04/12] hw/sd/sdhci: Make I/O region size " Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 06/12] hw/sd/sdhci: Allow SDHCI classes to register their own MemoryRegionOps Philippe Mathieu-Daudé
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
This is the default, but better be safe than sorry.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sdhci-pci.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/sd/sdhci-pci.c b/hw/sd/sdhci-pci.c
index 5268c0dee50..5f82178a76f 100644
--- a/hw/sd/sdhci-pci.c
+++ b/hw/sd/sdhci-pci.c
@@ -32,6 +32,7 @@ static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
SDHCIState *s = PCI_SDHCI(dev);
sdhci_initfn(s);
+ qdev_prop_set_uint8(DEVICE(dev), "endianness", DEVICE_LITTLE_ENDIAN);
sdhci_common_realize(s, errp);
if (*errp) {
return;
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 06/12] hw/sd/sdhci: Allow SDHCI classes to register their own MemoryRegionOps
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
` (4 preceding siblings ...)
2025-03-08 19:02 ` [PATCH v3 05/12] hw/sd/sdhci: Enforce little endianness on PCI devices Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 07/12] hw/sd/sdhci: Simplify MemoryRegionOps endianness check Philippe Mathieu-Daudé
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
Add MemoryRegionOps as a class property. For now it is only
used by TYPE_IMX_USDHC.
Otherwise the default remains in little endian.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/sd/sdhci.h | 1 +
hw/sd/sdhci.c | 22 ++++++++--------------
2 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
index 2709a7a69d5..60a0442c805 100644
--- a/include/hw/sd/sdhci.h
+++ b/include/hw/sd/sdhci.h
@@ -112,6 +112,7 @@ typedef struct SDHCIClass {
SysBusDeviceClass sbd_parent_class;
};
+ const MemoryRegionOps *io_ops;
uint32_t quirks;
uint64_t iomem_size;
} SDHCIClass;
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 59d506cafa3..d87a7bb45a4 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1427,8 +1427,6 @@ void sdhci_initfn(SDHCIState *s)
sdhci_raise_insertion_irq, s);
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
sdhci_data_transfer, s);
-
- s->io_ops = &sdhci_mmio_le_ops;
}
void sdhci_uninitfn(SDHCIState *s)
@@ -1445,6 +1443,7 @@ void sdhci_common_realize(SDHCIState *s, Error **errp)
ERRP_GUARD();
SDHCIClass *sc = SYSBUS_SDHCI_GET_CLASS(s);
+ s->io_ops = sc->io_ops ?: &sdhci_mmio_le_ops;
switch (s->endianness) {
case DEVICE_LITTLE_ENDIAN:
/* s->io_ops is little endian by default */
@@ -1888,17 +1887,11 @@ static const MemoryRegionOps usdhc_mmio_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
-static void imx_usdhc_init(Object *obj)
-{
- SDHCIState *s = SYSBUS_SDHCI(obj);
-
- s->io_ops = &usdhc_mmio_ops;
-}
-
static void imx_usdhc_class_init(ObjectClass *oc, void *data)
{
SDHCIClass *sc = SYSBUS_SDHCI_CLASS(oc);
+ sc->io_ops = &usdhc_mmio_ops;
sc->quirks = SDHCI_QUIRK_NO_BUSY_IRQ;
sdhci_common_class_init(oc, data);
@@ -1955,11 +1948,13 @@ static const MemoryRegionOps sdhci_s3c_mmio_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
-static void sdhci_s3c_init(Object *obj)
+static void sdhci_s3c_class_init(ObjectClass *oc, void *data)
{
- SDHCIState *s = SYSBUS_SDHCI(obj);
+ SDHCIClass *sc = SYSBUS_SDHCI_CLASS(oc);
- s->io_ops = &sdhci_s3c_mmio_ops;
+ sc->io_ops = &sdhci_s3c_mmio_ops;
+
+ sdhci_common_class_init(oc, data);
}
static const TypeInfo sdhci_types[] = {
@@ -1981,13 +1976,12 @@ static const TypeInfo sdhci_types[] = {
{
.name = TYPE_IMX_USDHC,
.parent = TYPE_SYSBUS_SDHCI,
- .instance_init = imx_usdhc_init,
.class_init = imx_usdhc_class_init,
},
{
.name = TYPE_S3C_SDHCI,
.parent = TYPE_SYSBUS_SDHCI,
- .instance_init = sdhci_s3c_init,
+ .class_init = sdhci_s3c_class_init,
},
};
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 07/12] hw/sd/sdhci: Simplify MemoryRegionOps endianness check
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
` (5 preceding siblings ...)
2025-03-08 19:02 ` [PATCH v3 06/12] hw/sd/sdhci: Allow SDHCI classes to register their own MemoryRegionOps Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 08/12] hw/sd/sdhci: Unify default MemoryRegionOps Philippe Mathieu-Daudé
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
While little endianness is the default, ome controllers
might be only implemented in big endianness.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sdhci.c | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index d87a7bb45a4..d115e88c4b9 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1443,20 +1443,10 @@ void sdhci_common_realize(SDHCIState *s, Error **errp)
ERRP_GUARD();
SDHCIClass *sc = SYSBUS_SDHCI_GET_CLASS(s);
- s->io_ops = sc->io_ops ?: &sdhci_mmio_le_ops;
- switch (s->endianness) {
- case DEVICE_LITTLE_ENDIAN:
- /* s->io_ops is little endian by default */
- break;
- case DEVICE_BIG_ENDIAN:
- if (s->io_ops != &sdhci_mmio_le_ops) {
- error_setg(errp, "SD controller doesn't support big endianness");
- return;
- }
- s->io_ops = &sdhci_mmio_be_ops;
- break;
- default:
- error_setg(errp, "Incorrect endianness");
+ s->io_ops = sc->io_ops ?: (s->endianness == DEVICE_BIG_ENDIAN ?
+ &sdhci_mmio_be_ops : &sdhci_mmio_le_ops);
+ if (s->io_ops->endianness != s->endianness) {
+ error_setg(errp, "Invalid endianness for SD controller");
return;
}
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 08/12] hw/sd/sdhci: Unify default MemoryRegionOps
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
` (6 preceding siblings ...)
2025-03-08 19:02 ` [PATCH v3 07/12] hw/sd/sdhci: Simplify MemoryRegionOps endianness check Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 09/12] hw/sd/sdhci: Add SDHCIClass::ro::capareg field Philippe Mathieu-Daudé
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
Note, sdhci_mmio_le_ops[] was missing .impl.access_size = 4.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sdhci.c | 41 ++++++++++++++++-------------------------
1 file changed, 16 insertions(+), 25 deletions(-)
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index d115e88c4b9..15e6976220f 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1372,30 +1372,22 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
value >> shift, value >> shift);
}
-static const MemoryRegionOps sdhci_mmio_le_ops = {
- .read = sdhci_read,
- .write = sdhci_write,
- .valid = {
- .min_access_size = 1,
- .max_access_size = 4,
- .unaligned = false
+static const MemoryRegionOps sdhci_mmio_ops[2] = {
+ [0 ... 1] = {
+ .read = sdhci_read,
+ .write = sdhci_write,
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ .unaligned = false
+ },
},
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static const MemoryRegionOps sdhci_mmio_be_ops = {
- .read = sdhci_read,
- .write = sdhci_write,
- .impl = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .valid = {
- .min_access_size = 1,
- .max_access_size = 4,
- .unaligned = false
- },
- .endianness = DEVICE_BIG_ENDIAN,
+ [0].endianness = DEVICE_LITTLE_ENDIAN,
+ [1].endianness = DEVICE_BIG_ENDIAN,
};
static void sdhci_init_readonly_registers(SDHCIState *s, Error **errp)
@@ -1443,8 +1435,7 @@ void sdhci_common_realize(SDHCIState *s, Error **errp)
ERRP_GUARD();
SDHCIClass *sc = SYSBUS_SDHCI_GET_CLASS(s);
- s->io_ops = sc->io_ops ?: (s->endianness == DEVICE_BIG_ENDIAN ?
- &sdhci_mmio_be_ops : &sdhci_mmio_le_ops);
+ s->io_ops = sc->io_ops ?: &sdhci_mmio_ops[s->endianness == DEVICE_BIG_ENDIAN];
if (s->io_ops->endianness != s->endianness) {
error_setg(errp, "Invalid endianness for SD controller");
return;
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 09/12] hw/sd/sdhci: Add SDHCIClass::ro::capareg field
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
` (7 preceding siblings ...)
2025-03-08 19:02 ` [PATCH v3 08/12] hw/sd/sdhci: Unify default MemoryRegionOps Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 10/12] hw/sd/sdhci: Allow SDHCI classes to have different register reset values Philippe Mathieu-Daudé
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
Capability register is read-only.
Since we allow instances to clear/set extra bits, log when
read-only bits normally set by hardware are cleared at
board level.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/sd/sdhci.h | 5 +++++
hw/sd/sdhci.c | 6 ++++++
2 files changed, 11 insertions(+)
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
index 60a0442c805..53aef17ad34 100644
--- a/include/hw/sd/sdhci.h
+++ b/include/hw/sd/sdhci.h
@@ -115,6 +115,11 @@ typedef struct SDHCIClass {
const MemoryRegionOps *io_ops;
uint32_t quirks;
uint64_t iomem_size;
+
+ /* Read-only registers */
+ struct {
+ uint64_t capareg;
+ } ro;
} SDHCIClass;
/*
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 15e6976220f..f08918587ef 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -73,6 +73,7 @@ static bool sdhci_check_capab_freq_range(SDHCIState *s, const char *desc,
static void sdhci_check_capareg(SDHCIState *s, Error **errp)
{
+ SDHCIClass *sc = SYSBUS_SDHCI_GET_CLASS(s);
uint64_t msk = s->capareg;
uint32_t val;
bool y;
@@ -208,6 +209,11 @@ static void sdhci_check_capareg(SDHCIState *s, Error **errp)
qemu_log_mask(LOG_UNIMP,
"SDHCI: unknown CAPAB mask: 0x%016" PRIx64 "\n", msk);
}
+ msk = sc->ro.capareg & ~s->capareg;
+ if (msk) {
+ qemu_log_mask(LOG_UNIMP,
+ "SDHCI: ignored CAPAB mask: 0x%016" PRIx64 "\n", msk);
+ }
}
static uint8_t sdhci_slotint(SDHCIState *s)
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 10/12] hw/sd/sdhci: Allow SDHCI classes to have different register reset values
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
` (8 preceding siblings ...)
2025-03-08 19:02 ` [PATCH v3 09/12] hw/sd/sdhci: Add SDHCIClass::ro::capareg field Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 11/12] hw/sd/sdhci: Implement Freescale eSDHC as TYPE_FSL_ESDHC Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 12/12] hw/ppc/e500: Replace generic SDHCI by Freescale eSDHC Philippe Mathieu-Daudé
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
For the registers which are not zeroed at reset, allow the
different implementations to set particular reset values.
Remove the misleading values commented in sdhci-internal.h.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sdhci-internal.h | 24 ++++++++++++------------
include/hw/sd/sdhci.h | 20 ++++++++++++++++++++
hw/sd/sdhci.c | 14 ++++++++++++++
3 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index 9072b06bdde..d99a8493db2 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -70,7 +70,7 @@
/* R/W Buffer Data Register 0x0 */
#define SDHC_BDATA 0x20
-/* R/ROC Present State Register 0x000A0000 */
+/* R/ROC Present State Register */
#define SDHC_PRNSTS 0x24
#define SDHC_CMD_INHIBIT 0x00000001
#define SDHC_DATA_INHIBIT 0x00000002
@@ -88,7 +88,7 @@ FIELD(SDHC_PRNSTS, CMD_LVL, 24, 1);
#define TRANSFERRING_DATA(x) \
((x) & (SDHC_DOING_READ | SDHC_DOING_WRITE))
-/* R/W Host control Register 0x0 */
+/* R/W Host control Register */
#define SDHC_HOSTCTL 0x28
#define SDHC_CTRL_LED 0x01
#define SDHC_CTRL_DATATRANSFERWIDTH 0x02 /* SD mode only */
@@ -104,17 +104,17 @@ FIELD(SDHC_PRNSTS, CMD_LVL, 24, 1);
#define SDHC_CTRL_CDTEST_INS 0x40
#define SDHC_CTRL_CDTEST_EN 0x80
-/* R/W Power Control Register 0x0 */
+/* R/W Power Control Register */
#define SDHC_PWRCON 0x29
#define SDHC_POWER_ON (1 << 0)
FIELD(SDHC_PWRCON, BUS_VOLTAGE, 1, 3);
-/* R/W Block Gap Control Register 0x0 */
+/* R/W Block Gap Control Register */
#define SDHC_BLKGAP 0x2A
#define SDHC_STOP_AT_GAP_REQ 0x01
#define SDHC_CONTINUE_REQ 0x02
-/* R/W WakeUp Control Register 0x0 */
+/* R/W WakeUp Control Register */
#define SDHC_WAKCON 0x2B
#define SDHC_WKUP_ON_INS (1 << 1)
#define SDHC_WKUP_ON_RMV (1 << 2)
@@ -128,17 +128,17 @@ FIELD(SDHC_PWRCON, BUS_VOLTAGE, 1, 3);
#define SDHC_CLOCK_IS_ON(x) \
(((x) & SDHC_CLOCK_CHK_MASK) == SDHC_CLOCK_CHK_MASK)
-/* R/W Timeout Control Register 0x0 */
+/* R/W Timeout Control Register */
#define SDHC_TIMEOUTCON 0x2E
FIELD(SDHC_TIMEOUTCON, COUNTER, 0, 4);
-/* R/W Software Reset Register 0x0 */
+/* R/W Software Reset Register */
#define SDHC_SWRST 0x2F
#define SDHC_RESET_ALL 0x01
#define SDHC_RESET_CMD 0x02
#define SDHC_RESET_DATA 0x04
-/* ROC/RW1C Normal Interrupt Status Register 0x0 */
+/* ROC/RW1C Normal Interrupt Status Register */
#define SDHC_NORINTSTS 0x30
#define SDHC_NIS_ERR 0x8000
#define SDHC_NIS_CMDCMP 0x0001
@@ -151,7 +151,7 @@ FIELD(SDHC_TIMEOUTCON, COUNTER, 0, 4);
#define SDHC_NIS_REMOVE 0x0080
#define SDHC_NIS_CARDINT 0x0100
-/* ROC/RW1C Error Interrupt Status Register 0x0 */
+/* ROC/RW1C Error Interrupt Status Register */
#define SDHC_ERRINTSTS 0x32
#define SDHC_EIS_CMDTIMEOUT 0x0001
#define SDHC_EIS_BLKGAP 0x0004
@@ -159,7 +159,7 @@ FIELD(SDHC_TIMEOUTCON, COUNTER, 0, 4);
#define SDHC_EIS_CMD12ERR 0x0100
#define SDHC_EIS_ADMAERR 0x0200
-/* R/W Normal Interrupt Status Enable Register 0x0 */
+/* R/W Normal Interrupt Status Enable Register */
#define SDHC_NORINTSTSEN 0x34
#define SDHC_NISEN_CMDCMP 0x0001
#define SDHC_NISEN_TRSCMP 0x0002
@@ -170,7 +170,7 @@ FIELD(SDHC_TIMEOUTCON, COUNTER, 0, 4);
#define SDHC_NISEN_REMOVE 0x0080
#define SDHC_NISEN_CARDINT 0x0100
-/* R/W Error Interrupt Status Enable Register 0x0 */
+/* R/W Error Interrupt Status Enable Register */
#define SDHC_ERRINTSTSEN 0x36
#define SDHC_EISEN_CMDTIMEOUT 0x0001
#define SDHC_EISEN_BLKGAP 0x0004
@@ -205,7 +205,7 @@ FIELD(SDHC_HOSTCTL2, VERSION4, 12, 1); /* since v4 */
FIELD(SDHC_HOSTCTL2, ASYNC_INT, 14, 1);
FIELD(SDHC_HOSTCTL2, PRESET_ENA, 15, 1);
-/* HWInit Capabilities Register 0x05E80080 */
+/* HWInit Capabilities Register */
#define SDHC_CAPAB 0x40
FIELD(SDHC_CAPAB, TOCLKFREQ, 0, 6);
FIELD(SDHC_CAPAB, TOUNIT, 7, 1);
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
index 53aef17ad34..e24392eb10d 100644
--- a/include/hw/sd/sdhci.h
+++ b/include/hw/sd/sdhci.h
@@ -116,6 +116,26 @@ typedef struct SDHCIClass {
uint32_t quirks;
uint64_t iomem_size;
+ /* Default reset values */
+ struct {
+ uint32_t sdmasysad;
+
+ uint16_t blksize;
+ uint16_t blkcnt;
+
+ uint32_t prnsts;
+
+ uint8_t hostctl1;
+ uint8_t pwrcon;
+ uint8_t blkgap;
+ uint8_t wakcon;
+
+ uint16_t clkcon;
+ uint8_t timeoutcon;
+
+ uint16_t norintstsen;
+ uint16_t errintstsen;
+ } reset;
/* Read-only registers */
struct {
uint64_t capareg;
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index f08918587ef..cda608f8ec2 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -294,6 +294,7 @@ static void sdhci_set_readonly(DeviceState *dev, bool level)
static void sdhci_reset(SDHCIState *s)
{
+ SDHCIClass *sc = SYSBUS_SDHCI_GET_CLASS(s);
DeviceState *dev = DEVICE(s);
timer_del(s->insert_timer);
@@ -306,6 +307,19 @@ static void sdhci_reset(SDHCIState *s)
*/
memset(&s->sdmasysad, 0, (uintptr_t)&s->capareg - (uintptr_t)&s->sdmasysad);
+ s->sdmasysad = sc->reset.sdmasysad;
+ s->blksize = sc->reset.blksize;
+ s->blkcnt = sc->reset.blkcnt;
+ s->prnsts = sc->reset.prnsts;
+ s->hostctl1 = sc->reset.hostctl1;
+ s->pwrcon = sc->reset.pwrcon;
+ s->blkgap = sc->reset.blkgap;
+ s->wakcon = sc->reset.wakcon;
+ s->clkcon = sc->reset.clkcon;
+ s->timeoutcon = sc->reset.timeoutcon;
+ s->norintstsen = sc->reset.norintstsen;
+ s->errintstsen = sc->reset.errintstsen;
+
/* Reset other state based on current card insertion/readonly status */
sdhci_set_inserted(dev, sdbus_get_inserted(&s->sdbus));
sdhci_set_readonly(dev, sdbus_get_readonly(&s->sdbus));
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 11/12] hw/sd/sdhci: Implement Freescale eSDHC as TYPE_FSL_ESDHC
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
` (9 preceding siblings ...)
2025-03-08 19:02 ` [PATCH v3 10/12] hw/sd/sdhci: Allow SDHCI classes to have different register reset values Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
2025-03-08 19:02 ` [PATCH v3 12/12] hw/ppc/e500: Replace generic SDHCI by Freescale eSDHC Philippe Mathieu-Daudé
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
Per the MPC8569E reference manual, its SDHC I/O range is 4KiB
wide, mapped in big endian order, and it only accepts 32-bit
aligned access. Set the default register reset values.
Reported-by: BALATON Zoltan <balaton@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/sd/sdhci.h | 2 ++
hw/sd/sdhci.c | 37 ++++++++++++++++++++++++++++++++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
index e24392eb10d..0e9d3b10d1b 100644
--- a/include/hw/sd/sdhci.h
+++ b/include/hw/sd/sdhci.h
@@ -161,6 +161,8 @@ DECLARE_INSTANCE_CHECKER(SDHCIState, SYSBUS_SDHCI,
DECLARE_CLASS_CHECKERS(SDHCIClass, SYSBUS_SDHCI,
TYPE_SYSBUS_SDHCI)
+#define TYPE_FSL_ESDHC "fsl-esdhc"
+
#define TYPE_IMX_USDHC "imx-usdhc"
#define TYPE_S3C_SDHCI "s3c-sdhci"
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index cda608f8ec2..a78cff40fb1 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1644,7 +1644,37 @@ static void sdhci_bus_class_init(ObjectClass *klass, void *data)
sbc->set_readonly = sdhci_set_readonly;
}
-/* --- qdev i.MX eSDHC --- */
+/* --- Freescale eSDHC (MPC8569ERM Rev.2 from 06/2011) --- */
+
+static const MemoryRegionOps fsl_esdhc_mmio_ops = {
+ .read = sdhci_read,
+ .write = sdhci_write,
+ .valid = {
+ .min_access_size = 4,
+ .unaligned = false
+ },
+ .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void fsl_esdhc_class_init(ObjectClass *oc, void *data)
+{
+ SDHCIClass *sc = SYSBUS_SDHCI_CLASS(oc);
+
+ sc->iomem_size = 0x1000;
+ sc->io_ops = &fsl_esdhc_mmio_ops;
+ sc->ro.capareg = 0x01e30000;
+ sc->reset.sdmasysad = 8;
+ sc->reset.blkcnt = 8;
+ sc->reset.prnsts = 0xff800000;
+ sc->reset.hostctl1 = 0x20; /* Endian mode (address-invariant) */
+ sc->reset.clkcon = 0x8000;
+ sc->reset.norintstsen = 0x013f;
+ sc->reset.errintstsen = 0x117f;
+
+ sdhci_common_class_init(oc, data);
+}
+
+/* --- qdev i.MX uSDHC --- */
#define USDHC_MIX_CTRL 0x48
@@ -1974,6 +2004,11 @@ static const TypeInfo sdhci_types[] = {
.class_size = sizeof(SDHCIClass),
.class_init = sdhci_sysbus_class_init,
},
+ {
+ .name = TYPE_FSL_ESDHC,
+ .parent = TYPE_SYSBUS_SDHCI,
+ .class_init = fsl_esdhc_class_init,
+ },
{
.name = TYPE_IMX_USDHC,
.parent = TYPE_SYSBUS_SDHCI,
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 12/12] hw/ppc/e500: Replace generic SDHCI by Freescale eSDHC
2025-03-08 19:02 [PATCH v3 00/12] hw/sd/sdhci: Set reset value of interrupt registers Philippe Mathieu-Daudé
` (10 preceding siblings ...)
2025-03-08 19:02 ` [PATCH v3 11/12] hw/sd/sdhci: Implement Freescale eSDHC as TYPE_FSL_ESDHC Philippe Mathieu-Daudé
@ 2025-03-08 19:02 ` Philippe Mathieu-Daudé
11 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-08 19:02 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel
Cc: Bernhard Beschow, Peter Maydell, qemu-ppc, Andrey Smirnov,
Jean-Christophe Dubois, Bin Meng, qemu-arm, qemu-block,
Guenter Roeck, Philippe Mathieu-Daudé
As Zoltan reported, some U-Boot versions seem to expect
correctly initialized registers before expecting interrupts.
Now than we have a proper Freescale eSDHC implementation,
use it.
Reported-by: BALATON Zoltan <balaton@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/ppc/e500.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index fe8b9f79621..e69551ccdb3 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -1027,20 +1027,12 @@ void ppce500_init(MachineState *machine)
/* eSDHC */
if (pmc->has_esdhc) {
- dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE);
- qdev_prop_set_string(dev, "name", "esdhc");
- qdev_prop_set_uint64(dev, "size", MPC85XX_ESDHC_REGS_SIZE);
- s = SYS_BUS_DEVICE(dev);
- sysbus_realize_and_unref(s, &error_fatal);
- memory_region_add_subregion(ccsr_addr_space, MPC85XX_ESDHC_REGS_OFFSET,
- sysbus_mmio_get_region(s, 0));
-
/*
* Compatible with:
* - SD Host Controller Specification Version 2.0 Part A2
* (See MPC8569E Reference Manual)
*/
- dev = qdev_new(TYPE_SYSBUS_SDHCI);
+ dev = qdev_new(TYPE_FSL_ESDHC);
qdev_prop_set_uint8(dev, "sd-spec-version", 2);
qdev_prop_set_uint8(dev, "endianness", DEVICE_BIG_ENDIAN);
s = SYS_BUS_DEVICE(dev);
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread