Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
[qemu.git] / hw / arm / npcm7xx.c
CommitLineData
2d8f048c
HS
1/*
2 * Nuvoton NPCM7xx SoC family.
3 *
4 * Copyright 2020 Google LLC
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17#include "qemu/osdep.h"
18
2d8f048c
HS
19#include "hw/arm/boot.h"
20#include "hw/arm/npcm7xx.h"
21#include "hw/char/serial.h"
22#include "hw/loader.h"
23#include "hw/misc/unimp.h"
0be12dc7 24#include "hw/qdev-clock.h"
2d8f048c
HS
25#include "hw/qdev-properties.h"
26#include "qapi/error.h"
27#include "qemu/units.h"
28#include "sysemu/sysemu.h"
29
30/*
31 * This covers the whole MMIO space. We'll use this to catch any MMIO accesses
32 * that aren't handled by any device.
33 */
34#define NPCM7XX_MMIO_BA (0x80000000)
35#define NPCM7XX_MMIO_SZ (0x7ffd0000)
36
c752bb07
HS
37/* OTP key storage and fuse strap array */
38#define NPCM7XX_OTP1_BA (0xf0189000)
39#define NPCM7XX_OTP2_BA (0xf018a000)
40
2d8f048c
HS
41/* Core system modules. */
42#define NPCM7XX_L2C_BA (0xf03fc000)
43#define NPCM7XX_CPUP_BA (0xf03fe000)
44#define NPCM7XX_GCR_BA (0xf0800000)
45#define NPCM7XX_CLK_BA (0xf0801000)
1351f892 46#define NPCM7XX_MC_BA (0xf0824000)
326ccfe2 47#define NPCM7XX_RNG_BA (0xf000b000)
2d8f048c 48
e23e7b12
HS
49/* USB Host modules */
50#define NPCM7XX_EHCI_BA (0xf0806000)
51#define NPCM7XX_OHCI_BA (0xf0807000)
52
77c05b0b
HW
53/* ADC Module */
54#define NPCM7XX_ADC_BA (0xf000c000)
55
2d8f048c
HS
56/* Internal AHB SRAM */
57#define NPCM7XX_RAM3_BA (0xc0008000)
58#define NPCM7XX_RAM3_SZ (4 * KiB)
59
60/* Memory blocks at the end of the address space */
61#define NPCM7XX_RAM2_BA (0xfffd0000)
62#define NPCM7XX_RAM2_SZ (128 * KiB)
63#define NPCM7XX_ROM_BA (0xffff0000)
64#define NPCM7XX_ROM_SZ (64 * KiB)
65
77c05b0b 66
2ddae9cc
HS
67/* Clock configuration values to be fixed up when bypassing bootloader */
68
69/* Run PLL1 at 1600 MHz */
70#define NPCM7XX_PLLCON1_FIXUP_VAL (0x00402101)
71/* Run the CPU from PLL1 and UART from PLL2 */
72#define NPCM7XX_CLKSEL_FIXUP_VAL (0x004aaba9)
73
2d8f048c
HS
74/*
75 * Interrupt lines going into the GIC. This does not include internal Cortex-A9
76 * interrupts.
77 */
78enum NPCM7xxInterrupt {
77c05b0b 79 NPCM7XX_ADC_IRQ = 0,
2d8f048c
HS
80 NPCM7XX_UART0_IRQ = 2,
81 NPCM7XX_UART1_IRQ,
82 NPCM7XX_UART2_IRQ,
83 NPCM7XX_UART3_IRQ,
77586436
DE
84 NPCM7XX_EMC1RX_IRQ = 15,
85 NPCM7XX_EMC1TX_IRQ,
2d8f048c
HS
86 NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
87 NPCM7XX_TIMER1_IRQ,
88 NPCM7XX_TIMER2_IRQ,
89 NPCM7XX_TIMER3_IRQ,
90 NPCM7XX_TIMER4_IRQ,
91 NPCM7XX_TIMER5_IRQ, /* Timer Module 1 */
92 NPCM7XX_TIMER6_IRQ,
93 NPCM7XX_TIMER7_IRQ,
94 NPCM7XX_TIMER8_IRQ,
95 NPCM7XX_TIMER9_IRQ,
96 NPCM7XX_TIMER10_IRQ, /* Timer Module 2 */
97 NPCM7XX_TIMER11_IRQ,
98 NPCM7XX_TIMER12_IRQ,
99 NPCM7XX_TIMER13_IRQ,
100 NPCM7XX_TIMER14_IRQ,
7d378ed6
HW
101 NPCM7XX_WDG0_IRQ = 47, /* Timer Module 0 Watchdog */
102 NPCM7XX_WDG1_IRQ, /* Timer Module 1 Watchdog */
103 NPCM7XX_WDG2_IRQ, /* Timer Module 2 Watchdog */
e23e7b12
HS
104 NPCM7XX_EHCI_IRQ = 61,
105 NPCM7XX_OHCI_IRQ = 62,
94e77879
HW
106 NPCM7XX_SMBUS0_IRQ = 64,
107 NPCM7XX_SMBUS1_IRQ,
108 NPCM7XX_SMBUS2_IRQ,
109 NPCM7XX_SMBUS3_IRQ,
110 NPCM7XX_SMBUS4_IRQ,
111 NPCM7XX_SMBUS5_IRQ,
112 NPCM7XX_SMBUS6_IRQ,
113 NPCM7XX_SMBUS7_IRQ,
114 NPCM7XX_SMBUS8_IRQ,
115 NPCM7XX_SMBUS9_IRQ,
116 NPCM7XX_SMBUS10_IRQ,
117 NPCM7XX_SMBUS11_IRQ,
118 NPCM7XX_SMBUS12_IRQ,
119 NPCM7XX_SMBUS13_IRQ,
120 NPCM7XX_SMBUS14_IRQ,
121 NPCM7XX_SMBUS15_IRQ,
1e943c58
HW
122 NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
123 NPCM7XX_PWM1_IRQ, /* PWM module 1 */
fc11115f
HW
124 NPCM7XX_MFT0_IRQ = 96, /* MFT module 0 */
125 NPCM7XX_MFT1_IRQ, /* MFT module 1 */
126 NPCM7XX_MFT2_IRQ, /* MFT module 2 */
127 NPCM7XX_MFT3_IRQ, /* MFT module 3 */
128 NPCM7XX_MFT4_IRQ, /* MFT module 4 */
129 NPCM7XX_MFT5_IRQ, /* MFT module 5 */
130 NPCM7XX_MFT6_IRQ, /* MFT module 6 */
131 NPCM7XX_MFT7_IRQ, /* MFT module 7 */
77586436
DE
132 NPCM7XX_EMC2RX_IRQ = 114,
133 NPCM7XX_EMC2TX_IRQ,
526dbbe0
HS
134 NPCM7XX_GPIO0_IRQ = 116,
135 NPCM7XX_GPIO1_IRQ,
136 NPCM7XX_GPIO2_IRQ,
137 NPCM7XX_GPIO3_IRQ,
138 NPCM7XX_GPIO4_IRQ,
139 NPCM7XX_GPIO5_IRQ,
140 NPCM7XX_GPIO6_IRQ,
141 NPCM7XX_GPIO7_IRQ,
2d8f048c
HS
142};
143
144/* Total number of GIC interrupts, including internal Cortex-A9 interrupts. */
145#define NPCM7XX_NUM_IRQ (160)
146
147/* Register base address for each Timer Module */
148static const hwaddr npcm7xx_tim_addr[] = {
149 0xf0008000,
150 0xf0009000,
151 0xf000a000,
152};
153
154/* Register base address for each 16550 UART */
155static const hwaddr npcm7xx_uart_addr[] = {
156 0xf0001000,
157 0xf0002000,
158 0xf0003000,
159 0xf0004000,
160};
161
b821242c
HS
162/* Direct memory-mapped access to SPI0 CS0-1. */
163static const hwaddr npcm7xx_fiu0_flash_addr[] = {
164 0x80000000, /* CS0 */
165 0x88000000, /* CS1 */
166};
167
168/* Direct memory-mapped access to SPI3 CS0-3. */
169static const hwaddr npcm7xx_fiu3_flash_addr[] = {
170 0xa0000000, /* CS0 */
171 0xa8000000, /* CS1 */
172 0xb0000000, /* CS2 */
173 0xb8000000, /* CS3 */
174};
175
1e943c58
HW
176/* Register base address for each PWM Module */
177static const hwaddr npcm7xx_pwm_addr[] = {
178 0xf0103000,
179 0xf0104000,
180};
181
fc11115f
HW
182/* Register base address for each MFT Module */
183static const hwaddr npcm7xx_mft_addr[] = {
184 0xf0180000,
185 0xf0181000,
186 0xf0182000,
187 0xf0183000,
188 0xf0184000,
189 0xf0185000,
190 0xf0186000,
191 0xf0187000,
192};
193
94e77879
HW
194/* Direct memory-mapped access to each SMBus Module. */
195static const hwaddr npcm7xx_smbus_addr[] = {
196 0xf0080000,
197 0xf0081000,
198 0xf0082000,
199 0xf0083000,
200 0xf0084000,
201 0xf0085000,
202 0xf0086000,
203 0xf0087000,
204 0xf0088000,
205 0xf0089000,
206 0xf008a000,
207 0xf008b000,
208 0xf008c000,
209 0xf008d000,
210 0xf008e000,
211 0xf008f000,
212};
213
77586436
DE
214/* Register base address for each EMC Module */
215static const hwaddr npcm7xx_emc_addr[] = {
216 0xf0825000,
217 0xf0826000,
218};
219
526dbbe0
HS
220static const struct {
221 hwaddr regs_addr;
222 uint32_t unconnected_pins;
223 uint32_t reset_pu;
224 uint32_t reset_pd;
225 uint32_t reset_osrc;
226 uint32_t reset_odsc;
227} npcm7xx_gpio[] = {
228 {
229 .regs_addr = 0xf0010000,
230 .reset_pu = 0xff03ffff,
231 .reset_pd = 0x00fc0000,
232 }, {
233 .regs_addr = 0xf0011000,
234 .unconnected_pins = 0x0000001e,
235 .reset_pu = 0xfefffe07,
236 .reset_pd = 0x010001e0,
237 }, {
238 .regs_addr = 0xf0012000,
239 .reset_pu = 0x780fffff,
240 .reset_pd = 0x07f00000,
241 .reset_odsc = 0x00700000,
242 }, {
243 .regs_addr = 0xf0013000,
244 .reset_pu = 0x00fc0000,
245 .reset_pd = 0xff000000,
246 }, {
247 .regs_addr = 0xf0014000,
248 .reset_pu = 0xffffffff,
249 }, {
250 .regs_addr = 0xf0015000,
251 .reset_pu = 0xbf83f801,
252 .reset_pd = 0x007c0000,
253 .reset_osrc = 0x000000f1,
254 .reset_odsc = 0x3f9f80f1,
255 }, {
256 .regs_addr = 0xf0016000,
257 .reset_pu = 0xfc00f801,
258 .reset_pd = 0x000007fe,
259 .reset_odsc = 0x00000800,
260 }, {
261 .regs_addr = 0xf0017000,
262 .unconnected_pins = 0xffffff00,
263 .reset_pu = 0x0000007f,
264 .reset_osrc = 0x0000007f,
265 .reset_odsc = 0x0000007f,
266 },
267};
268
b821242c
HS
269static const struct {
270 const char *name;
271 hwaddr regs_addr;
272 int cs_count;
273 const hwaddr *flash_addr;
274} npcm7xx_fiu[] = {
275 {
276 .name = "fiu0",
277 .regs_addr = 0xfb000000,
278 .cs_count = ARRAY_SIZE(npcm7xx_fiu0_flash_addr),
279 .flash_addr = npcm7xx_fiu0_flash_addr,
280 }, {
281 .name = "fiu3",
282 .regs_addr = 0xc0000000,
283 .cs_count = ARRAY_SIZE(npcm7xx_fiu3_flash_addr),
284 .flash_addr = npcm7xx_fiu3_flash_addr,
285 },
286};
287
2ddae9cc
HS
288static void npcm7xx_write_board_setup(ARMCPU *cpu,
289 const struct arm_boot_info *info)
290{
291 uint32_t board_setup[] = {
292 0xe59f0010, /* ldr r0, clk_base_addr */
293 0xe59f1010, /* ldr r1, pllcon1_value */
294 0xe5801010, /* str r1, [r0, #16] */
295 0xe59f100c, /* ldr r1, clksel_value */
296 0xe5801004, /* str r1, [r0, #4] */
297 0xe12fff1e, /* bx lr */
298 NPCM7XX_CLK_BA,
299 NPCM7XX_PLLCON1_FIXUP_VAL,
300 NPCM7XX_CLKSEL_FIXUP_VAL,
301 };
302 int i;
303
304 for (i = 0; i < ARRAY_SIZE(board_setup); i++) {
305 board_setup[i] = tswap32(board_setup[i]);
306 }
307 rom_add_blob_fixed("board-setup", board_setup, sizeof(board_setup),
308 info->board_setup_addr);
309}
310
2d8f048c
HS
311static void npcm7xx_write_secondary_boot(ARMCPU *cpu,
312 const struct arm_boot_info *info)
313{
314 /*
315 * The default smpboot stub halts the secondary CPU with a 'wfi'
316 * instruction, but the arch/arm/mach-npcm/platsmp.c in the Linux kernel
317 * does not send an IPI to wake it up, so the second CPU fails to boot. So
318 * we need to provide our own smpboot stub that can not use 'wfi', it has
319 * to spin the secondary CPU until the first CPU writes to the SCRPAD reg.
320 */
321 uint32_t smpboot[] = {
322 0xe59f2018, /* ldr r2, bootreg_addr */
323 0xe3a00000, /* mov r0, #0 */
324 0xe5820000, /* str r0, [r2] */
325 0xe320f002, /* wfe */
326 0xe5921000, /* ldr r1, [r2] */
327 0xe1110001, /* tst r1, r1 */
328 0x0afffffb, /* beq <wfe> */
329 0xe12fff11, /* bx r1 */
330 NPCM7XX_SMP_BOOTREG_ADDR,
331 };
332 int i;
333
334 for (i = 0; i < ARRAY_SIZE(smpboot); i++) {
335 smpboot[i] = tswap32(smpboot[i]);
336 }
337
338 rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
339 NPCM7XX_SMP_LOADER_START);
340}
341
342static struct arm_boot_info npcm7xx_binfo = {
343 .loader_start = NPCM7XX_LOADER_START,
344 .smp_loader_start = NPCM7XX_SMP_LOADER_START,
345 .smp_bootreg_addr = NPCM7XX_SMP_BOOTREG_ADDR,
346 .gic_cpu_if_addr = NPCM7XX_GIC_CPU_IF_ADDR,
347 .write_secondary_boot = npcm7xx_write_secondary_boot,
348 .board_id = -1,
2ddae9cc
HS
349 .board_setup_addr = NPCM7XX_BOARD_SETUP_ADDR,
350 .write_board_setup = npcm7xx_write_board_setup,
2d8f048c
HS
351};
352
353void npcm7xx_load_kernel(MachineState *machine, NPCM7xxState *soc)
354{
355 NPCM7xxClass *sc = NPCM7XX_GET_CLASS(soc);
356
357 npcm7xx_binfo.ram_size = machine->ram_size;
358 npcm7xx_binfo.nb_cpus = sc->num_cpus;
359
360 arm_load_kernel(&soc->cpu[0], machine, &npcm7xx_binfo);
361}
362
c752bb07
HS
363static void npcm7xx_init_fuses(NPCM7xxState *s)
364{
365 NPCM7xxClass *nc = NPCM7XX_GET_CLASS(s);
366 uint32_t value;
367
368 /*
369 * The initial mask of disabled modules indicates the chip derivative (e.g.
370 * NPCM750 or NPCM730).
371 */
372 value = tswap32(nc->disabled_modules);
373 npcm7xx_otp_array_write(&s->fuse_array, &value, NPCM7XX_FUSE_DERIVATIVE,
374 sizeof(value));
375}
376
77c05b0b
HW
377static void npcm7xx_write_adc_calibration(NPCM7xxState *s)
378{
379 /* Both ADC and the fuse array must have realized. */
380 QEMU_BUILD_BUG_ON(sizeof(s->adc.calibration_r_values) != 4);
381 npcm7xx_otp_array_write(&s->fuse_array, s->adc.calibration_r_values,
382 NPCM7XX_FUSE_ADC_CALIB, sizeof(s->adc.calibration_r_values));
383}
384
2d8f048c
HS
385static qemu_irq npcm7xx_irq(NPCM7xxState *s, int n)
386{
387 return qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
388}
389
390static void npcm7xx_init(Object *obj)
391{
392 NPCM7xxState *s = NPCM7XX(obj);
393 int i;
394
395 for (i = 0; i < NPCM7XX_MAX_NUM_CPUS; i++) {
396 object_initialize_child(obj, "cpu[*]", &s->cpu[i],
397 ARM_CPU_TYPE_NAME("cortex-a9"));
398 }
399
400 object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
401 object_initialize_child(obj, "gcr", &s->gcr, TYPE_NPCM7XX_GCR);
402 object_property_add_alias(obj, "power-on-straps", OBJECT(&s->gcr),
403 "power-on-straps");
404 object_initialize_child(obj, "clk", &s->clk, TYPE_NPCM7XX_CLK);
c752bb07
HS
405 object_initialize_child(obj, "otp1", &s->key_storage,
406 TYPE_NPCM7XX_KEY_STORAGE);
407 object_initialize_child(obj, "otp2", &s->fuse_array,
408 TYPE_NPCM7XX_FUSE_ARRAY);
1351f892 409 object_initialize_child(obj, "mc", &s->mc, TYPE_NPCM7XX_MC);
326ccfe2 410 object_initialize_child(obj, "rng", &s->rng, TYPE_NPCM7XX_RNG);
77c05b0b 411 object_initialize_child(obj, "adc", &s->adc, TYPE_NPCM7XX_ADC);
2d8f048c
HS
412
413 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
414 object_initialize_child(obj, "tim[*]", &s->tim[i], TYPE_NPCM7XX_TIMER);
415 }
b821242c 416
526dbbe0
HS
417 for (i = 0; i < ARRAY_SIZE(s->gpio); i++) {
418 object_initialize_child(obj, "gpio[*]", &s->gpio[i], TYPE_NPCM7XX_GPIO);
419 }
420
94e77879
HW
421 for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
422 object_initialize_child(obj, "smbus[*]", &s->smbus[i],
423 TYPE_NPCM7XX_SMBUS);
424 }
425
e23e7b12
HS
426 object_initialize_child(obj, "ehci", &s->ehci, TYPE_NPCM7XX_EHCI);
427 object_initialize_child(obj, "ohci", &s->ohci, TYPE_SYSBUS_OHCI);
428
b821242c
HS
429 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
430 for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
431 object_initialize_child(obj, npcm7xx_fiu[i].name, &s->fiu[i],
432 TYPE_NPCM7XX_FIU);
433 }
1e943c58
HW
434
435 for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
436 object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
437 }
77586436 438
fc11115f
HW
439 for (i = 0; i < ARRAY_SIZE(s->mft); i++) {
440 object_initialize_child(obj, "mft[*]", &s->mft[i], TYPE_NPCM7XX_MFT);
441 }
442
77586436
DE
443 for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
444 object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
445 }
2d8f048c
HS
446}
447
448static void npcm7xx_realize(DeviceState *dev, Error **errp)
449{
450 NPCM7xxState *s = NPCM7XX(dev);
451 NPCM7xxClass *nc = NPCM7XX_GET_CLASS(s);
452 int i;
453
454 if (memory_region_size(s->dram) > NPCM7XX_DRAM_SZ) {
455 error_setg(errp, "%s: NPCM7xx cannot address more than %" PRIu64
456 " MiB of DRAM", __func__, NPCM7XX_DRAM_SZ / MiB);
457 return;
458 }
459
460 /* CPUs */
461 for (i = 0; i < nc->num_cpus; i++) {
462 object_property_set_int(OBJECT(&s->cpu[i]), "mp-affinity",
463 arm_cpu_mp_affinity(i, NPCM7XX_MAX_NUM_CPUS),
464 &error_abort);
465 object_property_set_int(OBJECT(&s->cpu[i]), "reset-cbar",
466 NPCM7XX_GIC_CPU_IF_ADDR, &error_abort);
467 object_property_set_bool(OBJECT(&s->cpu[i]), "reset-hivecs", true,
468 &error_abort);
469
470 /* Disable security extensions. */
471 object_property_set_bool(OBJECT(&s->cpu[i]), "has_el3", false,
472 &error_abort);
473
474 if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
475 return;
476 }
477 }
478
479 /* A9MPCORE peripherals. Can only fail if we pass bad parameters here. */
480 object_property_set_int(OBJECT(&s->a9mpcore), "num-cpu", nc->num_cpus,
481 &error_abort);
482 object_property_set_int(OBJECT(&s->a9mpcore), "num-irq", NPCM7XX_NUM_IRQ,
483 &error_abort);
484 sysbus_realize(SYS_BUS_DEVICE(&s->a9mpcore), &error_abort);
485 sysbus_mmio_map(SYS_BUS_DEVICE(&s->a9mpcore), 0, NPCM7XX_CPUP_BA);
486
487 for (i = 0; i < nc->num_cpus; i++) {
488 sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i,
489 qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_IRQ));
490 sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i + nc->num_cpus,
491 qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_FIQ));
492 }
493
494 /* L2 cache controller */
495 sysbus_create_simple("l2x0", NPCM7XX_L2C_BA, NULL);
496
497 /* System Global Control Registers (GCR). Can fail due to user input. */
498 object_property_set_int(OBJECT(&s->gcr), "disabled-modules",
499 nc->disabled_modules, &error_abort);
500 object_property_add_const_link(OBJECT(&s->gcr), "dram-mr", OBJECT(s->dram));
501 if (!sysbus_realize(SYS_BUS_DEVICE(&s->gcr), errp)) {
502 return;
503 }
504 sysbus_mmio_map(SYS_BUS_DEVICE(&s->gcr), 0, NPCM7XX_GCR_BA);
505
506 /* Clock Control Registers (CLK). Cannot fail. */
507 sysbus_realize(SYS_BUS_DEVICE(&s->clk), &error_abort);
508 sysbus_mmio_map(SYS_BUS_DEVICE(&s->clk), 0, NPCM7XX_CLK_BA);
509
c752bb07
HS
510 /* OTP key storage and fuse strap array. Cannot fail. */
511 sysbus_realize(SYS_BUS_DEVICE(&s->key_storage), &error_abort);
512 sysbus_mmio_map(SYS_BUS_DEVICE(&s->key_storage), 0, NPCM7XX_OTP1_BA);
513 sysbus_realize(SYS_BUS_DEVICE(&s->fuse_array), &error_abort);
514 sysbus_mmio_map(SYS_BUS_DEVICE(&s->fuse_array), 0, NPCM7XX_OTP2_BA);
515 npcm7xx_init_fuses(s);
516
1351f892
HS
517 /* Fake Memory Controller (MC). Cannot fail. */
518 sysbus_realize(SYS_BUS_DEVICE(&s->mc), &error_abort);
519 sysbus_mmio_map(SYS_BUS_DEVICE(&s->mc), 0, NPCM7XX_MC_BA);
520
77c05b0b
HW
521 /* ADC Modules. Cannot fail. */
522 qdev_connect_clock_in(DEVICE(&s->adc), "clock", qdev_get_clock_out(
523 DEVICE(&s->clk), "adc-clock"));
524 sysbus_realize(SYS_BUS_DEVICE(&s->adc), &error_abort);
525 sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, NPCM7XX_ADC_BA);
526 sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
527 npcm7xx_irq(s, NPCM7XX_ADC_IRQ));
528 npcm7xx_write_adc_calibration(s);
529
2d8f048c
HS
530 /* Timer Modules (TIM). Cannot fail. */
531 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_tim_addr) != ARRAY_SIZE(s->tim));
532 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
533 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->tim[i]);
534 int first_irq;
535 int j;
536
0be12dc7
HW
537 /* Connect the timer clock. */
538 qdev_connect_clock_in(DEVICE(&s->tim[i]), "clock", qdev_get_clock_out(
539 DEVICE(&s->clk), "timer-clock"));
540
2d8f048c
HS
541 sysbus_realize(sbd, &error_abort);
542 sysbus_mmio_map(sbd, 0, npcm7xx_tim_addr[i]);
543
544 first_irq = NPCM7XX_TIMER0_IRQ + i * NPCM7XX_TIMERS_PER_CTRL;
545 for (j = 0; j < NPCM7XX_TIMERS_PER_CTRL; j++) {
546 qemu_irq irq = npcm7xx_irq(s, first_irq + j);
547 sysbus_connect_irq(sbd, j, irq);
548 }
7d378ed6
HW
549
550 /* IRQ for watchdogs */
551 sysbus_connect_irq(sbd, NPCM7XX_TIMERS_PER_CTRL,
552 npcm7xx_irq(s, NPCM7XX_WDG0_IRQ + i));
553 /* GPIO that connects clk module with watchdog */
554 qdev_connect_gpio_out_named(DEVICE(&s->tim[i]),
555 NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 0,
556 qdev_get_gpio_in_named(DEVICE(&s->clk),
557 NPCM7XX_WATCHDOG_RESET_GPIO_IN, i));
2d8f048c
HS
558 }
559
560 /* UART0..3 (16550 compatible) */
561 for (i = 0; i < ARRAY_SIZE(npcm7xx_uart_addr); i++) {
562 serial_mm_init(get_system_memory(), npcm7xx_uart_addr[i], 2,
563 npcm7xx_irq(s, NPCM7XX_UART0_IRQ + i), 115200,
564 serial_hd(i), DEVICE_LITTLE_ENDIAN);
565 }
566
326ccfe2
HS
567 /* Random Number Generator. Cannot fail. */
568 sysbus_realize(SYS_BUS_DEVICE(&s->rng), &error_abort);
569 sysbus_mmio_map(SYS_BUS_DEVICE(&s->rng), 0, NPCM7XX_RNG_BA);
570
526dbbe0
HS
571 /* GPIO modules. Cannot fail. */
572 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_gpio) != ARRAY_SIZE(s->gpio));
573 for (i = 0; i < ARRAY_SIZE(s->gpio); i++) {
574 Object *obj = OBJECT(&s->gpio[i]);
575
576 object_property_set_uint(obj, "reset-pullup",
577 npcm7xx_gpio[i].reset_pu, &error_abort);
578 object_property_set_uint(obj, "reset-pulldown",
579 npcm7xx_gpio[i].reset_pd, &error_abort);
580 object_property_set_uint(obj, "reset-osrc",
581 npcm7xx_gpio[i].reset_osrc, &error_abort);
582 object_property_set_uint(obj, "reset-odsc",
583 npcm7xx_gpio[i].reset_odsc, &error_abort);
584 sysbus_realize(SYS_BUS_DEVICE(obj), &error_abort);
585 sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm7xx_gpio[i].regs_addr);
586 sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0,
587 npcm7xx_irq(s, NPCM7XX_GPIO0_IRQ + i));
588 }
589
94e77879
HW
590 /* SMBus modules. Cannot fail. */
591 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_smbus_addr) != ARRAY_SIZE(s->smbus));
592 for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
593 Object *obj = OBJECT(&s->smbus[i]);
594
595 sysbus_realize(SYS_BUS_DEVICE(obj), &error_abort);
596 sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm7xx_smbus_addr[i]);
597 sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0,
598 npcm7xx_irq(s, NPCM7XX_SMBUS0_IRQ + i));
599 }
600
e23e7b12
HS
601 /* USB Host */
602 object_property_set_bool(OBJECT(&s->ehci), "companion-enable", true,
603 &error_abort);
604 sysbus_realize(SYS_BUS_DEVICE(&s->ehci), &error_abort);
605 sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci), 0, NPCM7XX_EHCI_BA);
606 sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci), 0,
607 npcm7xx_irq(s, NPCM7XX_EHCI_IRQ));
608
609 object_property_set_str(OBJECT(&s->ohci), "masterbus", "usb-bus.0",
610 &error_abort);
611 object_property_set_uint(OBJECT(&s->ohci), "num-ports", 1, &error_abort);
612 sysbus_realize(SYS_BUS_DEVICE(&s->ohci), &error_abort);
613 sysbus_mmio_map(SYS_BUS_DEVICE(&s->ohci), 0, NPCM7XX_OHCI_BA);
614 sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci), 0,
615 npcm7xx_irq(s, NPCM7XX_OHCI_IRQ));
616
1e943c58
HW
617 /* PWM Modules. Cannot fail. */
618 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pwm_addr) != ARRAY_SIZE(s->pwm));
619 for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
620 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->pwm[i]);
621
622 qdev_connect_clock_in(DEVICE(&s->pwm[i]), "clock", qdev_get_clock_out(
623 DEVICE(&s->clk), "apb3-clock"));
624 sysbus_realize(sbd, &error_abort);
625 sysbus_mmio_map(sbd, 0, npcm7xx_pwm_addr[i]);
626 sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
627 }
628
fc11115f
HW
629 /* MFT Modules. Cannot fail. */
630 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_mft_addr) != ARRAY_SIZE(s->mft));
631 for (i = 0; i < ARRAY_SIZE(s->mft); i++) {
632 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->mft[i]);
633
634 qdev_connect_clock_in(DEVICE(&s->mft[i]), "clock-in",
635 qdev_get_clock_out(DEVICE(&s->clk),
636 "apb4-clock"));
637 sysbus_realize(sbd, &error_abort);
638 sysbus_mmio_map(sbd, 0, npcm7xx_mft_addr[i]);
639 sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, NPCM7XX_MFT0_IRQ + i));
640 }
641
77586436
DE
642 /*
643 * EMC Modules. Cannot fail.
644 * The mapping of the device to its netdev backend works as follows:
645 * emc[i] = nd_table[i]
646 * This works around the inability to specify the netdev property for the
647 * emc device: it's not pluggable and thus the -device option can't be
648 * used.
649 */
650 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_emc_addr) != ARRAY_SIZE(s->emc));
651 QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->emc) != 2);
652 for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
653 s->emc[i].emc_num = i;
654 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->emc[i]);
655 if (nd_table[i].used) {
656 qemu_check_nic_model(&nd_table[i], TYPE_NPCM7XX_EMC);
657 qdev_set_nic_properties(DEVICE(sbd), &nd_table[i]);
658 }
659 /*
660 * The device exists regardless of whether it's connected to a QEMU
661 * netdev backend. So always instantiate it even if there is no
662 * backend.
663 */
664 sysbus_realize(sbd, &error_abort);
665 sysbus_mmio_map(sbd, 0, npcm7xx_emc_addr[i]);
666 int tx_irq = i == 0 ? NPCM7XX_EMC1TX_IRQ : NPCM7XX_EMC2TX_IRQ;
667 int rx_irq = i == 0 ? NPCM7XX_EMC1RX_IRQ : NPCM7XX_EMC2RX_IRQ;
668 /*
669 * N.B. The values for the second argument sysbus_connect_irq are
670 * chosen to match the registration order in npcm7xx_emc_realize.
671 */
672 sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, tx_irq));
673 sysbus_connect_irq(sbd, 1, npcm7xx_irq(s, rx_irq));
674 }
675
b821242c
HS
676 /*
677 * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
678 * specified, but this is a programming error.
679 */
680 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
681 for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
682 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->fiu[i]);
683 int j;
684
685 object_property_set_int(OBJECT(sbd), "cs-count",
686 npcm7xx_fiu[i].cs_count, &error_abort);
687 sysbus_realize(sbd, &error_abort);
688
689 sysbus_mmio_map(sbd, 0, npcm7xx_fiu[i].regs_addr);
690 for (j = 0; j < npcm7xx_fiu[i].cs_count; j++) {
691 sysbus_mmio_map(sbd, j + 1, npcm7xx_fiu[i].flash_addr[j]);
692 }
693 }
694
2d8f048c
HS
695 /* RAM2 (SRAM) */
696 memory_region_init_ram(&s->sram, OBJECT(dev), "ram2",
697 NPCM7XX_RAM2_SZ, &error_abort);
698 memory_region_add_subregion(get_system_memory(), NPCM7XX_RAM2_BA, &s->sram);
699
700 /* RAM3 (SRAM) */
701 memory_region_init_ram(&s->ram3, OBJECT(dev), "ram3",
702 NPCM7XX_RAM3_SZ, &error_abort);
703 memory_region_add_subregion(get_system_memory(), NPCM7XX_RAM3_BA, &s->ram3);
704
705 /* Internal ROM */
706 memory_region_init_rom(&s->irom, OBJECT(dev), "irom", NPCM7XX_ROM_SZ,
707 &error_abort);
708 memory_region_add_subregion(get_system_memory(), NPCM7XX_ROM_BA, &s->irom);
709
710 create_unimplemented_device("npcm7xx.shm", 0xc0001000, 4 * KiB);
711 create_unimplemented_device("npcm7xx.vdmx", 0xe0800000, 4 * KiB);
712 create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB);
713 create_unimplemented_device("npcm7xx.kcs", 0xf0007000, 4 * KiB);
2d8f048c 714 create_unimplemented_device("npcm7xx.gfxi", 0xf000e000, 4 * KiB);
2d8f048c
HS
715 create_unimplemented_device("npcm7xx.espi", 0xf009f000, 4 * KiB);
716 create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
717 create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
718 create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
2d8f048c
HS
719 create_unimplemented_device("npcm7xx.pspi1", 0xf0200000, 4 * KiB);
720 create_unimplemented_device("npcm7xx.pspi2", 0xf0201000, 4 * KiB);
721 create_unimplemented_device("npcm7xx.ahbpci", 0xf0400000, 1 * MiB);
722 create_unimplemented_device("npcm7xx.mcphy", 0xf05f0000, 64 * KiB);
723 create_unimplemented_device("npcm7xx.gmac1", 0xf0802000, 8 * KiB);
724 create_unimplemented_device("npcm7xx.gmac2", 0xf0804000, 8 * KiB);
2d8f048c
HS
725 create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
726 create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
727 create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);
2d8f048c
HS
728 create_unimplemented_device("npcm7xx.usbd[0]", 0xf0830000, 4 * KiB);
729 create_unimplemented_device("npcm7xx.usbd[1]", 0xf0831000, 4 * KiB);
730 create_unimplemented_device("npcm7xx.usbd[2]", 0xf0832000, 4 * KiB);
731 create_unimplemented_device("npcm7xx.usbd[3]", 0xf0833000, 4 * KiB);
732 create_unimplemented_device("npcm7xx.usbd[4]", 0xf0834000, 4 * KiB);
733 create_unimplemented_device("npcm7xx.usbd[5]", 0xf0835000, 4 * KiB);
734 create_unimplemented_device("npcm7xx.usbd[6]", 0xf0836000, 4 * KiB);
735 create_unimplemented_device("npcm7xx.usbd[7]", 0xf0837000, 4 * KiB);
736 create_unimplemented_device("npcm7xx.usbd[8]", 0xf0838000, 4 * KiB);
737 create_unimplemented_device("npcm7xx.usbd[9]", 0xf0839000, 4 * KiB);
738 create_unimplemented_device("npcm7xx.sd", 0xf0840000, 8 * KiB);
739 create_unimplemented_device("npcm7xx.mmc", 0xf0842000, 8 * KiB);
740 create_unimplemented_device("npcm7xx.pcimbx", 0xf0848000, 512 * KiB);
741 create_unimplemented_device("npcm7xx.aes", 0xf0858000, 4 * KiB);
742 create_unimplemented_device("npcm7xx.des", 0xf0859000, 4 * KiB);
743 create_unimplemented_device("npcm7xx.sha", 0xf085a000, 4 * KiB);
744 create_unimplemented_device("npcm7xx.secacc", 0xf085b000, 4 * KiB);
745 create_unimplemented_device("npcm7xx.spixcs0", 0xf8000000, 16 * MiB);
746 create_unimplemented_device("npcm7xx.spixcs1", 0xf9000000, 16 * MiB);
747 create_unimplemented_device("npcm7xx.spix", 0xfb001000, 4 * KiB);
748}
749
750static Property npcm7xx_properties[] = {
751 DEFINE_PROP_LINK("dram-mr", NPCM7xxState, dram, TYPE_MEMORY_REGION,
752 MemoryRegion *),
753 DEFINE_PROP_END_OF_LIST(),
754};
755
756static void npcm7xx_class_init(ObjectClass *oc, void *data)
757{
758 DeviceClass *dc = DEVICE_CLASS(oc);
759
760 dc->realize = npcm7xx_realize;
761 dc->user_creatable = false;
762 device_class_set_props(dc, npcm7xx_properties);
763}
764
765static void npcm730_class_init(ObjectClass *oc, void *data)
766{
767 NPCM7xxClass *nc = NPCM7XX_CLASS(oc);
768
769 /* NPCM730 is optimized for data center use, so no graphics, etc. */
770 nc->disabled_modules = 0x00300395;
771 nc->num_cpus = 2;
772}
773
774static void npcm750_class_init(ObjectClass *oc, void *data)
775{
776 NPCM7xxClass *nc = NPCM7XX_CLASS(oc);
777
778 /* NPCM750 has 2 cores and a full set of peripherals */
779 nc->disabled_modules = 0x00000000;
780 nc->num_cpus = 2;
781}
782
783static const TypeInfo npcm7xx_soc_types[] = {
784 {
785 .name = TYPE_NPCM7XX,
786 .parent = TYPE_DEVICE,
787 .instance_size = sizeof(NPCM7xxState),
788 .instance_init = npcm7xx_init,
789 .class_size = sizeof(NPCM7xxClass),
790 .class_init = npcm7xx_class_init,
791 .abstract = true,
792 }, {
793 .name = TYPE_NPCM730,
794 .parent = TYPE_NPCM7XX,
795 .class_init = npcm730_class_init,
796 }, {
797 .name = TYPE_NPCM750,
798 .parent = TYPE_NPCM7XX,
799 .class_init = npcm750_class_init,
800 },
801};
802
803DEFINE_TYPES(npcm7xx_soc_types);
This page took 0.265979 seconds and 4 git commands to generate.