|
|
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: *
1.1.1.7 root 7: * This code is licensed under the GPL.
1.1 root 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 "boards.h"
1.1.1.8 root 18: #include "exec-memory.h"
1.1 root 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.1.9 ! root 48: MemoryRegion iomem;
1.1 root 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];
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:
67: static 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:
74: static void gptm_stop(gptm_state *s, int n)
75: {
76: qemu_del_timer(s->timer[n]);
77: }
78:
79: static void gptm_reload(gptm_state *s, int n, int reset)
80: {
81: int64_t tick;
82: if (reset)
1.1.1.7 root 83: tick = qemu_get_clock_ns(vm_clock);
1.1 root 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);
91: tick += (int64_t)count * system_clock_scale;
92: } else if (s->config == 1) {
93: /* 32-bit RTC. 1Hz tick. */
1.1.1.4 root 94: tick += get_ticks_per_sec();
1.1 root 95: } else if (s->mode[n] == 0xa) {
96: /* PWM mode. Not implemented. */
97: } else {
1.1.1.3 root 98: hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
1.1 root 99: }
100: s->tick[n] = tick;
101: qemu_mod_timer(s->timer[n], tick);
102: }
103:
104: static 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. */
1.1.1.3 root 116: qemu_irq_pulse(s->trigger);
1.1 root 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 {
1.1.1.3 root 139: hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
1.1 root 140: }
141: gptm_update_irq(s);
142: }
143:
1.1.1.9 ! root 144: static uint64_t gptm_read(void *opaque, target_phys_addr_t offset,
! 145: unsigned size)
1.1 root 146: {
147: gptm_state *s = (gptm_state *)opaque;
148:
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 */
1.1.1.3 root 186: hw_error("TODO: Timer value read\n");
1.1 root 187: default:
1.1.1.3 root 188: hw_error("gptm_read: Bad offset 0x%x\n", (int)offset);
1.1 root 189: return 0;
190: }
191: }
192:
1.1.1.9 ! root 193: static void gptm_write(void *opaque, target_phys_addr_t offset,
! 194: uint64_t value, unsigned size)
1.1 root 195: {
196: gptm_state *s = (gptm_state *)opaque;
197: uint32_t oldval;
198:
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:
1.1.1.3 root 269: hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
1.1 root 270: }
271: gptm_update_irq(s);
272: }
273:
1.1.1.9 ! root 274: static const MemoryRegionOps gptm_ops = {
! 275: .read = gptm_read,
! 276: .write = gptm_write,
! 277: .endianness = DEVICE_NATIVE_ENDIAN,
1.1 root 278: };
279:
1.1.1.7 root 280: static 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),
291: VMSTATE_UNUSED(8),
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: };
1.1.1.2 root 302:
1.1.1.4 root 303: static int stellaris_gptm_init(SysBusDevice *dev)
1.1 root 304: {
1.1.1.3 root 305: gptm_state *s = FROM_SYSBUS(gptm_state, dev);
1.1 root 306:
1.1.1.3 root 307: sysbus_init_irq(dev, &s->irq);
308: qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
1.1 root 309:
1.1.1.9 ! root 310: memory_region_init_io(&s->iomem, &gptm_ops, s,
! 311: "gptm", 0x1000);
! 312: sysbus_init_mmio(dev, &s->iomem);
1.1.1.3 root 313:
314: s->opaque[0] = s->opaque[1] = s;
1.1.1.7 root 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]);
317: vmstate_register(&dev->qdev, -1, &vmstate_stellaris_gptm, s);
1.1.1.4 root 318: return 0;
1.1 root 319: }
320:
321:
322: /* System controller. */
323:
324: typedef struct {
1.1.1.9 ! root 325: MemoryRegion iomem;
1.1 root 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;
1.1.1.8 root 332: uint32_t rcc2;
1.1 root 333: uint32_t rcgc[3];
334: uint32_t scgc[3];
335: uint32_t dcgc[3];
336: uint32_t clkvclr;
337: uint32_t ldoarst;
338: uint32_t user0;
339: uint32_t user1;
340: qemu_irq irq;
341: stellaris_board_info *board;
342: } ssys_state;
343:
344: static void ssys_update(ssys_state *s)
345: {
346: qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
347: }
348:
349: static 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:
368: static 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:
1.1.1.8 root 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:
395: static 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:
1.1.1.9 ! root 413: static uint64_t ssys_read(void *opaque, target_phys_addr_t offset,
! 414: unsigned size)
1.1 root 415: {
416: ssys_state *s = (ssys_state *)opaque;
417:
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;
1.1.1.8 root 457: switch (ssys_board_class(s)) {
458: case DID0_CLASS_FURY:
1.1 root 459: return pllcfg_fury[xtal];
1.1.1.8 root 460: case DID0_CLASS_SANDSTORM:
1.1 root 461: return pllcfg_sandstorm[xtal];
1.1.1.8 root 462: default:
463: hw_error("ssys_read: Unhandled class for PLLCFG read.\n");
464: return 0;
1.1 root 465: }
466: }
1.1.1.8 root 467: case 0x070: /* RCC2 */
468: return s->rcc2;
1.1 root 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;
491: case 0x1e0: /* USER0 */
492: return s->user0;
493: case 0x1e4: /* USER1 */
494: return s->user1;
495: default:
1.1.1.3 root 496: hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
1.1 root 497: return 0;
498: }
499: }
500:
1.1.1.8 root 501: static 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: */
1.1.1.2 root 509: static void ssys_calculate_system_clock(ssys_state *s)
510: {
1.1.1.8 root 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: }
1.1.1.2 root 516: }
517:
1.1.1.9 ! root 518: static void ssys_write(void *opaque, target_phys_addr_t offset,
! 519: uint64_t value, unsigned size)
1.1 root 520: {
521: ssys_state *s = (ssys_state *)opaque;
522:
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;
1.1.1.2 root 550: ssys_calculate_system_clock(s);
1.1 root 551: break;
1.1.1.8 root 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;
1.1 root 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:
1.1.1.3 root 598: hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
1.1 root 599: }
600: ssys_update(s);
601: }
602:
1.1.1.9 ! root 603: static const MemoryRegionOps ssys_ops = {
! 604: .read = ssys_read,
! 605: .write = ssys_write,
! 606: .endianness = DEVICE_NATIVE_ENDIAN,
1.1 root 607: };
608:
609: static void ssys_reset(void *opaque)
610: {
611: ssys_state *s = (ssys_state *)opaque;
612:
613: s->pborctl = 0x7ffd;
614: s->rcc = 0x078e3ac0;
1.1.1.8 root 615:
616: if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
617: s->rcc2 = 0;
618: } else {
619: s->rcc2 = 0x07802810;
620: }
1.1 root 621: s->rcgc[0] = 1;
622: s->scgc[0] = 1;
623: s->dcgc[0] = 1;
1.1.1.9 ! root 624: ssys_calculate_system_clock(s);
1.1 root 625: }
626:
1.1.1.7 root 627: static int stellaris_sys_post_load(void *opaque, int version_id)
1.1.1.2 root 628: {
1.1.1.7 root 629: ssys_state *s = opaque;
1.1.1.2 root 630:
631: ssys_calculate_system_clock(s);
632:
633: return 0;
634: }
635:
1.1.1.7 root 636: static const VMStateDescription vmstate_stellaris_sys = {
637: .name = "stellaris_sys",
1.1.1.8 root 638: .version_id = 2,
1.1.1.7 root 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),
1.1.1.8 root 649: VMSTATE_UINT32_V(rcc2, ssys_state, 2),
1.1.1.7 root 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:
1.1.1.4 root 659: static int stellaris_sys_init(uint32_t base, qemu_irq irq,
660: stellaris_board_info * board,
661: uint8_t *macaddr)
1.1 root 662: {
663: ssys_state *s;
664:
1.1.1.8 root 665: s = (ssys_state *)g_malloc0(sizeof(ssys_state));
1.1 root 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.9 ! root 672: memory_region_init_io(&s->iomem, &ssys_ops, s, "ssys", 0x00001000);
! 673: memory_region_add_subregion(get_system_memory(), base, &s->iomem);
1.1 root 674: ssys_reset(s);
1.1.1.7 root 675: vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
1.1.1.4 root 676: return 0;
1.1 root 677: }
678:
679:
680: /* I2C controller. */
681:
682: typedef struct {
1.1.1.3 root 683: SysBusDevice busdev;
1.1 root 684: i2c_bus *bus;
685: qemu_irq irq;
1.1.1.9 ! root 686: MemoryRegion iomem;
1.1 root 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:
1.1.1.9 ! root 704: static uint64_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset,
! 705: unsigned size)
1.1 root 706: {
707: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
708:
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:
1.1.1.3 root 728: hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
1.1 root 729: return 0;
730: }
731: }
732:
733: static 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:
741: static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
1.1.1.9 ! root 742: uint64_t value, unsigned size)
1.1 root 743: {
744: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
745:
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)
1.1.1.3 root 804: hw_error(
1.1 root 805: "stellaris_i2c_write: Loopback not implemented\n");
806: if (value & 0x20)
1.1.1.3 root 807: hw_error(
1.1 root 808: "stellaris_i2c_write: Slave mode not implemented\n");
809: s->mcr = value & 0x31;
810: break;
811: default:
1.1.1.3 root 812: hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
1.1 root 813: (int)offset);
814: }
815: stellaris_i2c_update(s);
816: }
817:
818: static 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:
1.1.1.9 ! root 833: static const MemoryRegionOps stellaris_i2c_ops = {
! 834: .read = stellaris_i2c_read,
! 835: .write = stellaris_i2c_write,
! 836: .endianness = DEVICE_NATIVE_ENDIAN,
1.1 root 837: };
838:
1.1.1.7 root 839: static 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: };
1.1.1.2 root 855:
1.1.1.4 root 856: static int stellaris_i2c_init(SysBusDevice * dev)
1.1 root 857: {
1.1.1.3 root 858: stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
859: i2c_bus *bus;
1.1 root 860:
1.1.1.3 root 861: sysbus_init_irq(dev, &s->irq);
862: bus = i2c_init_bus(&dev->qdev, "i2c");
1.1 root 863: s->bus = bus;
864:
1.1.1.9 ! root 865: memory_region_init_io(&s->iomem, &stellaris_i2c_ops, s,
! 866: "i2c", 0x1000);
! 867: sysbus_init_mmio(dev, &s->iomem);
1.1 root 868: /* ??? For now we only implement the master interface. */
869: stellaris_i2c_reset(s);
1.1.1.7 root 870: vmstate_register(&dev->qdev, -1, &vmstate_stellaris_i2c, s);
1.1.1.4 root 871: return 0;
1.1 root 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:
888: typedef struct
889: {
1.1.1.3 root 890: SysBusDevice busdev;
1.1.1.9 ! root 891: MemoryRegion iomem;
1.1 root 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];
1.1.1.2 root 906: uint32_t noise;
1.1.1.3 root 907: qemu_irq irq[4];
1.1 root 908: } stellaris_adc_state;
909:
910: static 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:
926: static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
927: uint32_t value)
928: {
929: int head;
930:
1.1.1.3 root 931: /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
932: FIFO fir each sequencer. */
1.1 root 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:
946: static void stellaris_adc_update(stellaris_adc_state *s)
947: {
948: int level;
1.1.1.3 root 949: int n;
1.1 root 950:
1.1.1.3 root 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: }
1.1 root 955: }
956:
957: static void stellaris_adc_trigger(void *opaque, int irq, int level)
958: {
959: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1.1.1.3 root 960: int n;
1.1 root 961:
1.1.1.3 root 962: for (n = 0; n < 4; n++) {
963: if ((s->actss & (1 << n)) == 0) {
964: continue;
965: }
1.1 root 966:
1.1.1.3 root 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: }
1.1 root 979: }
980:
981: static 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:
1.1.1.9 ! root 992: static uint64_t stellaris_adc_read(void *opaque, target_phys_addr_t offset,
! 993: unsigned size)
1.1 root 994: {
995: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
996:
997: /* TODO: Implement this. */
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:
1.1.1.3 root 1034: hw_error("strllaris_adc_read: Bad offset 0x%x\n",
1.1 root 1035: (int)offset);
1036: return 0;
1037: }
1038: }
1039:
1040: static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
1.1.1.9 ! root 1041: uint64_t value, unsigned size)
1.1 root 1042: {
1043: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1044:
1045: /* TODO: Implement this. */
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) {
1.1.1.9 ! root 1055: hw_error("ADC: Unimplemented sequence %" PRIx64 "\n",
1.1 root 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;
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 */
1.1.1.3 root 1087: hw_error("Not implemented: ADC sample initiate\n");
1.1 root 1088: break;
1089: case 0x30: /* SAC */
1090: s->sac = value;
1091: break;
1092: default:
1.1.1.3 root 1093: hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
1.1 root 1094: }
1095: stellaris_adc_update(s);
1096: }
1097:
1.1.1.9 ! root 1098: static const MemoryRegionOps stellaris_adc_ops = {
! 1099: .read = stellaris_adc_read,
! 1100: .write = stellaris_adc_write,
! 1101: .endianness = DEVICE_NATIVE_ENDIAN,
1.1 root 1102: };
1103:
1.1.1.7 root 1104: static 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()
1.1.1.2 root 1136: }
1.1.1.7 root 1137: };
1.1.1.2 root 1138:
1.1.1.4 root 1139: static int stellaris_adc_init(SysBusDevice *dev)
1.1 root 1140: {
1.1.1.3 root 1141: stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
1142: int n;
1.1 root 1143:
1.1.1.3 root 1144: for (n = 0; n < 4; n++) {
1145: sysbus_init_irq(dev, &s->irq[n]);
1146: }
1.1 root 1147:
1.1.1.9 ! root 1148: memory_region_init_io(&s->iomem, &stellaris_adc_ops, s,
! 1149: "adc", 0x1000);
! 1150: sysbus_init_mmio(dev, &s->iomem);
1.1 root 1151: stellaris_adc_reset(s);
1.1.1.3 root 1152: qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
1.1.1.7 root 1153: vmstate_register(&dev->qdev, -1, &vmstate_stellaris_adc, s);
1.1.1.4 root 1154: return 0;
1.1 root 1155: }
1156:
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:
1164: typedef struct {
1.1.1.3 root 1165: SSISlave ssidev;
1.1 root 1166: qemu_irq irq;
1167: int current_dev;
1.1.1.3 root 1168: SSIBus *bus[2];
1.1 root 1169: } stellaris_ssi_bus_state;
1170:
1171: static 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:
1.1.1.3 root 1178: static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
1.1 root 1179: {
1.1.1.3 root 1180: stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1.1 root 1181:
1.1.1.3 root 1182: return ssi_transfer(s->bus[s->current_dev], val);
1.1 root 1183: }
1184:
1.1.1.7 root 1185: static 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: };
1.1.1.2 root 1195:
1.1.1.4 root 1196: static int stellaris_ssi_bus_init(SSISlave *dev)
1.1.1.3 root 1197: {
1198: stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1199:
1200: s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
1201: s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
1202: qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1203:
1.1.1.7 root 1204: vmstate_register(&dev->qdev, -1, &vmstate_stellaris_ssi_bus, s);
1.1.1.4 root 1205: return 0;
1.1 root 1206: }
1207:
1208: /* Board init. */
1209: static stellaris_board_info stellaris_boards[] = {
1210: { "LM3S811EVB",
1211: 0,
1212: 0x0032000e,
1213: 0x001f001f, /* dc0 */
1214: 0x001132bf,
1215: 0x01071013,
1216: 0x3f0f01ff,
1217: 0x0000001f,
1218: BP_OLED_I2C
1219: },
1220: { "LM3S6965EVB",
1221: 0x10010002,
1222: 0x1073402e,
1223: 0x00ff007f, /* dc0 */
1224: 0x001133ff,
1225: 0x030f5317,
1226: 0x0f0f87ff,
1227: 0x5000007f,
1228: BP_OLED_SSI | BP_GAMEPAD
1229: }
1230: };
1231:
1232: static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1.1.1.2 root 1233: stellaris_board_info *board)
1.1 root 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:
1.1.1.8 root 1242: MemoryRegion *address_space_mem = get_system_memory();
1.1 root 1243: qemu_irq *pic;
1.1.1.3 root 1244: DeviceState *gpio_dev[7];
1245: qemu_irq gpio_in[7][8];
1246: qemu_irq gpio_out[7][8];
1.1 root 1247: qemu_irq adc;
1248: int sram_size;
1249: int flash_size;
1250: i2c_bus *i2c;
1.1.1.3 root 1251: DeviceState *dev;
1.1 root 1252: int i;
1.1.1.3 root 1253: int j;
1.1 root 1254:
1255: flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1256: sram_size = (board->dc0 >> 18) + 1;
1.1.1.8 root 1257: pic = armv7m_init(address_space_mem,
1258: flash_size, sram_size, kernel_filename, cpu_model);
1.1 root 1259:
1260: if (board->dc1 & (1 << 16)) {
1.1.1.3 root 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);
1.1 root 1264: } else {
1265: adc = NULL;
1266: }
1267: for (i = 0; i < 4; i++) {
1268: if (board->dc2 & (0x10000 << i)) {
1.1.1.3 root 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);
1.1 root 1275: }
1276: }
1277:
1.1.1.7 root 1278: stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr.a);
1.1 root 1279:
1280: for (i = 0; i < 7; i++) {
1281: if (board->dc4 & (1 << i)) {
1.1.1.7 root 1282: gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
1.1.1.3 root 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: }
1.1 root 1288: }
1289: }
1290:
1291: if (board->dc2 & (1 << 12)) {
1.1.1.3 root 1292: dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
1293: i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
1.1 root 1294: if (board->peripherals & BP_OLED_I2C) {
1.1.1.3 root 1295: i2c_create_slave(i2c, "ssd0303", 0x3d);
1.1 root 1296: }
1297: }
1298:
1299: for (i = 0; i < 4; i++) {
1300: if (board->dc2 & (1 << i)) {
1.1.1.3 root 1301: sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1302: pic[uart_irq[i]]);
1.1 root 1303: }
1304: }
1305: if (board->dc2 & (1 << 4)) {
1.1.1.3 root 1306: dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
1.1 root 1307: if (board->peripherals & BP_OLED_SSI) {
1.1.1.3 root 1308: DeviceState *mux;
1309: void *bus;
1310:
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);
1314:
1315: bus = qdev_get_child_bus(mux, "ssi0");
1.1.1.5 root 1316: ssi_create_slave(bus, "ssi-sd");
1.1.1.3 root 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);
1.1 root 1321:
1322: /* Make sure the select pin is high. */
1323: qemu_irq_raise(gpio_out[GPIO_D][0]);
1324: }
1325: }
1.1.1.3 root 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");
1.1.1.4 root 1332: qdev_set_nic_properties(enet, &nd_table[0]);
1333: qdev_init_nofail(enet);
1.1.1.3 root 1334: sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
1335: sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
1336: }
1.1 root 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: }
1.1.1.3 root 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: }
1.1 root 1358: }
1359:
1360: /* FIXME: Figure out how to generate these from stellaris_boards. */
1.1.1.3 root 1361: static void lm3s811evb_init(ram_addr_t ram_size,
1.1.1.2 root 1362: const char *boot_device,
1.1 root 1363: const char *kernel_filename, const char *kernel_cmdline,
1364: const char *initrd_filename, const char *cpu_model)
1365: {
1.1.1.2 root 1366: stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
1.1 root 1367: }
1368:
1.1.1.3 root 1369: static void lm3s6965evb_init(ram_addr_t ram_size,
1.1.1.2 root 1370: const char *boot_device,
1.1 root 1371: const char *kernel_filename, const char *kernel_cmdline,
1372: const char *initrd_filename, const char *cpu_model)
1373: {
1.1.1.2 root 1374: stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
1.1 root 1375: }
1376:
1.1.1.3 root 1377: static QEMUMachine lm3s811evb_machine = {
1.1.1.2 root 1378: .name = "lm3s811evb",
1379: .desc = "Stellaris LM3S811EVB",
1380: .init = lm3s811evb_init,
1.1 root 1381: };
1382:
1.1.1.3 root 1383: static QEMUMachine lm3s6965evb_machine = {
1.1.1.2 root 1384: .name = "lm3s6965evb",
1385: .desc = "Stellaris LM3S6965EVB",
1386: .init = lm3s6965evb_init,
1.1 root 1387: };
1.1.1.3 root 1388:
1389: static void stellaris_machine_init(void)
1390: {
1391: qemu_register_machine(&lm3s811evb_machine);
1392: qemu_register_machine(&lm3s6965evb_machine);
1393: }
1394:
1395: machine_init(stellaris_machine_init);
1396:
1.1.1.9 ! root 1397: static 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:
! 1405: static 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,
! 1410: };
! 1411:
! 1412: static 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:
! 1419: static 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,
! 1424: };
! 1425:
! 1426: static 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:
! 1433: static 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,
! 1438: };
! 1439:
! 1440: static 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:
! 1447: static 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,
1.1.1.3 root 1452: };
1453:
1.1.1.9 ! root 1454: static void stellaris_register_types(void)
1.1.1.3 root 1455: {
1.1.1.9 ! root 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);
1.1.1.3 root 1460: }
1461:
1.1.1.9 ! root 1462: type_init(stellaris_register_types)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.