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