hw/sd: sd: Skip write protect groups check in sd_erase() for high capacity cards
[qemu/ar7.git] / hw / arm / npcm7xx.c
blobf8950f94708d077e4586e002ff8298ed68186618
1 /*
2 * Nuvoton NPCM7xx SoC family.
4 * Copyright 2020 Google LLC
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.
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.
17 #include "qemu/osdep.h"
19 #include "exec/address-spaces.h"
20 #include "hw/arm/boot.h"
21 #include "hw/arm/npcm7xx.h"
22 #include "hw/char/serial.h"
23 #include "hw/loader.h"
24 #include "hw/misc/unimp.h"
25 #include "hw/qdev-clock.h"
26 #include "hw/qdev-properties.h"
27 #include "qapi/error.h"
28 #include "qemu/units.h"
29 #include "sysemu/sysemu.h"
32 * This covers the whole MMIO space. We'll use this to catch any MMIO accesses
33 * that aren't handled by any device.
35 #define NPCM7XX_MMIO_BA (0x80000000)
36 #define NPCM7XX_MMIO_SZ (0x7ffd0000)
38 /* OTP key storage and fuse strap array */
39 #define NPCM7XX_OTP1_BA (0xf0189000)
40 #define NPCM7XX_OTP2_BA (0xf018a000)
42 /* Core system modules. */
43 #define NPCM7XX_L2C_BA (0xf03fc000)
44 #define NPCM7XX_CPUP_BA (0xf03fe000)
45 #define NPCM7XX_GCR_BA (0xf0800000)
46 #define NPCM7XX_CLK_BA (0xf0801000)
47 #define NPCM7XX_MC_BA (0xf0824000)
48 #define NPCM7XX_RNG_BA (0xf000b000)
50 /* USB Host modules */
51 #define NPCM7XX_EHCI_BA (0xf0806000)
52 #define NPCM7XX_OHCI_BA (0xf0807000)
54 /* ADC Module */
55 #define NPCM7XX_ADC_BA (0xf000c000)
57 /* Internal AHB SRAM */
58 #define NPCM7XX_RAM3_BA (0xc0008000)
59 #define NPCM7XX_RAM3_SZ (4 * KiB)
61 /* Memory blocks at the end of the address space */
62 #define NPCM7XX_RAM2_BA (0xfffd0000)
63 #define NPCM7XX_RAM2_SZ (128 * KiB)
64 #define NPCM7XX_ROM_BA (0xffff0000)
65 #define NPCM7XX_ROM_SZ (64 * KiB)
68 /* Clock configuration values to be fixed up when bypassing bootloader */
70 /* Run PLL1 at 1600 MHz */
71 #define NPCM7XX_PLLCON1_FIXUP_VAL (0x00402101)
72 /* Run the CPU from PLL1 and UART from PLL2 */
73 #define NPCM7XX_CLKSEL_FIXUP_VAL (0x004aaba9)
76 * Interrupt lines going into the GIC. This does not include internal Cortex-A9
77 * interrupts.
79 enum NPCM7xxInterrupt {
80 NPCM7XX_ADC_IRQ = 0,
81 NPCM7XX_UART0_IRQ = 2,
82 NPCM7XX_UART1_IRQ,
83 NPCM7XX_UART2_IRQ,
84 NPCM7XX_UART3_IRQ,
85 NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
86 NPCM7XX_TIMER1_IRQ,
87 NPCM7XX_TIMER2_IRQ,
88 NPCM7XX_TIMER3_IRQ,
89 NPCM7XX_TIMER4_IRQ,
90 NPCM7XX_TIMER5_IRQ, /* Timer Module 1 */
91 NPCM7XX_TIMER6_IRQ,
92 NPCM7XX_TIMER7_IRQ,
93 NPCM7XX_TIMER8_IRQ,
94 NPCM7XX_TIMER9_IRQ,
95 NPCM7XX_TIMER10_IRQ, /* Timer Module 2 */
96 NPCM7XX_TIMER11_IRQ,
97 NPCM7XX_TIMER12_IRQ,
98 NPCM7XX_TIMER13_IRQ,
99 NPCM7XX_TIMER14_IRQ,
100 NPCM7XX_WDG0_IRQ = 47, /* Timer Module 0 Watchdog */
101 NPCM7XX_WDG1_IRQ, /* Timer Module 1 Watchdog */
102 NPCM7XX_WDG2_IRQ, /* Timer Module 2 Watchdog */
103 NPCM7XX_EHCI_IRQ = 61,
104 NPCM7XX_OHCI_IRQ = 62,
105 NPCM7XX_SMBUS0_IRQ = 64,
106 NPCM7XX_SMBUS1_IRQ,
107 NPCM7XX_SMBUS2_IRQ,
108 NPCM7XX_SMBUS3_IRQ,
109 NPCM7XX_SMBUS4_IRQ,
110 NPCM7XX_SMBUS5_IRQ,
111 NPCM7XX_SMBUS6_IRQ,
112 NPCM7XX_SMBUS7_IRQ,
113 NPCM7XX_SMBUS8_IRQ,
114 NPCM7XX_SMBUS9_IRQ,
115 NPCM7XX_SMBUS10_IRQ,
116 NPCM7XX_SMBUS11_IRQ,
117 NPCM7XX_SMBUS12_IRQ,
118 NPCM7XX_SMBUS13_IRQ,
119 NPCM7XX_SMBUS14_IRQ,
120 NPCM7XX_SMBUS15_IRQ,
121 NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
122 NPCM7XX_PWM1_IRQ, /* PWM module 1 */
123 NPCM7XX_GPIO0_IRQ = 116,
124 NPCM7XX_GPIO1_IRQ,
125 NPCM7XX_GPIO2_IRQ,
126 NPCM7XX_GPIO3_IRQ,
127 NPCM7XX_GPIO4_IRQ,
128 NPCM7XX_GPIO5_IRQ,
129 NPCM7XX_GPIO6_IRQ,
130 NPCM7XX_GPIO7_IRQ,
133 /* Total number of GIC interrupts, including internal Cortex-A9 interrupts. */
134 #define NPCM7XX_NUM_IRQ (160)
136 /* Register base address for each Timer Module */
137 static const hwaddr npcm7xx_tim_addr[] = {
138 0xf0008000,
139 0xf0009000,
140 0xf000a000,
143 /* Register base address for each 16550 UART */
144 static const hwaddr npcm7xx_uart_addr[] = {
145 0xf0001000,
146 0xf0002000,
147 0xf0003000,
148 0xf0004000,
151 /* Direct memory-mapped access to SPI0 CS0-1. */
152 static const hwaddr npcm7xx_fiu0_flash_addr[] = {
153 0x80000000, /* CS0 */
154 0x88000000, /* CS1 */
157 /* Direct memory-mapped access to SPI3 CS0-3. */
158 static const hwaddr npcm7xx_fiu3_flash_addr[] = {
159 0xa0000000, /* CS0 */
160 0xa8000000, /* CS1 */
161 0xb0000000, /* CS2 */
162 0xb8000000, /* CS3 */
165 /* Register base address for each PWM Module */
166 static const hwaddr npcm7xx_pwm_addr[] = {
167 0xf0103000,
168 0xf0104000,
171 /* Direct memory-mapped access to each SMBus Module. */
172 static const hwaddr npcm7xx_smbus_addr[] = {
173 0xf0080000,
174 0xf0081000,
175 0xf0082000,
176 0xf0083000,
177 0xf0084000,
178 0xf0085000,
179 0xf0086000,
180 0xf0087000,
181 0xf0088000,
182 0xf0089000,
183 0xf008a000,
184 0xf008b000,
185 0xf008c000,
186 0xf008d000,
187 0xf008e000,
188 0xf008f000,
191 static const struct {
192 hwaddr regs_addr;
193 uint32_t unconnected_pins;
194 uint32_t reset_pu;
195 uint32_t reset_pd;
196 uint32_t reset_osrc;
197 uint32_t reset_odsc;
198 } npcm7xx_gpio[] = {
200 .regs_addr = 0xf0010000,
201 .reset_pu = 0xff03ffff,
202 .reset_pd = 0x00fc0000,
203 }, {
204 .regs_addr = 0xf0011000,
205 .unconnected_pins = 0x0000001e,
206 .reset_pu = 0xfefffe07,
207 .reset_pd = 0x010001e0,
208 }, {
209 .regs_addr = 0xf0012000,
210 .reset_pu = 0x780fffff,
211 .reset_pd = 0x07f00000,
212 .reset_odsc = 0x00700000,
213 }, {
214 .regs_addr = 0xf0013000,
215 .reset_pu = 0x00fc0000,
216 .reset_pd = 0xff000000,
217 }, {
218 .regs_addr = 0xf0014000,
219 .reset_pu = 0xffffffff,
220 }, {
221 .regs_addr = 0xf0015000,
222 .reset_pu = 0xbf83f801,
223 .reset_pd = 0x007c0000,
224 .reset_osrc = 0x000000f1,
225 .reset_odsc = 0x3f9f80f1,
226 }, {
227 .regs_addr = 0xf0016000,
228 .reset_pu = 0xfc00f801,
229 .reset_pd = 0x000007fe,
230 .reset_odsc = 0x00000800,
231 }, {
232 .regs_addr = 0xf0017000,
233 .unconnected_pins = 0xffffff00,
234 .reset_pu = 0x0000007f,
235 .reset_osrc = 0x0000007f,
236 .reset_odsc = 0x0000007f,
240 static const struct {
241 const char *name;
242 hwaddr regs_addr;
243 int cs_count;
244 const hwaddr *flash_addr;
245 } npcm7xx_fiu[] = {
247 .name = "fiu0",
248 .regs_addr = 0xfb000000,
249 .cs_count = ARRAY_SIZE(npcm7xx_fiu0_flash_addr),
250 .flash_addr = npcm7xx_fiu0_flash_addr,
251 }, {
252 .name = "fiu3",
253 .regs_addr = 0xc0000000,
254 .cs_count = ARRAY_SIZE(npcm7xx_fiu3_flash_addr),
255 .flash_addr = npcm7xx_fiu3_flash_addr,
259 static void npcm7xx_write_board_setup(ARMCPU *cpu,
260 const struct arm_boot_info *info)
262 uint32_t board_setup[] = {
263 0xe59f0010, /* ldr r0, clk_base_addr */
264 0xe59f1010, /* ldr r1, pllcon1_value */
265 0xe5801010, /* str r1, [r0, #16] */
266 0xe59f100c, /* ldr r1, clksel_value */
267 0xe5801004, /* str r1, [r0, #4] */
268 0xe12fff1e, /* bx lr */
269 NPCM7XX_CLK_BA,
270 NPCM7XX_PLLCON1_FIXUP_VAL,
271 NPCM7XX_CLKSEL_FIXUP_VAL,
273 int i;
275 for (i = 0; i < ARRAY_SIZE(board_setup); i++) {
276 board_setup[i] = tswap32(board_setup[i]);
278 rom_add_blob_fixed("board-setup", board_setup, sizeof(board_setup),
279 info->board_setup_addr);
282 static void npcm7xx_write_secondary_boot(ARMCPU *cpu,
283 const struct arm_boot_info *info)
286 * The default smpboot stub halts the secondary CPU with a 'wfi'
287 * instruction, but the arch/arm/mach-npcm/platsmp.c in the Linux kernel
288 * does not send an IPI to wake it up, so the second CPU fails to boot. So
289 * we need to provide our own smpboot stub that can not use 'wfi', it has
290 * to spin the secondary CPU until the first CPU writes to the SCRPAD reg.
292 uint32_t smpboot[] = {
293 0xe59f2018, /* ldr r2, bootreg_addr */
294 0xe3a00000, /* mov r0, #0 */
295 0xe5820000, /* str r0, [r2] */
296 0xe320f002, /* wfe */
297 0xe5921000, /* ldr r1, [r2] */
298 0xe1110001, /* tst r1, r1 */
299 0x0afffffb, /* beq <wfe> */
300 0xe12fff11, /* bx r1 */
301 NPCM7XX_SMP_BOOTREG_ADDR,
303 int i;
305 for (i = 0; i < ARRAY_SIZE(smpboot); i++) {
306 smpboot[i] = tswap32(smpboot[i]);
309 rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
310 NPCM7XX_SMP_LOADER_START);
313 static struct arm_boot_info npcm7xx_binfo = {
314 .loader_start = NPCM7XX_LOADER_START,
315 .smp_loader_start = NPCM7XX_SMP_LOADER_START,
316 .smp_bootreg_addr = NPCM7XX_SMP_BOOTREG_ADDR,
317 .gic_cpu_if_addr = NPCM7XX_GIC_CPU_IF_ADDR,
318 .write_secondary_boot = npcm7xx_write_secondary_boot,
319 .board_id = -1,
320 .board_setup_addr = NPCM7XX_BOARD_SETUP_ADDR,
321 .write_board_setup = npcm7xx_write_board_setup,
324 void npcm7xx_load_kernel(MachineState *machine, NPCM7xxState *soc)
326 NPCM7xxClass *sc = NPCM7XX_GET_CLASS(soc);
328 npcm7xx_binfo.ram_size = machine->ram_size;
329 npcm7xx_binfo.nb_cpus = sc->num_cpus;
331 arm_load_kernel(&soc->cpu[0], machine, &npcm7xx_binfo);
334 static void npcm7xx_init_fuses(NPCM7xxState *s)
336 NPCM7xxClass *nc = NPCM7XX_GET_CLASS(s);
337 uint32_t value;
340 * The initial mask of disabled modules indicates the chip derivative (e.g.
341 * NPCM750 or NPCM730).
343 value = tswap32(nc->disabled_modules);
344 npcm7xx_otp_array_write(&s->fuse_array, &value, NPCM7XX_FUSE_DERIVATIVE,
345 sizeof(value));
348 static void npcm7xx_write_adc_calibration(NPCM7xxState *s)
350 /* Both ADC and the fuse array must have realized. */
351 QEMU_BUILD_BUG_ON(sizeof(s->adc.calibration_r_values) != 4);
352 npcm7xx_otp_array_write(&s->fuse_array, s->adc.calibration_r_values,
353 NPCM7XX_FUSE_ADC_CALIB, sizeof(s->adc.calibration_r_values));
356 static qemu_irq npcm7xx_irq(NPCM7xxState *s, int n)
358 return qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
361 static void npcm7xx_init(Object *obj)
363 NPCM7xxState *s = NPCM7XX(obj);
364 int i;
366 for (i = 0; i < NPCM7XX_MAX_NUM_CPUS; i++) {
367 object_initialize_child(obj, "cpu[*]", &s->cpu[i],
368 ARM_CPU_TYPE_NAME("cortex-a9"));
371 object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
372 object_initialize_child(obj, "gcr", &s->gcr, TYPE_NPCM7XX_GCR);
373 object_property_add_alias(obj, "power-on-straps", OBJECT(&s->gcr),
374 "power-on-straps");
375 object_initialize_child(obj, "clk", &s->clk, TYPE_NPCM7XX_CLK);
376 object_initialize_child(obj, "otp1", &s->key_storage,
377 TYPE_NPCM7XX_KEY_STORAGE);
378 object_initialize_child(obj, "otp2", &s->fuse_array,
379 TYPE_NPCM7XX_FUSE_ARRAY);
380 object_initialize_child(obj, "mc", &s->mc, TYPE_NPCM7XX_MC);
381 object_initialize_child(obj, "rng", &s->rng, TYPE_NPCM7XX_RNG);
382 object_initialize_child(obj, "adc", &s->adc, TYPE_NPCM7XX_ADC);
384 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
385 object_initialize_child(obj, "tim[*]", &s->tim[i], TYPE_NPCM7XX_TIMER);
388 for (i = 0; i < ARRAY_SIZE(s->gpio); i++) {
389 object_initialize_child(obj, "gpio[*]", &s->gpio[i], TYPE_NPCM7XX_GPIO);
392 for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
393 object_initialize_child(obj, "smbus[*]", &s->smbus[i],
394 TYPE_NPCM7XX_SMBUS);
397 object_initialize_child(obj, "ehci", &s->ehci, TYPE_NPCM7XX_EHCI);
398 object_initialize_child(obj, "ohci", &s->ohci, TYPE_SYSBUS_OHCI);
400 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
401 for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
402 object_initialize_child(obj, npcm7xx_fiu[i].name, &s->fiu[i],
403 TYPE_NPCM7XX_FIU);
406 for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
407 object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
411 static void npcm7xx_realize(DeviceState *dev, Error **errp)
413 NPCM7xxState *s = NPCM7XX(dev);
414 NPCM7xxClass *nc = NPCM7XX_GET_CLASS(s);
415 int i;
417 if (memory_region_size(s->dram) > NPCM7XX_DRAM_SZ) {
418 error_setg(errp, "%s: NPCM7xx cannot address more than %" PRIu64
419 " MiB of DRAM", __func__, NPCM7XX_DRAM_SZ / MiB);
420 return;
423 /* CPUs */
424 for (i = 0; i < nc->num_cpus; i++) {
425 object_property_set_int(OBJECT(&s->cpu[i]), "mp-affinity",
426 arm_cpu_mp_affinity(i, NPCM7XX_MAX_NUM_CPUS),
427 &error_abort);
428 object_property_set_int(OBJECT(&s->cpu[i]), "reset-cbar",
429 NPCM7XX_GIC_CPU_IF_ADDR, &error_abort);
430 object_property_set_bool(OBJECT(&s->cpu[i]), "reset-hivecs", true,
431 &error_abort);
433 /* Disable security extensions. */
434 object_property_set_bool(OBJECT(&s->cpu[i]), "has_el3", false,
435 &error_abort);
437 if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
438 return;
442 /* A9MPCORE peripherals. Can only fail if we pass bad parameters here. */
443 object_property_set_int(OBJECT(&s->a9mpcore), "num-cpu", nc->num_cpus,
444 &error_abort);
445 object_property_set_int(OBJECT(&s->a9mpcore), "num-irq", NPCM7XX_NUM_IRQ,
446 &error_abort);
447 sysbus_realize(SYS_BUS_DEVICE(&s->a9mpcore), &error_abort);
448 sysbus_mmio_map(SYS_BUS_DEVICE(&s->a9mpcore), 0, NPCM7XX_CPUP_BA);
450 for (i = 0; i < nc->num_cpus; i++) {
451 sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i,
452 qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_IRQ));
453 sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i + nc->num_cpus,
454 qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_FIQ));
457 /* L2 cache controller */
458 sysbus_create_simple("l2x0", NPCM7XX_L2C_BA, NULL);
460 /* System Global Control Registers (GCR). Can fail due to user input. */
461 object_property_set_int(OBJECT(&s->gcr), "disabled-modules",
462 nc->disabled_modules, &error_abort);
463 object_property_add_const_link(OBJECT(&s->gcr), "dram-mr", OBJECT(s->dram));
464 if (!sysbus_realize(SYS_BUS_DEVICE(&s->gcr), errp)) {
465 return;
467 sysbus_mmio_map(SYS_BUS_DEVICE(&s->gcr), 0, NPCM7XX_GCR_BA);
469 /* Clock Control Registers (CLK). Cannot fail. */
470 sysbus_realize(SYS_BUS_DEVICE(&s->clk), &error_abort);
471 sysbus_mmio_map(SYS_BUS_DEVICE(&s->clk), 0, NPCM7XX_CLK_BA);
473 /* OTP key storage and fuse strap array. Cannot fail. */
474 sysbus_realize(SYS_BUS_DEVICE(&s->key_storage), &error_abort);
475 sysbus_mmio_map(SYS_BUS_DEVICE(&s->key_storage), 0, NPCM7XX_OTP1_BA);
476 sysbus_realize(SYS_BUS_DEVICE(&s->fuse_array), &error_abort);
477 sysbus_mmio_map(SYS_BUS_DEVICE(&s->fuse_array), 0, NPCM7XX_OTP2_BA);
478 npcm7xx_init_fuses(s);
480 /* Fake Memory Controller (MC). Cannot fail. */
481 sysbus_realize(SYS_BUS_DEVICE(&s->mc), &error_abort);
482 sysbus_mmio_map(SYS_BUS_DEVICE(&s->mc), 0, NPCM7XX_MC_BA);
484 /* ADC Modules. Cannot fail. */
485 qdev_connect_clock_in(DEVICE(&s->adc), "clock", qdev_get_clock_out(
486 DEVICE(&s->clk), "adc-clock"));
487 sysbus_realize(SYS_BUS_DEVICE(&s->adc), &error_abort);
488 sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, NPCM7XX_ADC_BA);
489 sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
490 npcm7xx_irq(s, NPCM7XX_ADC_IRQ));
491 npcm7xx_write_adc_calibration(s);
493 /* Timer Modules (TIM). Cannot fail. */
494 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_tim_addr) != ARRAY_SIZE(s->tim));
495 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
496 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->tim[i]);
497 int first_irq;
498 int j;
500 /* Connect the timer clock. */
501 qdev_connect_clock_in(DEVICE(&s->tim[i]), "clock", qdev_get_clock_out(
502 DEVICE(&s->clk), "timer-clock"));
504 sysbus_realize(sbd, &error_abort);
505 sysbus_mmio_map(sbd, 0, npcm7xx_tim_addr[i]);
507 first_irq = NPCM7XX_TIMER0_IRQ + i * NPCM7XX_TIMERS_PER_CTRL;
508 for (j = 0; j < NPCM7XX_TIMERS_PER_CTRL; j++) {
509 qemu_irq irq = npcm7xx_irq(s, first_irq + j);
510 sysbus_connect_irq(sbd, j, irq);
513 /* IRQ for watchdogs */
514 sysbus_connect_irq(sbd, NPCM7XX_TIMERS_PER_CTRL,
515 npcm7xx_irq(s, NPCM7XX_WDG0_IRQ + i));
516 /* GPIO that connects clk module with watchdog */
517 qdev_connect_gpio_out_named(DEVICE(&s->tim[i]),
518 NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 0,
519 qdev_get_gpio_in_named(DEVICE(&s->clk),
520 NPCM7XX_WATCHDOG_RESET_GPIO_IN, i));
523 /* UART0..3 (16550 compatible) */
524 for (i = 0; i < ARRAY_SIZE(npcm7xx_uart_addr); i++) {
525 serial_mm_init(get_system_memory(), npcm7xx_uart_addr[i], 2,
526 npcm7xx_irq(s, NPCM7XX_UART0_IRQ + i), 115200,
527 serial_hd(i), DEVICE_LITTLE_ENDIAN);
530 /* Random Number Generator. Cannot fail. */
531 sysbus_realize(SYS_BUS_DEVICE(&s->rng), &error_abort);
532 sysbus_mmio_map(SYS_BUS_DEVICE(&s->rng), 0, NPCM7XX_RNG_BA);
534 /* GPIO modules. Cannot fail. */
535 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_gpio) != ARRAY_SIZE(s->gpio));
536 for (i = 0; i < ARRAY_SIZE(s->gpio); i++) {
537 Object *obj = OBJECT(&s->gpio[i]);
539 object_property_set_uint(obj, "reset-pullup",
540 npcm7xx_gpio[i].reset_pu, &error_abort);
541 object_property_set_uint(obj, "reset-pulldown",
542 npcm7xx_gpio[i].reset_pd, &error_abort);
543 object_property_set_uint(obj, "reset-osrc",
544 npcm7xx_gpio[i].reset_osrc, &error_abort);
545 object_property_set_uint(obj, "reset-odsc",
546 npcm7xx_gpio[i].reset_odsc, &error_abort);
547 sysbus_realize(SYS_BUS_DEVICE(obj), &error_abort);
548 sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm7xx_gpio[i].regs_addr);
549 sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0,
550 npcm7xx_irq(s, NPCM7XX_GPIO0_IRQ + i));
553 /* SMBus modules. Cannot fail. */
554 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_smbus_addr) != ARRAY_SIZE(s->smbus));
555 for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
556 Object *obj = OBJECT(&s->smbus[i]);
558 sysbus_realize(SYS_BUS_DEVICE(obj), &error_abort);
559 sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm7xx_smbus_addr[i]);
560 sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0,
561 npcm7xx_irq(s, NPCM7XX_SMBUS0_IRQ + i));
564 /* USB Host */
565 object_property_set_bool(OBJECT(&s->ehci), "companion-enable", true,
566 &error_abort);
567 sysbus_realize(SYS_BUS_DEVICE(&s->ehci), &error_abort);
568 sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci), 0, NPCM7XX_EHCI_BA);
569 sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci), 0,
570 npcm7xx_irq(s, NPCM7XX_EHCI_IRQ));
572 object_property_set_str(OBJECT(&s->ohci), "masterbus", "usb-bus.0",
573 &error_abort);
574 object_property_set_uint(OBJECT(&s->ohci), "num-ports", 1, &error_abort);
575 sysbus_realize(SYS_BUS_DEVICE(&s->ohci), &error_abort);
576 sysbus_mmio_map(SYS_BUS_DEVICE(&s->ohci), 0, NPCM7XX_OHCI_BA);
577 sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci), 0,
578 npcm7xx_irq(s, NPCM7XX_OHCI_IRQ));
580 /* PWM Modules. Cannot fail. */
581 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pwm_addr) != ARRAY_SIZE(s->pwm));
582 for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
583 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->pwm[i]);
585 qdev_connect_clock_in(DEVICE(&s->pwm[i]), "clock", qdev_get_clock_out(
586 DEVICE(&s->clk), "apb3-clock"));
587 sysbus_realize(sbd, &error_abort);
588 sysbus_mmio_map(sbd, 0, npcm7xx_pwm_addr[i]);
589 sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
593 * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
594 * specified, but this is a programming error.
596 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
597 for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
598 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->fiu[i]);
599 int j;
601 object_property_set_int(OBJECT(sbd), "cs-count",
602 npcm7xx_fiu[i].cs_count, &error_abort);
603 sysbus_realize(sbd, &error_abort);
605 sysbus_mmio_map(sbd, 0, npcm7xx_fiu[i].regs_addr);
606 for (j = 0; j < npcm7xx_fiu[i].cs_count; j++) {
607 sysbus_mmio_map(sbd, j + 1, npcm7xx_fiu[i].flash_addr[j]);
611 /* RAM2 (SRAM) */
612 memory_region_init_ram(&s->sram, OBJECT(dev), "ram2",
613 NPCM7XX_RAM2_SZ, &error_abort);
614 memory_region_add_subregion(get_system_memory(), NPCM7XX_RAM2_BA, &s->sram);
616 /* RAM3 (SRAM) */
617 memory_region_init_ram(&s->ram3, OBJECT(dev), "ram3",
618 NPCM7XX_RAM3_SZ, &error_abort);
619 memory_region_add_subregion(get_system_memory(), NPCM7XX_RAM3_BA, &s->ram3);
621 /* Internal ROM */
622 memory_region_init_rom(&s->irom, OBJECT(dev), "irom", NPCM7XX_ROM_SZ,
623 &error_abort);
624 memory_region_add_subregion(get_system_memory(), NPCM7XX_ROM_BA, &s->irom);
626 create_unimplemented_device("npcm7xx.shm", 0xc0001000, 4 * KiB);
627 create_unimplemented_device("npcm7xx.vdmx", 0xe0800000, 4 * KiB);
628 create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB);
629 create_unimplemented_device("npcm7xx.kcs", 0xf0007000, 4 * KiB);
630 create_unimplemented_device("npcm7xx.gfxi", 0xf000e000, 4 * KiB);
631 create_unimplemented_device("npcm7xx.espi", 0xf009f000, 4 * KiB);
632 create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
633 create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
634 create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
635 create_unimplemented_device("npcm7xx.mft[0]", 0xf0180000, 4 * KiB);
636 create_unimplemented_device("npcm7xx.mft[1]", 0xf0181000, 4 * KiB);
637 create_unimplemented_device("npcm7xx.mft[2]", 0xf0182000, 4 * KiB);
638 create_unimplemented_device("npcm7xx.mft[3]", 0xf0183000, 4 * KiB);
639 create_unimplemented_device("npcm7xx.mft[4]", 0xf0184000, 4 * KiB);
640 create_unimplemented_device("npcm7xx.mft[5]", 0xf0185000, 4 * KiB);
641 create_unimplemented_device("npcm7xx.mft[6]", 0xf0186000, 4 * KiB);
642 create_unimplemented_device("npcm7xx.mft[7]", 0xf0187000, 4 * KiB);
643 create_unimplemented_device("npcm7xx.pspi1", 0xf0200000, 4 * KiB);
644 create_unimplemented_device("npcm7xx.pspi2", 0xf0201000, 4 * KiB);
645 create_unimplemented_device("npcm7xx.ahbpci", 0xf0400000, 1 * MiB);
646 create_unimplemented_device("npcm7xx.mcphy", 0xf05f0000, 64 * KiB);
647 create_unimplemented_device("npcm7xx.gmac1", 0xf0802000, 8 * KiB);
648 create_unimplemented_device("npcm7xx.gmac2", 0xf0804000, 8 * KiB);
649 create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
650 create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
651 create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);
652 create_unimplemented_device("npcm7xx.emc1", 0xf0825000, 4 * KiB);
653 create_unimplemented_device("npcm7xx.emc2", 0xf0826000, 4 * KiB);
654 create_unimplemented_device("npcm7xx.usbd[0]", 0xf0830000, 4 * KiB);
655 create_unimplemented_device("npcm7xx.usbd[1]", 0xf0831000, 4 * KiB);
656 create_unimplemented_device("npcm7xx.usbd[2]", 0xf0832000, 4 * KiB);
657 create_unimplemented_device("npcm7xx.usbd[3]", 0xf0833000, 4 * KiB);
658 create_unimplemented_device("npcm7xx.usbd[4]", 0xf0834000, 4 * KiB);
659 create_unimplemented_device("npcm7xx.usbd[5]", 0xf0835000, 4 * KiB);
660 create_unimplemented_device("npcm7xx.usbd[6]", 0xf0836000, 4 * KiB);
661 create_unimplemented_device("npcm7xx.usbd[7]", 0xf0837000, 4 * KiB);
662 create_unimplemented_device("npcm7xx.usbd[8]", 0xf0838000, 4 * KiB);
663 create_unimplemented_device("npcm7xx.usbd[9]", 0xf0839000, 4 * KiB);
664 create_unimplemented_device("npcm7xx.sd", 0xf0840000, 8 * KiB);
665 create_unimplemented_device("npcm7xx.mmc", 0xf0842000, 8 * KiB);
666 create_unimplemented_device("npcm7xx.pcimbx", 0xf0848000, 512 * KiB);
667 create_unimplemented_device("npcm7xx.aes", 0xf0858000, 4 * KiB);
668 create_unimplemented_device("npcm7xx.des", 0xf0859000, 4 * KiB);
669 create_unimplemented_device("npcm7xx.sha", 0xf085a000, 4 * KiB);
670 create_unimplemented_device("npcm7xx.secacc", 0xf085b000, 4 * KiB);
671 create_unimplemented_device("npcm7xx.spixcs0", 0xf8000000, 16 * MiB);
672 create_unimplemented_device("npcm7xx.spixcs1", 0xf9000000, 16 * MiB);
673 create_unimplemented_device("npcm7xx.spix", 0xfb001000, 4 * KiB);
676 static Property npcm7xx_properties[] = {
677 DEFINE_PROP_LINK("dram-mr", NPCM7xxState, dram, TYPE_MEMORY_REGION,
678 MemoryRegion *),
679 DEFINE_PROP_END_OF_LIST(),
682 static void npcm7xx_class_init(ObjectClass *oc, void *data)
684 DeviceClass *dc = DEVICE_CLASS(oc);
686 dc->realize = npcm7xx_realize;
687 dc->user_creatable = false;
688 device_class_set_props(dc, npcm7xx_properties);
691 static void npcm730_class_init(ObjectClass *oc, void *data)
693 NPCM7xxClass *nc = NPCM7XX_CLASS(oc);
695 /* NPCM730 is optimized for data center use, so no graphics, etc. */
696 nc->disabled_modules = 0x00300395;
697 nc->num_cpus = 2;
700 static void npcm750_class_init(ObjectClass *oc, void *data)
702 NPCM7xxClass *nc = NPCM7XX_CLASS(oc);
704 /* NPCM750 has 2 cores and a full set of peripherals */
705 nc->disabled_modules = 0x00000000;
706 nc->num_cpus = 2;
709 static const TypeInfo npcm7xx_soc_types[] = {
711 .name = TYPE_NPCM7XX,
712 .parent = TYPE_DEVICE,
713 .instance_size = sizeof(NPCM7xxState),
714 .instance_init = npcm7xx_init,
715 .class_size = sizeof(NPCM7xxClass),
716 .class_init = npcm7xx_class_init,
717 .abstract = true,
718 }, {
719 .name = TYPE_NPCM730,
720 .parent = TYPE_NPCM7XX,
721 .class_init = npcm730_class_init,
722 }, {
723 .name = TYPE_NPCM750,
724 .parent = TYPE_NPCM7XX,
725 .class_init = npcm750_class_init,
729 DEFINE_TYPES(npcm7xx_soc_types);