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