This patch add a new model for Axiado SD host controller which is compatible with SDHCI 3.0 spec
This device model also includes a eMMC PHY which helps to control SD/eMMC Signed-off-by: Kuan-Jui Chiu <[email protected]> --- MAINTAINERS | 2 + hw/sd/Kconfig | 4 ++ hw/sd/axiado_sdhci.c | 114 +++++++++++++++++++++++++++++++++++ hw/sd/meson.build | 1 + include/hw/sd/axiado_sdhci.h | 21 +++++++ 5 files changed, 142 insertions(+) create mode 100644 hw/sd/axiado_sdhci.c create mode 100644 include/hw/sd/axiado_sdhci.h diff --git a/MAINTAINERS b/MAINTAINERS index 340428cda55..0c112890818 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1299,7 +1299,9 @@ M: Kuan-Jui Chiu <[email protected]> L: [email protected] S: Maintained F: hw/arm/ax3000*.c +F: hw/*/axiado*.c F: include/hw/arm/ax3000*.h +F: include/hw/*/axiado*.h AVR Machines ------------- diff --git a/hw/sd/Kconfig b/hw/sd/Kconfig index 633b9afec91..c69bf24f8de 100644 --- a/hw/sd/Kconfig +++ b/hw/sd/Kconfig @@ -23,3 +23,7 @@ config SDHCI_PCI config CADENCE_SDHCI bool select SDHCI + +config AXIADO_SDHCI + bool + select SDHCI diff --git a/hw/sd/axiado_sdhci.c b/hw/sd/axiado_sdhci.c new file mode 100644 index 00000000000..e1a76b80a67 --- /dev/null +++ b/hw/sd/axiado_sdhci.c @@ -0,0 +1,114 @@ +/* + * Axiado SD Host Controller + * + * Author: Kuan-Jui Chiu <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/sd/axiado_sdhci.h" +#include "sdhci-internal.h" +#include "qapi/error.h" +#include "hw/core/qdev-properties.h" + +#define EMMC_PHY_ID 0x00 +#define EMMC_PHY_STATUS 0x50 + +#define DLL_RDY (1u << 0) +#define CAL_DONE (1u << 6) + +static uint64_t emmc_phy_read(void *opaque, hwaddr offset, unsigned size) +{ + uint32_t val = 0x00; + + switch (offset) { + case EMMC_PHY_ID: + val = 0x3dff6870; + break; + case EMMC_PHY_STATUS: + val = DLL_RDY | CAL_DONE; + break; + default: + break; + } + + return val; +} + +static void emmc_phy_write(void *opaque, hwaddr offset, uint64_t value, + unsigned size) +{ +} + +static const MemoryRegionOps emmc_phy_ops = { + .read = emmc_phy_read, + .write = emmc_phy_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 2, + .max_access_size = 4, + }, + .valid = { + .min_access_size = 2, + .max_access_size = 4, + } +}; + +static void axiado_sdhci_realize(DeviceState *dev, Error **errp) +{ + AxiadoSDHCIState *s = AXIADO_SDHCI(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + SysBusDevice *sdhci_sbd; + + qdev_prop_set_uint64(DEVICE(&s->sdhci), "capareg", 0x216737eed0b0); + qdev_prop_set_uint64(DEVICE(&s->sdhci), "sd-spec-version", 3); + + sdhci_sbd = SYS_BUS_DEVICE(&s->sdhci); + if (!sysbus_realize(sdhci_sbd, errp)) { + return; + } + + sysbus_init_mmio(sbd, sysbus_mmio_get_region(sdhci_sbd, 0)); + + /* Propagate IRQ from SDHCI and SD bus */ + sysbus_pass_irq(sbd, sdhci_sbd); + s->sd_bus = qdev_get_child_bus(DEVICE(sdhci_sbd), "sd-bus"); + + /* Initialize eMMC PHY MMIO */ + memory_region_init_io(&s->emmc_phy, OBJECT(s), &emmc_phy_ops, s, + "axiado.emmc-phy", 0x1000); + + sysbus_init_mmio(sbd, &s->emmc_phy); +} + +static void axiado_sdhci_instance_init(Object *obj) +{ + AxiadoSDHCIState *s = AXIADO_SDHCI(obj); + + object_initialize_child(OBJECT(s), "sdhci", &s->sdhci, + TYPE_SYSBUS_SDHCI); +} + +static void axiado_sdhci_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = axiado_sdhci_realize; + dc->desc = "Axiado SD Host Controller with eMMC PHY"; +} + +static const TypeInfo axiado_sdhci_info = { + .name = TYPE_AXIADO_SDHCI, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(AxiadoSDHCIState), + .instance_init = axiado_sdhci_instance_init, + .class_init = axiado_sdhci_class_init, +}; + +static void axiado_sdhci_register_types(void) +{ + type_register_static(&axiado_sdhci_info); +} + +type_init(axiado_sdhci_register_types); diff --git a/hw/sd/meson.build b/hw/sd/meson.build index b43d45bc564..ebf09e30a48 100644 --- a/hw/sd/meson.build +++ b/hw/sd/meson.build @@ -10,3 +10,4 @@ system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_sdhci.c')) system_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-sdhost.c')) system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_sdhci.c')) system_ss.add(when: 'CONFIG_CADENCE_SDHCI', if_true: files('cadence_sdhci.c')) +system_ss.add(when: 'CONFIG_AXIADO_SDHCI', if_true: files('axiado_sdhci.c')) diff --git a/include/hw/sd/axiado_sdhci.h b/include/hw/sd/axiado_sdhci.h new file mode 100644 index 00000000000..85afebad931 --- /dev/null +++ b/include/hw/sd/axiado_sdhci.h @@ -0,0 +1,21 @@ +/* + * Axiado SD Host Controller + * + * Author: Kuan-Jui Chiu <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "hw/sd/sdhci.h" +#include "qom/object.h" + +#define TYPE_AXIADO_SDHCI "axiado-sdhci" +OBJECT_DECLARE_SIMPLE_TYPE(AxiadoSDHCIState, AXIADO_SDHCI) + +typedef struct AxiadoSDHCIState { + SysBusDevice parent; + + SDHCIState sdhci; + MemoryRegion emmc_phy; + BusState *sd_bus; +} AxiadoSDHCIState; -- 2.34.1
