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)); + + card = qdev_new(TYPE_SD_CARD); + qdev_prop_set_drive_err(card, "drive", + blk_by_legacy_dinfo((drive_get(IF_SD, 0, 0))), + &error_fatal); + qdev_realize_and_unref(card, s->sdhci0.sd_bus, &error_fatal); } static void ax3000_class_init(ObjectClass *oc, const void *data) diff --git a/include/hw/arm/ax3000-soc.h b/include/hw/arm/ax3000-soc.h index 329aa4e7698..52b47aa8294 100644 --- a/include/hw/arm/ax3000-soc.h +++ b/include/hw/arm/ax3000-soc.h @@ -13,6 +13,7 @@ #include "hw/intc/arm_gicv3_common.h" #include "hw/char/cadence_uart.h" #include "hw/misc/axiado_clk.h" +#include "hw/sd/axiado_sdhci.h" #include "hw/core/sysbus.h" #include "qemu/units.h" @@ -34,6 +35,9 @@ OBJECT_DECLARE_TYPE(Ax3000SoCState, Ax3000SoCClass, AX3000_SOC) #define AX3000_UART2_BASE 0x80620000 #define AX3000_UART3_BASE 0x80520800 +#define AX3000_SDHCI0_BASE 0x86000000 +#define AX3000_EMMC_PHY_BASE 0x80801C00 + #define AX3000_TIMER_CTRL 0x8A020000 #define AX3000_PLL_BASE 0x80000000 @@ -52,6 +56,7 @@ typedef struct Ax3000SoCState { MemoryRegion dram[AX3000_NUM_BANKS]; Ax3000ClkState ax3000_clk; CadenceUARTState uart[AX3000_NUM_UARTS]; + AxiadoSDHCIState sdhci0; } Ax3000SoCState; typedef struct Ax3000SoCClass { @@ -65,6 +70,8 @@ enum Ax3000Irqs { AX3000_UART1_IRQ = 113, AX3000_UART2_IRQ = 114, AX3000_UART3_IRQ = 170, + + AX3000_SDHCI0_IRQ = 123, }; #endif /* AXIADO_AX3000_H */ -- 2.34.1
