|
|
1.1 root 1: /*
1.1.1.2 root 2: * Luminary Micro Stellaris peripherals
1.1 root 3: *
4: * Copyright (c) 2006 CodeSourcery.
5: * Written by Paul Brook
6: *
7: * This code is licenced under the GPL.
8: */
9:
1.1.1.3 root 10: #include "sysbus.h"
11: #include "ssi.h"
1.1 root 12: #include "arm-misc.h"
13: #include "devices.h"
14: #include "qemu-timer.h"
15: #include "i2c.h"
16: #include "net.h"
17: #include "sysemu.h"
18: #include "boards.h"
19:
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:
32: typedef 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;
41: uint32_t peripherals;
42: } stellaris_board_info;
43:
44: /* General purpose timer module. */
45:
46: typedef struct gptm_state {
1.1.1.3 root 47: SysBusDevice busdev;
1.1 root 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];
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:
66: static 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:
73: static void gptm_stop(gptm_state *s, int n)
74: {
75: qemu_del_timer(s->timer[n]);
76: }
77:
78: static 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);
90: tick += (int64_t)count * system_clock_scale;
91: } else if (s->config == 1) {
92: /* 32-bit RTC. 1Hz tick. */
1.1.1.4 ! root 93: tick += get_ticks_per_sec();
1.1 root 94: } else if (s->mode[n] == 0xa) {
95: /* PWM mode. Not implemented. */
96: } else {
1.1.1.3 root 97: hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
1.1 root 98: }
99: s->tick[n] = tick;
100: qemu_mod_timer(s->timer[n], tick);
101: }
102:
103: static 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. */
1.1.1.3 root 115: qemu_irq_pulse(s->trigger);
1.1 root 116: }
117: if (s->mode[0] & 1) {
118: /* One-shot. */
119: s->control &= ~1;
120: } else {
121: /* Periodic. */
122: gptm_reload(s, 0, 0);
123: }
124: } else if (s->config == 1) {
125: /* RTC. */
126: uint32_t match;
127: s->rtc++;
128: match = s->match[0] | (s->match[1] << 16);
129: if (s->rtc > match)
130: s->rtc = 0;
131: if (s->rtc == 0) {
132: s->state |= 8;
133: }
134: gptm_reload(s, 0, 0);
135: } else if (s->mode[n] == 0xa) {
136: /* PWM mode. Not implemented. */
137: } else {
1.1.1.3 root 138: hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
1.1 root 139: }
140: gptm_update_irq(s);
141: }
142:
143: static uint32_t gptm_read(void *opaque, target_phys_addr_t offset)
144: {
145: gptm_state *s = (gptm_state *)opaque;
146:
147: switch (offset) {
148: case 0x00: /* CFG */
149: return s->config;
150: case 0x04: /* TAMR */
151: return s->mode[0];
152: case 0x08: /* TBMR */
153: return s->mode[1];
154: case 0x0c: /* CTL */
155: return s->control;
156: case 0x18: /* IMR */
157: return s->mask;
158: case 0x1c: /* RIS */
159: return s->state;
160: case 0x20: /* MIS */
161: return s->state & s->mask;
162: case 0x24: /* CR */
163: return 0;
164: case 0x28: /* TAILR */
165: return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
166: case 0x2c: /* TBILR */
167: return s->load[1];
168: case 0x30: /* TAMARCHR */
169: return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
170: case 0x34: /* TBMATCHR */
171: return s->match[1];
172: case 0x38: /* TAPR */
173: return s->prescale[0];
174: case 0x3c: /* TBPR */
175: return s->prescale[1];
176: case 0x40: /* TAPMR */
177: return s->match_prescale[0];
178: case 0x44: /* TBPMR */
179: return s->match_prescale[1];
180: case 0x48: /* TAR */
181: if (s->control == 1)
182: return s->rtc;
183: case 0x4c: /* TBR */
1.1.1.3 root 184: hw_error("TODO: Timer value read\n");
1.1 root 185: default:
1.1.1.3 root 186: hw_error("gptm_read: Bad offset 0x%x\n", (int)offset);
1.1 root 187: return 0;
188: }
189: }
190:
191: static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value)
192: {
193: gptm_state *s = (gptm_state *)opaque;
194: uint32_t oldval;
195:
196: /* The timers should be disabled before changing the configuration.
197: We take advantage of this and defer everything until the timer
198: is enabled. */
199: switch (offset) {
200: case 0x00: /* CFG */
201: s->config = value;
202: break;
203: case 0x04: /* TAMR */
204: s->mode[0] = value;
205: break;
206: case 0x08: /* TBMR */
207: s->mode[1] = value;
208: break;
209: case 0x0c: /* CTL */
210: oldval = s->control;
211: s->control = value;
212: /* TODO: Implement pause. */
213: if ((oldval ^ value) & 1) {
214: if (value & 1) {
215: gptm_reload(s, 0, 1);
216: } else {
217: gptm_stop(s, 0);
218: }
219: }
220: if (((oldval ^ value) & 0x100) && s->config >= 4) {
221: if (value & 0x100) {
222: gptm_reload(s, 1, 1);
223: } else {
224: gptm_stop(s, 1);
225: }
226: }
227: break;
228: case 0x18: /* IMR */
229: s->mask = value & 0x77;
230: gptm_update_irq(s);
231: break;
232: case 0x24: /* CR */
233: s->state &= ~value;
234: break;
235: case 0x28: /* TAILR */
236: s->load[0] = value & 0xffff;
237: if (s->config < 4) {
238: s->load[1] = value >> 16;
239: }
240: break;
241: case 0x2c: /* TBILR */
242: s->load[1] = value & 0xffff;
243: break;
244: case 0x30: /* TAMARCHR */
245: s->match[0] = value & 0xffff;
246: if (s->config < 4) {
247: s->match[1] = value >> 16;
248: }
249: break;
250: case 0x34: /* TBMATCHR */
251: s->match[1] = value >> 16;
252: break;
253: case 0x38: /* TAPR */
254: s->prescale[0] = value;
255: break;
256: case 0x3c: /* TBPR */
257: s->prescale[1] = value;
258: break;
259: case 0x40: /* TAPMR */
260: s->match_prescale[0] = value;
261: break;
262: case 0x44: /* TBPMR */
263: s->match_prescale[0] = value;
264: break;
265: default:
1.1.1.3 root 266: hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
1.1 root 267: }
268: gptm_update_irq(s);
269: }
270:
1.1.1.4 ! root 271: static CPUReadMemoryFunc * const gptm_readfn[] = {
1.1 root 272: gptm_read,
273: gptm_read,
274: gptm_read
275: };
276:
1.1.1.4 ! root 277: static CPUWriteMemoryFunc * const gptm_writefn[] = {
1.1 root 278: gptm_write,
279: gptm_write,
280: gptm_write
281: };
282:
1.1.1.2 root 283: static void gptm_save(QEMUFile *f, void *opaque)
284: {
285: gptm_state *s = (gptm_state *)opaque;
286:
287: qemu_put_be32(f, s->config);
288: qemu_put_be32(f, s->mode[0]);
289: qemu_put_be32(f, s->mode[1]);
290: qemu_put_be32(f, s->control);
291: qemu_put_be32(f, s->state);
292: qemu_put_be32(f, s->mask);
293: qemu_put_be32(f, s->mode[0]);
294: qemu_put_be32(f, s->mode[0]);
295: qemu_put_be32(f, s->load[0]);
296: qemu_put_be32(f, s->load[1]);
297: qemu_put_be32(f, s->match[0]);
298: qemu_put_be32(f, s->match[1]);
299: qemu_put_be32(f, s->prescale[0]);
300: qemu_put_be32(f, s->prescale[1]);
301: qemu_put_be32(f, s->match_prescale[0]);
302: qemu_put_be32(f, s->match_prescale[1]);
303: qemu_put_be32(f, s->rtc);
304: qemu_put_be64(f, s->tick[0]);
305: qemu_put_be64(f, s->tick[1]);
306: qemu_put_timer(f, s->timer[0]);
307: qemu_put_timer(f, s->timer[1]);
308: }
309:
310: static int gptm_load(QEMUFile *f, void *opaque, int version_id)
311: {
312: gptm_state *s = (gptm_state *)opaque;
313:
314: if (version_id != 1)
315: return -EINVAL;
316:
317: s->config = qemu_get_be32(f);
318: s->mode[0] = qemu_get_be32(f);
319: s->mode[1] = qemu_get_be32(f);
320: s->control = qemu_get_be32(f);
321: s->state = qemu_get_be32(f);
322: s->mask = qemu_get_be32(f);
323: s->mode[0] = qemu_get_be32(f);
324: s->mode[0] = qemu_get_be32(f);
325: s->load[0] = qemu_get_be32(f);
326: s->load[1] = qemu_get_be32(f);
327: s->match[0] = qemu_get_be32(f);
328: s->match[1] = qemu_get_be32(f);
329: s->prescale[0] = qemu_get_be32(f);
330: s->prescale[1] = qemu_get_be32(f);
331: s->match_prescale[0] = qemu_get_be32(f);
332: s->match_prescale[1] = qemu_get_be32(f);
333: s->rtc = qemu_get_be32(f);
334: s->tick[0] = qemu_get_be64(f);
335: s->tick[1] = qemu_get_be64(f);
336: qemu_get_timer(f, s->timer[0]);
337: qemu_get_timer(f, s->timer[1]);
338:
339: return 0;
340: }
341:
1.1.1.4 ! root 342: static int stellaris_gptm_init(SysBusDevice *dev)
1.1 root 343: {
344: int iomemtype;
1.1.1.3 root 345: gptm_state *s = FROM_SYSBUS(gptm_state, dev);
1.1 root 346:
1.1.1.3 root 347: sysbus_init_irq(dev, &s->irq);
348: qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
1.1 root 349:
1.1.1.3 root 350: iomemtype = cpu_register_io_memory(gptm_readfn,
1.1 root 351: gptm_writefn, s);
1.1.1.3 root 352: sysbus_init_mmio(dev, 0x1000, iomemtype);
353:
354: s->opaque[0] = s->opaque[1] = s;
1.1 root 355: s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);
356: s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]);
1.1.1.2 root 357: register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s);
1.1.1.4 ! root 358: return 0;
1.1 root 359: }
360:
361:
362: /* System controller. */
363:
364: typedef struct {
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;
376: uint32_t user0;
377: uint32_t user1;
378: qemu_irq irq;
379: stellaris_board_info *board;
380: } ssys_state;
381:
382: static void ssys_update(ssys_state *s)
383: {
384: qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
385: }
386:
387: static 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:
406: static 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:
425: static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
426: {
427: ssys_state *s = (ssys_state *)opaque;
428:
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;
496: case 0x1e0: /* USER0 */
497: return s->user0;
498: case 0x1e4: /* USER1 */
499: return s->user1;
500: default:
1.1.1.3 root 501: hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
1.1 root 502: return 0;
503: }
504: }
505:
1.1.1.2 root 506: static void ssys_calculate_system_clock(ssys_state *s)
507: {
508: system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
509: }
510:
1.1 root 511: static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
512: {
513: ssys_state *s = (ssys_state *)opaque;
514:
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;
1.1.1.2 root 542: ssys_calculate_system_clock(s);
1.1 root 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:
1.1.1.3 root 578: hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
1.1 root 579: }
580: ssys_update(s);
581: }
582:
1.1.1.4 ! root 583: static CPUReadMemoryFunc * const ssys_readfn[] = {
1.1 root 584: ssys_read,
585: ssys_read,
586: ssys_read
587: };
588:
1.1.1.4 ! root 589: static CPUWriteMemoryFunc * const ssys_writefn[] = {
1.1 root 590: ssys_write,
591: ssys_write,
592: ssys_write
593: };
594:
595: static void ssys_reset(void *opaque)
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:
1.1.1.2 root 606: static 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:
629: static 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:
1.1.1.4 ! root 658: static int stellaris_sys_init(uint32_t base, qemu_irq irq,
! 659: stellaris_board_info * board,
! 660: uint8_t *macaddr)
1.1 root 661: {
662: int iomemtype;
663: ssys_state *s;
664:
665: s = (ssys_state *)qemu_mallocz(sizeof(ssys_state));
666: s->irq = irq;
667: s->board = board;
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);
671:
1.1.1.3 root 672: iomemtype = cpu_register_io_memory(ssys_readfn,
1.1 root 673: ssys_writefn, s);
674: cpu_register_physical_memory(base, 0x00001000, iomemtype);
675: ssys_reset(s);
1.1.1.2 root 676: register_savevm("stellaris_sys", -1, 1, ssys_save, ssys_load, s);
1.1.1.4 ! root 677: return 0;
1.1 root 678: }
679:
680:
681: /* I2C controller. */
682:
683: typedef struct {
1.1.1.3 root 684: SysBusDevice busdev;
1.1 root 685: i2c_bus *bus;
686: qemu_irq irq;
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:
704: static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
705: {
706: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
707:
708: switch (offset) {
709: case 0x00: /* MSA */
710: return s->msa;
711: case 0x04: /* MCS */
712: /* We don't emulate timing, so the controller is never busy. */
713: return s->mcs | STELLARIS_I2C_MCS_IDLE;
714: case 0x08: /* MDR */
715: return s->mdr;
716: case 0x0c: /* MTPR */
717: return s->mtpr;
718: case 0x10: /* MIMR */
719: return s->mimr;
720: case 0x14: /* MRIS */
721: return s->mris;
722: case 0x18: /* MMIS */
723: return s->mris & s->mimr;
724: case 0x20: /* MCR */
725: return s->mcr;
726: default:
1.1.1.3 root 727: hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
1.1 root 728: return 0;
729: }
730: }
731:
732: static void stellaris_i2c_update(stellaris_i2c_state *s)
733: {
734: int level;
735:
736: level = (s->mris & s->mimr) != 0;
737: qemu_set_irq(s->irq, level);
738: }
739:
740: static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
741: uint32_t value)
742: {
743: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
744:
745: switch (offset) {
746: case 0x00: /* MSA */
747: s->msa = value & 0xff;
748: break;
749: case 0x04: /* MCS */
750: if ((s->mcr & 0x10) == 0) {
751: /* Disabled. Do nothing. */
752: break;
753: }
754: /* Grab the bus if this is starting a transfer. */
755: if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
756: if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
757: s->mcs |= STELLARIS_I2C_MCS_ARBLST;
758: } else {
759: s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
760: s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
761: }
762: }
763: /* If we don't have the bus then indicate an error. */
764: if (!i2c_bus_busy(s->bus)
765: || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
766: s->mcs |= STELLARIS_I2C_MCS_ERROR;
767: break;
768: }
769: s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
770: if (value & 1) {
771: /* Transfer a byte. */
772: /* TODO: Handle errors. */
773: if (s->msa & 1) {
774: /* Recv */
775: s->mdr = i2c_recv(s->bus) & 0xff;
776: } else {
777: /* Send */
778: i2c_send(s->bus, s->mdr);
779: }
780: /* Raise an interrupt. */
781: s->mris |= 1;
782: }
783: if (value & 4) {
784: /* Finish transfer. */
785: i2c_end_transfer(s->bus);
786: s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
787: }
788: break;
789: case 0x08: /* MDR */
790: s->mdr = value & 0xff;
791: break;
792: case 0x0c: /* MTPR */
793: s->mtpr = value & 0xff;
794: break;
795: case 0x10: /* MIMR */
796: s->mimr = 1;
797: break;
798: case 0x1c: /* MICR */
799: s->mris &= ~value;
800: break;
801: case 0x20: /* MCR */
802: if (value & 1)
1.1.1.3 root 803: hw_error(
1.1 root 804: "stellaris_i2c_write: Loopback not implemented\n");
805: if (value & 0x20)
1.1.1.3 root 806: hw_error(
1.1 root 807: "stellaris_i2c_write: Slave mode not implemented\n");
808: s->mcr = value & 0x31;
809: break;
810: default:
1.1.1.3 root 811: hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
1.1 root 812: (int)offset);
813: }
814: stellaris_i2c_update(s);
815: }
816:
817: static void stellaris_i2c_reset(stellaris_i2c_state *s)
818: {
819: if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
820: i2c_end_transfer(s->bus);
821:
822: s->msa = 0;
823: s->mcs = 0;
824: s->mdr = 0;
825: s->mtpr = 1;
826: s->mimr = 0;
827: s->mris = 0;
828: s->mcr = 0;
829: stellaris_i2c_update(s);
830: }
831:
1.1.1.4 ! root 832: static CPUReadMemoryFunc * const stellaris_i2c_readfn[] = {
1.1 root 833: stellaris_i2c_read,
834: stellaris_i2c_read,
835: stellaris_i2c_read
836: };
837:
1.1.1.4 ! root 838: static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = {
1.1 root 839: stellaris_i2c_write,
840: stellaris_i2c_write,
841: stellaris_i2c_write
842: };
843:
1.1.1.2 root 844: static void stellaris_i2c_save(QEMUFile *f, void *opaque)
845: {
846: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
847:
848: qemu_put_be32(f, s->msa);
849: qemu_put_be32(f, s->mcs);
850: qemu_put_be32(f, s->mdr);
851: qemu_put_be32(f, s->mtpr);
852: qemu_put_be32(f, s->mimr);
853: qemu_put_be32(f, s->mris);
854: qemu_put_be32(f, s->mcr);
855: }
856:
857: static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id)
858: {
859: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
860:
861: if (version_id != 1)
862: return -EINVAL;
863:
864: s->msa = qemu_get_be32(f);
865: s->mcs = qemu_get_be32(f);
866: s->mdr = qemu_get_be32(f);
867: s->mtpr = qemu_get_be32(f);
868: s->mimr = qemu_get_be32(f);
869: s->mris = qemu_get_be32(f);
870: s->mcr = qemu_get_be32(f);
871:
872: return 0;
873: }
874:
1.1.1.4 ! root 875: static int stellaris_i2c_init(SysBusDevice * dev)
1.1 root 876: {
1.1.1.3 root 877: stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
878: i2c_bus *bus;
1.1 root 879: int iomemtype;
880:
1.1.1.3 root 881: sysbus_init_irq(dev, &s->irq);
882: bus = i2c_init_bus(&dev->qdev, "i2c");
1.1 root 883: s->bus = bus;
884:
1.1.1.3 root 885: iomemtype = cpu_register_io_memory(stellaris_i2c_readfn,
1.1 root 886: stellaris_i2c_writefn, s);
1.1.1.3 root 887: sysbus_init_mmio(dev, 0x1000, iomemtype);
1.1 root 888: /* ??? For now we only implement the master interface. */
889: stellaris_i2c_reset(s);
1.1.1.2 root 890: register_savevm("stellaris_i2c", -1, 1,
891: stellaris_i2c_save, stellaris_i2c_load, s);
1.1.1.4 ! root 892: return 0;
1.1 root 893: }
894:
895: /* Analogue to Digital Converter. This is only partially implemented,
896: enough for applications that use a combined ADC and timer tick. */
897:
898: #define STELLARIS_ADC_EM_CONTROLLER 0
899: #define STELLARIS_ADC_EM_COMP 1
900: #define STELLARIS_ADC_EM_EXTERNAL 4
901: #define STELLARIS_ADC_EM_TIMER 5
902: #define STELLARIS_ADC_EM_PWM0 6
903: #define STELLARIS_ADC_EM_PWM1 7
904: #define STELLARIS_ADC_EM_PWM2 8
905:
906: #define STELLARIS_ADC_FIFO_EMPTY 0x0100
907: #define STELLARIS_ADC_FIFO_FULL 0x1000
908:
909: typedef struct
910: {
1.1.1.3 root 911: SysBusDevice busdev;
1.1 root 912: uint32_t actss;
913: uint32_t ris;
914: uint32_t im;
915: uint32_t emux;
916: uint32_t ostat;
917: uint32_t ustat;
918: uint32_t sspri;
919: uint32_t sac;
920: struct {
921: uint32_t state;
922: uint32_t data[16];
923: } fifo[4];
924: uint32_t ssmux[4];
925: uint32_t ssctl[4];
1.1.1.2 root 926: uint32_t noise;
1.1.1.3 root 927: qemu_irq irq[4];
1.1 root 928: } stellaris_adc_state;
929:
930: static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
931: {
932: int tail;
933:
934: tail = s->fifo[n].state & 0xf;
935: if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
936: s->ustat |= 1 << n;
937: } else {
938: s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
939: s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
940: if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
941: s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
942: }
943: return s->fifo[n].data[tail];
944: }
945:
946: static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
947: uint32_t value)
948: {
949: int head;
950:
1.1.1.3 root 951: /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
952: FIFO fir each sequencer. */
1.1 root 953: head = (s->fifo[n].state >> 4) & 0xf;
954: if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
955: s->ostat |= 1 << n;
956: return;
957: }
958: s->fifo[n].data[head] = value;
959: head = (head + 1) & 0xf;
960: s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
961: s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
962: if ((s->fifo[n].state & 0xf) == head)
963: s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
964: }
965:
966: static void stellaris_adc_update(stellaris_adc_state *s)
967: {
968: int level;
1.1.1.3 root 969: int n;
1.1 root 970:
1.1.1.3 root 971: for (n = 0; n < 4; n++) {
972: level = (s->ris & s->im & (1 << n)) != 0;
973: qemu_set_irq(s->irq[n], level);
974: }
1.1 root 975: }
976:
977: static void stellaris_adc_trigger(void *opaque, int irq, int level)
978: {
979: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1.1.1.3 root 980: int n;
1.1 root 981:
1.1.1.3 root 982: for (n = 0; n < 4; n++) {
983: if ((s->actss & (1 << n)) == 0) {
984: continue;
985: }
1.1 root 986:
1.1.1.3 root 987: if (((s->emux >> (n * 4)) & 0xff) != 5) {
988: continue;
989: }
990:
991: /* Some applications use the ADC as a random number source, so introduce
992: some variation into the signal. */
993: s->noise = s->noise * 314159 + 1;
994: /* ??? actual inputs not implemented. Return an arbitrary value. */
995: stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
996: s->ris |= (1 << n);
997: stellaris_adc_update(s);
998: }
1.1 root 999: }
1000:
1001: static void stellaris_adc_reset(stellaris_adc_state *s)
1002: {
1003: int n;
1004:
1005: for (n = 0; n < 4; n++) {
1006: s->ssmux[n] = 0;
1007: s->ssctl[n] = 0;
1008: s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
1009: }
1010: }
1011:
1012: static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
1013: {
1014: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1015:
1016: /* TODO: Implement this. */
1017: if (offset >= 0x40 && offset < 0xc0) {
1018: int n;
1019: n = (offset - 0x40) >> 5;
1020: switch (offset & 0x1f) {
1021: case 0x00: /* SSMUX */
1022: return s->ssmux[n];
1023: case 0x04: /* SSCTL */
1024: return s->ssctl[n];
1025: case 0x08: /* SSFIFO */
1026: return stellaris_adc_fifo_read(s, n);
1027: case 0x0c: /* SSFSTAT */
1028: return s->fifo[n].state;
1029: default:
1030: break;
1031: }
1032: }
1033: switch (offset) {
1034: case 0x00: /* ACTSS */
1035: return s->actss;
1036: case 0x04: /* RIS */
1037: return s->ris;
1038: case 0x08: /* IM */
1039: return s->im;
1040: case 0x0c: /* ISC */
1041: return s->ris & s->im;
1042: case 0x10: /* OSTAT */
1043: return s->ostat;
1044: case 0x14: /* EMUX */
1045: return s->emux;
1046: case 0x18: /* USTAT */
1047: return s->ustat;
1048: case 0x20: /* SSPRI */
1049: return s->sspri;
1050: case 0x30: /* SAC */
1051: return s->sac;
1052: default:
1.1.1.3 root 1053: hw_error("strllaris_adc_read: Bad offset 0x%x\n",
1.1 root 1054: (int)offset);
1055: return 0;
1056: }
1057: }
1058:
1059: static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
1060: uint32_t value)
1061: {
1062: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1063:
1064: /* TODO: Implement this. */
1065: if (offset >= 0x40 && offset < 0xc0) {
1066: int n;
1067: n = (offset - 0x40) >> 5;
1068: switch (offset & 0x1f) {
1069: case 0x00: /* SSMUX */
1070: s->ssmux[n] = value & 0x33333333;
1071: return;
1072: case 0x04: /* SSCTL */
1073: if (value != 6) {
1.1.1.3 root 1074: hw_error("ADC: Unimplemented sequence %x\n",
1.1 root 1075: value);
1076: }
1077: s->ssctl[n] = value;
1078: return;
1079: default:
1080: break;
1081: }
1082: }
1083: switch (offset) {
1084: case 0x00: /* ACTSS */
1085: s->actss = value & 0xf;
1086: break;
1087: case 0x08: /* IM */
1088: s->im = value;
1089: break;
1090: case 0x0c: /* ISC */
1091: s->ris &= ~value;
1092: break;
1093: case 0x10: /* OSTAT */
1094: s->ostat &= ~value;
1095: break;
1096: case 0x14: /* EMUX */
1097: s->emux = value;
1098: break;
1099: case 0x18: /* USTAT */
1100: s->ustat &= ~value;
1101: break;
1102: case 0x20: /* SSPRI */
1103: s->sspri = value;
1104: break;
1105: case 0x28: /* PSSI */
1.1.1.3 root 1106: hw_error("Not implemented: ADC sample initiate\n");
1.1 root 1107: break;
1108: case 0x30: /* SAC */
1109: s->sac = value;
1110: break;
1111: default:
1.1.1.3 root 1112: hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
1.1 root 1113: }
1114: stellaris_adc_update(s);
1115: }
1116:
1.1.1.4 ! root 1117: static CPUReadMemoryFunc * const stellaris_adc_readfn[] = {
1.1 root 1118: stellaris_adc_read,
1119: stellaris_adc_read,
1120: stellaris_adc_read
1121: };
1122:
1.1.1.4 ! root 1123: static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = {
1.1 root 1124: stellaris_adc_write,
1125: stellaris_adc_write,
1126: stellaris_adc_write
1127: };
1128:
1.1.1.2 root 1129: static void stellaris_adc_save(QEMUFile *f, void *opaque)
1130: {
1131: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1132: int i;
1133: int j;
1134:
1135: qemu_put_be32(f, s->actss);
1136: qemu_put_be32(f, s->ris);
1137: qemu_put_be32(f, s->im);
1138: qemu_put_be32(f, s->emux);
1139: qemu_put_be32(f, s->ostat);
1140: qemu_put_be32(f, s->ustat);
1141: qemu_put_be32(f, s->sspri);
1142: qemu_put_be32(f, s->sac);
1143: for (i = 0; i < 4; i++) {
1144: qemu_put_be32(f, s->fifo[i].state);
1145: for (j = 0; j < 16; j++) {
1146: qemu_put_be32(f, s->fifo[i].data[j]);
1147: }
1148: qemu_put_be32(f, s->ssmux[i]);
1149: qemu_put_be32(f, s->ssctl[i]);
1150: }
1151: qemu_put_be32(f, s->noise);
1152: }
1153:
1154: static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
1155: {
1156: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1157: int i;
1158: int j;
1159:
1160: if (version_id != 1)
1161: return -EINVAL;
1162:
1163: s->actss = qemu_get_be32(f);
1164: s->ris = qemu_get_be32(f);
1165: s->im = qemu_get_be32(f);
1166: s->emux = qemu_get_be32(f);
1167: s->ostat = qemu_get_be32(f);
1168: s->ustat = qemu_get_be32(f);
1169: s->sspri = qemu_get_be32(f);
1170: s->sac = qemu_get_be32(f);
1171: for (i = 0; i < 4; i++) {
1172: s->fifo[i].state = qemu_get_be32(f);
1173: for (j = 0; j < 16; j++) {
1174: s->fifo[i].data[j] = qemu_get_be32(f);
1175: }
1176: s->ssmux[i] = qemu_get_be32(f);
1177: s->ssctl[i] = qemu_get_be32(f);
1178: }
1179: s->noise = qemu_get_be32(f);
1180:
1181: return 0;
1182: }
1183:
1.1.1.4 ! root 1184: static int stellaris_adc_init(SysBusDevice *dev)
1.1 root 1185: {
1.1.1.3 root 1186: stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
1.1 root 1187: int iomemtype;
1.1.1.3 root 1188: int n;
1.1 root 1189:
1.1.1.3 root 1190: for (n = 0; n < 4; n++) {
1191: sysbus_init_irq(dev, &s->irq[n]);
1192: }
1.1 root 1193:
1.1.1.3 root 1194: iomemtype = cpu_register_io_memory(stellaris_adc_readfn,
1.1 root 1195: stellaris_adc_writefn, s);
1.1.1.3 root 1196: sysbus_init_mmio(dev, 0x1000, iomemtype);
1.1 root 1197: stellaris_adc_reset(s);
1.1.1.3 root 1198: qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
1.1.1.2 root 1199: register_savevm("stellaris_adc", -1, 1,
1200: stellaris_adc_save, stellaris_adc_load, s);
1.1.1.4 ! root 1201: return 0;
1.1 root 1202: }
1203:
1204: /* Some boards have both an OLED controller and SD card connected to
1205: the same SSI port, with the SD card chip select connected to a
1206: GPIO pin. Technically the OLED chip select is connected to the SSI
1207: Fss pin. We do not bother emulating that as both devices should
1208: never be selected simultaneously, and our OLED controller ignores stray
1209: 0xff commands that occur when deselecting the SD card. */
1210:
1211: typedef struct {
1.1.1.3 root 1212: SSISlave ssidev;
1.1 root 1213: qemu_irq irq;
1214: int current_dev;
1.1.1.3 root 1215: SSIBus *bus[2];
1.1 root 1216: } stellaris_ssi_bus_state;
1217:
1218: static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1219: {
1220: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1221:
1222: s->current_dev = level;
1223: }
1224:
1.1.1.3 root 1225: static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
1.1 root 1226: {
1.1.1.3 root 1227: stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1.1 root 1228:
1.1.1.3 root 1229: return ssi_transfer(s->bus[s->current_dev], val);
1.1 root 1230: }
1231:
1.1.1.2 root 1232: static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque)
1233: {
1234: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1235:
1236: qemu_put_be32(f, s->current_dev);
1237: }
1238:
1239: static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id)
1240: {
1241: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1242:
1243: if (version_id != 1)
1244: return -EINVAL;
1245:
1246: s->current_dev = qemu_get_be32(f);
1247:
1248: return 0;
1249: }
1250:
1.1.1.4 ! root 1251: static int stellaris_ssi_bus_init(SSISlave *dev)
1.1.1.3 root 1252: {
1253: stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1254:
1255: s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
1256: s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
1257: qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1258:
1.1.1.2 root 1259: register_savevm("stellaris_ssi_bus", -1, 1,
1260: stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
1.1.1.4 ! root 1261: return 0;
1.1 root 1262: }
1263:
1264: /* Board init. */
1265: static stellaris_board_info stellaris_boards[] = {
1266: { "LM3S811EVB",
1267: 0,
1268: 0x0032000e,
1269: 0x001f001f, /* dc0 */
1270: 0x001132bf,
1271: 0x01071013,
1272: 0x3f0f01ff,
1273: 0x0000001f,
1274: BP_OLED_I2C
1275: },
1276: { "LM3S6965EVB",
1277: 0x10010002,
1278: 0x1073402e,
1279: 0x00ff007f, /* dc0 */
1280: 0x001133ff,
1281: 0x030f5317,
1282: 0x0f0f87ff,
1283: 0x5000007f,
1284: BP_OLED_SSI | BP_GAMEPAD
1285: }
1286: };
1287:
1288: static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1.1.1.2 root 1289: stellaris_board_info *board)
1.1 root 1290: {
1291: static const int uart_irq[] = {5, 6, 33, 34};
1292: static const int timer_irq[] = {19, 21, 23, 35};
1293: static const uint32_t gpio_addr[7] =
1294: { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1295: 0x40024000, 0x40025000, 0x40026000};
1296: static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1297:
1298: qemu_irq *pic;
1.1.1.3 root 1299: DeviceState *gpio_dev[7];
1300: qemu_irq gpio_in[7][8];
1301: qemu_irq gpio_out[7][8];
1.1 root 1302: qemu_irq adc;
1303: int sram_size;
1304: int flash_size;
1305: i2c_bus *i2c;
1.1.1.3 root 1306: DeviceState *dev;
1.1 root 1307: int i;
1.1.1.3 root 1308: int j;
1.1 root 1309:
1310: flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1311: sram_size = (board->dc0 >> 18) + 1;
1312: pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1313:
1314: if (board->dc1 & (1 << 16)) {
1.1.1.3 root 1315: dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
1316: pic[14], pic[15], pic[16], pic[17], NULL);
1317: adc = qdev_get_gpio_in(dev, 0);
1.1 root 1318: } else {
1319: adc = NULL;
1320: }
1321: for (i = 0; i < 4; i++) {
1322: if (board->dc2 & (0x10000 << i)) {
1.1.1.3 root 1323: dev = sysbus_create_simple("stellaris-gptm",
1324: 0x40030000 + i * 0x1000,
1325: pic[timer_irq[i]]);
1326: /* TODO: This is incorrect, but we get away with it because
1327: the ADC output is only ever pulsed. */
1328: qdev_connect_gpio_out(dev, 0, adc);
1.1 root 1329: }
1330: }
1331:
1332: stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr);
1333:
1334: for (i = 0; i < 7; i++) {
1335: if (board->dc4 & (1 << i)) {
1.1.1.3 root 1336: gpio_dev[i] = sysbus_create_simple("pl061", gpio_addr[i],
1337: pic[gpio_irq[i]]);
1338: for (j = 0; j < 8; j++) {
1339: gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
1340: gpio_out[i][j] = NULL;
1341: }
1.1 root 1342: }
1343: }
1344:
1345: if (board->dc2 & (1 << 12)) {
1.1.1.3 root 1346: dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
1347: i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
1.1 root 1348: if (board->peripherals & BP_OLED_I2C) {
1.1.1.3 root 1349: i2c_create_slave(i2c, "ssd0303", 0x3d);
1.1 root 1350: }
1351: }
1352:
1353: for (i = 0; i < 4; i++) {
1354: if (board->dc2 & (1 << i)) {
1.1.1.3 root 1355: sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1356: pic[uart_irq[i]]);
1.1 root 1357: }
1358: }
1359: if (board->dc2 & (1 << 4)) {
1.1.1.3 root 1360: dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
1.1 root 1361: if (board->peripherals & BP_OLED_SSI) {
1.1.1.3 root 1362: DeviceState *mux;
1363: void *bus;
1364:
1365: bus = qdev_get_child_bus(dev, "ssi");
1366: mux = ssi_create_slave(bus, "evb6965-ssi");
1367: gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
1368:
1369: bus = qdev_get_child_bus(mux, "ssi0");
1370: dev = ssi_create_slave(bus, "ssi-sd");
1371:
1372: bus = qdev_get_child_bus(mux, "ssi1");
1373: dev = ssi_create_slave(bus, "ssd0323");
1374: gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0);
1.1 root 1375:
1376: /* Make sure the select pin is high. */
1377: qemu_irq_raise(gpio_out[GPIO_D][0]);
1378: }
1379: }
1.1.1.3 root 1380: if (board->dc4 & (1 << 28)) {
1381: DeviceState *enet;
1382:
1383: qemu_check_nic_model(&nd_table[0], "stellaris");
1384:
1385: enet = qdev_create(NULL, "stellaris_enet");
1.1.1.4 ! root 1386: qdev_set_nic_properties(enet, &nd_table[0]);
! 1387: qdev_init_nofail(enet);
1.1.1.3 root 1388: sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
1389: sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
1390: }
1.1 root 1391: if (board->peripherals & BP_GAMEPAD) {
1392: qemu_irq gpad_irq[5];
1393: static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1394:
1395: gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1396: gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1397: gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1398: gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1399: gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1400:
1401: stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1402: }
1.1.1.3 root 1403: for (i = 0; i < 7; i++) {
1404: if (board->dc4 & (1 << i)) {
1405: for (j = 0; j < 8; j++) {
1406: if (gpio_out[i][j]) {
1407: qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
1408: }
1409: }
1410: }
1411: }
1.1 root 1412: }
1413:
1414: /* FIXME: Figure out how to generate these from stellaris_boards. */
1.1.1.3 root 1415: static void lm3s811evb_init(ram_addr_t ram_size,
1.1.1.2 root 1416: const char *boot_device,
1.1 root 1417: const char *kernel_filename, const char *kernel_cmdline,
1418: const char *initrd_filename, const char *cpu_model)
1419: {
1.1.1.2 root 1420: stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
1.1 root 1421: }
1422:
1.1.1.3 root 1423: static void lm3s6965evb_init(ram_addr_t ram_size,
1.1.1.2 root 1424: const char *boot_device,
1.1 root 1425: const char *kernel_filename, const char *kernel_cmdline,
1426: const char *initrd_filename, const char *cpu_model)
1427: {
1.1.1.2 root 1428: stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
1.1 root 1429: }
1430:
1.1.1.3 root 1431: static QEMUMachine lm3s811evb_machine = {
1.1.1.2 root 1432: .name = "lm3s811evb",
1433: .desc = "Stellaris LM3S811EVB",
1434: .init = lm3s811evb_init,
1.1 root 1435: };
1436:
1.1.1.3 root 1437: static QEMUMachine lm3s6965evb_machine = {
1.1.1.2 root 1438: .name = "lm3s6965evb",
1439: .desc = "Stellaris LM3S6965EVB",
1440: .init = lm3s6965evb_init,
1.1 root 1441: };
1.1.1.3 root 1442:
1443: static void stellaris_machine_init(void)
1444: {
1445: qemu_register_machine(&lm3s811evb_machine);
1446: qemu_register_machine(&lm3s6965evb_machine);
1447: }
1448:
1449: machine_init(stellaris_machine_init);
1450:
1451: static SSISlaveInfo stellaris_ssi_bus_info = {
1452: .qdev.name = "evb6965-ssi",
1453: .qdev.size = sizeof(stellaris_ssi_bus_state),
1454: .init = stellaris_ssi_bus_init,
1455: .transfer = stellaris_ssi_bus_transfer
1456: };
1457:
1458: static void stellaris_register_devices(void)
1459: {
1460: sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
1461: stellaris_i2c_init);
1462: sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
1463: stellaris_gptm_init);
1464: sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
1465: stellaris_adc_init);
1466: ssi_register_slave(&stellaris_ssi_bus_info);
1467: }
1468:
1469: device_init(stellaris_register_devices)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.