mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 02:03:56 -06:00
sifive_prci: Read and write PRCI registers
Writes to the SiFive PRCI registers are preserved while leaving the ready bits set for the HFX/HFR oscillators and the lock bit set for the PLL. Signed-off-by: Nathaniel Graff <nathaniel.graff@sifive.com> Reviewed-by: Michael Clark <mjc@sifive.com> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
This commit is contained in:
parent
b55d7d34f6
commit
b9d1848ebe
2 changed files with 73 additions and 8 deletions
|
@ -24,15 +24,18 @@
|
|||
#include "target/riscv/cpu.h"
|
||||
#include "hw/riscv/sifive_prci.h"
|
||||
|
||||
/* currently implements enough to mock freedom-e-sdk BSP clock programming */
|
||||
|
||||
static uint64_t sifive_prci_read(void *opaque, hwaddr addr, unsigned int size)
|
||||
{
|
||||
if (addr == 0 /* PRCI_HFROSCCFG */) {
|
||||
return 1 << 31; /* ROSC_RDY */
|
||||
}
|
||||
if (addr == 8 /* PRCI_PLLCFG */) {
|
||||
return 1 << 31; /* PLL_LOCK */
|
||||
SiFivePRCIState *s = opaque;
|
||||
switch (addr) {
|
||||
case SIFIVE_PRCI_HFROSCCFG:
|
||||
return s->hfrosccfg;
|
||||
case SIFIVE_PRCI_HFXOSCCFG:
|
||||
return s->hfxosccfg;
|
||||
case SIFIVE_PRCI_PLLCFG:
|
||||
return s->pllcfg;
|
||||
case SIFIVE_PRCI_PLLOUTDIV:
|
||||
return s->plloutdiv;
|
||||
}
|
||||
hw_error("%s: read: addr=0x%x\n", __func__, (int)addr);
|
||||
return 0;
|
||||
|
@ -41,7 +44,30 @@ static uint64_t sifive_prci_read(void *opaque, hwaddr addr, unsigned int size)
|
|||
static void sifive_prci_write(void *opaque, hwaddr addr,
|
||||
uint64_t val64, unsigned int size)
|
||||
{
|
||||
/* discard writes */
|
||||
SiFivePRCIState *s = opaque;
|
||||
switch (addr) {
|
||||
case SIFIVE_PRCI_HFROSCCFG:
|
||||
s->hfrosccfg = (uint32_t) val64;
|
||||
/* OSC stays ready */
|
||||
s->hfrosccfg |= SIFIVE_PRCI_HFROSCCFG_RDY;
|
||||
break;
|
||||
case SIFIVE_PRCI_HFXOSCCFG:
|
||||
s->hfxosccfg = (uint32_t) val64;
|
||||
/* OSC stays ready */
|
||||
s->hfxosccfg |= SIFIVE_PRCI_HFXOSCCFG_RDY;
|
||||
break;
|
||||
case SIFIVE_PRCI_PLLCFG:
|
||||
s->pllcfg = (uint32_t) val64;
|
||||
/* PLL stays locked */
|
||||
s->pllcfg |= SIFIVE_PRCI_PLLCFG_LOCK;
|
||||
break;
|
||||
case SIFIVE_PRCI_PLLOUTDIV:
|
||||
s->plloutdiv = (uint32_t) val64;
|
||||
break;
|
||||
default:
|
||||
hw_error("%s: bad write: addr=0x%x v=0x%x\n",
|
||||
__func__, (int)addr, (int)val64);
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps sifive_prci_ops = {
|
||||
|
@ -61,6 +87,13 @@ static void sifive_prci_init(Object *obj)
|
|||
memory_region_init_io(&s->mmio, obj, &sifive_prci_ops, s,
|
||||
TYPE_SIFIVE_PRCI, 0x8000);
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
|
||||
|
||||
s->hfrosccfg = (SIFIVE_PRCI_HFROSCCFG_RDY | SIFIVE_PRCI_HFROSCCFG_EN);
|
||||
s->hfxosccfg = (SIFIVE_PRCI_HFROSCCFG_RDY | SIFIVE_PRCI_HFROSCCFG_EN);
|
||||
s->pllcfg = (SIFIVE_PRCI_PLLCFG_REFSEL | SIFIVE_PRCI_PLLCFG_BYPASS |
|
||||
SIFIVE_PRCI_PLLCFG_LOCK);
|
||||
s->plloutdiv = SIFIVE_PRCI_PLLOUTDIV_DIV1;
|
||||
|
||||
}
|
||||
|
||||
static const TypeInfo sifive_prci_info = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue