hw/arm/allwinner-r40: add Clock Control Unit

The CCU provides the registers to program the PLLs and the controls
most of the clock generation, division, distribution, synchronization
and gating.

This commit adds support for the Clock Control Unit which emulates
a simple read/write register interface.

Signed-off-by: qianfan Zhao <qianfanguijin@163.com>
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
qianfan Zhao 2023-06-06 10:19:31 +01:00 committed by Peter Maydell
parent 8d9006aeca
commit dc2a070d12
5 changed files with 284 additions and 1 deletions

View file

@ -42,6 +42,7 @@ const hwaddr allwinner_r40_memmap[] = {
[AW_R40_DEV_MMC1] = 0x01c10000,
[AW_R40_DEV_MMC2] = 0x01c11000,
[AW_R40_DEV_MMC3] = 0x01c12000,
[AW_R40_DEV_CCU] = 0x01c20000,
[AW_R40_DEV_PIT] = 0x01c20c00,
[AW_R40_DEV_UART0] = 0x01c28000,
[AW_R40_DEV_GIC_DIST] = 0x01c81000,
@ -80,7 +81,6 @@ static struct AwR40Unimplemented r40_unimplemented[] = {
{ "usb2-host", 0x01c1c000, 4 * KiB },
{ "cs1", 0x01c1d000, 4 * KiB },
{ "spi3", 0x01c1f000, 4 * KiB },
{ "ccu", 0x01c20000, 1 * KiB },
{ "rtc", 0x01c20400, 1 * KiB },
{ "pio", 0x01c20800, 1 * KiB },
{ "owa", 0x01c21000, 1 * KiB },
@ -250,6 +250,8 @@ static void allwinner_r40_init(Object *obj)
object_property_add_alias(obj, "clk1-freq", OBJECT(&s->timer),
"clk1-freq");
object_initialize_child(obj, "ccu", &s->ccu, TYPE_AW_R40_CCU);
for (int i = 0; i < AW_R40_NUM_MMCS; i++) {
object_initialize_child(obj, mmc_names[i], &s->mmc[i],
TYPE_AW_SDHOST_SUN5I);
@ -364,6 +366,10 @@ static void allwinner_r40_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(get_system_memory(),
s->memmap[AW_R40_DEV_SRAM_A4], &s->sram_a4);
/* Clock Control Unit */
sysbus_realize(SYS_BUS_DEVICE(&s->ccu), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccu), 0, s->memmap[AW_R40_DEV_CCU]);
/* SD/MMC */
for (int i = 0; i < AW_R40_NUM_MMCS; i++) {
qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->gic),