From c85fba508b6a7e2fdf6be8005998f216a57fba3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 22 Oct 2019 16:50:37 +0100 Subject: [PATCH] hw/sd/sdhci: Add dummy Samsung SDHCI controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Linux kernel access few S3C-specific registers [1] to set some clock. We don't care about this part for device emulation [2]. Add a dummy device to properly ignore these accesses, so we can focus on the important registers missing. [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/mmc/host/sdhci-s3c-regs.h?h=cc014f3 [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/mmc/host/sdhci-s3c.c?h=v5.3#n263 Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Krzysztof Kozlowski Message-id: 20191005154748.21718-4-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/sd/sdhci.c | 65 +++++++++++++++++++++++++++++++++++++++++++ include/hw/sd/sdhci.h | 2 ++ 2 files changed, 67 insertions(+) diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 82ec5c1b4a..88404d0e9d 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1761,11 +1761,76 @@ static const TypeInfo imx_usdhc_info = { .instance_init = imx_usdhc_init, }; +/* --- qdev Samsung s3c --- */ + +#define S3C_SDHCI_CONTROL2 0x80 +#define S3C_SDHCI_CONTROL3 0x84 +#define S3C_SDHCI_CONTROL4 0x8c + +static uint64_t sdhci_s3c_read(void *opaque, hwaddr offset, unsigned size) +{ + uint64_t ret; + + switch (offset) { + case S3C_SDHCI_CONTROL2: + case S3C_SDHCI_CONTROL3: + case S3C_SDHCI_CONTROL4: + /* ignore */ + ret = 0; + break; + default: + ret = sdhci_read(opaque, offset, size); + break; + } + + return ret; +} + +static void sdhci_s3c_write(void *opaque, hwaddr offset, uint64_t val, + unsigned size) +{ + switch (offset) { + case S3C_SDHCI_CONTROL2: + case S3C_SDHCI_CONTROL3: + case S3C_SDHCI_CONTROL4: + /* ignore */ + break; + default: + sdhci_write(opaque, offset, val, size); + break; + } +} + +static const MemoryRegionOps sdhci_s3c_mmio_ops = { + .read = sdhci_s3c_read, + .write = sdhci_s3c_write, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + .unaligned = false + }, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void sdhci_s3c_init(Object *obj) +{ + SDHCIState *s = SYSBUS_SDHCI(obj); + + s->io_ops = &sdhci_s3c_mmio_ops; +} + +static const TypeInfo sdhci_s3c_info = { + .name = TYPE_S3C_SDHCI , + .parent = TYPE_SYSBUS_SDHCI, + .instance_init = sdhci_s3c_init, +}; + static void sdhci_register_types(void) { type_register_static(&sdhci_sysbus_info); type_register_static(&sdhci_bus_info); type_register_static(&imx_usdhc_info); + type_register_static(&sdhci_s3c_info); } type_init(sdhci_register_types) diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h index cbf415e43a..c6868c9699 100644 --- a/include/hw/sd/sdhci.h +++ b/include/hw/sd/sdhci.h @@ -116,4 +116,6 @@ typedef struct SDHCIState { #define TYPE_IMX_USDHC "imx-usdhc" +#define TYPE_S3C_SDHCI "s3c-sdhci" + #endif /* SDHCI_H */