]> git.proxmox.com Git - qemu.git/blame - hw/stellaris.c
qdev: register all types natively through QEMU Object Model
[qemu.git] / hw / stellaris.c
CommitLineData
9ee6e8bb 1/*
1654b2d6 2 * Luminary Micro Stellaris peripherals
9ee6e8bb
PB
3 *
4 * Copyright (c) 2006 CodeSourcery.
5 * Written by Paul Brook
6 *
8e31bf38 7 * This code is licensed under the GPL.
9ee6e8bb
PB
8 */
9
a7d518a6 10#include "sysbus.h"
5493e33f 11#include "ssi.h"
87ecb68b 12#include "arm-misc.h"
87ecb68b
PB
13#include "devices.h"
14#include "qemu-timer.h"
15#include "i2c.h"
eea589cc 16#include "net.h"
87ecb68b 17#include "boards.h"
7d6f78cf 18#include "exec-memory.h"
9ee6e8bb 19
cf0dbb21
PB
20#define GPIO_A 0
21#define GPIO_B 1
22#define GPIO_C 2
23#define GPIO_D 3
24#define GPIO_E 4
25#define GPIO_F 5
26#define GPIO_G 6
27
28#define BP_OLED_I2C 0x01
29#define BP_OLED_SSI 0x02
30#define BP_GAMEPAD 0x04
31
9ee6e8bb
PB
32typedef const struct {
33 const char *name;
34 uint32_t did0;
35 uint32_t did1;
36 uint32_t dc0;
37 uint32_t dc1;
38 uint32_t dc2;
39 uint32_t dc3;
40 uint32_t dc4;
cf0dbb21 41 uint32_t peripherals;
9ee6e8bb
PB
42} stellaris_board_info;
43
44/* General purpose timer module. */
45
9ee6e8bb 46typedef struct gptm_state {
40905a6a 47 SysBusDevice busdev;
2443fa27 48 MemoryRegion iomem;
9ee6e8bb
PB
49 uint32_t config;
50 uint32_t mode[2];
51 uint32_t control;
52 uint32_t state;
53 uint32_t mask;
54 uint32_t load[2];
55 uint32_t match[2];
56 uint32_t prescale[2];
57 uint32_t match_prescale[2];
58 uint32_t rtc;
59 int64_t tick[2];
60 struct gptm_state *opaque[2];
9ee6e8bb
PB
61 QEMUTimer *timer[2];
62 /* The timers have an alternate output used to trigger the ADC. */
63 qemu_irq trigger;
64 qemu_irq irq;
65} gptm_state;
66
67static void gptm_update_irq(gptm_state *s)
68{
69 int level;
70 level = (s->state & s->mask) != 0;
71 qemu_set_irq(s->irq, level);
72}
73
74static void gptm_stop(gptm_state *s, int n)
75{
76 qemu_del_timer(s->timer[n]);
77}
78
79static void gptm_reload(gptm_state *s, int n, int reset)
80{
81 int64_t tick;
82 if (reset)
74475455 83 tick = qemu_get_clock_ns(vm_clock);
9ee6e8bb
PB
84 else
85 tick = s->tick[n];
86
87 if (s->config == 0) {
88 /* 32-bit CountDown. */
89 uint32_t count;
90 count = s->load[0] | (s->load[1] << 16);
e57ec016 91 tick += (int64_t)count * system_clock_scale;
9ee6e8bb
PB
92 } else if (s->config == 1) {
93 /* 32-bit RTC. 1Hz tick. */
6ee093c9 94 tick += get_ticks_per_sec();
9ee6e8bb
PB
95 } else if (s->mode[n] == 0xa) {
96 /* PWM mode. Not implemented. */
97 } else {
2ac71179 98 hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
9ee6e8bb
PB
99 }
100 s->tick[n] = tick;
101 qemu_mod_timer(s->timer[n], tick);
102}
103
104static void gptm_tick(void *opaque)
105{
106 gptm_state **p = (gptm_state **)opaque;
107 gptm_state *s;
108 int n;
109
110 s = *p;
111 n = p - s->opaque;
112 if (s->config == 0) {
113 s->state |= 1;
114 if ((s->control & 0x20)) {
115 /* Output trigger. */
40905a6a 116 qemu_irq_pulse(s->trigger);
9ee6e8bb
PB
117 }
118 if (s->mode[0] & 1) {
119 /* One-shot. */
120 s->control &= ~1;
121 } else {
122 /* Periodic. */
123 gptm_reload(s, 0, 0);
124 }
125 } else if (s->config == 1) {
126 /* RTC. */
127 uint32_t match;
128 s->rtc++;
129 match = s->match[0] | (s->match[1] << 16);
130 if (s->rtc > match)
131 s->rtc = 0;
132 if (s->rtc == 0) {
133 s->state |= 8;
134 }
135 gptm_reload(s, 0, 0);
136 } else if (s->mode[n] == 0xa) {
137 /* PWM mode. Not implemented. */
138 } else {
2ac71179 139 hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
9ee6e8bb
PB
140 }
141 gptm_update_irq(s);
142}
143
2443fa27
BC
144static uint64_t gptm_read(void *opaque, target_phys_addr_t offset,
145 unsigned size)
9ee6e8bb
PB
146{
147 gptm_state *s = (gptm_state *)opaque;
148
9ee6e8bb
PB
149 switch (offset) {
150 case 0x00: /* CFG */
151 return s->config;
152 case 0x04: /* TAMR */
153 return s->mode[0];
154 case 0x08: /* TBMR */
155 return s->mode[1];
156 case 0x0c: /* CTL */
157 return s->control;
158 case 0x18: /* IMR */
159 return s->mask;
160 case 0x1c: /* RIS */
161 return s->state;
162 case 0x20: /* MIS */
163 return s->state & s->mask;
164 case 0x24: /* CR */
165 return 0;
166 case 0x28: /* TAILR */
167 return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
168 case 0x2c: /* TBILR */
169 return s->load[1];
170 case 0x30: /* TAMARCHR */
171 return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
172 case 0x34: /* TBMATCHR */
173 return s->match[1];
174 case 0x38: /* TAPR */
175 return s->prescale[0];
176 case 0x3c: /* TBPR */
177 return s->prescale[1];
178 case 0x40: /* TAPMR */
179 return s->match_prescale[0];
180 case 0x44: /* TBPMR */
181 return s->match_prescale[1];
182 case 0x48: /* TAR */
183 if (s->control == 1)
184 return s->rtc;
185 case 0x4c: /* TBR */
2ac71179 186 hw_error("TODO: Timer value read\n");
9ee6e8bb 187 default:
2ac71179 188 hw_error("gptm_read: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
189 return 0;
190 }
191}
192
2443fa27
BC
193static void gptm_write(void *opaque, target_phys_addr_t offset,
194 uint64_t value, unsigned size)
9ee6e8bb
PB
195{
196 gptm_state *s = (gptm_state *)opaque;
197 uint32_t oldval;
198
9ee6e8bb
PB
199 /* The timers should be disabled before changing the configuration.
200 We take advantage of this and defer everything until the timer
201 is enabled. */
202 switch (offset) {
203 case 0x00: /* CFG */
204 s->config = value;
205 break;
206 case 0x04: /* TAMR */
207 s->mode[0] = value;
208 break;
209 case 0x08: /* TBMR */
210 s->mode[1] = value;
211 break;
212 case 0x0c: /* CTL */
213 oldval = s->control;
214 s->control = value;
215 /* TODO: Implement pause. */
216 if ((oldval ^ value) & 1) {
217 if (value & 1) {
218 gptm_reload(s, 0, 1);
219 } else {
220 gptm_stop(s, 0);
221 }
222 }
223 if (((oldval ^ value) & 0x100) && s->config >= 4) {
224 if (value & 0x100) {
225 gptm_reload(s, 1, 1);
226 } else {
227 gptm_stop(s, 1);
228 }
229 }
230 break;
231 case 0x18: /* IMR */
232 s->mask = value & 0x77;
233 gptm_update_irq(s);
234 break;
235 case 0x24: /* CR */
236 s->state &= ~value;
237 break;
238 case 0x28: /* TAILR */
239 s->load[0] = value & 0xffff;
240 if (s->config < 4) {
241 s->load[1] = value >> 16;
242 }
243 break;
244 case 0x2c: /* TBILR */
245 s->load[1] = value & 0xffff;
246 break;
247 case 0x30: /* TAMARCHR */
248 s->match[0] = value & 0xffff;
249 if (s->config < 4) {
250 s->match[1] = value >> 16;
251 }
252 break;
253 case 0x34: /* TBMATCHR */
254 s->match[1] = value >> 16;
255 break;
256 case 0x38: /* TAPR */
257 s->prescale[0] = value;
258 break;
259 case 0x3c: /* TBPR */
260 s->prescale[1] = value;
261 break;
262 case 0x40: /* TAPMR */
263 s->match_prescale[0] = value;
264 break;
265 case 0x44: /* TBPMR */
266 s->match_prescale[0] = value;
267 break;
268 default:
2ac71179 269 hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
270 }
271 gptm_update_irq(s);
272}
273
2443fa27
BC
274static const MemoryRegionOps gptm_ops = {
275 .read = gptm_read,
276 .write = gptm_write,
277 .endianness = DEVICE_NATIVE_ENDIAN,
9ee6e8bb
PB
278};
279
10f85a29
JQ
280static const VMStateDescription vmstate_stellaris_gptm = {
281 .name = "stellaris_gptm",
282 .version_id = 1,
283 .minimum_version_id = 1,
284 .minimum_version_id_old = 1,
285 .fields = (VMStateField[]) {
286 VMSTATE_UINT32(config, gptm_state),
287 VMSTATE_UINT32_ARRAY(mode, gptm_state, 2),
288 VMSTATE_UINT32(control, gptm_state),
289 VMSTATE_UINT32(state, gptm_state),
290 VMSTATE_UINT32(mask, gptm_state),
dd8a4dcd 291 VMSTATE_UNUSED(8),
10f85a29
JQ
292 VMSTATE_UINT32_ARRAY(load, gptm_state, 2),
293 VMSTATE_UINT32_ARRAY(match, gptm_state, 2),
294 VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2),
295 VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2),
296 VMSTATE_UINT32(rtc, gptm_state),
297 VMSTATE_INT64_ARRAY(tick, gptm_state, 2),
298 VMSTATE_TIMER_ARRAY(timer, gptm_state, 2),
299 VMSTATE_END_OF_LIST()
300 }
301};
23e39294 302
81a322d4 303static int stellaris_gptm_init(SysBusDevice *dev)
9ee6e8bb 304{
40905a6a 305 gptm_state *s = FROM_SYSBUS(gptm_state, dev);
9ee6e8bb 306
40905a6a
PB
307 sysbus_init_irq(dev, &s->irq);
308 qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
9ee6e8bb 309
2443fa27
BC
310 memory_region_init_io(&s->iomem, &gptm_ops, s,
311 "gptm", 0x1000);
750ecd44 312 sysbus_init_mmio(dev, &s->iomem);
40905a6a
PB
313
314 s->opaque[0] = s->opaque[1] = s;
74475455
PB
315 s->timer[0] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[0]);
316 s->timer[1] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[1]);
10f85a29 317 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_gptm, s);
81a322d4 318 return 0;
9ee6e8bb
PB
319}
320
321
322/* System controller. */
323
324typedef struct {
5699301f 325 MemoryRegion iomem;
9ee6e8bb
PB
326 uint32_t pborctl;
327 uint32_t ldopctl;
328 uint32_t int_status;
329 uint32_t int_mask;
330 uint32_t resc;
331 uint32_t rcc;
dc804ab7 332 uint32_t rcc2;
9ee6e8bb
PB
333 uint32_t rcgc[3];
334 uint32_t scgc[3];
335 uint32_t dcgc[3];
336 uint32_t clkvclr;
337 uint32_t ldoarst;
eea589cc
PB
338 uint32_t user0;
339 uint32_t user1;
9ee6e8bb
PB
340 qemu_irq irq;
341 stellaris_board_info *board;
342} ssys_state;
343
344static void ssys_update(ssys_state *s)
345{
346 qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
347}
348
349static uint32_t pllcfg_sandstorm[16] = {
350 0x31c0, /* 1 Mhz */
351 0x1ae0, /* 1.8432 Mhz */
352 0x18c0, /* 2 Mhz */
353 0xd573, /* 2.4576 Mhz */
354 0x37a6, /* 3.57954 Mhz */
355 0x1ae2, /* 3.6864 Mhz */
356 0x0c40, /* 4 Mhz */
357 0x98bc, /* 4.906 Mhz */
358 0x935b, /* 4.9152 Mhz */
359 0x09c0, /* 5 Mhz */
360 0x4dee, /* 5.12 Mhz */
361 0x0c41, /* 6 Mhz */
362 0x75db, /* 6.144 Mhz */
363 0x1ae6, /* 7.3728 Mhz */
364 0x0600, /* 8 Mhz */
365 0x585b /* 8.192 Mhz */
366};
367
368static uint32_t pllcfg_fury[16] = {
369 0x3200, /* 1 Mhz */
370 0x1b20, /* 1.8432 Mhz */
371 0x1900, /* 2 Mhz */
372 0xf42b, /* 2.4576 Mhz */
373 0x37e3, /* 3.57954 Mhz */
374 0x1b21, /* 3.6864 Mhz */
375 0x0c80, /* 4 Mhz */
376 0x98ee, /* 4.906 Mhz */
377 0xd5b4, /* 4.9152 Mhz */
378 0x0a00, /* 5 Mhz */
379 0x4e27, /* 5.12 Mhz */
380 0x1902, /* 6 Mhz */
381 0xec1c, /* 6.144 Mhz */
382 0x1b23, /* 7.3728 Mhz */
383 0x0640, /* 8 Mhz */
384 0xb11c /* 8.192 Mhz */
385};
386
dc804ab7
EA
387#define DID0_VER_MASK 0x70000000
388#define DID0_VER_0 0x00000000
389#define DID0_VER_1 0x10000000
390
391#define DID0_CLASS_MASK 0x00FF0000
392#define DID0_CLASS_SANDSTORM 0x00000000
393#define DID0_CLASS_FURY 0x00010000
394
395static int ssys_board_class(const ssys_state *s)
396{
397 uint32_t did0 = s->board->did0;
398 switch (did0 & DID0_VER_MASK) {
399 case DID0_VER_0:
400 return DID0_CLASS_SANDSTORM;
401 case DID0_VER_1:
402 switch (did0 & DID0_CLASS_MASK) {
403 case DID0_CLASS_SANDSTORM:
404 case DID0_CLASS_FURY:
405 return did0 & DID0_CLASS_MASK;
406 }
407 /* for unknown classes, fall through */
408 default:
409 hw_error("ssys_board_class: Unknown class 0x%08x\n", did0);
410 }
411}
412
5699301f
BC
413static uint64_t ssys_read(void *opaque, target_phys_addr_t offset,
414 unsigned size)
9ee6e8bb
PB
415{
416 ssys_state *s = (ssys_state *)opaque;
417
9ee6e8bb
PB
418 switch (offset) {
419 case 0x000: /* DID0 */
420 return s->board->did0;
421 case 0x004: /* DID1 */
422 return s->board->did1;
423 case 0x008: /* DC0 */
424 return s->board->dc0;
425 case 0x010: /* DC1 */
426 return s->board->dc1;
427 case 0x014: /* DC2 */
428 return s->board->dc2;
429 case 0x018: /* DC3 */
430 return s->board->dc3;
431 case 0x01c: /* DC4 */
432 return s->board->dc4;
433 case 0x030: /* PBORCTL */
434 return s->pborctl;
435 case 0x034: /* LDOPCTL */
436 return s->ldopctl;
437 case 0x040: /* SRCR0 */
438 return 0;
439 case 0x044: /* SRCR1 */
440 return 0;
441 case 0x048: /* SRCR2 */
442 return 0;
443 case 0x050: /* RIS */
444 return s->int_status;
445 case 0x054: /* IMC */
446 return s->int_mask;
447 case 0x058: /* MISC */
448 return s->int_status & s->int_mask;
449 case 0x05c: /* RESC */
450 return s->resc;
451 case 0x060: /* RCC */
452 return s->rcc;
453 case 0x064: /* PLLCFG */
454 {
455 int xtal;
456 xtal = (s->rcc >> 6) & 0xf;
dc804ab7
EA
457 switch (ssys_board_class(s)) {
458 case DID0_CLASS_FURY:
9ee6e8bb 459 return pllcfg_fury[xtal];
dc804ab7 460 case DID0_CLASS_SANDSTORM:
9ee6e8bb 461 return pllcfg_sandstorm[xtal];
dc804ab7
EA
462 default:
463 hw_error("ssys_read: Unhandled class for PLLCFG read.\n");
464 return 0;
9ee6e8bb
PB
465 }
466 }
dc804ab7
EA
467 case 0x070: /* RCC2 */
468 return s->rcc2;
9ee6e8bb
PB
469 case 0x100: /* RCGC0 */
470 return s->rcgc[0];
471 case 0x104: /* RCGC1 */
472 return s->rcgc[1];
473 case 0x108: /* RCGC2 */
474 return s->rcgc[2];
475 case 0x110: /* SCGC0 */
476 return s->scgc[0];
477 case 0x114: /* SCGC1 */
478 return s->scgc[1];
479 case 0x118: /* SCGC2 */
480 return s->scgc[2];
481 case 0x120: /* DCGC0 */
482 return s->dcgc[0];
483 case 0x124: /* DCGC1 */
484 return s->dcgc[1];
485 case 0x128: /* DCGC2 */
486 return s->dcgc[2];
487 case 0x150: /* CLKVCLR */
488 return s->clkvclr;
489 case 0x160: /* LDOARST */
490 return s->ldoarst;
eea589cc
PB
491 case 0x1e0: /* USER0 */
492 return s->user0;
493 case 0x1e4: /* USER1 */
494 return s->user1;
9ee6e8bb 495 default:
2ac71179 496 hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
497 return 0;
498 }
499}
500
dc804ab7
EA
501static bool ssys_use_rcc2(ssys_state *s)
502{
503 return (s->rcc2 >> 31) & 0x1;
504}
505
506/*
507 * Caculate the sys. clock period in ms.
508 */
23e39294
PB
509static void ssys_calculate_system_clock(ssys_state *s)
510{
dc804ab7
EA
511 if (ssys_use_rcc2(s)) {
512 system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
513 } else {
514 system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
515 }
23e39294
PB
516}
517
5699301f
BC
518static void ssys_write(void *opaque, target_phys_addr_t offset,
519 uint64_t value, unsigned size)
9ee6e8bb
PB
520{
521 ssys_state *s = (ssys_state *)opaque;
522
9ee6e8bb
PB
523 switch (offset) {
524 case 0x030: /* PBORCTL */
525 s->pborctl = value & 0xffff;
526 break;
527 case 0x034: /* LDOPCTL */
528 s->ldopctl = value & 0x1f;
529 break;
530 case 0x040: /* SRCR0 */
531 case 0x044: /* SRCR1 */
532 case 0x048: /* SRCR2 */
533 fprintf(stderr, "Peripheral reset not implemented\n");
534 break;
535 case 0x054: /* IMC */
536 s->int_mask = value & 0x7f;
537 break;
538 case 0x058: /* MISC */
539 s->int_status &= ~value;
540 break;
541 case 0x05c: /* RESC */
542 s->resc = value & 0x3f;
543 break;
544 case 0x060: /* RCC */
545 if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
546 /* PLL enable. */
547 s->int_status |= (1 << 6);
548 }
549 s->rcc = value;
23e39294 550 ssys_calculate_system_clock(s);
9ee6e8bb 551 break;
dc804ab7
EA
552 case 0x070: /* RCC2 */
553 if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
554 break;
555 }
556
557 if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
558 /* PLL enable. */
559 s->int_status |= (1 << 6);
560 }
561 s->rcc2 = value;
562 ssys_calculate_system_clock(s);
563 break;
9ee6e8bb
PB
564 case 0x100: /* RCGC0 */
565 s->rcgc[0] = value;
566 break;
567 case 0x104: /* RCGC1 */
568 s->rcgc[1] = value;
569 break;
570 case 0x108: /* RCGC2 */
571 s->rcgc[2] = value;
572 break;
573 case 0x110: /* SCGC0 */
574 s->scgc[0] = value;
575 break;
576 case 0x114: /* SCGC1 */
577 s->scgc[1] = value;
578 break;
579 case 0x118: /* SCGC2 */
580 s->scgc[2] = value;
581 break;
582 case 0x120: /* DCGC0 */
583 s->dcgc[0] = value;
584 break;
585 case 0x124: /* DCGC1 */
586 s->dcgc[1] = value;
587 break;
588 case 0x128: /* DCGC2 */
589 s->dcgc[2] = value;
590 break;
591 case 0x150: /* CLKVCLR */
592 s->clkvclr = value;
593 break;
594 case 0x160: /* LDOARST */
595 s->ldoarst = value;
596 break;
597 default:
2ac71179 598 hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
599 }
600 ssys_update(s);
601}
602
5699301f
BC
603static const MemoryRegionOps ssys_ops = {
604 .read = ssys_read,
605 .write = ssys_write,
606 .endianness = DEVICE_NATIVE_ENDIAN,
9ee6e8bb
PB
607};
608
9596ebb7 609static void ssys_reset(void *opaque)
9ee6e8bb
PB
610{
611 ssys_state *s = (ssys_state *)opaque;
612
613 s->pborctl = 0x7ffd;
614 s->rcc = 0x078e3ac0;
dc804ab7
EA
615
616 if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
617 s->rcc2 = 0;
618 } else {
619 s->rcc2 = 0x07802810;
620 }
9ee6e8bb
PB
621 s->rcgc[0] = 1;
622 s->scgc[0] = 1;
623 s->dcgc[0] = 1;
bfc213af 624 ssys_calculate_system_clock(s);
9ee6e8bb
PB
625}
626
293c16aa 627static int stellaris_sys_post_load(void *opaque, int version_id)
23e39294 628{
293c16aa 629 ssys_state *s = opaque;
23e39294 630
23e39294
PB
631 ssys_calculate_system_clock(s);
632
633 return 0;
634}
635
293c16aa
JQ
636static const VMStateDescription vmstate_stellaris_sys = {
637 .name = "stellaris_sys",
dc804ab7 638 .version_id = 2,
293c16aa
JQ
639 .minimum_version_id = 1,
640 .minimum_version_id_old = 1,
641 .post_load = stellaris_sys_post_load,
642 .fields = (VMStateField[]) {
643 VMSTATE_UINT32(pborctl, ssys_state),
644 VMSTATE_UINT32(ldopctl, ssys_state),
645 VMSTATE_UINT32(int_mask, ssys_state),
646 VMSTATE_UINT32(int_status, ssys_state),
647 VMSTATE_UINT32(resc, ssys_state),
648 VMSTATE_UINT32(rcc, ssys_state),
dc804ab7 649 VMSTATE_UINT32_V(rcc2, ssys_state, 2),
293c16aa
JQ
650 VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
651 VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
652 VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
653 VMSTATE_UINT32(clkvclr, ssys_state),
654 VMSTATE_UINT32(ldoarst, ssys_state),
655 VMSTATE_END_OF_LIST()
656 }
657};
658
81a322d4
GH
659static int stellaris_sys_init(uint32_t base, qemu_irq irq,
660 stellaris_board_info * board,
661 uint8_t *macaddr)
9ee6e8bb 662{
9ee6e8bb
PB
663 ssys_state *s;
664
7267c094 665 s = (ssys_state *)g_malloc0(sizeof(ssys_state));
9ee6e8bb
PB
666 s->irq = irq;
667 s->board = board;
eea589cc
PB
668 /* Most devices come preprogrammed with a MAC address in the user data. */
669 s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
670 s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
9ee6e8bb 671
5699301f
BC
672 memory_region_init_io(&s->iomem, &ssys_ops, s, "ssys", 0x00001000);
673 memory_region_add_subregion(get_system_memory(), base, &s->iomem);
9ee6e8bb 674 ssys_reset(s);
293c16aa 675 vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
81a322d4 676 return 0;
9ee6e8bb
PB
677}
678
679
680/* I2C controller. */
681
682typedef struct {
1de9610c 683 SysBusDevice busdev;
9ee6e8bb
PB
684 i2c_bus *bus;
685 qemu_irq irq;
8ea72f38 686 MemoryRegion iomem;
9ee6e8bb
PB
687 uint32_t msa;
688 uint32_t mcs;
689 uint32_t mdr;
690 uint32_t mtpr;
691 uint32_t mimr;
692 uint32_t mris;
693 uint32_t mcr;
694} stellaris_i2c_state;
695
696#define STELLARIS_I2C_MCS_BUSY 0x01
697#define STELLARIS_I2C_MCS_ERROR 0x02
698#define STELLARIS_I2C_MCS_ADRACK 0x04
699#define STELLARIS_I2C_MCS_DATACK 0x08
700#define STELLARIS_I2C_MCS_ARBLST 0x10
701#define STELLARIS_I2C_MCS_IDLE 0x20
702#define STELLARIS_I2C_MCS_BUSBSY 0x40
703
8ea72f38
BC
704static uint64_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset,
705 unsigned size)
9ee6e8bb
PB
706{
707 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
708
9ee6e8bb
PB
709 switch (offset) {
710 case 0x00: /* MSA */
711 return s->msa;
712 case 0x04: /* MCS */
713 /* We don't emulate timing, so the controller is never busy. */
714 return s->mcs | STELLARIS_I2C_MCS_IDLE;
715 case 0x08: /* MDR */
716 return s->mdr;
717 case 0x0c: /* MTPR */
718 return s->mtpr;
719 case 0x10: /* MIMR */
720 return s->mimr;
721 case 0x14: /* MRIS */
722 return s->mris;
723 case 0x18: /* MMIS */
724 return s->mris & s->mimr;
725 case 0x20: /* MCR */
726 return s->mcr;
727 default:
2ac71179 728 hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
729 return 0;
730 }
731}
732
733static void stellaris_i2c_update(stellaris_i2c_state *s)
734{
735 int level;
736
737 level = (s->mris & s->mimr) != 0;
738 qemu_set_irq(s->irq, level);
739}
740
c227f099 741static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
8ea72f38 742 uint64_t value, unsigned size)
9ee6e8bb
PB
743{
744 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
745
9ee6e8bb
PB
746 switch (offset) {
747 case 0x00: /* MSA */
748 s->msa = value & 0xff;
749 break;
750 case 0x04: /* MCS */
751 if ((s->mcr & 0x10) == 0) {
752 /* Disabled. Do nothing. */
753 break;
754 }
755 /* Grab the bus if this is starting a transfer. */
756 if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
757 if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
758 s->mcs |= STELLARIS_I2C_MCS_ARBLST;
759 } else {
760 s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
761 s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
762 }
763 }
764 /* If we don't have the bus then indicate an error. */
765 if (!i2c_bus_busy(s->bus)
766 || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
767 s->mcs |= STELLARIS_I2C_MCS_ERROR;
768 break;
769 }
770 s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
771 if (value & 1) {
772 /* Transfer a byte. */
773 /* TODO: Handle errors. */
774 if (s->msa & 1) {
775 /* Recv */
776 s->mdr = i2c_recv(s->bus) & 0xff;
777 } else {
778 /* Send */
779 i2c_send(s->bus, s->mdr);
780 }
781 /* Raise an interrupt. */
782 s->mris |= 1;
783 }
784 if (value & 4) {
785 /* Finish transfer. */
786 i2c_end_transfer(s->bus);
787 s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
788 }
789 break;
790 case 0x08: /* MDR */
791 s->mdr = value & 0xff;
792 break;
793 case 0x0c: /* MTPR */
794 s->mtpr = value & 0xff;
795 break;
796 case 0x10: /* MIMR */
797 s->mimr = 1;
798 break;
799 case 0x1c: /* MICR */
800 s->mris &= ~value;
801 break;
802 case 0x20: /* MCR */
803 if (value & 1)
2ac71179 804 hw_error(
9ee6e8bb
PB
805 "stellaris_i2c_write: Loopback not implemented\n");
806 if (value & 0x20)
2ac71179 807 hw_error(
9ee6e8bb
PB
808 "stellaris_i2c_write: Slave mode not implemented\n");
809 s->mcr = value & 0x31;
810 break;
811 default:
2ac71179 812 hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
9ee6e8bb
PB
813 (int)offset);
814 }
815 stellaris_i2c_update(s);
816}
817
818static void stellaris_i2c_reset(stellaris_i2c_state *s)
819{
820 if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
821 i2c_end_transfer(s->bus);
822
823 s->msa = 0;
824 s->mcs = 0;
825 s->mdr = 0;
826 s->mtpr = 1;
827 s->mimr = 0;
828 s->mris = 0;
829 s->mcr = 0;
830 stellaris_i2c_update(s);
831}
832
8ea72f38
BC
833static const MemoryRegionOps stellaris_i2c_ops = {
834 .read = stellaris_i2c_read,
835 .write = stellaris_i2c_write,
836 .endianness = DEVICE_NATIVE_ENDIAN,
9ee6e8bb
PB
837};
838
ff269cd0
JQ
839static const VMStateDescription vmstate_stellaris_i2c = {
840 .name = "stellaris_i2c",
841 .version_id = 1,
842 .minimum_version_id = 1,
843 .minimum_version_id_old = 1,
844 .fields = (VMStateField[]) {
845 VMSTATE_UINT32(msa, stellaris_i2c_state),
846 VMSTATE_UINT32(mcs, stellaris_i2c_state),
847 VMSTATE_UINT32(mdr, stellaris_i2c_state),
848 VMSTATE_UINT32(mtpr, stellaris_i2c_state),
849 VMSTATE_UINT32(mimr, stellaris_i2c_state),
850 VMSTATE_UINT32(mris, stellaris_i2c_state),
851 VMSTATE_UINT32(mcr, stellaris_i2c_state),
852 VMSTATE_END_OF_LIST()
853 }
854};
23e39294 855
81a322d4 856static int stellaris_i2c_init(SysBusDevice * dev)
9ee6e8bb 857{
1de9610c 858 stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
02e2da45 859 i2c_bus *bus;
9ee6e8bb 860
1de9610c 861 sysbus_init_irq(dev, &s->irq);
02e2da45 862 bus = i2c_init_bus(&dev->qdev, "i2c");
9ee6e8bb
PB
863 s->bus = bus;
864
8ea72f38
BC
865 memory_region_init_io(&s->iomem, &stellaris_i2c_ops, s,
866 "i2c", 0x1000);
750ecd44 867 sysbus_init_mmio(dev, &s->iomem);
9ee6e8bb
PB
868 /* ??? For now we only implement the master interface. */
869 stellaris_i2c_reset(s);
ff269cd0 870 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_i2c, s);
81a322d4 871 return 0;
9ee6e8bb
PB
872}
873
874/* Analogue to Digital Converter. This is only partially implemented,
875 enough for applications that use a combined ADC and timer tick. */
876
877#define STELLARIS_ADC_EM_CONTROLLER 0
878#define STELLARIS_ADC_EM_COMP 1
879#define STELLARIS_ADC_EM_EXTERNAL 4
880#define STELLARIS_ADC_EM_TIMER 5
881#define STELLARIS_ADC_EM_PWM0 6
882#define STELLARIS_ADC_EM_PWM1 7
883#define STELLARIS_ADC_EM_PWM2 8
884
885#define STELLARIS_ADC_FIFO_EMPTY 0x0100
886#define STELLARIS_ADC_FIFO_FULL 0x1000
887
888typedef struct
889{
40905a6a 890 SysBusDevice busdev;
71a2df05 891 MemoryRegion iomem;
9ee6e8bb
PB
892 uint32_t actss;
893 uint32_t ris;
894 uint32_t im;
895 uint32_t emux;
896 uint32_t ostat;
897 uint32_t ustat;
898 uint32_t sspri;
899 uint32_t sac;
900 struct {
901 uint32_t state;
902 uint32_t data[16];
903 } fifo[4];
904 uint32_t ssmux[4];
905 uint32_t ssctl[4];
23e39294 906 uint32_t noise;
2c6554bc 907 qemu_irq irq[4];
9ee6e8bb
PB
908} stellaris_adc_state;
909
910static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
911{
912 int tail;
913
914 tail = s->fifo[n].state & 0xf;
915 if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
916 s->ustat |= 1 << n;
917 } else {
918 s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
919 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
920 if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
921 s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
922 }
923 return s->fifo[n].data[tail];
924}
925
926static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
927 uint32_t value)
928{
929 int head;
930
2c6554bc
PB
931 /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
932 FIFO fir each sequencer. */
9ee6e8bb
PB
933 head = (s->fifo[n].state >> 4) & 0xf;
934 if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
935 s->ostat |= 1 << n;
936 return;
937 }
938 s->fifo[n].data[head] = value;
939 head = (head + 1) & 0xf;
940 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
941 s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
942 if ((s->fifo[n].state & 0xf) == head)
943 s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
944}
945
946static void stellaris_adc_update(stellaris_adc_state *s)
947{
948 int level;
2c6554bc 949 int n;
9ee6e8bb 950
2c6554bc
PB
951 for (n = 0; n < 4; n++) {
952 level = (s->ris & s->im & (1 << n)) != 0;
953 qemu_set_irq(s->irq[n], level);
954 }
9ee6e8bb
PB
955}
956
957static void stellaris_adc_trigger(void *opaque, int irq, int level)
958{
959 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
2c6554bc 960 int n;
9ee6e8bb 961
2c6554bc
PB
962 for (n = 0; n < 4; n++) {
963 if ((s->actss & (1 << n)) == 0) {
964 continue;
965 }
9ee6e8bb 966
2c6554bc
PB
967 if (((s->emux >> (n * 4)) & 0xff) != 5) {
968 continue;
969 }
970
971 /* Some applications use the ADC as a random number source, so introduce
972 some variation into the signal. */
973 s->noise = s->noise * 314159 + 1;
974 /* ??? actual inputs not implemented. Return an arbitrary value. */
975 stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
976 s->ris |= (1 << n);
977 stellaris_adc_update(s);
978 }
9ee6e8bb
PB
979}
980
981static void stellaris_adc_reset(stellaris_adc_state *s)
982{
983 int n;
984
985 for (n = 0; n < 4; n++) {
986 s->ssmux[n] = 0;
987 s->ssctl[n] = 0;
988 s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
989 }
990}
991
71a2df05
BC
992static uint64_t stellaris_adc_read(void *opaque, target_phys_addr_t offset,
993 unsigned size)
9ee6e8bb
PB
994{
995 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
996
997 /* TODO: Implement this. */
9ee6e8bb
PB
998 if (offset >= 0x40 && offset < 0xc0) {
999 int n;
1000 n = (offset - 0x40) >> 5;
1001 switch (offset & 0x1f) {
1002 case 0x00: /* SSMUX */
1003 return s->ssmux[n];
1004 case 0x04: /* SSCTL */
1005 return s->ssctl[n];
1006 case 0x08: /* SSFIFO */
1007 return stellaris_adc_fifo_read(s, n);
1008 case 0x0c: /* SSFSTAT */
1009 return s->fifo[n].state;
1010 default:
1011 break;
1012 }
1013 }
1014 switch (offset) {
1015 case 0x00: /* ACTSS */
1016 return s->actss;
1017 case 0x04: /* RIS */
1018 return s->ris;
1019 case 0x08: /* IM */
1020 return s->im;
1021 case 0x0c: /* ISC */
1022 return s->ris & s->im;
1023 case 0x10: /* OSTAT */
1024 return s->ostat;
1025 case 0x14: /* EMUX */
1026 return s->emux;
1027 case 0x18: /* USTAT */
1028 return s->ustat;
1029 case 0x20: /* SSPRI */
1030 return s->sspri;
1031 case 0x30: /* SAC */
1032 return s->sac;
1033 default:
2ac71179 1034 hw_error("strllaris_adc_read: Bad offset 0x%x\n",
9ee6e8bb
PB
1035 (int)offset);
1036 return 0;
1037 }
1038}
1039
c227f099 1040static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
71a2df05 1041 uint64_t value, unsigned size)
9ee6e8bb
PB
1042{
1043 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1044
1045 /* TODO: Implement this. */
9ee6e8bb
PB
1046 if (offset >= 0x40 && offset < 0xc0) {
1047 int n;
1048 n = (offset - 0x40) >> 5;
1049 switch (offset & 0x1f) {
1050 case 0x00: /* SSMUX */
1051 s->ssmux[n] = value & 0x33333333;
1052 return;
1053 case 0x04: /* SSCTL */
1054 if (value != 6) {
71a2df05 1055 hw_error("ADC: Unimplemented sequence %" PRIx64 "\n",
9ee6e8bb
PB
1056 value);
1057 }
1058 s->ssctl[n] = value;
1059 return;
1060 default:
1061 break;
1062 }
1063 }
1064 switch (offset) {
1065 case 0x00: /* ACTSS */
1066 s->actss = value & 0xf;
9ee6e8bb
PB
1067 break;
1068 case 0x08: /* IM */
1069 s->im = value;
1070 break;
1071 case 0x0c: /* ISC */
1072 s->ris &= ~value;
1073 break;
1074 case 0x10: /* OSTAT */
1075 s->ostat &= ~value;
1076 break;
1077 case 0x14: /* EMUX */
1078 s->emux = value;
1079 break;
1080 case 0x18: /* USTAT */
1081 s->ustat &= ~value;
1082 break;
1083 case 0x20: /* SSPRI */
1084 s->sspri = value;
1085 break;
1086 case 0x28: /* PSSI */
2ac71179 1087 hw_error("Not implemented: ADC sample initiate\n");
9ee6e8bb
PB
1088 break;
1089 case 0x30: /* SAC */
1090 s->sac = value;
1091 break;
1092 default:
2ac71179 1093 hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
1094 }
1095 stellaris_adc_update(s);
1096}
1097
71a2df05
BC
1098static const MemoryRegionOps stellaris_adc_ops = {
1099 .read = stellaris_adc_read,
1100 .write = stellaris_adc_write,
1101 .endianness = DEVICE_NATIVE_ENDIAN,
9ee6e8bb
PB
1102};
1103
cf1d31dc
JQ
1104static const VMStateDescription vmstate_stellaris_adc = {
1105 .name = "stellaris_adc",
1106 .version_id = 1,
1107 .minimum_version_id = 1,
1108 .minimum_version_id_old = 1,
1109 .fields = (VMStateField[]) {
1110 VMSTATE_UINT32(actss, stellaris_adc_state),
1111 VMSTATE_UINT32(ris, stellaris_adc_state),
1112 VMSTATE_UINT32(im, stellaris_adc_state),
1113 VMSTATE_UINT32(emux, stellaris_adc_state),
1114 VMSTATE_UINT32(ostat, stellaris_adc_state),
1115 VMSTATE_UINT32(ustat, stellaris_adc_state),
1116 VMSTATE_UINT32(sspri, stellaris_adc_state),
1117 VMSTATE_UINT32(sac, stellaris_adc_state),
1118 VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
1119 VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
1120 VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
1121 VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
1122 VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
1123 VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
1124 VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
1125 VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
1126 VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
1127 VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
1128 VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
1129 VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
1130 VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
1131 VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
1132 VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
1133 VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
1134 VMSTATE_UINT32(noise, stellaris_adc_state),
1135 VMSTATE_END_OF_LIST()
23e39294 1136 }
cf1d31dc 1137};
23e39294 1138
81a322d4 1139static int stellaris_adc_init(SysBusDevice *dev)
9ee6e8bb 1140{
40905a6a 1141 stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
2c6554bc 1142 int n;
9ee6e8bb 1143
2c6554bc 1144 for (n = 0; n < 4; n++) {
40905a6a 1145 sysbus_init_irq(dev, &s->irq[n]);
2c6554bc 1146 }
9ee6e8bb 1147
71a2df05
BC
1148 memory_region_init_io(&s->iomem, &stellaris_adc_ops, s,
1149 "adc", 0x1000);
750ecd44 1150 sysbus_init_mmio(dev, &s->iomem);
9ee6e8bb 1151 stellaris_adc_reset(s);
40905a6a 1152 qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
cf1d31dc 1153 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_adc, s);
81a322d4 1154 return 0;
9ee6e8bb
PB
1155}
1156
775616c3
PB
1157/* Some boards have both an OLED controller and SD card connected to
1158 the same SSI port, with the SD card chip select connected to a
1159 GPIO pin. Technically the OLED chip select is connected to the SSI
1160 Fss pin. We do not bother emulating that as both devices should
1161 never be selected simultaneously, and our OLED controller ignores stray
1162 0xff commands that occur when deselecting the SD card. */
1163
1164typedef struct {
5493e33f 1165 SSISlave ssidev;
775616c3
PB
1166 qemu_irq irq;
1167 int current_dev;
5493e33f 1168 SSIBus *bus[2];
775616c3
PB
1169} stellaris_ssi_bus_state;
1170
1171static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1172{
1173 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1174
1175 s->current_dev = level;
1176}
1177
5493e33f 1178static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
775616c3 1179{
5493e33f 1180 stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
775616c3 1181
5493e33f 1182 return ssi_transfer(s->bus[s->current_dev], val);
775616c3
PB
1183}
1184
a4dec1d0
JQ
1185static const VMStateDescription vmstate_stellaris_ssi_bus = {
1186 .name = "stellaris_ssi_bus",
1187 .version_id = 1,
1188 .minimum_version_id = 1,
1189 .minimum_version_id_old = 1,
1190 .fields = (VMStateField[]) {
1191 VMSTATE_INT32(current_dev, stellaris_ssi_bus_state),
1192 VMSTATE_END_OF_LIST()
1193 }
1194};
23e39294 1195
81a322d4 1196static int stellaris_ssi_bus_init(SSISlave *dev)
775616c3 1197{
5493e33f
PB
1198 stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1199
02e2da45
PB
1200 s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
1201 s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
5493e33f
PB
1202 qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1203
a4dec1d0 1204 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_ssi_bus, s);
81a322d4 1205 return 0;
775616c3
PB
1206}
1207
9ee6e8bb
PB
1208/* Board init. */
1209static stellaris_board_info stellaris_boards[] = {
1210 { "LM3S811EVB",
1211 0,
1212 0x0032000e,
1213 0x001f001f, /* dc0 */
1214 0x001132bf,
1215 0x01071013,
1216 0x3f0f01ff,
1217 0x0000001f,
cf0dbb21 1218 BP_OLED_I2C
9ee6e8bb
PB
1219 },
1220 { "LM3S6965EVB",
1221 0x10010002,
1222 0x1073402e,
1223 0x00ff007f, /* dc0 */
1224 0x001133ff,
1225 0x030f5317,
1226 0x0f0f87ff,
1227 0x5000007f,
cf0dbb21 1228 BP_OLED_SSI | BP_GAMEPAD
9ee6e8bb
PB
1229 }
1230};
1231
1232static void stellaris_init(const char *kernel_filename, const char *cpu_model,
3023f332 1233 stellaris_board_info *board)
9ee6e8bb
PB
1234{
1235 static const int uart_irq[] = {5, 6, 33, 34};
1236 static const int timer_irq[] = {19, 21, 23, 35};
1237 static const uint32_t gpio_addr[7] =
1238 { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1239 0x40024000, 0x40025000, 0x40026000};
1240 static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1241
7d6f78cf 1242 MemoryRegion *address_space_mem = get_system_memory();
9ee6e8bb 1243 qemu_irq *pic;
40905a6a
PB
1244 DeviceState *gpio_dev[7];
1245 qemu_irq gpio_in[7][8];
1246 qemu_irq gpio_out[7][8];
9ee6e8bb
PB
1247 qemu_irq adc;
1248 int sram_size;
1249 int flash_size;
1250 i2c_bus *i2c;
40905a6a 1251 DeviceState *dev;
9ee6e8bb 1252 int i;
40905a6a 1253 int j;
9ee6e8bb
PB
1254
1255 flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1256 sram_size = (board->dc0 >> 18) + 1;
7d6f78cf
AK
1257 pic = armv7m_init(address_space_mem,
1258 flash_size, sram_size, kernel_filename, cpu_model);
9ee6e8bb
PB
1259
1260 if (board->dc1 & (1 << 16)) {
40905a6a
PB
1261 dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
1262 pic[14], pic[15], pic[16], pic[17], NULL);
1263 adc = qdev_get_gpio_in(dev, 0);
9ee6e8bb
PB
1264 } else {
1265 adc = NULL;
1266 }
1267 for (i = 0; i < 4; i++) {
1268 if (board->dc2 & (0x10000 << i)) {
40905a6a
PB
1269 dev = sysbus_create_simple("stellaris-gptm",
1270 0x40030000 + i * 0x1000,
1271 pic[timer_irq[i]]);
1272 /* TODO: This is incorrect, but we get away with it because
1273 the ADC output is only ever pulsed. */
1274 qdev_connect_gpio_out(dev, 0, adc);
9ee6e8bb
PB
1275 }
1276 }
1277
6eed1856 1278 stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr.a);
9ee6e8bb
PB
1279
1280 for (i = 0; i < 7; i++) {
1281 if (board->dc4 & (1 << i)) {
7063f49f 1282 gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
40905a6a
PB
1283 pic[gpio_irq[i]]);
1284 for (j = 0; j < 8; j++) {
1285 gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
1286 gpio_out[i][j] = NULL;
1287 }
9ee6e8bb
PB
1288 }
1289 }
1290
1291 if (board->dc2 & (1 << 12)) {
1de9610c 1292 dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
02e2da45 1293 i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
cf0dbb21 1294 if (board->peripherals & BP_OLED_I2C) {
d2199005 1295 i2c_create_slave(i2c, "ssd0303", 0x3d);
9ee6e8bb
PB
1296 }
1297 }
1298
1299 for (i = 0; i < 4; i++) {
1300 if (board->dc2 & (1 << i)) {
a7d518a6
PB
1301 sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1302 pic[uart_irq[i]]);
9ee6e8bb
PB
1303 }
1304 }
1305 if (board->dc2 & (1 << 4)) {
5493e33f 1306 dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
cf0dbb21 1307 if (board->peripherals & BP_OLED_SSI) {
5493e33f
PB
1308 DeviceState *mux;
1309 void *bus;
775616c3 1310
5493e33f
PB
1311 bus = qdev_get_child_bus(dev, "ssi");
1312 mux = ssi_create_slave(bus, "evb6965-ssi");
1313 gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
775616c3 1314
5493e33f 1315 bus = qdev_get_child_bus(mux, "ssi0");
22ed1d34 1316 ssi_create_slave(bus, "ssi-sd");
5493e33f
PB
1317
1318 bus = qdev_get_child_bus(mux, "ssi1");
1319 dev = ssi_create_slave(bus, "ssd0323");
1320 gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0);
775616c3 1321
775616c3
PB
1322 /* Make sure the select pin is high. */
1323 qemu_irq_raise(gpio_out[GPIO_D][0]);
9ee6e8bb
PB
1324 }
1325 }
a5580466
PB
1326 if (board->dc4 & (1 << 28)) {
1327 DeviceState *enet;
1328
1329 qemu_check_nic_model(&nd_table[0], "stellaris");
1330
1331 enet = qdev_create(NULL, "stellaris_enet");
540f006a 1332 qdev_set_nic_properties(enet, &nd_table[0]);
e23a1b33 1333 qdev_init_nofail(enet);
a5580466
PB
1334 sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
1335 sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
1336 }
cf0dbb21
PB
1337 if (board->peripherals & BP_GAMEPAD) {
1338 qemu_irq gpad_irq[5];
1339 static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1340
1341 gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1342 gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1343 gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1344 gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1345 gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1346
1347 stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1348 }
40905a6a
PB
1349 for (i = 0; i < 7; i++) {
1350 if (board->dc4 & (1 << i)) {
1351 for (j = 0; j < 8; j++) {
1352 if (gpio_out[i][j]) {
1353 qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
1354 }
1355 }
1356 }
1357 }
9ee6e8bb
PB
1358}
1359
1360/* FIXME: Figure out how to generate these from stellaris_boards. */
c227f099 1361static void lm3s811evb_init(ram_addr_t ram_size,
3023f332 1362 const char *boot_device,
9ee6e8bb
PB
1363 const char *kernel_filename, const char *kernel_cmdline,
1364 const char *initrd_filename, const char *cpu_model)
1365{
3023f332 1366 stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
9ee6e8bb
PB
1367}
1368
c227f099 1369static void lm3s6965evb_init(ram_addr_t ram_size,
3023f332 1370 const char *boot_device,
9ee6e8bb
PB
1371 const char *kernel_filename, const char *kernel_cmdline,
1372 const char *initrd_filename, const char *cpu_model)
1373{
3023f332 1374 stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
9ee6e8bb
PB
1375}
1376
f80f9ec9 1377static QEMUMachine lm3s811evb_machine = {
4b32e168
AL
1378 .name = "lm3s811evb",
1379 .desc = "Stellaris LM3S811EVB",
1380 .init = lm3s811evb_init,
9ee6e8bb
PB
1381};
1382
f80f9ec9 1383static QEMUMachine lm3s6965evb_machine = {
4b32e168
AL
1384 .name = "lm3s6965evb",
1385 .desc = "Stellaris LM3S6965EVB",
1386 .init = lm3s6965evb_init,
9ee6e8bb 1387};
1de9610c 1388
f80f9ec9
AL
1389static void stellaris_machine_init(void)
1390{
1391 qemu_register_machine(&lm3s811evb_machine);
1392 qemu_register_machine(&lm3s6965evb_machine);
1393}
1394
1395machine_init(stellaris_machine_init);
1396
cd6c4cf2
AL
1397static void stellaris_ssi_bus_class_init(ObjectClass *klass, void *data)
1398{
1399 SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
1400
1401 k->init = stellaris_ssi_bus_init;
1402 k->transfer = stellaris_ssi_bus_transfer;
1403}
1404
39bffca2
AL
1405static TypeInfo stellaris_ssi_bus_info = {
1406 .name = "evb6965-ssi",
1407 .parent = TYPE_SSI_SLAVE,
1408 .instance_size = sizeof(stellaris_ssi_bus_state),
1409 .class_init = stellaris_ssi_bus_class_init,
5493e33f
PB
1410};
1411
999e12bb
AL
1412static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
1413{
1414 SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
1415
1416 sdc->init = stellaris_i2c_init;
1417}
1418
39bffca2
AL
1419static TypeInfo stellaris_i2c_info = {
1420 .name = "stellaris-i2c",
1421 .parent = TYPE_SYS_BUS_DEVICE,
1422 .instance_size = sizeof(stellaris_i2c_state),
1423 .class_init = stellaris_i2c_class_init,
999e12bb
AL
1424};
1425
1426static void stellaris_gptm_class_init(ObjectClass *klass, void *data)
1427{
1428 SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
1429
1430 sdc->init = stellaris_gptm_init;
1431}
1432
39bffca2
AL
1433static TypeInfo stellaris_gptm_info = {
1434 .name = "stellaris-gptm",
1435 .parent = TYPE_SYS_BUS_DEVICE,
1436 .instance_size = sizeof(gptm_state),
1437 .class_init = stellaris_gptm_class_init,
999e12bb
AL
1438};
1439
1440static void stellaris_adc_class_init(ObjectClass *klass, void *data)
1441{
1442 SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
1443
1444 sdc->init = stellaris_adc_init;
1445}
1446
39bffca2
AL
1447static TypeInfo stellaris_adc_info = {
1448 .name = "stellaris-adc",
1449 .parent = TYPE_SYS_BUS_DEVICE,
1450 .instance_size = sizeof(stellaris_adc_state),
1451 .class_init = stellaris_adc_class_init,
999e12bb
AL
1452};
1453
1de9610c
PB
1454static void stellaris_register_devices(void)
1455{
39bffca2
AL
1456 type_register_static(&stellaris_i2c_info);
1457 type_register_static(&stellaris_gptm_info);
1458 type_register_static(&stellaris_adc_info);
1459 type_register_static(&stellaris_ssi_bus_info);
1de9610c
PB
1460}
1461
1462device_init(stellaris_register_devices)