1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include "qemu/osdep.h"
18
19#include "hw/arm/npcm7xx.h"
20#include "hw/core/cpu.h"
21#include "hw/i2c/i2c_mux_pca954x.h"
22#include "hw/i2c/smbus_eeprom.h"
23#include "hw/loader.h"
24#include "hw/qdev-core.h"
25#include "hw/qdev-properties.h"
26#include "qapi/error.h"
27#include "qemu-common.h"
28#include "qemu/datadir.h"
29#include "qemu/units.h"
30
31#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
32#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
33#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
34
35static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
36
37static void npcm7xx_load_bootrom(MachineState *machine, NPCM7xxState *soc)
38{
39 const char *bios_name = machine->firmware ?: npcm7xx_default_bootrom;
40 g_autofree char *filename = NULL;
41 int ret;
42
43 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
44 if (!filename) {
45 error_report("Could not find ROM image '%s'", bios_name);
46 if (!machine->kernel_filename) {
47
48 exit(1);
49 }
50 return;
51 }
52 ret = load_image_mr(filename, &soc->irom);
53 if (ret < 0) {
54 error_report("Failed to load ROM image '%s'", filename);
55 exit(1);
56 }
57}
58
59static void npcm7xx_connect_flash(NPCM7xxFIUState *fiu, int cs_no,
60 const char *flash_type, DriveInfo *dinfo)
61{
62 DeviceState *flash;
63 qemu_irq flash_cs;
64
65 flash = qdev_new(flash_type);
66 if (dinfo) {
67 qdev_prop_set_drive(flash, "drive", blk_by_legacy_dinfo(dinfo));
68 }
69 qdev_realize_and_unref(flash, BUS(fiu->spi), &error_fatal);
70
71 flash_cs = qdev_get_gpio_in_named(flash, SSI_GPIO_CS, 0);
72 qdev_connect_gpio_out_named(DEVICE(fiu), "cs", cs_no, flash_cs);
73}
74
75static void npcm7xx_connect_dram(NPCM7xxState *soc, MemoryRegion *dram)
76{
77 memory_region_add_subregion(get_system_memory(), NPCM7XX_DRAM_BA, dram);
78
79 object_property_set_link(OBJECT(soc), "dram-mr", OBJECT(dram),
80 &error_abort);
81}
82
83static NPCM7xxState *npcm7xx_create_soc(MachineState *machine,
84 uint32_t hw_straps)
85{
86 NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_GET_CLASS(machine);
87 MachineClass *mc = MACHINE_CLASS(nmc);
88 Object *obj;
89
90 if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
91 error_report("This board can only be used with %s",
92 mc->default_cpu_type);
93 exit(1);
94 }
95
96 obj = object_new_with_props(nmc->soc_type, OBJECT(machine), "soc",
97 &error_abort, NULL);
98 object_property_set_uint(obj, "power-on-straps", hw_straps, &error_abort);
99
100 return NPCM7XX(obj);
101}
102
103static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, uint32_t num)
104{
105 g_assert(num < ARRAY_SIZE(soc->smbus));
106 return I2C_BUS(qdev_get_child_bus(DEVICE(&soc->smbus[num]), "i2c-bus"));
107}
108
109static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
110 uint32_t rsize)
111{
112 I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
113 I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
114 DeviceState *dev = DEVICE(i2c_dev);
115
116 qdev_prop_set_uint32(dev, "rom-size", rsize);
117 i2c_slave_realize_and_unref(i2c_dev, i2c_bus, &error_abort);
118}
119
120static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
121 NPCM7xxState *soc, const int *fan_counts)
122{
123 SplitIRQ *splitters = machine->fan_splitter;
124
125
126
127
128
129 for (int i = 0; i < NPCM7XX_NR_PWM_MODULES; ++i) {
130 for (int j = 0; j < NPCM7XX_PWM_PER_MODULE; ++j) {
131 int splitter_no = i * NPCM7XX_PWM_PER_MODULE + j;
132 DeviceState *splitter;
133
134 if (fan_counts[splitter_no] < 1) {
135 continue;
136 }
137 object_initialize_child(OBJECT(machine), "fan-splitter[*]",
138 &splitters[splitter_no], TYPE_SPLIT_IRQ);
139 splitter = DEVICE(&splitters[splitter_no]);
140 qdev_prop_set_uint16(splitter, "num-lines",
141 fan_counts[splitter_no]);
142 qdev_realize(splitter, NULL, &error_abort);
143 qdev_connect_gpio_out_named(DEVICE(&soc->pwm[i]), "duty-gpio-out",
144 j, qdev_get_gpio_in(splitter, 0));
145 }
146 }
147}
148
149static void npcm7xx_connect_pwm_fan(NPCM7xxState *soc, SplitIRQ *splitter,
150 int fan_no, int output_no)
151{
152 DeviceState *fan;
153 int fan_input;
154 qemu_irq fan_duty_gpio;
155
156 g_assert(fan_no >= 0 && fan_no <= NPCM7XX_MFT_MAX_FAN_INPUT);
157
158
159
160
161
162
163
164
165 if (fan_no < 16) {
166 fan = DEVICE(&soc->mft[fan_no / 2]);
167 fan_input = fan_no % 2;
168 } else {
169 fan = DEVICE(&soc->mft[(fan_no - 16) / 2]);
170 fan_input = fan_no % 2 + 2;
171 }
172
173
174 fan_duty_gpio = qdev_get_gpio_in_named(fan, "duty", fan_input);
175 qdev_connect_gpio_out(DEVICE(splitter), output_no, fan_duty_gpio);
176}
177
178static void npcm750_evb_i2c_init(NPCM7xxState *soc)
179{
180
181 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 0), "tmp105", 0x48);
182
183 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x48);
184
185 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x48);
186
187 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
188}
189
190static void npcm750_evb_fan_init(NPCM7xxMachine *machine, NPCM7xxState *soc)
191{
192 SplitIRQ *splitter = machine->fan_splitter;
193 static const int fan_counts[] = {2, 2, 2, 2, 2, 2, 2, 2};
194
195 npcm7xx_init_pwm_splitter(machine, soc, fan_counts);
196 npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x00, 0);
197 npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x01, 1);
198 npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x02, 0);
199 npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x03, 1);
200 npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x04, 0);
201 npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x05, 1);
202 npcm7xx_connect_pwm_fan(soc, &splitter[3], 0x06, 0);
203 npcm7xx_connect_pwm_fan(soc, &splitter[3], 0x07, 1);
204 npcm7xx_connect_pwm_fan(soc, &splitter[4], 0x08, 0);
205 npcm7xx_connect_pwm_fan(soc, &splitter[4], 0x09, 1);
206 npcm7xx_connect_pwm_fan(soc, &splitter[5], 0x0a, 0);
207 npcm7xx_connect_pwm_fan(soc, &splitter[5], 0x0b, 1);
208 npcm7xx_connect_pwm_fan(soc, &splitter[6], 0x0c, 0);
209 npcm7xx_connect_pwm_fan(soc, &splitter[6], 0x0d, 1);
210 npcm7xx_connect_pwm_fan(soc, &splitter[7], 0x0e, 0);
211 npcm7xx_connect_pwm_fan(soc, &splitter[7], 0x0f, 1);
212}
213
214static void quanta_gsj_i2c_init(NPCM7xxState *soc)
215{
216
217 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x5c);
218 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x5c);
219 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
220 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
221
222 at24c_eeprom_init(soc, 9, 0x55, 8192);
223 at24c_eeprom_init(soc, 10, 0x55, 8192);
224
225
226
227
228
229
230
231
232
233
234
235
236 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 15), "pca9548", 0x75);
237}
238
239static void quanta_gsj_fan_init(NPCM7xxMachine *machine, NPCM7xxState *soc)
240{
241 SplitIRQ *splitter = machine->fan_splitter;
242 static const int fan_counts[] = {2, 2, 2, 0, 0, 0, 0, 0};
243
244 npcm7xx_init_pwm_splitter(machine, soc, fan_counts);
245 npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x00, 0);
246 npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x01, 1);
247 npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x02, 0);
248 npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x03, 1);
249 npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x04, 0);
250 npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x05, 1);
251}
252
253static void quanta_gbs_i2c_init(NPCM7xxState *soc)
254{
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310}
311
312static void npcm750_evb_init(MachineState *machine)
313{
314 NPCM7xxState *soc;
315
316 soc = npcm7xx_create_soc(machine, NPCM750_EVB_POWER_ON_STRAPS);
317 npcm7xx_connect_dram(soc, machine->ram);
318 qdev_realize(DEVICE(soc), NULL, &error_fatal);
319
320 npcm7xx_load_bootrom(machine, soc);
321 npcm7xx_connect_flash(&soc->fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0));
322 npcm750_evb_i2c_init(soc);
323 npcm750_evb_fan_init(NPCM7XX_MACHINE(machine), soc);
324 npcm7xx_load_kernel(machine, soc);
325}
326
327static void quanta_gsj_init(MachineState *machine)
328{
329 NPCM7xxState *soc;
330
331 soc = npcm7xx_create_soc(machine, QUANTA_GSJ_POWER_ON_STRAPS);
332 npcm7xx_connect_dram(soc, machine->ram);
333 qdev_realize(DEVICE(soc), NULL, &error_fatal);
334
335 npcm7xx_load_bootrom(machine, soc);
336 npcm7xx_connect_flash(&soc->fiu[0], 0, "mx25l25635e",
337 drive_get(IF_MTD, 0, 0));
338 quanta_gsj_i2c_init(soc);
339 quanta_gsj_fan_init(NPCM7XX_MACHINE(machine), soc);
340 npcm7xx_load_kernel(machine, soc);
341}
342
343static void quanta_gbs_init(MachineState *machine)
344{
345 NPCM7xxState *soc;
346
347 soc = npcm7xx_create_soc(machine, QUANTA_GBS_POWER_ON_STRAPS);
348 npcm7xx_connect_dram(soc, machine->ram);
349 qdev_realize(DEVICE(soc), NULL, &error_fatal);
350
351 npcm7xx_load_bootrom(machine, soc);
352
353 npcm7xx_connect_flash(&soc->fiu[0], 0, "mx66u51235f",
354 drive_get(IF_MTD, 0, 0));
355
356 quanta_gbs_i2c_init(soc);
357 npcm7xx_load_kernel(machine, soc);
358}
359
360static void npcm7xx_set_soc_type(NPCM7xxMachineClass *nmc, const char *type)
361{
362 NPCM7xxClass *sc = NPCM7XX_CLASS(object_class_by_name(type));
363 MachineClass *mc = MACHINE_CLASS(nmc);
364
365 nmc->soc_type = type;
366 mc->default_cpus = mc->min_cpus = mc->max_cpus = sc->num_cpus;
367}
368
369static void npcm7xx_machine_class_init(ObjectClass *oc, void *data)
370{
371 MachineClass *mc = MACHINE_CLASS(oc);
372
373 mc->no_floppy = 1;
374 mc->no_cdrom = 1;
375 mc->no_parallel = 1;
376 mc->default_ram_id = "ram";
377 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
378}
379
380
381
382
383
384static void npcm750_evb_machine_class_init(ObjectClass *oc, void *data)
385{
386 NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc);
387 MachineClass *mc = MACHINE_CLASS(oc);
388
389 npcm7xx_set_soc_type(nmc, TYPE_NPCM750);
390
391 mc->desc = "Nuvoton NPCM750 Evaluation Board (Cortex-A9)";
392 mc->init = npcm750_evb_init;
393 mc->default_ram_size = 512 * MiB;
394};
395
396static void gsj_machine_class_init(ObjectClass *oc, void *data)
397{
398 NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc);
399 MachineClass *mc = MACHINE_CLASS(oc);
400
401 npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
402
403 mc->desc = "Quanta GSJ (Cortex-A9)";
404 mc->init = quanta_gsj_init;
405 mc->default_ram_size = 512 * MiB;
406};
407
408static void gbs_bmc_machine_class_init(ObjectClass *oc, void *data)
409{
410 NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc);
411 MachineClass *mc = MACHINE_CLASS(oc);
412
413 npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
414
415 mc->desc = "Quanta GBS (Cortex-A9)";
416 mc->init = quanta_gbs_init;
417 mc->default_ram_size = 1 * GiB;
418}
419
420static const TypeInfo npcm7xx_machine_types[] = {
421 {
422 .name = TYPE_NPCM7XX_MACHINE,
423 .parent = TYPE_MACHINE,
424 .instance_size = sizeof(NPCM7xxMachine),
425 .class_size = sizeof(NPCM7xxMachineClass),
426 .class_init = npcm7xx_machine_class_init,
427 .abstract = true,
428 }, {
429 .name = MACHINE_TYPE_NAME("npcm750-evb"),
430 .parent = TYPE_NPCM7XX_MACHINE,
431 .class_init = npcm750_evb_machine_class_init,
432 }, {
433 .name = MACHINE_TYPE_NAME("quanta-gsj"),
434 .parent = TYPE_NPCM7XX_MACHINE,
435 .class_init = gsj_machine_class_init,
436 }, {
437 .name = MACHINE_TYPE_NAME("quanta-gbs-bmc"),
438 .parent = TYPE_NPCM7XX_MACHINE,
439 .class_init = gbs_bmc_machine_class_init,
440 },
441};
442
443DEFINE_TYPES(npcm7xx_machine_types)
444