CAUTION: This email originated from outside of the organization. Do
not click links or open attachments unless you recognize the sender
and know the content is safe.
Hi Kuan-Jui,
On 18/6/26 12:12, Kuan-Jui Chiu wrote:
Enable SD host controller into Axiado AX3000 SoC to load kernel and
rootfs
from eMMC.
Signed-off-by: Kuan-Jui Chiu <[email protected]>
Reviewed-by: Peter Maydell <[email protected]>
---
hw/arm/Kconfig | 1 +
hw/arm/ax3000-soc.c | 18 ++++++++++++++++++
include/hw/arm/ax3000-soc.h | 7 +++++++
3 files changed, 26 insertions(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 866e4b14e6f..13c0b44a180 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -724,4 +724,5 @@ config AXIADO_SOC
select ARM_GIC
select CADENCE # UART
select AXIADO_CLK
+ select AXIADO_SDHCI
select UNIMP
diff --git a/hw/arm/ax3000-soc.c b/hw/arm/ax3000-soc.c
index 9a01d23bcc6..159385cf913 100644
--- a/hw/arm/ax3000-soc.c
+++ b/hw/arm/ax3000-soc.c
@@ -35,6 +35,7 @@ static void ax3000_init(Object *obj)
}
object_initialize_child(obj, "clk", &s->ax3000_clk,
TYPE_AX3000_CLK);
+ object_initialize_child(obj, "sdhci0", &s->sdhci0,
TYPE_AXIADO_SDHCI);
}
static void ax3000_realize(DeviceState *dev, Error **errp)
@@ -165,6 +166,23 @@ static void ax3000_realize(DeviceState *dev,
Error **errp)
return;
}
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ax3000_clk), 0,
AX3000_PLL_BASE);
+
+ /* SDHCI */
+ sdhci0_sbd = SYS_BUS_DEVICE(&s->sdhci0);
+ if (!sysbus_realize(sdhci0_sbd, errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(sdhci0_sbd, 0, AX3000_SDHCI0_BASE);
+ sysbus_mmio_map(sdhci0_sbd, 1, AX3000_EMMC_PHY_BASE);
+ sysbus_connect_irq(sdhci0_sbd, 0,
+ qdev_get_gpio_in(gic_dev, AX3000_SDHCI0_IRQ));
So there is no link between the SDHCI and the PHY. Thus no need for a
particular AXIADO_SDHCI, simply instantiate a generic SDHCI here, and
register the MMIO region for the PHY.
in ax3000_init():
object_initialize_child(obj, "sdhci[0]", &s->sdhci[0],
TYPE_SYSBUS_SDHCI);
and in ax3000_realize():
object_property_set_uint(OBJECT(&s->sdhci[0]), "sd-spec-version", 3,
&error_abort);
object_property_set_uint(OBJECT(&s->sdhci[0]), "capareg",
0x216737eed0b0, &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci[0]), errp)) {
return;
}
sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci[0]), 0,
qdev_get_gpio_in(gic_dev, AX3000_SDHCI0_IRQ));
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci[0]),
0, AX3000_SDHCI0_BASE);
Then you simply map the state-less eMMC PHY region:
memory_region_init_io(&s->emmc_phy, OBJECT(s), &emmc_phy_ops, s,
"axiado.emmc-phy", 0x1000);
memory_region_add_subregion(get_system_memory(),
AX3000_EMMC_PHY_BASE, &s->emmc_phy);