@samitouri / QOSamiQemu / commits / 7623bf5664

hw: misc: Implement Microchip mpfs ioscb PLLs and sysreg clock dividers

Minimal clock register configuration required to boot Linux without backtraces in the clock code. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Conor Dooley <conor.dooley@microchip.com> Acked-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260514-reference-overhand-749149e36a88@spud> [ Changes by AF: - Fixup checkpatch errors ] Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Guenter Roeck committed May 14, 2026 at 16:23 UTC 7623bf5664ef433097f090aa5080ce2ddb838a05
3 files changed +61 -1
hw/misc/mchp_pfsoc_ioscb.c
+46 -1
@@ -53,6 +53,8 @@
53 #define IOSCB_MAILBOX_BASE 0x07020800
54 #define IOSCB_CFG_BASE 0x07080000
55 #define IOSCB_CCC_BASE 0x08000000
56 +#define IOSCB_PLL_NW0_BASE 0x08100000
57 +#define IOSCB_PLL_NW1_BASE 0x08200000
58 #define IOSCB_PLL_MSS_BASE 0x0E001000
59 #define IOSCB_CFM_MSS_BASE 0x0E002000
60 #define IOSCB_PLL_DDR_BASE 0x0E010000
@@ -92,6 +94,16 @@ static const MemoryRegionOps mchp_pfsoc_dummy_ops = {
94 /* All PLL modules in IOSCB have the same register layout */
95
96 #define PLL_CTRL 0x04
97 +#define PLL_REF_FB 0x08
98 +#define PLL_DIV_0_1 0x10
99 +#define PLL_DIV_2_3 0x14
100 +#define PLL_CTRL2 0x18
101 +#define PLL_CAL 0x1c
102 +#define PLL_PHADJ 0x20
103 +#define SSCG_REG_0 0x24
104 +#define SSCG_REG_1 0x28
105 +#define SSCG_REG_2 0x2c
106 +#define SSCG_REG_3 0x30
107
108 static uint64_t mchp_pfsoc_pll_read(void *opaque, hwaddr offset,
109 unsigned size)
@@ -103,6 +115,22 @@ static uint64_t mchp_pfsoc_pll_read(void *opaque, hwaddr offset,
115 /* PLL is locked */
116 val = BIT(25);
117 break;
118 + case PLL_DIV_0_1:
119 + case PLL_DIV_2_3:
120 + val = 0x01000100; /* return valid post divider values */
121 + break;
122 + case PLL_CTRL2:
123 + val = 0x00001110;
124 + break;
125 + case PLL_REF_FB:
126 + val = 0x00000100; /* RFDIV := 1 */
127 + break;
128 + case SSCG_REG_2:
129 + val = 0x00000001; /* INTIN := 1 */
130 + break;
131 + case PLL_PHADJ:
132 + val = 0x00000401;
133 + break;
134 default:
135 qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
136 "(size %d, offset 0x%" HWADDR_PRIx ")\n",
@@ -113,9 +141,18 @@ static uint64_t mchp_pfsoc_pll_read(void *opaque, hwaddr offset,
141 return val;
142 }
143
144 +static void mchp_pfsoc_pll_write(void *opaque, hwaddr offset,
145 + uint64_t value, unsigned size)
146 +{
147 + qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
148 + "(size %d, value 0x%" PRIx64
149 + ", offset 0x%" HWADDR_PRIx ")\n",
150 + __func__, size, value, offset);
151 +}
152 +
153 static const MemoryRegionOps mchp_pfsoc_pll_ops = {
154 .read = mchp_pfsoc_pll_read,
118 - .write = mchp_pfsoc_dummy_write,
155 + .write = mchp_pfsoc_pll_write,
156 .endianness = DEVICE_LITTLE_ENDIAN,
157 };
158
@@ -240,6 +277,14 @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
277 "mchp.pfsoc.ioscb.ccc", IOSCB_CCC_REG_SIZE);
278 memory_region_add_subregion(&s->container, IOSCB_CCC_BASE, &s->ccc);
279
280 + memory_region_init_io(&s->pll_nw_0, OBJECT(s), &mchp_pfsoc_pll_ops, s,
281 + "mchp.pfsoc.ioscb.pll_nw_0", IOSCB_SUBMOD_REG_SIZE);
282 + memory_region_add_subregion(&s->container, IOSCB_PLL_NW0_BASE, &s->pll_nw_0);
283 +
284 + memory_region_init_io(&s->pll_nw_1, OBJECT(s), &mchp_pfsoc_pll_ops, s,
285 + "mchp.pfsoc.ioscb.pll_nw_1", IOSCB_SUBMOD_REG_SIZE);
286 + memory_region_add_subregion(&s->container, IOSCB_PLL_NW1_BASE, &s->pll_nw_1);
287 +
288 memory_region_init_io(&s->pll_mss, OBJECT(s), &mchp_pfsoc_pll_ops, s,
289 "mchp.pfsoc.ioscb.pll_mss", IOSCB_SUBMOD_REG_SIZE);
290 memory_region_add_subregion(&s->container, IOSCB_PLL_MSS_BASE, &s->pll_mss);
hw/misc/mchp_pfsoc_sysreg.c
+13
@@ -29,6 +29,8 @@
29 #include "hw/misc/mchp_pfsoc_sysreg.h"
30 #include "system/runstate.h"
31
32 +#define CLOCK_CONFIG_CR 0x8
33 +#define RTC_CLOCK_CR 0xc
34 #define MSS_RESET_CR 0x18
35 #define ENVM_CR 0xb8
36 #define MESSAGE_INT 0x118c
@@ -39,6 +41,17 @@ static uint64_t mchp_pfsoc_sysreg_read(void *opaque, hwaddr offset,
41 uint32_t val = 0;
42
43 switch (offset) {
44 + case CLOCK_CONFIG_CR:
45 + /* Icicle kit reference design cpu/axi/ahb divider setting */
46 + val = 0x24;
47 + break;
48 + case RTC_CLOCK_CR:
49 + /*
50 + * Bit 16 enables the RTC clock, 0x7d is the required divider
51 + * setting for a 125 MHz reference.
52 + */
53 + val = BIT(16) | 0x7d;
54 + break;
55 case ENVM_CR:
56 /* Indicate the eNVM is running at the configured divider rate */
57 val = BIT(6);
include/hw/misc/mchp_pfsoc_ioscb.h
+2
@@ -35,6 +35,8 @@ typedef struct MchpPfSoCIoscbState {
35 MemoryRegion mailbox;
36 MemoryRegion cfg;
37 MemoryRegion ccc;
38 + MemoryRegion pll_nw_0;
39 + MemoryRegion pll_nw_1;
40 MemoryRegion pll_mss;
41 MemoryRegion cfm_mss;
42 MemoryRegion pll_ddr;