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