1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "qemu/osdep.h"
25#include "qapi/error.h"
26#include "cpu.h"
27#include "hw/cpu/a9mpcore.h"
28#include "hw/irq.h"
29#include "sysemu/blockdev.h"
30#include "sysemu/sysemu.h"
31#include "hw/sysbus.h"
32#include "hw/arm/boot.h"
33#include "hw/loader.h"
34#include "hw/qdev-properties.h"
35#include "hw/arm/exynos4210.h"
36#include "hw/sd/sdhci.h"
37#include "hw/usb/hcd-ehci.h"
38
39#define EXYNOS4210_CHIPID_ADDR 0x10000000
40
41
42#define EXYNOS4210_PWM_BASE_ADDR 0x139D0000
43
44
45#define EXYNOS4210_RTC_BASE_ADDR 0x10070000
46
47
48#define EXYNOS4210_MCT_BASE_ADDR 0x10050000
49
50
51#define EXYNOS4210_I2C_SHIFT 0x00010000
52#define EXYNOS4210_I2C_BASE_ADDR 0x13860000
53
54#define EXYNOS4210_I2C_INTG 27
55#define EXYNOS4210_HDMI_INTG 16
56
57
58#define EXYNOS4210_UART0_BASE_ADDR 0x13800000
59#define EXYNOS4210_UART1_BASE_ADDR 0x13810000
60#define EXYNOS4210_UART2_BASE_ADDR 0x13820000
61#define EXYNOS4210_UART3_BASE_ADDR 0x13830000
62#define EXYNOS4210_UART0_FIFO_SIZE 256
63#define EXYNOS4210_UART1_FIFO_SIZE 64
64#define EXYNOS4210_UART2_FIFO_SIZE 16
65#define EXYNOS4210_UART3_FIFO_SIZE 16
66
67#define EXYNOS4210_UART_INT_GRP 26
68
69
70#define EXYNOS4210_EXT_GIC_CPU_BASE_ADDR 0x10480000
71#define EXYNOS4210_EXT_GIC_DIST_BASE_ADDR 0x10490000
72
73
74#define EXYNOS4210_EXT_COMBINER_BASE_ADDR 0x10440000
75#define EXYNOS4210_INT_COMBINER_BASE_ADDR 0x10448000
76
77
78#define EXYNOS4210_SDHCI_CAPABILITIES 0x05E80080
79#define EXYNOS4210_SDHCI_BASE_ADDR 0x12510000
80#define EXYNOS4210_SDHCI_ADDR(n) (EXYNOS4210_SDHCI_BASE_ADDR + \
81 0x00010000 * (n))
82#define EXYNOS4210_SDHCI_NUMBER 4
83
84
85#define EXYNOS4210_PMU_BASE_ADDR 0x10020000
86
87
88#define EXYNOS4210_CLK_BASE_ADDR 0x10030000
89
90
91#define EXYNOS4210_RNG_BASE_ADDR 0x10830400
92
93
94#define EXYNOS4210_FIMD0_BASE_ADDR 0x11C00000
95
96
97#define EXYNOS4210_EHCI_BASE_ADDR 0x12580000
98
99
100#define EXYNOS4210_PL330_BASE0_ADDR 0x12680000
101#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
102#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
103
104enum ExtGicId {
105 EXT_GIC_ID_MDMA_LCD0 = 66,
106 EXT_GIC_ID_PDMA0,
107 EXT_GIC_ID_PDMA1,
108 EXT_GIC_ID_TIMER0,
109 EXT_GIC_ID_TIMER1,
110 EXT_GIC_ID_TIMER2,
111 EXT_GIC_ID_TIMER3,
112 EXT_GIC_ID_TIMER4,
113 EXT_GIC_ID_MCT_L0,
114 EXT_GIC_ID_WDT,
115 EXT_GIC_ID_RTC_ALARM,
116 EXT_GIC_ID_RTC_TIC,
117 EXT_GIC_ID_GPIO_XB,
118 EXT_GIC_ID_GPIO_XA,
119 EXT_GIC_ID_MCT_L1,
120 EXT_GIC_ID_IEM_APC,
121 EXT_GIC_ID_IEM_IEC,
122 EXT_GIC_ID_NFC,
123 EXT_GIC_ID_UART0,
124 EXT_GIC_ID_UART1,
125 EXT_GIC_ID_UART2,
126 EXT_GIC_ID_UART3,
127 EXT_GIC_ID_UART4,
128 EXT_GIC_ID_MCT_G0,
129 EXT_GIC_ID_I2C0,
130 EXT_GIC_ID_I2C1,
131 EXT_GIC_ID_I2C2,
132 EXT_GIC_ID_I2C3,
133 EXT_GIC_ID_I2C4,
134 EXT_GIC_ID_I2C5,
135 EXT_GIC_ID_I2C6,
136 EXT_GIC_ID_I2C7,
137 EXT_GIC_ID_SPI0,
138 EXT_GIC_ID_SPI1,
139 EXT_GIC_ID_SPI2,
140 EXT_GIC_ID_MCT_G1,
141 EXT_GIC_ID_USB_HOST,
142 EXT_GIC_ID_USB_DEVICE,
143 EXT_GIC_ID_MODEMIF,
144 EXT_GIC_ID_HSMMC0,
145 EXT_GIC_ID_HSMMC1,
146 EXT_GIC_ID_HSMMC2,
147 EXT_GIC_ID_HSMMC3,
148 EXT_GIC_ID_SDMMC,
149 EXT_GIC_ID_MIPI_CSI_4LANE,
150 EXT_GIC_ID_MIPI_DSI_4LANE,
151 EXT_GIC_ID_MIPI_CSI_2LANE,
152 EXT_GIC_ID_MIPI_DSI_2LANE,
153 EXT_GIC_ID_ONENAND_AUDI,
154 EXT_GIC_ID_ROTATOR,
155 EXT_GIC_ID_FIMC0,
156 EXT_GIC_ID_FIMC1,
157 EXT_GIC_ID_FIMC2,
158 EXT_GIC_ID_FIMC3,
159 EXT_GIC_ID_JPEG,
160 EXT_GIC_ID_2D,
161 EXT_GIC_ID_PCIe,
162 EXT_GIC_ID_MIXER,
163 EXT_GIC_ID_HDMI,
164 EXT_GIC_ID_HDMI_I2C,
165 EXT_GIC_ID_MFC,
166 EXT_GIC_ID_TVENC,
167};
168
169enum ExtInt {
170 EXT_GIC_ID_EXTINT0 = 48,
171 EXT_GIC_ID_EXTINT1,
172 EXT_GIC_ID_EXTINT2,
173 EXT_GIC_ID_EXTINT3,
174 EXT_GIC_ID_EXTINT4,
175 EXT_GIC_ID_EXTINT5,
176 EXT_GIC_ID_EXTINT6,
177 EXT_GIC_ID_EXTINT7,
178 EXT_GIC_ID_EXTINT8,
179 EXT_GIC_ID_EXTINT9,
180 EXT_GIC_ID_EXTINT10,
181 EXT_GIC_ID_EXTINT11,
182 EXT_GIC_ID_EXTINT12,
183 EXT_GIC_ID_EXTINT13,
184 EXT_GIC_ID_EXTINT14,
185 EXT_GIC_ID_EXTINT15
186};
187
188
189
190
191
192
193
194static const uint32_t
195combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
196
197 { }, { }, { }, { },
198
199 { 0, EXT_GIC_ID_MDMA_LCD0 },
200
201 { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
202
203 { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
204 EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
205
206 { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
207
208 { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
209
210 { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
211
212 { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
213 EXT_GIC_ID_UART4 },
214
215 { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
216 EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
217 EXT_GIC_ID_I2C7 },
218
219 { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
220
221 { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
222 EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
223
224 { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
225
226 { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
227
228 { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
229
230 { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
231
232 { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
233
234 { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
235
236 { EXT_GIC_ID_MIXER },
237
238 { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
239 EXT_GIC_ID_EXTINT7 },
240
241 { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
242
243 { EXT_GIC_ID_MCT_L0 },
244
245 { },
246
247 { EXT_GIC_ID_WDT },
248
249 { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
250};
251
252#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
253#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
254#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
255 ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
256
257
258
259
260
261
262
263
264
265#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
266#define IRQNONE 0
267
268#define COMBINERMAP_SIZE 16
269
270static const int combinermap[COMBINERMAP_SIZE][6] = {
271
272 { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
273 { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
274 { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
275 { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
276
277 { IRQNO(2, 4), IRQNO(3, 4), IRQNONE },
278 { IRQNO(2, 5), IRQNO(3, 5), IRQNONE },
279 { IRQNO(2, 6), IRQNO(3, 6), IRQNONE },
280 { IRQNO(2, 7), IRQNO(3, 7), IRQNONE },
281
282 { IRQNO(11, 4), IRQNO(12, 0), IRQNONE },
283 { IRQNO(11, 5), IRQNO(12, 1), IRQNONE },
284 { IRQNO(11, 6), IRQNO(12, 2), IRQNONE },
285 { IRQNO(11, 7), IRQNO(12, 3), IRQNONE },
286
287 { IRQNO(1, 4), IRQNO(12, 4), IRQNO(35, 4), IRQNO(51, 4), IRQNO(53, 4), IRQNONE },
288 { IRQNO(1, 5), IRQNO(12, 5), IRQNO(35, 5), IRQNO(51, 5), IRQNO(53, 5), IRQNONE },
289 { IRQNO(1, 6), IRQNO(12, 6), IRQNO(35, 6), IRQNO(51, 6), IRQNO(53, 6), IRQNONE },
290 { IRQNO(1, 7), IRQNO(12, 7), IRQNO(35, 7), IRQNO(51, 7), IRQNO(53, 7), IRQNONE },
291};
292
293#undef IRQNO
294
295static const int *combinermap_entry(int irq)
296{
297
298
299
300
301
302 int i;
303 for (i = 0; i < COMBINERMAP_SIZE; i++) {
304 if (combinermap[i][0] == irq) {
305 return combinermap[i];
306 }
307 }
308 return NULL;
309}
310
311static int mapline_size(const int *mapline)
312{
313
314 int i = 0;
315
316 if (!mapline) {
317
318 return 1;
319 }
320 while (*mapline != IRQNONE) {
321 mapline++;
322 i++;
323 }
324 return i;
325}
326
327
328
329
330
331static void exynos4210_init_board_irqs(Exynos4210State *s)
332{
333 uint32_t grp, bit, irq_id, n;
334 DeviceState *extgicdev = DEVICE(&s->ext_gic);
335 DeviceState *intcdev = DEVICE(&s->int_combiner);
336 DeviceState *extcdev = DEVICE(&s->ext_combiner);
337 int splitcount = 0;
338 DeviceState *splitter;
339 const int *mapline;
340 int numlines, splitin, in;
341
342 for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
343 irq_id = 0;
344 if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
345
346 irq_id = EXT_GIC_ID_MCT_G0;
347 }
348 if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
349
350 irq_id = EXT_GIC_ID_MCT_G1;
351 }
352
353 if (s->irq_table[n]) {
354
355
356
357
358 continue;
359 }
360 mapline = combinermap_entry(n);
361
362
363
364
365 numlines = 2 * mapline_size(mapline);
366 if (irq_id) {
367 numlines++;
368 }
369 assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
370 splitter = DEVICE(&s->splitter[splitcount]);
371 qdev_prop_set_uint16(splitter, "num-lines", numlines);
372 qdev_realize(splitter, NULL, &error_abort);
373 splitcount++;
374
375 in = n;
376 splitin = 0;
377 for (;;) {
378 s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
379 qdev_connect_gpio_out(splitter, splitin,
380 qdev_get_gpio_in(intcdev, in));
381 qdev_connect_gpio_out(splitter, splitin + 1,
382 qdev_get_gpio_in(extcdev, in));
383 splitin += 2;
384 if (!mapline) {
385 break;
386 }
387 mapline++;
388 in = *mapline;
389 if (in == IRQNONE) {
390 break;
391 }
392 }
393 if (irq_id) {
394 qdev_connect_gpio_out(splitter, splitin,
395 qdev_get_gpio_in(extgicdev, irq_id - 32));
396 }
397 }
398 for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
399
400 grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
401 bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
402 irq_id = combiner_grp_to_gic_id[grp -
403 EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
404
405 if (s->irq_table[n]) {
406
407
408
409
410 continue;
411 }
412
413 if (irq_id) {
414 assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
415 splitter = DEVICE(&s->splitter[splitcount]);
416 qdev_prop_set_uint16(splitter, "num-lines", 2);
417 qdev_realize(splitter, NULL, &error_abort);
418 splitcount++;
419 s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
420 qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
421 qdev_connect_gpio_out(splitter, 1,
422 qdev_get_gpio_in(extgicdev, irq_id - 32));
423 } else {
424 s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
425 }
426 }
427
428
429
430
431
432 assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
433}
434
435
436
437
438
439
440
441uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
442{
443 return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
444}
445
446static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
447 0x09, 0x00, 0x00, 0x00 };
448
449static uint64_t exynos4210_chipid_and_omr_read(void *opaque, hwaddr offset,
450 unsigned size)
451{
452 assert(offset < sizeof(chipid_and_omr));
453 return chipid_and_omr[offset];
454}
455
456static void exynos4210_chipid_and_omr_write(void *opaque, hwaddr offset,
457 uint64_t value, unsigned size)
458{
459 return;
460}
461
462static const MemoryRegionOps exynos4210_chipid_and_omr_ops = {
463 .read = exynos4210_chipid_and_omr_read,
464 .write = exynos4210_chipid_and_omr_write,
465 .endianness = DEVICE_NATIVE_ENDIAN,
466 .impl = {
467 .max_access_size = 1,
468 }
469};
470
471void exynos4210_write_secondary(ARMCPU *cpu,
472 const struct arm_boot_info *info)
473{
474 int n;
475 uint32_t smpboot[] = {
476 0xe59f3034,
477 0xe59f2034,
478 0xe59f0034,
479 0xe3a01001,
480 0xe5821000,
481 0xe5831000,
482 0xe3a010ff,
483 0xe5821004,
484 0xe5831004,
485 0xf57ff04f,
486 0xe320f003,
487 0xe5901000,
488 0xe1110001,
489 0x0afffffb,
490 0xe12fff11,
491 EXYNOS4210_EXT_GIC_CPU_BASE_ADDR,
492 0,
493 0
494 };
495 smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
496 smpboot[ARRAY_SIZE(smpboot) - 2] = info->gic_cpu_if_addr;
497 for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
498 smpboot[n] = tswap32(smpboot[n]);
499 }
500 rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
501 info->smp_loader_start);
502}
503
504static uint64_t exynos4210_calc_affinity(int cpu)
505{
506
507 return (0x9 << ARM_AFF1_SHIFT) | cpu;
508}
509
510static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
511 qemu_irq irq, int nreq, int nevents, int width)
512{
513 SysBusDevice *busdev;
514 DeviceState *dev;
515 int i;
516
517 dev = qdev_new("pl330");
518 object_property_set_link(OBJECT(dev), "memory",
519 OBJECT(get_system_memory()),
520 &error_fatal);
521 qdev_prop_set_uint8(dev, "num_events", nevents);
522 qdev_prop_set_uint8(dev, "num_chnls", 8);
523 qdev_prop_set_uint8(dev, "num_periph_req", nreq);
524
525 qdev_prop_set_uint8(dev, "wr_cap", 4);
526 qdev_prop_set_uint8(dev, "wr_q_dep", 8);
527 qdev_prop_set_uint8(dev, "rd_cap", 4);
528 qdev_prop_set_uint8(dev, "rd_q_dep", 8);
529 qdev_prop_set_uint8(dev, "data_width", width);
530 qdev_prop_set_uint16(dev, "data_buffer_dep", width);
531 busdev = SYS_BUS_DEVICE(dev);
532 sysbus_realize_and_unref(busdev, &error_fatal);
533 sysbus_mmio_map(busdev, 0, base);
534
535 object_property_set_int(OBJECT(orgate), "num-lines", nevents + 1,
536 &error_abort);
537 qdev_realize(DEVICE(orgate), NULL, &error_abort);
538
539 for (i = 0; i < nevents + 1; i++) {
540 sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
541 }
542 qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
543 return dev;
544}
545
546static void exynos4210_realize(DeviceState *socdev, Error **errp)
547{
548 Exynos4210State *s = EXYNOS4210_SOC(socdev);
549 MemoryRegion *system_mem = get_system_memory();
550 SysBusDevice *busdev;
551 DeviceState *dev, *uart[4], *pl330[3];
552 int i, n;
553
554 for (n = 0; n < EXYNOS4210_NCPUS; n++) {
555 Object *cpuobj = object_new(ARM_CPU_TYPE_NAME("cortex-a9"));
556
557
558
559
560 if (object_property_find(cpuobj, "has_el3")) {
561 object_property_set_bool(cpuobj, "has_el3", false, &error_fatal);
562 }
563
564 s->cpu[n] = ARM_CPU(cpuobj);
565 object_property_set_int(cpuobj, "mp-affinity",
566 exynos4210_calc_affinity(n), &error_abort);
567 object_property_set_int(cpuobj, "reset-cbar",
568 EXYNOS4210_SMP_PRIVATE_BASE_ADDR,
569 &error_abort);
570 qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
571 }
572
573
574 for (i = 0; i < EXYNOS4210_NCPUS; i++) {
575 DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
576 object_property_set_int(OBJECT(orgate), "num-lines",
577 EXYNOS4210_IRQ_GATE_NINPUTS,
578 &error_abort);
579 qdev_realize(orgate, NULL, &error_abort);
580 qdev_connect_gpio_out(orgate, 0,
581 qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
582 }
583
584
585 qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
586 busdev = SYS_BUS_DEVICE(&s->a9mpcore);
587 sysbus_realize(busdev, &error_fatal);
588 sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
589 for (n = 0; n < EXYNOS4210_NCPUS; n++) {
590 sysbus_connect_irq(busdev, n,
591 qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
592 }
593
594
595 sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
596
597
598 qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
599 busdev = SYS_BUS_DEVICE(&s->ext_gic);
600 sysbus_realize(busdev, &error_fatal);
601
602 sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
603
604 sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
605 for (n = 0; n < EXYNOS4210_NCPUS; n++) {
606 sysbus_connect_irq(busdev, n,
607 qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
608 }
609
610
611 busdev = SYS_BUS_DEVICE(&s->int_combiner);
612 sysbus_realize(busdev, &error_fatal);
613 for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
614 sysbus_connect_irq(busdev, n,
615 qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
616 }
617 sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
618
619
620 qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
621 busdev = SYS_BUS_DEVICE(&s->ext_combiner);
622 sysbus_realize(busdev, &error_fatal);
623 for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
624 sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
625 }
626 sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
627
628
629 exynos4210_init_board_irqs(s);
630
631
632
633
634 memory_region_init_io(&s->chipid_mem, OBJECT(socdev),
635 &exynos4210_chipid_and_omr_ops, NULL,
636 "exynos4210.chipid", sizeof(chipid_and_omr));
637 memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
638 &s->chipid_mem);
639
640
641 memory_region_init_rom(&s->irom_mem, OBJECT(socdev), "exynos4210.irom",
642 EXYNOS4210_IROM_SIZE, &error_fatal);
643 memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
644 &s->irom_mem);
645
646 memory_region_init_alias(&s->irom_alias_mem, OBJECT(socdev),
647 "exynos4210.irom_alias", &s->irom_mem, 0,
648 EXYNOS4210_IROM_SIZE);
649 memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
650 &s->irom_alias_mem);
651
652
653 memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
654 EXYNOS4210_IRAM_SIZE, &error_fatal);
655 memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
656 &s->iram_mem);
657
658
659
660
661
662 sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);
663
664 sysbus_create_simple("exynos4210.clk", EXYNOS4210_CLK_BASE_ADDR, NULL);
665 sysbus_create_simple("exynos4210.rng", EXYNOS4210_RNG_BASE_ADDR, NULL);
666
667
668 sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
669 s->irq_table[exynos4210_get_irq(22, 0)],
670 s->irq_table[exynos4210_get_irq(22, 1)],
671 s->irq_table[exynos4210_get_irq(22, 2)],
672 s->irq_table[exynos4210_get_irq(22, 3)],
673 s->irq_table[exynos4210_get_irq(22, 4)],
674 NULL);
675
676 sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR,
677 s->irq_table[exynos4210_get_irq(23, 0)],
678 s->irq_table[exynos4210_get_irq(23, 1)],
679 NULL);
680
681
682 dev = qdev_new("exynos4210.mct");
683 busdev = SYS_BUS_DEVICE(dev);
684 sysbus_realize_and_unref(busdev, &error_fatal);
685 for (n = 0; n < 4; n++) {
686
687 sysbus_connect_irq(busdev, n,
688 s->irq_table[exynos4210_get_irq(1, 4 + n)]);
689 }
690
691 sysbus_connect_irq(busdev, 4,
692 s->irq_table[exynos4210_get_irq(51, 0)]);
693 sysbus_connect_irq(busdev, 5,
694 s->irq_table[exynos4210_get_irq(35, 3)]);
695 sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);
696
697
698 for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) {
699 uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n;
700 qemu_irq i2c_irq;
701
702 if (n < 8) {
703 i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)];
704 } else {
705 i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)];
706 }
707
708 dev = qdev_new("exynos4210.i2c");
709 busdev = SYS_BUS_DEVICE(dev);
710 sysbus_realize_and_unref(busdev, &error_fatal);
711 sysbus_connect_irq(busdev, 0, i2c_irq);
712 sysbus_mmio_map(busdev, 0, addr);
713 s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c");
714 }
715
716
717
718 uart[0] = exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
719 EXYNOS4210_UART0_FIFO_SIZE, 0, serial_hd(0),
720 s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);
721
722 uart[1] = exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
723 EXYNOS4210_UART1_FIFO_SIZE, 1, serial_hd(1),
724 s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);
725
726 uart[2] = exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
727 EXYNOS4210_UART2_FIFO_SIZE, 2, serial_hd(2),
728 s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);
729
730 uart[3] = exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
731 EXYNOS4210_UART3_FIFO_SIZE, 3, serial_hd(3),
732 s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);
733
734
735 for (n = 0; n < EXYNOS4210_SDHCI_NUMBER; n++) {
736 DeviceState *carddev;
737 BlockBackend *blk;
738 DriveInfo *di;
739
740
741
742
743
744
745
746
747
748
749
750
751
752 dev = qdev_new(TYPE_S3C_SDHCI);
753 qdev_prop_set_uint64(dev, "capareg", EXYNOS4210_SDHCI_CAPABILITIES);
754
755 busdev = SYS_BUS_DEVICE(dev);
756 sysbus_realize_and_unref(busdev, &error_fatal);
757 sysbus_mmio_map(busdev, 0, EXYNOS4210_SDHCI_ADDR(n));
758 sysbus_connect_irq(busdev, 0, s->irq_table[exynos4210_get_irq(29, n)]);
759
760 di = drive_get(IF_SD, 0, n);
761 blk = di ? blk_by_legacy_dinfo(di) : NULL;
762 carddev = qdev_new(TYPE_SD_CARD);
763 qdev_prop_set_drive(carddev, "drive", blk);
764 qdev_realize_and_unref(carddev, qdev_get_child_bus(dev, "sd-bus"),
765 &error_fatal);
766 }
767
768
769 sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR,
770 s->irq_table[exynos4210_get_irq(11, 0)],
771 s->irq_table[exynos4210_get_irq(11, 1)],
772 s->irq_table[exynos4210_get_irq(11, 2)],
773 NULL);
774
775 sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR,
776 s->irq_table[exynos4210_get_irq(28, 3)]);
777
778
779 pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
780 &s->pl330_irq_orgate[0],
781 s->irq_table[exynos4210_get_irq(21, 0)],
782 32, 32, 32);
783 pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
784 &s->pl330_irq_orgate[1],
785 s->irq_table[exynos4210_get_irq(21, 1)],
786 32, 32, 32);
787 pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
788 &s->pl330_irq_orgate[2],
789 s->irq_table[exynos4210_get_irq(20, 1)],
790 1, 31, 64);
791
792 sysbus_connect_irq(SYS_BUS_DEVICE(uart[0]), 1,
793 qdev_get_gpio_in(pl330[0], 15));
794 sysbus_connect_irq(SYS_BUS_DEVICE(uart[1]), 1,
795 qdev_get_gpio_in(pl330[1], 15));
796 sysbus_connect_irq(SYS_BUS_DEVICE(uart[2]), 1,
797 qdev_get_gpio_in(pl330[0], 17));
798 sysbus_connect_irq(SYS_BUS_DEVICE(uart[3]), 1,
799 qdev_get_gpio_in(pl330[1], 17));
800}
801
802static void exynos4210_init(Object *obj)
803{
804 Exynos4210State *s = EXYNOS4210_SOC(obj);
805 int i;
806
807 for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
808 char *name = g_strdup_printf("pl330-irq-orgate%d", i);
809 qemu_or_irq *orgate = &s->pl330_irq_orgate[i];
810
811 object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
812 g_free(name);
813 }
814
815 for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
816 g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
817 object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
818 }
819
820 for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
821 g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
822 object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
823 }
824
825 object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
826 object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
827 object_initialize_child(obj, "int-combiner", &s->int_combiner,
828 TYPE_EXYNOS4210_COMBINER);
829 object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
830 TYPE_EXYNOS4210_COMBINER);
831}
832
833static void exynos4210_class_init(ObjectClass *klass, void *data)
834{
835 DeviceClass *dc = DEVICE_CLASS(klass);
836
837 dc->realize = exynos4210_realize;
838}
839
840static const TypeInfo exynos4210_info = {
841 .name = TYPE_EXYNOS4210_SOC,
842 .parent = TYPE_SYS_BUS_DEVICE,
843 .instance_size = sizeof(Exynos4210State),
844 .instance_init = exynos4210_init,
845 .class_init = exynos4210_class_init,
846};
847
848static void exynos4210_register_types(void)
849{
850 type_register_static(&exynos4210_info);
851}
852
853type_init(exynos4210_register_types)
854