On 8/11/20 2:45 AM, Havard Skinnemoen wrote: > Enough functionality to boot the Linux kernel has been implemented. This > includes: > > - Correct power-on reset values so the various clock rates can be > accurately calculated. > - Clock enables stick around when written. > > In addition, a best effort attempt to implement SECCNT and CNTR25M was > made even though I don't think the kernel needs them. > > Reviewed-by: Tyrone Ting <kft...@nuvoton.com> > Reviewed-by: Joel Stanley <j...@jms.id.au> > Reviewed-by: Cédric Le Goater <c...@kaod.org> > Signed-off-by: Havard Skinnemoen <hskinnem...@google.com> > --- > hw/misc/Makefile.objs | 1 + > hw/misc/npcm7xx_clk.c | 234 ++++++++++++++++++++++++++++++++++ > hw/misc/trace-events | 4 + > include/hw/misc/npcm7xx_clk.h | 72 +++++++++++ > 4 files changed, 311 insertions(+) > create mode 100644 hw/misc/npcm7xx_clk.c > create mode 100644 include/hw/misc/npcm7xx_clk.h > > diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs > index e00b839f03..9a73c1f77f 100644 > --- a/hw/misc/Makefile.objs > +++ b/hw/misc/Makefile.objs > @@ -51,6 +51,7 @@ common-obj-$(CONFIG_IMX) += imx_rngc.o > common-obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o > common-obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o > common-obj-$(CONFIG_MAINSTONE) += mst_fpga.o > +common-obj-$(CONFIG_NPCM7XX) += npcm7xx_clk.o > common-obj-$(CONFIG_NPCM7XX) += npcm7xx_gcr.o > common-obj-$(CONFIG_OMAP) += omap_clk.o > common-obj-$(CONFIG_OMAP) += omap_gpmc.o > diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c > new file mode 100644 > index 0000000000..55beecc06f > --- /dev/null > +++ b/hw/misc/npcm7xx_clk.c [...] > +static void npcm7xx_clk_init(Object *obj) > +{ > + NPCM7xxCLKState *s = NPCM7XX_CLK(obj); > + > + memory_region_init_io(&s->iomem, obj, &npcm7xx_clk_ops, s, > + TYPE_NPCM7XX_CLK, 4 * KiB); > + sysbus_init_mmio(&s->parent, &s->iomem); > +} > + > +static const VMStateDescription vmstate_npcm7xx_clk = { > + .name = "npcm7xx-clk", > + .version_id = 0, > + .minimum_version_id = 0, > + .fields = (VMStateField[]) { > + VMSTATE_UINT32_ARRAY(regs, NPCM7xxCLKState, NPCM7XX_CLK_NR_REGS),
I wonder if this won't be a migration problem later if you add more entries to NPCM7xxCLKRegisters... > + VMSTATE_INT64(ref_ns, NPCM7xxCLKState), > + VMSTATE_END_OF_LIST(), > + }, > +}; > + > +static void npcm7xx_clk_class_init(ObjectClass *klass, void *data) > +{ > + ResettableClass *rc = RESETTABLE_CLASS(klass); > + DeviceClass *dc = DEVICE_CLASS(klass); > + > + dc->desc = "NPCM7xx Clock Control Registers"; > + dc->vmsd = &vmstate_npcm7xx_clk; > + rc->phases.enter = npcm7xx_clk_enter_reset; > +} > + > +static const TypeInfo npcm7xx_clk_info = { > + .name = TYPE_NPCM7XX_CLK, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(NPCM7xxCLKState), > + .instance_init = npcm7xx_clk_init, > + .class_init = npcm7xx_clk_class_init, > +}; > + > +static void npcm7xx_clk_register_type(void) > +{ > + type_register_static(&npcm7xx_clk_info); > +} > +type_init(npcm7xx_clk_register_type); > diff --git a/hw/misc/trace-events b/hw/misc/trace-events > index dbf90db8ed..a010699b4f 100644 > --- a/hw/misc/trace-events > +++ b/hw/misc/trace-events > @@ -111,6 +111,10 @@ mos6522_set_sr_int(void) "set sr_int" > mos6522_write(uint64_t addr, uint64_t val) "reg=0x%"PRIx64 " val=0x%"PRIx64 > mos6522_read(uint64_t addr, unsigned val) "reg=0x%"PRIx64 " val=0x%x" > > +# npcm7xx_clk.c > +npcm7xx_clk_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " > value: 0x%08" PRIx32 > +npcm7xx_clk_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " > value: 0x%08" PRIx32 > + > # npcm7xx_gcr.c > npcm7xx_gcr_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " > value: 0x%08" PRIx32 > npcm7xx_gcr_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " > value: 0x%08" PRIx32 > diff --git a/include/hw/misc/npcm7xx_clk.h b/include/hw/misc/npcm7xx_clk.h > new file mode 100644 > index 0000000000..40ed64ff15 > --- /dev/null > +++ b/include/hw/misc/npcm7xx_clk.h > @@ -0,0 +1,72 @@ > +/* > + * Nuvoton NPCM7xx Clock Control Registers. > + * > + * Copyright 2020 Google LLC > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License as published by the > + * Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, but > WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > + * for more details. > + */ > +#ifndef NPCM7XX_CLK_H > +#define NPCM7XX_CLK_H > + > +#include "exec/memory.h" > +#include "hw/sysbus.h" > + > +/* > + * The reference clock frequency for the timer modules, and the SECCNT and > + * CNTR25M registers in this module, is always 25 MHz. > + */ > +#define NPCM7XX_TIMER_REF_HZ (25000000) > + > +enum NPCM7xxCLKRegisters { > + NPCM7XX_CLK_CLKEN1, > + NPCM7XX_CLK_CLKSEL, > + NPCM7XX_CLK_CLKDIV1, > + NPCM7XX_CLK_PLLCON0, > + NPCM7XX_CLK_PLLCON1, > + NPCM7XX_CLK_SWRSTR, > + NPCM7XX_CLK_IPSRST1 = 0x20 / sizeof(uint32_t), > + NPCM7XX_CLK_IPSRST2, > + NPCM7XX_CLK_CLKEN2, > + NPCM7XX_CLK_CLKDIV2, > + NPCM7XX_CLK_CLKEN3, > + NPCM7XX_CLK_IPSRST3, > + NPCM7XX_CLK_WD0RCR, > + NPCM7XX_CLK_WD1RCR, > + NPCM7XX_CLK_WD2RCR, > + NPCM7XX_CLK_SWRSTC1, > + NPCM7XX_CLK_SWRSTC2, > + NPCM7XX_CLK_SWRSTC3, > + NPCM7XX_CLK_SWRSTC4, > + NPCM7XX_CLK_PLLCON2, > + NPCM7XX_CLK_CLKDIV3, > + NPCM7XX_CLK_CORSTC, > + NPCM7XX_CLK_PLLCONG, > + NPCM7XX_CLK_AHBCKFI, > + NPCM7XX_CLK_SECCNT, > + NPCM7XX_CLK_CNTR25M, > + NPCM7XX_CLK_NR_REGS, ... it might be simpler to define NPCM7XX_CLK_NR_REGS here, and keep NPCM7xxCLKRegisters in the source file, eventually adding something like QEMU_BUILD_BUG_ON(NPCM7XX_CLK_xxx >= NPCM7XX_CLK_NR_REGS). > +}; > + > +typedef struct NPCM7xxCLKState { > + SysBusDevice parent; > + > + MemoryRegion iomem; > + > + uint32_t regs[NPCM7XX_CLK_NR_REGS]; > + > + /* Time reference for SECCNT and CNTR25M, initialized by power on reset > */ > + int64_t ref_ns; > +} NPCM7xxCLKState; > + > +#define TYPE_NPCM7XX_CLK "npcm7xx-clk" > +#define NPCM7XX_CLK(obj) OBJECT_CHECK(NPCM7xxCLKState, (obj), > TYPE_NPCM7XX_CLK) > + > +#endif /* NPCM7XX_CLK_H */ >