From: Alistair Francis <alistair23@gmail.com> To: Bin Meng <bmeng.cn@gmail.com> Cc: "open list:RISC-V" <qemu-riscv@nongnu.org>, Palmer Dabbelt <palmer@sifive.com>, Alistair Francis <Alistair.Francis@wdc.com>, "qemu-devel@nongnu.org Developers" <qemu-devel@nongnu.org> Subject: Re: [Qemu-devel] [PATCH v5 19/30] riscv: sifive: Implement PRCI model for FU540 Date: Fri, 23 Aug 2019 16:45:30 -0700 [thread overview] Message-ID: <CAKmqyKMCPn1FNobgx0HuOCGH9AeJXF+Yfa+cuJULGXz8DKPMBw@mail.gmail.com> (raw) In-Reply-To: <1566537069-22741-20-git-send-email-bmeng.cn@gmail.com> On Thu, Aug 22, 2019 at 10:21 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > This adds a simple PRCI model for FU540 (sifive_u). It has different > register layout from the existing PRCI model for FE310 (sifive_e). > > Signed-off-by: Bin Meng <bmeng.cn@gmail.com> > > --- > > Changes in v5: > - change to use defines instead of enums > - change to use qemu_log_mask(LOG_GUEST_ERROR,...) in sifive_u_prci > - creating a 32-bit val variable and using that instead of casting > everywhere in sifive_u_prci_write() > - move all register initialization to sifive_u_prci_reset() function > - drop sifive_u_prci_create() > - s/codes that worked/code that works/g > > Changes in v4: > - prefix all macros/variables/functions with SIFIVE_U/sifive_u > in the sifive_u_prci driver > > Changes in v3: None > Changes in v2: None > > hw/riscv/Makefile.objs | 1 + > hw/riscv/sifive_u_prci.c | 171 +++++++++++++++++++++++++++++++++++++++ > include/hw/riscv/sifive_u_prci.h | 81 +++++++++++++++++++ > 3 files changed, 253 insertions(+) > create mode 100644 hw/riscv/sifive_u_prci.c > create mode 100644 include/hw/riscv/sifive_u_prci.h > > diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs > index c859697..b95bbd5 100644 > --- a/hw/riscv/Makefile.objs > +++ b/hw/riscv/Makefile.objs > @@ -8,6 +8,7 @@ obj-$(CONFIG_SIFIVE) += sifive_gpio.o > obj-$(CONFIG_SIFIVE) += sifive_plic.o > obj-$(CONFIG_SIFIVE) += sifive_test.o > obj-$(CONFIG_SIFIVE_U) += sifive_u.o > +obj-$(CONFIG_SIFIVE_U) += sifive_u_prci.o > obj-$(CONFIG_SIFIVE) += sifive_uart.o > obj-$(CONFIG_SPIKE) += spike.o > obj-$(CONFIG_RISCV_VIRT) += virt.o > diff --git a/hw/riscv/sifive_u_prci.c b/hw/riscv/sifive_u_prci.c > new file mode 100644 > index 0000000..c6438fb > --- /dev/null > +++ b/hw/riscv/sifive_u_prci.c > @@ -0,0 +1,171 @@ > +/* > + * QEMU SiFive U PRCI (Power, Reset, Clock, Interrupt) > + * > + * Copyright (c) 2019 Bin Meng <bmeng.cn@gmail.com> > + * > + * Simple model of the PRCI to emulate register reads made by the SDK BSP > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2 or later, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope 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. > + * > + * You should have received a copy of the GNU General Public License along with > + * this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include "qemu/osdep.h" > +#include "hw/sysbus.h" > +#include "qemu/log.h" > +#include "qemu/module.h" > +#include "hw/riscv/sifive_u_prci.h" > + > +static uint64_t sifive_u_prci_read(void *opaque, hwaddr addr, unsigned int size) > +{ > + SiFiveUPRCIState *s = opaque; > + > + switch (addr) { > + case SIFIVE_U_PRCI_HFXOSCCFG: > + return s->hfxosccfg; > + case SIFIVE_U_PRCI_COREPLLCFG0: > + return s->corepllcfg0; > + case SIFIVE_U_PRCI_DDRPLLCFG0: > + return s->ddrpllcfg0; > + case SIFIVE_U_PRCI_DDRPLLCFG1: > + return s->ddrpllcfg1; > + case SIFIVE_U_PRCI_GEMGXLPLLCFG0: > + return s->gemgxlpllcfg0; > + case SIFIVE_U_PRCI_GEMGXLPLLCFG1: > + return s->gemgxlpllcfg1; > + case SIFIVE_U_PRCI_CORECLKSEL: > + return s->coreclksel; > + case SIFIVE_U_PRCI_DEVICESRESET: > + return s->devicesreset; > + case SIFIVE_U_PRCI_CLKMUXSTATUS: > + return s->clkmuxstatus; > + } > + > + qemu_log_mask(LOG_GUEST_ERROR, "%s: read: addr=0x%x\n", > + __func__, (int)addr); > + > + return 0; > +} > + > +static void sifive_u_prci_write(void *opaque, hwaddr addr, > + uint64_t val64, unsigned int size) > +{ > + SiFiveUPRCIState *s = opaque; > + uint32_t val32 = (uint32_t)val64; > + > + switch (addr) { > + case SIFIVE_U_PRCI_HFXOSCCFG: > + s->hfxosccfg = val32; > + /* OSC stays ready */ > + s->hfxosccfg |= SIFIVE_U_PRCI_HFXOSCCFG_RDY; > + break; > + case SIFIVE_U_PRCI_COREPLLCFG0: > + s->corepllcfg0 = val32; > + /* internal feedback */ > + s->corepllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE; > + /* PLL stays locked */ > + s->corepllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK; > + break; > + case SIFIVE_U_PRCI_DDRPLLCFG0: > + s->ddrpllcfg0 = val32; > + /* internal feedback */ > + s->ddrpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE; > + /* PLL stays locked */ > + s->ddrpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK; > + break; > + case SIFIVE_U_PRCI_DDRPLLCFG1: > + s->ddrpllcfg1 = val32; > + break; > + case SIFIVE_U_PRCI_GEMGXLPLLCFG0: > + s->gemgxlpllcfg0 = val32; > + /* internal feedback */ > + s->gemgxlpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE; > + /* PLL stays locked */ This line seems to be incorrectly indented. > + s->gemgxlpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK; > + break; > + case SIFIVE_U_PRCI_GEMGXLPLLCFG1: > + s->gemgxlpllcfg1 = val32; > + break; > + case SIFIVE_U_PRCI_CORECLKSEL: > + s->coreclksel = val32; > + break; > + case SIFIVE_U_PRCI_DEVICESRESET: > + s->devicesreset = val32; > + break; > + case SIFIVE_U_PRCI_CLKMUXSTATUS: > + s->clkmuxstatus = val32; > + break; > + default: > + qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write: addr=0x%x v=0x%x\n", > + __func__, (int)addr, (int)val64); > + } > +} > + > +static const MemoryRegionOps sifive_u_prci_ops = { > + .read = sifive_u_prci_read, > + .write = sifive_u_prci_write, > + .endianness = DEVICE_NATIVE_ENDIAN, > + .valid = { > + .min_access_size = 4, > + .max_access_size = 4 > + } > +}; > + > +static void sifive_u_prci_realize(DeviceState *dev, Error **errp) > +{ > + SiFiveUPRCIState *s = SIFIVE_U_PRCI(dev); > + > + memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_u_prci_ops, s, > + TYPE_SIFIVE_U_PRCI, SIFIVE_U_PRCI_REG_SIZE); > + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); > +} > + > +static void sifive_u_prci_reset(DeviceState *dev) > +{ > + SiFiveUPRCIState *s = SIFIVE_U_PRCI(dev); > + > + /* Initialize register to power-on-reset values */ > + s->hfxosccfg = (SIFIVE_U_PRCI_HFXOSCCFG_RDY | SIFIVE_U_PRCI_HFXOSCCFG_EN); > + s->corepllcfg0 = (SIFIVE_U_PRCI_PLLCFG0_DIVR | SIFIVE_U_PRCI_PLLCFG0_DIVF | > + SIFIVE_U_PRCI_PLLCFG0_DIVQ | SIFIVE_U_PRCI_PLLCFG0_FSE | > + SIFIVE_U_PRCI_PLLCFG0_LOCK); > + s->ddrpllcfg0 = (SIFIVE_U_PRCI_PLLCFG0_DIVR | SIFIVE_U_PRCI_PLLCFG0_DIVF | > + SIFIVE_U_PRCI_PLLCFG0_DIVQ | SIFIVE_U_PRCI_PLLCFG0_FSE | > + SIFIVE_U_PRCI_PLLCFG0_LOCK); > + s->gemgxlpllcfg0 = (SIFIVE_U_PRCI_PLLCFG0_DIVR | > + SIFIVE_U_PRCI_PLLCFG0_DIVF | > + SIFIVE_U_PRCI_PLLCFG0_DIVQ | > + SIFIVE_U_PRCI_PLLCFG0_FSE | > + SIFIVE_U_PRCI_PLLCFG0_LOCK); You don't need brackets around these. Besides the nits: Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > + s->coreclksel = SIFIVE_U_PRCI_CORECLKSEL_HFCLK; > +} > + > +static void sifive_u_prci_class_init(ObjectClass *klass, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(klass); > + > + dc->realize = sifive_u_prci_realize; > + dc->reset = sifive_u_prci_reset; > +} > + > +static const TypeInfo sifive_u_prci_info = { > + .name = TYPE_SIFIVE_U_PRCI, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(SiFiveUPRCIState), > + .class_init = sifive_u_prci_class_init, > +}; > + > +static void sifive_u_prci_register_types(void) > +{ > + type_register_static(&sifive_u_prci_info); > +} > + > +type_init(sifive_u_prci_register_types) > diff --git a/include/hw/riscv/sifive_u_prci.h b/include/hw/riscv/sifive_u_prci.h > new file mode 100644 > index 0000000..60a2eab > --- /dev/null > +++ b/include/hw/riscv/sifive_u_prci.h > @@ -0,0 +1,81 @@ > +/* > + * QEMU SiFive U PRCI (Power, Reset, Clock, Interrupt) interface > + * > + * Copyright (c) 2019 Bin Meng <bmeng.cn@gmail.com> > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2 or later, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope 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. > + * > + * You should have received a copy of the GNU General Public License along with > + * this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef HW_SIFIVE_U_PRCI_H > +#define HW_SIFIVE_U_PRCI_H > + > +#define SIFIVE_U_PRCI_HFXOSCCFG 0x00 > +#define SIFIVE_U_PRCI_COREPLLCFG0 0x04 > +#define SIFIVE_U_PRCI_DDRPLLCFG0 0x0C > +#define SIFIVE_U_PRCI_DDRPLLCFG1 0x10 > +#define SIFIVE_U_PRCI_GEMGXLPLLCFG0 0x1C > +#define SIFIVE_U_PRCI_GEMGXLPLLCFG1 0x20 > +#define SIFIVE_U_PRCI_CORECLKSEL 0x24 > +#define SIFIVE_U_PRCI_DEVICESRESET 0x28 > +#define SIFIVE_U_PRCI_CLKMUXSTATUS 0x2C > + > +/* > + * Current FU540-C000 manual says ready bit is at bit 29, but > + * freedom-u540-c000-bootloader codes (ux00prci.h) says it is at bit 31. > + * We have to trust the actual code that works. > + * > + * see https://github.com/sifive/freedom-u540-c000-bootloader > + */ > + > +#define SIFIVE_U_PRCI_HFXOSCCFG_EN (1 << 30) > +#define SIFIVE_U_PRCI_HFXOSCCFG_RDY (1 << 31) > + > +/* xxxPLLCFG0 register bits */ > +#define SIFIVE_U_PRCI_PLLCFG0_DIVR (1 << 0) > +#define SIFIVE_U_PRCI_PLLCFG0_DIVF (31 << 6) > +#define SIFIVE_U_PRCI_PLLCFG0_DIVQ (3 << 15) > +#define SIFIVE_U_PRCI_PLLCFG0_FSE (1 << 25) > +#define SIFIVE_U_PRCI_PLLCFG0_LOCK (1 << 31) > + > +/* xxxPLLCFG1 register bits */ > +#define SIFIVE_U_PRCI_PLLCFG1_CKE (1 << 24) > + > +/* coreclksel register bits */ > +#define SIFIVE_U_PRCI_CORECLKSEL_HFCLK (1 << 0) > + > + > +#define SIFIVE_U_PRCI_REG_SIZE 0x1000 > + > +#define TYPE_SIFIVE_U_PRCI "riscv.sifive.u.prci" > + > +#define SIFIVE_U_PRCI(obj) \ > + OBJECT_CHECK(SiFiveUPRCIState, (obj), TYPE_SIFIVE_U_PRCI) > + > +typedef struct SiFiveUPRCIState { > + /*< private >*/ > + SysBusDevice parent_obj; > + > + /*< public >*/ > + MemoryRegion mmio; > + uint32_t hfxosccfg; > + uint32_t corepllcfg0; > + uint32_t ddrpllcfg0; > + uint32_t ddrpllcfg1; > + uint32_t gemgxlpllcfg0; > + uint32_t gemgxlpllcfg1; > + uint32_t coreclksel; > + uint32_t devicesreset; > + uint32_t clkmuxstatus; > +} SiFiveUPRCIState; > + > +#endif /* HW_SIFIVE_U_PRCI_H */ > -- > 2.7.4 > >
WARNING: multiple messages have this Message-ID (diff)
From: Alistair Francis <alistair23@gmail.com> To: Bin Meng <bmeng.cn@gmail.com> Cc: Alistair Francis <Alistair.Francis@wdc.com>, Palmer Dabbelt <palmer@sifive.com>, "qemu-devel@nongnu.org Developers" <qemu-devel@nongnu.org>, "open list:RISC-V" <qemu-riscv@nongnu.org> Subject: Re: [Qemu-riscv] [Qemu-devel] [PATCH v5 19/30] riscv: sifive: Implement PRCI model for FU540 Date: Fri, 23 Aug 2019 16:45:30 -0700 [thread overview] Message-ID: <CAKmqyKMCPn1FNobgx0HuOCGH9AeJXF+Yfa+cuJULGXz8DKPMBw@mail.gmail.com> (raw) In-Reply-To: <1566537069-22741-20-git-send-email-bmeng.cn@gmail.com> On Thu, Aug 22, 2019 at 10:21 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > This adds a simple PRCI model for FU540 (sifive_u). It has different > register layout from the existing PRCI model for FE310 (sifive_e). > > Signed-off-by: Bin Meng <bmeng.cn@gmail.com> > > --- > > Changes in v5: > - change to use defines instead of enums > - change to use qemu_log_mask(LOG_GUEST_ERROR,...) in sifive_u_prci > - creating a 32-bit val variable and using that instead of casting > everywhere in sifive_u_prci_write() > - move all register initialization to sifive_u_prci_reset() function > - drop sifive_u_prci_create() > - s/codes that worked/code that works/g > > Changes in v4: > - prefix all macros/variables/functions with SIFIVE_U/sifive_u > in the sifive_u_prci driver > > Changes in v3: None > Changes in v2: None > > hw/riscv/Makefile.objs | 1 + > hw/riscv/sifive_u_prci.c | 171 +++++++++++++++++++++++++++++++++++++++ > include/hw/riscv/sifive_u_prci.h | 81 +++++++++++++++++++ > 3 files changed, 253 insertions(+) > create mode 100644 hw/riscv/sifive_u_prci.c > create mode 100644 include/hw/riscv/sifive_u_prci.h > > diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs > index c859697..b95bbd5 100644 > --- a/hw/riscv/Makefile.objs > +++ b/hw/riscv/Makefile.objs > @@ -8,6 +8,7 @@ obj-$(CONFIG_SIFIVE) += sifive_gpio.o > obj-$(CONFIG_SIFIVE) += sifive_plic.o > obj-$(CONFIG_SIFIVE) += sifive_test.o > obj-$(CONFIG_SIFIVE_U) += sifive_u.o > +obj-$(CONFIG_SIFIVE_U) += sifive_u_prci.o > obj-$(CONFIG_SIFIVE) += sifive_uart.o > obj-$(CONFIG_SPIKE) += spike.o > obj-$(CONFIG_RISCV_VIRT) += virt.o > diff --git a/hw/riscv/sifive_u_prci.c b/hw/riscv/sifive_u_prci.c > new file mode 100644 > index 0000000..c6438fb > --- /dev/null > +++ b/hw/riscv/sifive_u_prci.c > @@ -0,0 +1,171 @@ > +/* > + * QEMU SiFive U PRCI (Power, Reset, Clock, Interrupt) > + * > + * Copyright (c) 2019 Bin Meng <bmeng.cn@gmail.com> > + * > + * Simple model of the PRCI to emulate register reads made by the SDK BSP > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2 or later, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope 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. > + * > + * You should have received a copy of the GNU General Public License along with > + * this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include "qemu/osdep.h" > +#include "hw/sysbus.h" > +#include "qemu/log.h" > +#include "qemu/module.h" > +#include "hw/riscv/sifive_u_prci.h" > + > +static uint64_t sifive_u_prci_read(void *opaque, hwaddr addr, unsigned int size) > +{ > + SiFiveUPRCIState *s = opaque; > + > + switch (addr) { > + case SIFIVE_U_PRCI_HFXOSCCFG: > + return s->hfxosccfg; > + case SIFIVE_U_PRCI_COREPLLCFG0: > + return s->corepllcfg0; > + case SIFIVE_U_PRCI_DDRPLLCFG0: > + return s->ddrpllcfg0; > + case SIFIVE_U_PRCI_DDRPLLCFG1: > + return s->ddrpllcfg1; > + case SIFIVE_U_PRCI_GEMGXLPLLCFG0: > + return s->gemgxlpllcfg0; > + case SIFIVE_U_PRCI_GEMGXLPLLCFG1: > + return s->gemgxlpllcfg1; > + case SIFIVE_U_PRCI_CORECLKSEL: > + return s->coreclksel; > + case SIFIVE_U_PRCI_DEVICESRESET: > + return s->devicesreset; > + case SIFIVE_U_PRCI_CLKMUXSTATUS: > + return s->clkmuxstatus; > + } > + > + qemu_log_mask(LOG_GUEST_ERROR, "%s: read: addr=0x%x\n", > + __func__, (int)addr); > + > + return 0; > +} > + > +static void sifive_u_prci_write(void *opaque, hwaddr addr, > + uint64_t val64, unsigned int size) > +{ > + SiFiveUPRCIState *s = opaque; > + uint32_t val32 = (uint32_t)val64; > + > + switch (addr) { > + case SIFIVE_U_PRCI_HFXOSCCFG: > + s->hfxosccfg = val32; > + /* OSC stays ready */ > + s->hfxosccfg |= SIFIVE_U_PRCI_HFXOSCCFG_RDY; > + break; > + case SIFIVE_U_PRCI_COREPLLCFG0: > + s->corepllcfg0 = val32; > + /* internal feedback */ > + s->corepllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE; > + /* PLL stays locked */ > + s->corepllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK; > + break; > + case SIFIVE_U_PRCI_DDRPLLCFG0: > + s->ddrpllcfg0 = val32; > + /* internal feedback */ > + s->ddrpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE; > + /* PLL stays locked */ > + s->ddrpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK; > + break; > + case SIFIVE_U_PRCI_DDRPLLCFG1: > + s->ddrpllcfg1 = val32; > + break; > + case SIFIVE_U_PRCI_GEMGXLPLLCFG0: > + s->gemgxlpllcfg0 = val32; > + /* internal feedback */ > + s->gemgxlpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE; > + /* PLL stays locked */ This line seems to be incorrectly indented. > + s->gemgxlpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK; > + break; > + case SIFIVE_U_PRCI_GEMGXLPLLCFG1: > + s->gemgxlpllcfg1 = val32; > + break; > + case SIFIVE_U_PRCI_CORECLKSEL: > + s->coreclksel = val32; > + break; > + case SIFIVE_U_PRCI_DEVICESRESET: > + s->devicesreset = val32; > + break; > + case SIFIVE_U_PRCI_CLKMUXSTATUS: > + s->clkmuxstatus = val32; > + break; > + default: > + qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write: addr=0x%x v=0x%x\n", > + __func__, (int)addr, (int)val64); > + } > +} > + > +static const MemoryRegionOps sifive_u_prci_ops = { > + .read = sifive_u_prci_read, > + .write = sifive_u_prci_write, > + .endianness = DEVICE_NATIVE_ENDIAN, > + .valid = { > + .min_access_size = 4, > + .max_access_size = 4 > + } > +}; > + > +static void sifive_u_prci_realize(DeviceState *dev, Error **errp) > +{ > + SiFiveUPRCIState *s = SIFIVE_U_PRCI(dev); > + > + memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_u_prci_ops, s, > + TYPE_SIFIVE_U_PRCI, SIFIVE_U_PRCI_REG_SIZE); > + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); > +} > + > +static void sifive_u_prci_reset(DeviceState *dev) > +{ > + SiFiveUPRCIState *s = SIFIVE_U_PRCI(dev); > + > + /* Initialize register to power-on-reset values */ > + s->hfxosccfg = (SIFIVE_U_PRCI_HFXOSCCFG_RDY | SIFIVE_U_PRCI_HFXOSCCFG_EN); > + s->corepllcfg0 = (SIFIVE_U_PRCI_PLLCFG0_DIVR | SIFIVE_U_PRCI_PLLCFG0_DIVF | > + SIFIVE_U_PRCI_PLLCFG0_DIVQ | SIFIVE_U_PRCI_PLLCFG0_FSE | > + SIFIVE_U_PRCI_PLLCFG0_LOCK); > + s->ddrpllcfg0 = (SIFIVE_U_PRCI_PLLCFG0_DIVR | SIFIVE_U_PRCI_PLLCFG0_DIVF | > + SIFIVE_U_PRCI_PLLCFG0_DIVQ | SIFIVE_U_PRCI_PLLCFG0_FSE | > + SIFIVE_U_PRCI_PLLCFG0_LOCK); > + s->gemgxlpllcfg0 = (SIFIVE_U_PRCI_PLLCFG0_DIVR | > + SIFIVE_U_PRCI_PLLCFG0_DIVF | > + SIFIVE_U_PRCI_PLLCFG0_DIVQ | > + SIFIVE_U_PRCI_PLLCFG0_FSE | > + SIFIVE_U_PRCI_PLLCFG0_LOCK); You don't need brackets around these. Besides the nits: Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > + s->coreclksel = SIFIVE_U_PRCI_CORECLKSEL_HFCLK; > +} > + > +static void sifive_u_prci_class_init(ObjectClass *klass, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(klass); > + > + dc->realize = sifive_u_prci_realize; > + dc->reset = sifive_u_prci_reset; > +} > + > +static const TypeInfo sifive_u_prci_info = { > + .name = TYPE_SIFIVE_U_PRCI, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(SiFiveUPRCIState), > + .class_init = sifive_u_prci_class_init, > +}; > + > +static void sifive_u_prci_register_types(void) > +{ > + type_register_static(&sifive_u_prci_info); > +} > + > +type_init(sifive_u_prci_register_types) > diff --git a/include/hw/riscv/sifive_u_prci.h b/include/hw/riscv/sifive_u_prci.h > new file mode 100644 > index 0000000..60a2eab > --- /dev/null > +++ b/include/hw/riscv/sifive_u_prci.h > @@ -0,0 +1,81 @@ > +/* > + * QEMU SiFive U PRCI (Power, Reset, Clock, Interrupt) interface > + * > + * Copyright (c) 2019 Bin Meng <bmeng.cn@gmail.com> > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2 or later, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope 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. > + * > + * You should have received a copy of the GNU General Public License along with > + * this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef HW_SIFIVE_U_PRCI_H > +#define HW_SIFIVE_U_PRCI_H > + > +#define SIFIVE_U_PRCI_HFXOSCCFG 0x00 > +#define SIFIVE_U_PRCI_COREPLLCFG0 0x04 > +#define SIFIVE_U_PRCI_DDRPLLCFG0 0x0C > +#define SIFIVE_U_PRCI_DDRPLLCFG1 0x10 > +#define SIFIVE_U_PRCI_GEMGXLPLLCFG0 0x1C > +#define SIFIVE_U_PRCI_GEMGXLPLLCFG1 0x20 > +#define SIFIVE_U_PRCI_CORECLKSEL 0x24 > +#define SIFIVE_U_PRCI_DEVICESRESET 0x28 > +#define SIFIVE_U_PRCI_CLKMUXSTATUS 0x2C > + > +/* > + * Current FU540-C000 manual says ready bit is at bit 29, but > + * freedom-u540-c000-bootloader codes (ux00prci.h) says it is at bit 31. > + * We have to trust the actual code that works. > + * > + * see https://github.com/sifive/freedom-u540-c000-bootloader > + */ > + > +#define SIFIVE_U_PRCI_HFXOSCCFG_EN (1 << 30) > +#define SIFIVE_U_PRCI_HFXOSCCFG_RDY (1 << 31) > + > +/* xxxPLLCFG0 register bits */ > +#define SIFIVE_U_PRCI_PLLCFG0_DIVR (1 << 0) > +#define SIFIVE_U_PRCI_PLLCFG0_DIVF (31 << 6) > +#define SIFIVE_U_PRCI_PLLCFG0_DIVQ (3 << 15) > +#define SIFIVE_U_PRCI_PLLCFG0_FSE (1 << 25) > +#define SIFIVE_U_PRCI_PLLCFG0_LOCK (1 << 31) > + > +/* xxxPLLCFG1 register bits */ > +#define SIFIVE_U_PRCI_PLLCFG1_CKE (1 << 24) > + > +/* coreclksel register bits */ > +#define SIFIVE_U_PRCI_CORECLKSEL_HFCLK (1 << 0) > + > + > +#define SIFIVE_U_PRCI_REG_SIZE 0x1000 > + > +#define TYPE_SIFIVE_U_PRCI "riscv.sifive.u.prci" > + > +#define SIFIVE_U_PRCI(obj) \ > + OBJECT_CHECK(SiFiveUPRCIState, (obj), TYPE_SIFIVE_U_PRCI) > + > +typedef struct SiFiveUPRCIState { > + /*< private >*/ > + SysBusDevice parent_obj; > + > + /*< public >*/ > + MemoryRegion mmio; > + uint32_t hfxosccfg; > + uint32_t corepllcfg0; > + uint32_t ddrpllcfg0; > + uint32_t ddrpllcfg1; > + uint32_t gemgxlpllcfg0; > + uint32_t gemgxlpllcfg1; > + uint32_t coreclksel; > + uint32_t devicesreset; > + uint32_t clkmuxstatus; > +} SiFiveUPRCIState; > + > +#endif /* HW_SIFIVE_U_PRCI_H */ > -- > 2.7.4 > >
next prev parent reply other threads:[~2019-08-24 0:14 UTC|newest] Thread overview: 82+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-08-23 5:10 [Qemu-devel] [PATCH v5 00/30] riscv: sifive_u: Improve the emulation fidelity of sifive_u machine Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 01/30] riscv: hw: Remove superfluous "linux, phandle" property Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 02/30] riscv: hw: Use qemu_fdt_setprop_cell() for property with only 1 cell Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 03/30] riscv: hw: Remove not needed PLIC properties in device tree Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 04/30] riscv: hw: Change create_fdt() to return void Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 05/30] riscv: hw: Change to use qemu_log_mask(LOG_GUEST_ERROR, ...) instead Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 17:38 ` [Qemu-devel] " Alistair Francis 2019-08-23 17:38 ` [Qemu-riscv] " Alistair Francis 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 06/30] riscv: hw: Remove the unnecessary include of target/riscv/cpu.h Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 17:38 ` [Qemu-devel] " Alistair Francis 2019-08-23 17:38 ` [Qemu-riscv] " Alistair Francis 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 07/30] riscv: roms: Remove executable attribute of opensbi images Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 08/30] riscv: sifive_u: Remove the unnecessary include of prci header Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 09/30] riscv: sifive: Rename sifive_prci.{c, h} to sifive_e_prci.{c, h} Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 10/30] riscv: sifive_e: prci: Fix a typo of hfxosccfg register programming Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 11/30] riscv: sifive_e: prci: Update the PRCI register block size Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 13/30] riscv: Add a sifive_cpu.h to include both E and U cpu type defines Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 14/30] riscv: hart: Extract hart realize to a separate routine Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 15/30] riscv: hart: Add a "hartid-base" property to RISC-V hart array Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 18:31 ` [Qemu-devel] " Alistair Francis 2019-08-23 18:31 ` [Qemu-riscv] " Alistair Francis 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 16/30] riscv: sifive_u: Update hart configuration to reflect the real FU540 SoC Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 17:36 ` [Qemu-devel] " Alistair Francis 2019-08-23 17:36 ` [Qemu-riscv] " Alistair Francis 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 17/30] riscv: sifive_u: Set the minimum number of cpus to 2 Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 18:34 ` [Qemu-devel] " Alistair Francis 2019-08-23 18:34 ` [Qemu-riscv] " Alistair Francis 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 18/30] riscv: sifive_u: Update PLIC hart topology configuration string Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 19/30] riscv: sifive: Implement PRCI model for FU540 Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 23:45 ` Alistair Francis [this message] 2019-08-23 23:45 ` [Qemu-riscv] [Qemu-devel] " Alistair Francis 2019-08-23 5:10 ` [Qemu-devel] [PATCH v5 20/30] riscv: sifive_u: Generate hfclk and rtcclk nodes Bin Meng 2019-08-23 5:10 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:11 ` [Qemu-devel] [PATCH v5 21/30] riscv: sifive_u: Add PRCI block to the SoC Bin Meng 2019-08-23 5:11 ` [Qemu-riscv] " Bin Meng 2019-08-23 23:52 ` [Qemu-devel] " Alistair Francis 2019-08-23 23:52 ` [Qemu-riscv] " Alistair Francis 2019-08-23 5:11 ` [Qemu-devel] [PATCH v5 22/30] riscv: sifive_u: Reference PRCI clocks in UART and ethernet nodes Bin Meng 2019-08-23 5:11 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:11 ` [Qemu-devel] [PATCH v5 23/30] riscv: sifive_u: Update UART base addresses and IRQs Bin Meng 2019-08-23 5:11 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:11 ` [Qemu-devel] [PATCH v5 24/30] riscv: sifive_u: Change UART node name in device tree Bin Meng 2019-08-23 5:11 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:11 ` [Qemu-devel] [PATCH v5 25/30] riscv: roms: Update default bios for sifive_u machine Bin Meng 2019-08-23 5:11 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:11 ` [Qemu-devel] [PATCH v5 26/30] riscv: sifive: Implement a model for SiFive FU540 OTP Bin Meng 2019-08-23 5:11 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:11 ` [Qemu-devel] [PATCH v5 28/30] riscv: sifive_u: Fix broken GEM support Bin Meng 2019-08-23 5:11 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:11 ` [Qemu-devel] [PATCH v5 29/30] riscv: sifive_u: Remove handcrafted clock nodes for UART and ethernet Bin Meng 2019-08-23 5:11 ` [Qemu-riscv] " Bin Meng 2019-08-23 5:11 ` [Qemu-devel] [PATCH v5 30/30] riscv: sifive_u: Update model and compatible strings in device tree Bin Meng 2019-08-23 5:11 ` [Qemu-riscv] " Bin Meng 2019-08-23 17:24 ` [Qemu-devel] [PATCH v5 00/30] riscv: sifive_u: Improve the emulation fidelity of sifive_u machine Alistair Francis 2019-08-23 17:24 ` [Qemu-riscv] " Alistair Francis 2019-08-24 5:07 ` Bin Meng 2019-08-24 5:07 ` [Qemu-riscv] " Bin Meng 2019-08-26 21:33 ` Alistair Francis 2019-08-26 21:33 ` [Qemu-riscv] " Alistair Francis 2019-08-23 17:40 ` Alistair Francis 2019-08-23 17:40 ` [Qemu-riscv] " Alistair Francis [not found] ` <1566537069-22741-13-git-send-email-bmeng.cn@gmail.com> 2019-08-26 21:36 ` [Qemu-devel] [PATCH v5 12/30] riscv: sifive_e: Drop sifive_mmio_emulate() Alistair Francis 2019-08-26 21:36 ` [Qemu-riscv] " Alistair Francis
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=CAKmqyKMCPn1FNobgx0HuOCGH9AeJXF+Yfa+cuJULGXz8DKPMBw@mail.gmail.com \ --to=alistair23@gmail.com \ --cc=Alistair.Francis@wdc.com \ --cc=bmeng.cn@gmail.com \ --cc=palmer@sifive.com \ --cc=qemu-devel@nongnu.org \ --cc=qemu-riscv@nongnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.