|
|
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.5 ! root 357: register_savevm(&dev->qdev, "stellaris_gptm", -1, 1,
! 358: gptm_save, gptm_load, s);
1.1.1.4 root 359: return 0;
1.1 root 360: }
361:
362:
363: /* System controller. */
364:
365: typedef struct {
366: uint32_t pborctl;
367: uint32_t ldopctl;
368: uint32_t int_status;
369: uint32_t int_mask;
370: uint32_t resc;
371: uint32_t rcc;
372: uint32_t rcgc[3];
373: uint32_t scgc[3];
374: uint32_t dcgc[3];
375: uint32_t clkvclr;
376: uint32_t ldoarst;
377: uint32_t user0;
378: uint32_t user1;
379: qemu_irq irq;
380: stellaris_board_info *board;
381: } ssys_state;
382:
383: static void ssys_update(ssys_state *s)
384: {
385: qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
386: }
387:
388: static uint32_t pllcfg_sandstorm[16] = {
389: 0x31c0, /* 1 Mhz */
390: 0x1ae0, /* 1.8432 Mhz */
391: 0x18c0, /* 2 Mhz */
392: 0xd573, /* 2.4576 Mhz */
393: 0x37a6, /* 3.57954 Mhz */
394: 0x1ae2, /* 3.6864 Mhz */
395: 0x0c40, /* 4 Mhz */
396: 0x98bc, /* 4.906 Mhz */
397: 0x935b, /* 4.9152 Mhz */
398: 0x09c0, /* 5 Mhz */
399: 0x4dee, /* 5.12 Mhz */
400: 0x0c41, /* 6 Mhz */
401: 0x75db, /* 6.144 Mhz */
402: 0x1ae6, /* 7.3728 Mhz */
403: 0x0600, /* 8 Mhz */
404: 0x585b /* 8.192 Mhz */
405: };
406:
407: static uint32_t pllcfg_fury[16] = {
408: 0x3200, /* 1 Mhz */
409: 0x1b20, /* 1.8432 Mhz */
410: 0x1900, /* 2 Mhz */
411: 0xf42b, /* 2.4576 Mhz */
412: 0x37e3, /* 3.57954 Mhz */
413: 0x1b21, /* 3.6864 Mhz */
414: 0x0c80, /* 4 Mhz */
415: 0x98ee, /* 4.906 Mhz */
416: 0xd5b4, /* 4.9152 Mhz */
417: 0x0a00, /* 5 Mhz */
418: 0x4e27, /* 5.12 Mhz */
419: 0x1902, /* 6 Mhz */
420: 0xec1c, /* 6.144 Mhz */
421: 0x1b23, /* 7.3728 Mhz */
422: 0x0640, /* 8 Mhz */
423: 0xb11c /* 8.192 Mhz */
424: };
425:
426: static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
427: {
428: ssys_state *s = (ssys_state *)opaque;
429:
430: switch (offset) {
431: case 0x000: /* DID0 */
432: return s->board->did0;
433: case 0x004: /* DID1 */
434: return s->board->did1;
435: case 0x008: /* DC0 */
436: return s->board->dc0;
437: case 0x010: /* DC1 */
438: return s->board->dc1;
439: case 0x014: /* DC2 */
440: return s->board->dc2;
441: case 0x018: /* DC3 */
442: return s->board->dc3;
443: case 0x01c: /* DC4 */
444: return s->board->dc4;
445: case 0x030: /* PBORCTL */
446: return s->pborctl;
447: case 0x034: /* LDOPCTL */
448: return s->ldopctl;
449: case 0x040: /* SRCR0 */
450: return 0;
451: case 0x044: /* SRCR1 */
452: return 0;
453: case 0x048: /* SRCR2 */
454: return 0;
455: case 0x050: /* RIS */
456: return s->int_status;
457: case 0x054: /* IMC */
458: return s->int_mask;
459: case 0x058: /* MISC */
460: return s->int_status & s->int_mask;
461: case 0x05c: /* RESC */
462: return s->resc;
463: case 0x060: /* RCC */
464: return s->rcc;
465: case 0x064: /* PLLCFG */
466: {
467: int xtal;
468: xtal = (s->rcc >> 6) & 0xf;
469: if (s->board->did0 & (1 << 16)) {
470: return pllcfg_fury[xtal];
471: } else {
472: return pllcfg_sandstorm[xtal];
473: }
474: }
475: case 0x100: /* RCGC0 */
476: return s->rcgc[0];
477: case 0x104: /* RCGC1 */
478: return s->rcgc[1];
479: case 0x108: /* RCGC2 */
480: return s->rcgc[2];
481: case 0x110: /* SCGC0 */
482: return s->scgc[0];
483: case 0x114: /* SCGC1 */
484: return s->scgc[1];
485: case 0x118: /* SCGC2 */
486: return s->scgc[2];
487: case 0x120: /* DCGC0 */
488: return s->dcgc[0];
489: case 0x124: /* DCGC1 */
490: return s->dcgc[1];
491: case 0x128: /* DCGC2 */
492: return s->dcgc[2];
493: case 0x150: /* CLKVCLR */
494: return s->clkvclr;
495: case 0x160: /* LDOARST */
496: return s->ldoarst;
497: case 0x1e0: /* USER0 */
498: return s->user0;
499: case 0x1e4: /* USER1 */
500: return s->user1;
501: default:
1.1.1.3 root 502: hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
1.1 root 503: return 0;
504: }
505: }
506:
1.1.1.2 root 507: static void ssys_calculate_system_clock(ssys_state *s)
508: {
509: system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
510: }
511:
1.1 root 512: static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
513: {
514: ssys_state *s = (ssys_state *)opaque;
515:
516: switch (offset) {
517: case 0x030: /* PBORCTL */
518: s->pborctl = value & 0xffff;
519: break;
520: case 0x034: /* LDOPCTL */
521: s->ldopctl = value & 0x1f;
522: break;
523: case 0x040: /* SRCR0 */
524: case 0x044: /* SRCR1 */
525: case 0x048: /* SRCR2 */
526: fprintf(stderr, "Peripheral reset not implemented\n");
527: break;
528: case 0x054: /* IMC */
529: s->int_mask = value & 0x7f;
530: break;
531: case 0x058: /* MISC */
532: s->int_status &= ~value;
533: break;
534: case 0x05c: /* RESC */
535: s->resc = value & 0x3f;
536: break;
537: case 0x060: /* RCC */
538: if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
539: /* PLL enable. */
540: s->int_status |= (1 << 6);
541: }
542: s->rcc = value;
1.1.1.2 root 543: ssys_calculate_system_clock(s);
1.1 root 544: break;
545: case 0x100: /* RCGC0 */
546: s->rcgc[0] = value;
547: break;
548: case 0x104: /* RCGC1 */
549: s->rcgc[1] = value;
550: break;
551: case 0x108: /* RCGC2 */
552: s->rcgc[2] = value;
553: break;
554: case 0x110: /* SCGC0 */
555: s->scgc[0] = value;
556: break;
557: case 0x114: /* SCGC1 */
558: s->scgc[1] = value;
559: break;
560: case 0x118: /* SCGC2 */
561: s->scgc[2] = value;
562: break;
563: case 0x120: /* DCGC0 */
564: s->dcgc[0] = value;
565: break;
566: case 0x124: /* DCGC1 */
567: s->dcgc[1] = value;
568: break;
569: case 0x128: /* DCGC2 */
570: s->dcgc[2] = value;
571: break;
572: case 0x150: /* CLKVCLR */
573: s->clkvclr = value;
574: break;
575: case 0x160: /* LDOARST */
576: s->ldoarst = value;
577: break;
578: default:
1.1.1.3 root 579: hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
1.1 root 580: }
581: ssys_update(s);
582: }
583:
1.1.1.4 root 584: static CPUReadMemoryFunc * const ssys_readfn[] = {
1.1 root 585: ssys_read,
586: ssys_read,
587: ssys_read
588: };
589:
1.1.1.4 root 590: static CPUWriteMemoryFunc * const ssys_writefn[] = {
1.1 root 591: ssys_write,
592: ssys_write,
593: ssys_write
594: };
595:
596: static void ssys_reset(void *opaque)
597: {
598: ssys_state *s = (ssys_state *)opaque;
599:
600: s->pborctl = 0x7ffd;
601: s->rcc = 0x078e3ac0;
602: s->rcgc[0] = 1;
603: s->scgc[0] = 1;
604: s->dcgc[0] = 1;
605: }
606:
1.1.1.2 root 607: static void ssys_save(QEMUFile *f, void *opaque)
608: {
609: ssys_state *s = (ssys_state *)opaque;
610:
611: qemu_put_be32(f, s->pborctl);
612: qemu_put_be32(f, s->ldopctl);
613: qemu_put_be32(f, s->int_mask);
614: qemu_put_be32(f, s->int_status);
615: qemu_put_be32(f, s->resc);
616: qemu_put_be32(f, s->rcc);
617: qemu_put_be32(f, s->rcgc[0]);
618: qemu_put_be32(f, s->rcgc[1]);
619: qemu_put_be32(f, s->rcgc[2]);
620: qemu_put_be32(f, s->scgc[0]);
621: qemu_put_be32(f, s->scgc[1]);
622: qemu_put_be32(f, s->scgc[2]);
623: qemu_put_be32(f, s->dcgc[0]);
624: qemu_put_be32(f, s->dcgc[1]);
625: qemu_put_be32(f, s->dcgc[2]);
626: qemu_put_be32(f, s->clkvclr);
627: qemu_put_be32(f, s->ldoarst);
628: }
629:
630: static int ssys_load(QEMUFile *f, void *opaque, int version_id)
631: {
632: ssys_state *s = (ssys_state *)opaque;
633:
634: if (version_id != 1)
635: return -EINVAL;
636:
637: s->pborctl = qemu_get_be32(f);
638: s->ldopctl = qemu_get_be32(f);
639: s->int_mask = qemu_get_be32(f);
640: s->int_status = qemu_get_be32(f);
641: s->resc = qemu_get_be32(f);
642: s->rcc = qemu_get_be32(f);
643: s->rcgc[0] = qemu_get_be32(f);
644: s->rcgc[1] = qemu_get_be32(f);
645: s->rcgc[2] = qemu_get_be32(f);
646: s->scgc[0] = qemu_get_be32(f);
647: s->scgc[1] = qemu_get_be32(f);
648: s->scgc[2] = qemu_get_be32(f);
649: s->dcgc[0] = qemu_get_be32(f);
650: s->dcgc[1] = qemu_get_be32(f);
651: s->dcgc[2] = qemu_get_be32(f);
652: s->clkvclr = qemu_get_be32(f);
653: s->ldoarst = qemu_get_be32(f);
654: ssys_calculate_system_clock(s);
655:
656: return 0;
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: int iomemtype;
664: ssys_state *s;
665:
666: s = (ssys_state *)qemu_mallocz(sizeof(ssys_state));
667: s->irq = irq;
668: s->board = board;
669: /* Most devices come preprogrammed with a MAC address in the user data. */
670: s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
671: s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
672:
1.1.1.3 root 673: iomemtype = cpu_register_io_memory(ssys_readfn,
1.1 root 674: ssys_writefn, s);
675: cpu_register_physical_memory(base, 0x00001000, iomemtype);
676: ssys_reset(s);
1.1.1.5 ! root 677: register_savevm(NULL, "stellaris_sys", -1, 1, ssys_save, ssys_load, s);
1.1.1.4 root 678: return 0;
1.1 root 679: }
680:
681:
682: /* I2C controller. */
683:
684: typedef struct {
1.1.1.3 root 685: SysBusDevice busdev;
1.1 root 686: i2c_bus *bus;
687: qemu_irq irq;
688: uint32_t msa;
689: uint32_t mcs;
690: uint32_t mdr;
691: uint32_t mtpr;
692: uint32_t mimr;
693: uint32_t mris;
694: uint32_t mcr;
695: } stellaris_i2c_state;
696:
697: #define STELLARIS_I2C_MCS_BUSY 0x01
698: #define STELLARIS_I2C_MCS_ERROR 0x02
699: #define STELLARIS_I2C_MCS_ADRACK 0x04
700: #define STELLARIS_I2C_MCS_DATACK 0x08
701: #define STELLARIS_I2C_MCS_ARBLST 0x10
702: #define STELLARIS_I2C_MCS_IDLE 0x20
703: #define STELLARIS_I2C_MCS_BUSBSY 0x40
704:
705: static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
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,
742: uint32_t value)
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.4 root 833: static CPUReadMemoryFunc * const stellaris_i2c_readfn[] = {
1.1 root 834: stellaris_i2c_read,
835: stellaris_i2c_read,
836: stellaris_i2c_read
837: };
838:
1.1.1.4 root 839: static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = {
1.1 root 840: stellaris_i2c_write,
841: stellaris_i2c_write,
842: stellaris_i2c_write
843: };
844:
1.1.1.2 root 845: static void stellaris_i2c_save(QEMUFile *f, void *opaque)
846: {
847: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
848:
849: qemu_put_be32(f, s->msa);
850: qemu_put_be32(f, s->mcs);
851: qemu_put_be32(f, s->mdr);
852: qemu_put_be32(f, s->mtpr);
853: qemu_put_be32(f, s->mimr);
854: qemu_put_be32(f, s->mris);
855: qemu_put_be32(f, s->mcr);
856: }
857:
858: static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id)
859: {
860: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
861:
862: if (version_id != 1)
863: return -EINVAL;
864:
865: s->msa = qemu_get_be32(f);
866: s->mcs = qemu_get_be32(f);
867: s->mdr = qemu_get_be32(f);
868: s->mtpr = qemu_get_be32(f);
869: s->mimr = qemu_get_be32(f);
870: s->mris = qemu_get_be32(f);
871: s->mcr = qemu_get_be32(f);
872:
873: return 0;
874: }
875:
1.1.1.4 root 876: static int stellaris_i2c_init(SysBusDevice * dev)
1.1 root 877: {
1.1.1.3 root 878: stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
879: i2c_bus *bus;
1.1 root 880: int iomemtype;
881:
1.1.1.3 root 882: sysbus_init_irq(dev, &s->irq);
883: bus = i2c_init_bus(&dev->qdev, "i2c");
1.1 root 884: s->bus = bus;
885:
1.1.1.3 root 886: iomemtype = cpu_register_io_memory(stellaris_i2c_readfn,
1.1 root 887: stellaris_i2c_writefn, s);
1.1.1.3 root 888: sysbus_init_mmio(dev, 0x1000, iomemtype);
1.1 root 889: /* ??? For now we only implement the master interface. */
890: stellaris_i2c_reset(s);
1.1.1.5 ! root 891: register_savevm(&dev->qdev, "stellaris_i2c", -1, 1,
1.1.1.2 root 892: stellaris_i2c_save, stellaris_i2c_load, s);
1.1.1.4 root 893: return 0;
1.1 root 894: }
895:
896: /* Analogue to Digital Converter. This is only partially implemented,
897: enough for applications that use a combined ADC and timer tick. */
898:
899: #define STELLARIS_ADC_EM_CONTROLLER 0
900: #define STELLARIS_ADC_EM_COMP 1
901: #define STELLARIS_ADC_EM_EXTERNAL 4
902: #define STELLARIS_ADC_EM_TIMER 5
903: #define STELLARIS_ADC_EM_PWM0 6
904: #define STELLARIS_ADC_EM_PWM1 7
905: #define STELLARIS_ADC_EM_PWM2 8
906:
907: #define STELLARIS_ADC_FIFO_EMPTY 0x0100
908: #define STELLARIS_ADC_FIFO_FULL 0x1000
909:
910: typedef struct
911: {
1.1.1.3 root 912: SysBusDevice busdev;
1.1 root 913: uint32_t actss;
914: uint32_t ris;
915: uint32_t im;
916: uint32_t emux;
917: uint32_t ostat;
918: uint32_t ustat;
919: uint32_t sspri;
920: uint32_t sac;
921: struct {
922: uint32_t state;
923: uint32_t data[16];
924: } fifo[4];
925: uint32_t ssmux[4];
926: uint32_t ssctl[4];
1.1.1.2 root 927: uint32_t noise;
1.1.1.3 root 928: qemu_irq irq[4];
1.1 root 929: } stellaris_adc_state;
930:
931: static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
932: {
933: int tail;
934:
935: tail = s->fifo[n].state & 0xf;
936: if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
937: s->ustat |= 1 << n;
938: } else {
939: s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
940: s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
941: if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
942: s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
943: }
944: return s->fifo[n].data[tail];
945: }
946:
947: static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
948: uint32_t value)
949: {
950: int head;
951:
1.1.1.3 root 952: /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
953: FIFO fir each sequencer. */
1.1 root 954: head = (s->fifo[n].state >> 4) & 0xf;
955: if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
956: s->ostat |= 1 << n;
957: return;
958: }
959: s->fifo[n].data[head] = value;
960: head = (head + 1) & 0xf;
961: s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
962: s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
963: if ((s->fifo[n].state & 0xf) == head)
964: s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
965: }
966:
967: static void stellaris_adc_update(stellaris_adc_state *s)
968: {
969: int level;
1.1.1.3 root 970: int n;
1.1 root 971:
1.1.1.3 root 972: for (n = 0; n < 4; n++) {
973: level = (s->ris & s->im & (1 << n)) != 0;
974: qemu_set_irq(s->irq[n], level);
975: }
1.1 root 976: }
977:
978: static void stellaris_adc_trigger(void *opaque, int irq, int level)
979: {
980: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1.1.1.3 root 981: int n;
1.1 root 982:
1.1.1.3 root 983: for (n = 0; n < 4; n++) {
984: if ((s->actss & (1 << n)) == 0) {
985: continue;
986: }
1.1 root 987:
1.1.1.3 root 988: if (((s->emux >> (n * 4)) & 0xff) != 5) {
989: continue;
990: }
991:
992: /* Some applications use the ADC as a random number source, so introduce
993: some variation into the signal. */
994: s->noise = s->noise * 314159 + 1;
995: /* ??? actual inputs not implemented. Return an arbitrary value. */
996: stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
997: s->ris |= (1 << n);
998: stellaris_adc_update(s);
999: }
1.1 root 1000: }
1001:
1002: static void stellaris_adc_reset(stellaris_adc_state *s)
1003: {
1004: int n;
1005:
1006: for (n = 0; n < 4; n++) {
1007: s->ssmux[n] = 0;
1008: s->ssctl[n] = 0;
1009: s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
1010: }
1011: }
1012:
1013: static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
1014: {
1015: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1016:
1017: /* TODO: Implement this. */
1018: if (offset >= 0x40 && offset < 0xc0) {
1019: int n;
1020: n = (offset - 0x40) >> 5;
1021: switch (offset & 0x1f) {
1022: case 0x00: /* SSMUX */
1023: return s->ssmux[n];
1024: case 0x04: /* SSCTL */
1025: return s->ssctl[n];
1026: case 0x08: /* SSFIFO */
1027: return stellaris_adc_fifo_read(s, n);
1028: case 0x0c: /* SSFSTAT */
1029: return s->fifo[n].state;
1030: default:
1031: break;
1032: }
1033: }
1034: switch (offset) {
1035: case 0x00: /* ACTSS */
1036: return s->actss;
1037: case 0x04: /* RIS */
1038: return s->ris;
1039: case 0x08: /* IM */
1040: return s->im;
1041: case 0x0c: /* ISC */
1042: return s->ris & s->im;
1043: case 0x10: /* OSTAT */
1044: return s->ostat;
1045: case 0x14: /* EMUX */
1046: return s->emux;
1047: case 0x18: /* USTAT */
1048: return s->ustat;
1049: case 0x20: /* SSPRI */
1050: return s->sspri;
1051: case 0x30: /* SAC */
1052: return s->sac;
1053: default:
1.1.1.3 root 1054: hw_error("strllaris_adc_read: Bad offset 0x%x\n",
1.1 root 1055: (int)offset);
1056: return 0;
1057: }
1058: }
1059:
1060: static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
1061: uint32_t value)
1062: {
1063: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1064:
1065: /* TODO: Implement this. */
1066: if (offset >= 0x40 && offset < 0xc0) {
1067: int n;
1068: n = (offset - 0x40) >> 5;
1069: switch (offset & 0x1f) {
1070: case 0x00: /* SSMUX */
1071: s->ssmux[n] = value & 0x33333333;
1072: return;
1073: case 0x04: /* SSCTL */
1074: if (value != 6) {
1.1.1.3 root 1075: hw_error("ADC: Unimplemented sequence %x\n",
1.1 root 1076: value);
1077: }
1078: s->ssctl[n] = value;
1079: return;
1080: default:
1081: break;
1082: }
1083: }
1084: switch (offset) {
1085: case 0x00: /* ACTSS */
1086: s->actss = value & 0xf;
1087: break;
1088: case 0x08: /* IM */
1089: s->im = value;
1090: break;
1091: case 0x0c: /* ISC */
1092: s->ris &= ~value;
1093: break;
1094: case 0x10: /* OSTAT */
1095: s->ostat &= ~value;
1096: break;
1097: case 0x14: /* EMUX */
1098: s->emux = value;
1099: break;
1100: case 0x18: /* USTAT */
1101: s->ustat &= ~value;
1102: break;
1103: case 0x20: /* SSPRI */
1104: s->sspri = value;
1105: break;
1106: case 0x28: /* PSSI */
1.1.1.3 root 1107: hw_error("Not implemented: ADC sample initiate\n");
1.1 root 1108: break;
1109: case 0x30: /* SAC */
1110: s->sac = value;
1111: break;
1112: default:
1.1.1.3 root 1113: hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
1.1 root 1114: }
1115: stellaris_adc_update(s);
1116: }
1117:
1.1.1.4 root 1118: static CPUReadMemoryFunc * const stellaris_adc_readfn[] = {
1.1 root 1119: stellaris_adc_read,
1120: stellaris_adc_read,
1121: stellaris_adc_read
1122: };
1123:
1.1.1.4 root 1124: static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = {
1.1 root 1125: stellaris_adc_write,
1126: stellaris_adc_write,
1127: stellaris_adc_write
1128: };
1129:
1.1.1.2 root 1130: static void stellaris_adc_save(QEMUFile *f, void *opaque)
1131: {
1132: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1133: int i;
1134: int j;
1135:
1136: qemu_put_be32(f, s->actss);
1137: qemu_put_be32(f, s->ris);
1138: qemu_put_be32(f, s->im);
1139: qemu_put_be32(f, s->emux);
1140: qemu_put_be32(f, s->ostat);
1141: qemu_put_be32(f, s->ustat);
1142: qemu_put_be32(f, s->sspri);
1143: qemu_put_be32(f, s->sac);
1144: for (i = 0; i < 4; i++) {
1145: qemu_put_be32(f, s->fifo[i].state);
1146: for (j = 0; j < 16; j++) {
1147: qemu_put_be32(f, s->fifo[i].data[j]);
1148: }
1149: qemu_put_be32(f, s->ssmux[i]);
1150: qemu_put_be32(f, s->ssctl[i]);
1151: }
1152: qemu_put_be32(f, s->noise);
1153: }
1154:
1155: static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
1156: {
1157: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1158: int i;
1159: int j;
1160:
1161: if (version_id != 1)
1162: return -EINVAL;
1163:
1164: s->actss = qemu_get_be32(f);
1165: s->ris = qemu_get_be32(f);
1166: s->im = qemu_get_be32(f);
1167: s->emux = qemu_get_be32(f);
1168: s->ostat = qemu_get_be32(f);
1169: s->ustat = qemu_get_be32(f);
1170: s->sspri = qemu_get_be32(f);
1171: s->sac = qemu_get_be32(f);
1172: for (i = 0; i < 4; i++) {
1173: s->fifo[i].state = qemu_get_be32(f);
1174: for (j = 0; j < 16; j++) {
1175: s->fifo[i].data[j] = qemu_get_be32(f);
1176: }
1177: s->ssmux[i] = qemu_get_be32(f);
1178: s->ssctl[i] = qemu_get_be32(f);
1179: }
1180: s->noise = qemu_get_be32(f);
1181:
1182: return 0;
1183: }
1184:
1.1.1.4 root 1185: static int stellaris_adc_init(SysBusDevice *dev)
1.1 root 1186: {
1.1.1.3 root 1187: stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
1.1 root 1188: int iomemtype;
1.1.1.3 root 1189: int n;
1.1 root 1190:
1.1.1.3 root 1191: for (n = 0; n < 4; n++) {
1192: sysbus_init_irq(dev, &s->irq[n]);
1193: }
1.1 root 1194:
1.1.1.3 root 1195: iomemtype = cpu_register_io_memory(stellaris_adc_readfn,
1.1 root 1196: stellaris_adc_writefn, s);
1.1.1.3 root 1197: sysbus_init_mmio(dev, 0x1000, iomemtype);
1.1 root 1198: stellaris_adc_reset(s);
1.1.1.3 root 1199: qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
1.1.1.5 ! root 1200: register_savevm(&dev->qdev, "stellaris_adc", -1, 1,
1.1.1.2 root 1201: stellaris_adc_save, stellaris_adc_load, s);
1.1.1.4 root 1202: return 0;
1.1 root 1203: }
1204:
1205: /* Some boards have both an OLED controller and SD card connected to
1206: the same SSI port, with the SD card chip select connected to a
1207: GPIO pin. Technically the OLED chip select is connected to the SSI
1208: Fss pin. We do not bother emulating that as both devices should
1209: never be selected simultaneously, and our OLED controller ignores stray
1210: 0xff commands that occur when deselecting the SD card. */
1211:
1212: typedef struct {
1.1.1.3 root 1213: SSISlave ssidev;
1.1 root 1214: qemu_irq irq;
1215: int current_dev;
1.1.1.3 root 1216: SSIBus *bus[2];
1.1 root 1217: } stellaris_ssi_bus_state;
1218:
1219: static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1220: {
1221: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1222:
1223: s->current_dev = level;
1224: }
1225:
1.1.1.3 root 1226: static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
1.1 root 1227: {
1.1.1.3 root 1228: stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1.1 root 1229:
1.1.1.3 root 1230: return ssi_transfer(s->bus[s->current_dev], val);
1.1 root 1231: }
1232:
1.1.1.2 root 1233: static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque)
1234: {
1235: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1236:
1237: qemu_put_be32(f, s->current_dev);
1238: }
1239:
1240: static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id)
1241: {
1242: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1243:
1244: if (version_id != 1)
1245: return -EINVAL;
1246:
1247: s->current_dev = qemu_get_be32(f);
1248:
1249: return 0;
1250: }
1251:
1.1.1.4 root 1252: static int stellaris_ssi_bus_init(SSISlave *dev)
1.1.1.3 root 1253: {
1254: stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1255:
1256: s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
1257: s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
1258: qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1259:
1.1.1.5 ! root 1260: register_savevm(&dev->qdev, "stellaris_ssi_bus", -1, 1,
1.1.1.2 root 1261: stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
1.1.1.4 root 1262: return 0;
1.1 root 1263: }
1264:
1265: /* Board init. */
1266: static stellaris_board_info stellaris_boards[] = {
1267: { "LM3S811EVB",
1268: 0,
1269: 0x0032000e,
1270: 0x001f001f, /* dc0 */
1271: 0x001132bf,
1272: 0x01071013,
1273: 0x3f0f01ff,
1274: 0x0000001f,
1275: BP_OLED_I2C
1276: },
1277: { "LM3S6965EVB",
1278: 0x10010002,
1279: 0x1073402e,
1280: 0x00ff007f, /* dc0 */
1281: 0x001133ff,
1282: 0x030f5317,
1283: 0x0f0f87ff,
1284: 0x5000007f,
1285: BP_OLED_SSI | BP_GAMEPAD
1286: }
1287: };
1288:
1289: static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1.1.1.2 root 1290: stellaris_board_info *board)
1.1 root 1291: {
1292: static const int uart_irq[] = {5, 6, 33, 34};
1293: static const int timer_irq[] = {19, 21, 23, 35};
1294: static const uint32_t gpio_addr[7] =
1295: { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1296: 0x40024000, 0x40025000, 0x40026000};
1297: static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1298:
1299: qemu_irq *pic;
1.1.1.3 root 1300: DeviceState *gpio_dev[7];
1301: qemu_irq gpio_in[7][8];
1302: qemu_irq gpio_out[7][8];
1.1 root 1303: qemu_irq adc;
1304: int sram_size;
1305: int flash_size;
1306: i2c_bus *i2c;
1.1.1.3 root 1307: DeviceState *dev;
1.1 root 1308: int i;
1.1.1.3 root 1309: int j;
1.1 root 1310:
1311: flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1312: sram_size = (board->dc0 >> 18) + 1;
1313: pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1314:
1315: if (board->dc1 & (1 << 16)) {
1.1.1.3 root 1316: dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
1317: pic[14], pic[15], pic[16], pic[17], NULL);
1318: adc = qdev_get_gpio_in(dev, 0);
1.1 root 1319: } else {
1320: adc = NULL;
1321: }
1322: for (i = 0; i < 4; i++) {
1323: if (board->dc2 & (0x10000 << i)) {
1.1.1.3 root 1324: dev = sysbus_create_simple("stellaris-gptm",
1325: 0x40030000 + i * 0x1000,
1326: pic[timer_irq[i]]);
1327: /* TODO: This is incorrect, but we get away with it because
1328: the ADC output is only ever pulsed. */
1329: qdev_connect_gpio_out(dev, 0, adc);
1.1 root 1330: }
1331: }
1332:
1333: stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr);
1334:
1335: for (i = 0; i < 7; i++) {
1336: if (board->dc4 & (1 << i)) {
1.1.1.3 root 1337: gpio_dev[i] = sysbus_create_simple("pl061", gpio_addr[i],
1338: pic[gpio_irq[i]]);
1339: for (j = 0; j < 8; j++) {
1340: gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
1341: gpio_out[i][j] = NULL;
1342: }
1.1 root 1343: }
1344: }
1345:
1346: if (board->dc2 & (1 << 12)) {
1.1.1.3 root 1347: dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
1348: i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
1.1 root 1349: if (board->peripherals & BP_OLED_I2C) {
1.1.1.3 root 1350: i2c_create_slave(i2c, "ssd0303", 0x3d);
1.1 root 1351: }
1352: }
1353:
1354: for (i = 0; i < 4; i++) {
1355: if (board->dc2 & (1 << i)) {
1.1.1.3 root 1356: sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1357: pic[uart_irq[i]]);
1.1 root 1358: }
1359: }
1360: if (board->dc2 & (1 << 4)) {
1.1.1.3 root 1361: dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
1.1 root 1362: if (board->peripherals & BP_OLED_SSI) {
1.1.1.3 root 1363: DeviceState *mux;
1364: void *bus;
1365:
1366: bus = qdev_get_child_bus(dev, "ssi");
1367: mux = ssi_create_slave(bus, "evb6965-ssi");
1368: gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
1369:
1370: bus = qdev_get_child_bus(mux, "ssi0");
1.1.1.5 ! root 1371: ssi_create_slave(bus, "ssi-sd");
1.1.1.3 root 1372:
1373: bus = qdev_get_child_bus(mux, "ssi1");
1374: dev = ssi_create_slave(bus, "ssd0323");
1375: gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0);
1.1 root 1376:
1377: /* Make sure the select pin is high. */
1378: qemu_irq_raise(gpio_out[GPIO_D][0]);
1379: }
1380: }
1.1.1.3 root 1381: if (board->dc4 & (1 << 28)) {
1382: DeviceState *enet;
1383:
1384: qemu_check_nic_model(&nd_table[0], "stellaris");
1385:
1386: enet = qdev_create(NULL, "stellaris_enet");
1.1.1.4 root 1387: qdev_set_nic_properties(enet, &nd_table[0]);
1388: qdev_init_nofail(enet);
1.1.1.3 root 1389: sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
1390: sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
1391: }
1.1 root 1392: if (board->peripherals & BP_GAMEPAD) {
1393: qemu_irq gpad_irq[5];
1394: static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1395:
1396: gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1397: gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1398: gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1399: gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1400: gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1401:
1402: stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1403: }
1.1.1.3 root 1404: for (i = 0; i < 7; i++) {
1405: if (board->dc4 & (1 << i)) {
1406: for (j = 0; j < 8; j++) {
1407: if (gpio_out[i][j]) {
1408: qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
1409: }
1410: }
1411: }
1412: }
1.1 root 1413: }
1414:
1415: /* FIXME: Figure out how to generate these from stellaris_boards. */
1.1.1.3 root 1416: static void lm3s811evb_init(ram_addr_t ram_size,
1.1.1.2 root 1417: const char *boot_device,
1.1 root 1418: const char *kernel_filename, const char *kernel_cmdline,
1419: const char *initrd_filename, const char *cpu_model)
1420: {
1.1.1.2 root 1421: stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
1.1 root 1422: }
1423:
1.1.1.3 root 1424: static void lm3s6965evb_init(ram_addr_t ram_size,
1.1.1.2 root 1425: const char *boot_device,
1.1 root 1426: const char *kernel_filename, const char *kernel_cmdline,
1427: const char *initrd_filename, const char *cpu_model)
1428: {
1.1.1.2 root 1429: stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
1.1 root 1430: }
1431:
1.1.1.3 root 1432: static QEMUMachine lm3s811evb_machine = {
1.1.1.2 root 1433: .name = "lm3s811evb",
1434: .desc = "Stellaris LM3S811EVB",
1435: .init = lm3s811evb_init,
1.1 root 1436: };
1437:
1.1.1.3 root 1438: static QEMUMachine lm3s6965evb_machine = {
1.1.1.2 root 1439: .name = "lm3s6965evb",
1440: .desc = "Stellaris LM3S6965EVB",
1441: .init = lm3s6965evb_init,
1.1 root 1442: };
1.1.1.3 root 1443:
1444: static void stellaris_machine_init(void)
1445: {
1446: qemu_register_machine(&lm3s811evb_machine);
1447: qemu_register_machine(&lm3s6965evb_machine);
1448: }
1449:
1450: machine_init(stellaris_machine_init);
1451:
1452: static SSISlaveInfo stellaris_ssi_bus_info = {
1453: .qdev.name = "evb6965-ssi",
1454: .qdev.size = sizeof(stellaris_ssi_bus_state),
1455: .init = stellaris_ssi_bus_init,
1456: .transfer = stellaris_ssi_bus_transfer
1457: };
1458:
1459: static void stellaris_register_devices(void)
1460: {
1461: sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
1462: stellaris_i2c_init);
1463: sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
1464: stellaris_gptm_init);
1465: sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
1466: stellaris_adc_init);
1467: ssi_register_slave(&stellaris_ssi_bus_info);
1468: }
1469:
1470: device_init(stellaris_register_devices)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.