|
|
1.1 root 1: /*
1.1.1.2 root 2: * Luminary Micro Stellaris peripherals
1.1 root 3: *
4: * Copyright (c) 2006 CodeSourcery.
5: * Written by Paul Brook
6: *
1.1.1.7 ! root 7: * This code is licensed under the GPL.
1.1 root 8: */
9:
1.1.1.3 root 10: #include "sysbus.h"
11: #include "ssi.h"
1.1 root 12: #include "arm-misc.h"
13: #include "devices.h"
14: #include "qemu-timer.h"
15: #include "i2c.h"
16: #include "net.h"
17: #include "boards.h"
18:
19: #define GPIO_A 0
20: #define GPIO_B 1
21: #define GPIO_C 2
22: #define GPIO_D 3
23: #define GPIO_E 4
24: #define GPIO_F 5
25: #define GPIO_G 6
26:
27: #define BP_OLED_I2C 0x01
28: #define BP_OLED_SSI 0x02
29: #define BP_GAMEPAD 0x04
30:
31: typedef const struct {
32: const char *name;
33: uint32_t did0;
34: uint32_t did1;
35: uint32_t dc0;
36: uint32_t dc1;
37: uint32_t dc2;
38: uint32_t dc3;
39: uint32_t dc4;
40: uint32_t peripherals;
41: } stellaris_board_info;
42:
43: /* General purpose timer module. */
44:
45: typedef struct gptm_state {
1.1.1.3 root 46: SysBusDevice busdev;
1.1 root 47: uint32_t config;
48: uint32_t mode[2];
49: uint32_t control;
50: uint32_t state;
51: uint32_t mask;
52: uint32_t load[2];
53: uint32_t match[2];
54: uint32_t prescale[2];
55: uint32_t match_prescale[2];
56: uint32_t rtc;
57: int64_t tick[2];
58: struct gptm_state *opaque[2];
59: QEMUTimer *timer[2];
60: /* The timers have an alternate output used to trigger the ADC. */
61: qemu_irq trigger;
62: qemu_irq irq;
63: } gptm_state;
64:
65: static void gptm_update_irq(gptm_state *s)
66: {
67: int level;
68: level = (s->state & s->mask) != 0;
69: qemu_set_irq(s->irq, level);
70: }
71:
72: static void gptm_stop(gptm_state *s, int n)
73: {
74: qemu_del_timer(s->timer[n]);
75: }
76:
77: static void gptm_reload(gptm_state *s, int n, int reset)
78: {
79: int64_t tick;
80: if (reset)
1.1.1.7 ! root 81: tick = qemu_get_clock_ns(vm_clock);
1.1 root 82: else
83: tick = s->tick[n];
84:
85: if (s->config == 0) {
86: /* 32-bit CountDown. */
87: uint32_t count;
88: count = s->load[0] | (s->load[1] << 16);
89: tick += (int64_t)count * system_clock_scale;
90: } else if (s->config == 1) {
91: /* 32-bit RTC. 1Hz tick. */
1.1.1.4 root 92: tick += get_ticks_per_sec();
1.1 root 93: } else if (s->mode[n] == 0xa) {
94: /* PWM mode. Not implemented. */
95: } else {
1.1.1.3 root 96: hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
1.1 root 97: }
98: s->tick[n] = tick;
99: qemu_mod_timer(s->timer[n], tick);
100: }
101:
102: static void gptm_tick(void *opaque)
103: {
104: gptm_state **p = (gptm_state **)opaque;
105: gptm_state *s;
106: int n;
107:
108: s = *p;
109: n = p - s->opaque;
110: if (s->config == 0) {
111: s->state |= 1;
112: if ((s->control & 0x20)) {
113: /* Output trigger. */
1.1.1.3 root 114: qemu_irq_pulse(s->trigger);
1.1 root 115: }
116: if (s->mode[0] & 1) {
117: /* One-shot. */
118: s->control &= ~1;
119: } else {
120: /* Periodic. */
121: gptm_reload(s, 0, 0);
122: }
123: } else if (s->config == 1) {
124: /* RTC. */
125: uint32_t match;
126: s->rtc++;
127: match = s->match[0] | (s->match[1] << 16);
128: if (s->rtc > match)
129: s->rtc = 0;
130: if (s->rtc == 0) {
131: s->state |= 8;
132: }
133: gptm_reload(s, 0, 0);
134: } else if (s->mode[n] == 0xa) {
135: /* PWM mode. Not implemented. */
136: } else {
1.1.1.3 root 137: hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
1.1 root 138: }
139: gptm_update_irq(s);
140: }
141:
142: static uint32_t gptm_read(void *opaque, target_phys_addr_t offset)
143: {
144: gptm_state *s = (gptm_state *)opaque;
145:
146: switch (offset) {
147: case 0x00: /* CFG */
148: return s->config;
149: case 0x04: /* TAMR */
150: return s->mode[0];
151: case 0x08: /* TBMR */
152: return s->mode[1];
153: case 0x0c: /* CTL */
154: return s->control;
155: case 0x18: /* IMR */
156: return s->mask;
157: case 0x1c: /* RIS */
158: return s->state;
159: case 0x20: /* MIS */
160: return s->state & s->mask;
161: case 0x24: /* CR */
162: return 0;
163: case 0x28: /* TAILR */
164: return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
165: case 0x2c: /* TBILR */
166: return s->load[1];
167: case 0x30: /* TAMARCHR */
168: return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
169: case 0x34: /* TBMATCHR */
170: return s->match[1];
171: case 0x38: /* TAPR */
172: return s->prescale[0];
173: case 0x3c: /* TBPR */
174: return s->prescale[1];
175: case 0x40: /* TAPMR */
176: return s->match_prescale[0];
177: case 0x44: /* TBPMR */
178: return s->match_prescale[1];
179: case 0x48: /* TAR */
180: if (s->control == 1)
181: return s->rtc;
182: case 0x4c: /* TBR */
1.1.1.3 root 183: hw_error("TODO: Timer value read\n");
1.1 root 184: default:
1.1.1.3 root 185: hw_error("gptm_read: Bad offset 0x%x\n", (int)offset);
1.1 root 186: return 0;
187: }
188: }
189:
190: static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value)
191: {
192: gptm_state *s = (gptm_state *)opaque;
193: uint32_t oldval;
194:
195: /* The timers should be disabled before changing the configuration.
196: We take advantage of this and defer everything until the timer
197: is enabled. */
198: switch (offset) {
199: case 0x00: /* CFG */
200: s->config = value;
201: break;
202: case 0x04: /* TAMR */
203: s->mode[0] = value;
204: break;
205: case 0x08: /* TBMR */
206: s->mode[1] = value;
207: break;
208: case 0x0c: /* CTL */
209: oldval = s->control;
210: s->control = value;
211: /* TODO: Implement pause. */
212: if ((oldval ^ value) & 1) {
213: if (value & 1) {
214: gptm_reload(s, 0, 1);
215: } else {
216: gptm_stop(s, 0);
217: }
218: }
219: if (((oldval ^ value) & 0x100) && s->config >= 4) {
220: if (value & 0x100) {
221: gptm_reload(s, 1, 1);
222: } else {
223: gptm_stop(s, 1);
224: }
225: }
226: break;
227: case 0x18: /* IMR */
228: s->mask = value & 0x77;
229: gptm_update_irq(s);
230: break;
231: case 0x24: /* CR */
232: s->state &= ~value;
233: break;
234: case 0x28: /* TAILR */
235: s->load[0] = value & 0xffff;
236: if (s->config < 4) {
237: s->load[1] = value >> 16;
238: }
239: break;
240: case 0x2c: /* TBILR */
241: s->load[1] = value & 0xffff;
242: break;
243: case 0x30: /* TAMARCHR */
244: s->match[0] = value & 0xffff;
245: if (s->config < 4) {
246: s->match[1] = value >> 16;
247: }
248: break;
249: case 0x34: /* TBMATCHR */
250: s->match[1] = value >> 16;
251: break;
252: case 0x38: /* TAPR */
253: s->prescale[0] = value;
254: break;
255: case 0x3c: /* TBPR */
256: s->prescale[1] = value;
257: break;
258: case 0x40: /* TAPMR */
259: s->match_prescale[0] = value;
260: break;
261: case 0x44: /* TBPMR */
262: s->match_prescale[0] = value;
263: break;
264: default:
1.1.1.3 root 265: hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
1.1 root 266: }
267: gptm_update_irq(s);
268: }
269:
1.1.1.4 root 270: static CPUReadMemoryFunc * const gptm_readfn[] = {
1.1 root 271: gptm_read,
272: gptm_read,
273: gptm_read
274: };
275:
1.1.1.4 root 276: static CPUWriteMemoryFunc * const gptm_writefn[] = {
1.1 root 277: gptm_write,
278: gptm_write,
279: gptm_write
280: };
281:
1.1.1.7 ! root 282: static const VMStateDescription vmstate_stellaris_gptm = {
! 283: .name = "stellaris_gptm",
! 284: .version_id = 1,
! 285: .minimum_version_id = 1,
! 286: .minimum_version_id_old = 1,
! 287: .fields = (VMStateField[]) {
! 288: VMSTATE_UINT32(config, gptm_state),
! 289: VMSTATE_UINT32_ARRAY(mode, gptm_state, 2),
! 290: VMSTATE_UINT32(control, gptm_state),
! 291: VMSTATE_UINT32(state, gptm_state),
! 292: VMSTATE_UINT32(mask, gptm_state),
! 293: VMSTATE_UNUSED(8),
! 294: VMSTATE_UINT32_ARRAY(load, gptm_state, 2),
! 295: VMSTATE_UINT32_ARRAY(match, gptm_state, 2),
! 296: VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2),
! 297: VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2),
! 298: VMSTATE_UINT32(rtc, gptm_state),
! 299: VMSTATE_INT64_ARRAY(tick, gptm_state, 2),
! 300: VMSTATE_TIMER_ARRAY(timer, gptm_state, 2),
! 301: VMSTATE_END_OF_LIST()
! 302: }
! 303: };
1.1.1.2 root 304:
1.1.1.4 root 305: static int stellaris_gptm_init(SysBusDevice *dev)
1.1 root 306: {
307: int iomemtype;
1.1.1.3 root 308: gptm_state *s = FROM_SYSBUS(gptm_state, dev);
1.1 root 309:
1.1.1.3 root 310: sysbus_init_irq(dev, &s->irq);
311: qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
1.1 root 312:
1.1.1.3 root 313: iomemtype = cpu_register_io_memory(gptm_readfn,
1.1.1.6 root 314: gptm_writefn, s,
315: DEVICE_NATIVE_ENDIAN);
1.1.1.3 root 316: sysbus_init_mmio(dev, 0x1000, iomemtype);
317:
318: s->opaque[0] = s->opaque[1] = s;
1.1.1.7 ! root 319: s->timer[0] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[0]);
! 320: s->timer[1] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[1]);
! 321: vmstate_register(&dev->qdev, -1, &vmstate_stellaris_gptm, s);
1.1.1.4 root 322: return 0;
1.1 root 323: }
324:
325:
326: /* System controller. */
327:
328: typedef struct {
329: uint32_t pborctl;
330: uint32_t ldopctl;
331: uint32_t int_status;
332: uint32_t int_mask;
333: uint32_t resc;
334: uint32_t rcc;
335: uint32_t rcgc[3];
336: uint32_t scgc[3];
337: uint32_t dcgc[3];
338: uint32_t clkvclr;
339: uint32_t ldoarst;
340: uint32_t user0;
341: uint32_t user1;
342: qemu_irq irq;
343: stellaris_board_info *board;
344: } ssys_state;
345:
346: static void ssys_update(ssys_state *s)
347: {
348: qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
349: }
350:
351: static uint32_t pllcfg_sandstorm[16] = {
352: 0x31c0, /* 1 Mhz */
353: 0x1ae0, /* 1.8432 Mhz */
354: 0x18c0, /* 2 Mhz */
355: 0xd573, /* 2.4576 Mhz */
356: 0x37a6, /* 3.57954 Mhz */
357: 0x1ae2, /* 3.6864 Mhz */
358: 0x0c40, /* 4 Mhz */
359: 0x98bc, /* 4.906 Mhz */
360: 0x935b, /* 4.9152 Mhz */
361: 0x09c0, /* 5 Mhz */
362: 0x4dee, /* 5.12 Mhz */
363: 0x0c41, /* 6 Mhz */
364: 0x75db, /* 6.144 Mhz */
365: 0x1ae6, /* 7.3728 Mhz */
366: 0x0600, /* 8 Mhz */
367: 0x585b /* 8.192 Mhz */
368: };
369:
370: static uint32_t pllcfg_fury[16] = {
371: 0x3200, /* 1 Mhz */
372: 0x1b20, /* 1.8432 Mhz */
373: 0x1900, /* 2 Mhz */
374: 0xf42b, /* 2.4576 Mhz */
375: 0x37e3, /* 3.57954 Mhz */
376: 0x1b21, /* 3.6864 Mhz */
377: 0x0c80, /* 4 Mhz */
378: 0x98ee, /* 4.906 Mhz */
379: 0xd5b4, /* 4.9152 Mhz */
380: 0x0a00, /* 5 Mhz */
381: 0x4e27, /* 5.12 Mhz */
382: 0x1902, /* 6 Mhz */
383: 0xec1c, /* 6.144 Mhz */
384: 0x1b23, /* 7.3728 Mhz */
385: 0x0640, /* 8 Mhz */
386: 0xb11c /* 8.192 Mhz */
387: };
388:
389: static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
390: {
391: ssys_state *s = (ssys_state *)opaque;
392:
393: switch (offset) {
394: case 0x000: /* DID0 */
395: return s->board->did0;
396: case 0x004: /* DID1 */
397: return s->board->did1;
398: case 0x008: /* DC0 */
399: return s->board->dc0;
400: case 0x010: /* DC1 */
401: return s->board->dc1;
402: case 0x014: /* DC2 */
403: return s->board->dc2;
404: case 0x018: /* DC3 */
405: return s->board->dc3;
406: case 0x01c: /* DC4 */
407: return s->board->dc4;
408: case 0x030: /* PBORCTL */
409: return s->pborctl;
410: case 0x034: /* LDOPCTL */
411: return s->ldopctl;
412: case 0x040: /* SRCR0 */
413: return 0;
414: case 0x044: /* SRCR1 */
415: return 0;
416: case 0x048: /* SRCR2 */
417: return 0;
418: case 0x050: /* RIS */
419: return s->int_status;
420: case 0x054: /* IMC */
421: return s->int_mask;
422: case 0x058: /* MISC */
423: return s->int_status & s->int_mask;
424: case 0x05c: /* RESC */
425: return s->resc;
426: case 0x060: /* RCC */
427: return s->rcc;
428: case 0x064: /* PLLCFG */
429: {
430: int xtal;
431: xtal = (s->rcc >> 6) & 0xf;
432: if (s->board->did0 & (1 << 16)) {
433: return pllcfg_fury[xtal];
434: } else {
435: return pllcfg_sandstorm[xtal];
436: }
437: }
438: case 0x100: /* RCGC0 */
439: return s->rcgc[0];
440: case 0x104: /* RCGC1 */
441: return s->rcgc[1];
442: case 0x108: /* RCGC2 */
443: return s->rcgc[2];
444: case 0x110: /* SCGC0 */
445: return s->scgc[0];
446: case 0x114: /* SCGC1 */
447: return s->scgc[1];
448: case 0x118: /* SCGC2 */
449: return s->scgc[2];
450: case 0x120: /* DCGC0 */
451: return s->dcgc[0];
452: case 0x124: /* DCGC1 */
453: return s->dcgc[1];
454: case 0x128: /* DCGC2 */
455: return s->dcgc[2];
456: case 0x150: /* CLKVCLR */
457: return s->clkvclr;
458: case 0x160: /* LDOARST */
459: return s->ldoarst;
460: case 0x1e0: /* USER0 */
461: return s->user0;
462: case 0x1e4: /* USER1 */
463: return s->user1;
464: default:
1.1.1.3 root 465: hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
1.1 root 466: return 0;
467: }
468: }
469:
1.1.1.2 root 470: static void ssys_calculate_system_clock(ssys_state *s)
471: {
472: system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
473: }
474:
1.1 root 475: static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
476: {
477: ssys_state *s = (ssys_state *)opaque;
478:
479: switch (offset) {
480: case 0x030: /* PBORCTL */
481: s->pborctl = value & 0xffff;
482: break;
483: case 0x034: /* LDOPCTL */
484: s->ldopctl = value & 0x1f;
485: break;
486: case 0x040: /* SRCR0 */
487: case 0x044: /* SRCR1 */
488: case 0x048: /* SRCR2 */
489: fprintf(stderr, "Peripheral reset not implemented\n");
490: break;
491: case 0x054: /* IMC */
492: s->int_mask = value & 0x7f;
493: break;
494: case 0x058: /* MISC */
495: s->int_status &= ~value;
496: break;
497: case 0x05c: /* RESC */
498: s->resc = value & 0x3f;
499: break;
500: case 0x060: /* RCC */
501: if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
502: /* PLL enable. */
503: s->int_status |= (1 << 6);
504: }
505: s->rcc = value;
1.1.1.2 root 506: ssys_calculate_system_clock(s);
1.1 root 507: break;
508: case 0x100: /* RCGC0 */
509: s->rcgc[0] = value;
510: break;
511: case 0x104: /* RCGC1 */
512: s->rcgc[1] = value;
513: break;
514: case 0x108: /* RCGC2 */
515: s->rcgc[2] = value;
516: break;
517: case 0x110: /* SCGC0 */
518: s->scgc[0] = value;
519: break;
520: case 0x114: /* SCGC1 */
521: s->scgc[1] = value;
522: break;
523: case 0x118: /* SCGC2 */
524: s->scgc[2] = value;
525: break;
526: case 0x120: /* DCGC0 */
527: s->dcgc[0] = value;
528: break;
529: case 0x124: /* DCGC1 */
530: s->dcgc[1] = value;
531: break;
532: case 0x128: /* DCGC2 */
533: s->dcgc[2] = value;
534: break;
535: case 0x150: /* CLKVCLR */
536: s->clkvclr = value;
537: break;
538: case 0x160: /* LDOARST */
539: s->ldoarst = value;
540: break;
541: default:
1.1.1.3 root 542: hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
1.1 root 543: }
544: ssys_update(s);
545: }
546:
1.1.1.4 root 547: static CPUReadMemoryFunc * const ssys_readfn[] = {
1.1 root 548: ssys_read,
549: ssys_read,
550: ssys_read
551: };
552:
1.1.1.4 root 553: static CPUWriteMemoryFunc * const ssys_writefn[] = {
1.1 root 554: ssys_write,
555: ssys_write,
556: ssys_write
557: };
558:
559: static void ssys_reset(void *opaque)
560: {
561: ssys_state *s = (ssys_state *)opaque;
562:
563: s->pborctl = 0x7ffd;
564: s->rcc = 0x078e3ac0;
565: s->rcgc[0] = 1;
566: s->scgc[0] = 1;
567: s->dcgc[0] = 1;
568: }
569:
1.1.1.7 ! root 570: static int stellaris_sys_post_load(void *opaque, int version_id)
1.1.1.2 root 571: {
1.1.1.7 ! root 572: ssys_state *s = opaque;
1.1.1.2 root 573:
574: ssys_calculate_system_clock(s);
575:
576: return 0;
577: }
578:
1.1.1.7 ! root 579: static const VMStateDescription vmstate_stellaris_sys = {
! 580: .name = "stellaris_sys",
! 581: .version_id = 1,
! 582: .minimum_version_id = 1,
! 583: .minimum_version_id_old = 1,
! 584: .post_load = stellaris_sys_post_load,
! 585: .fields = (VMStateField[]) {
! 586: VMSTATE_UINT32(pborctl, ssys_state),
! 587: VMSTATE_UINT32(ldopctl, ssys_state),
! 588: VMSTATE_UINT32(int_mask, ssys_state),
! 589: VMSTATE_UINT32(int_status, ssys_state),
! 590: VMSTATE_UINT32(resc, ssys_state),
! 591: VMSTATE_UINT32(rcc, ssys_state),
! 592: VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
! 593: VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
! 594: VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
! 595: VMSTATE_UINT32(clkvclr, ssys_state),
! 596: VMSTATE_UINT32(ldoarst, ssys_state),
! 597: VMSTATE_END_OF_LIST()
! 598: }
! 599: };
! 600:
1.1.1.4 root 601: static int stellaris_sys_init(uint32_t base, qemu_irq irq,
602: stellaris_board_info * board,
603: uint8_t *macaddr)
1.1 root 604: {
605: int iomemtype;
606: ssys_state *s;
607:
608: s = (ssys_state *)qemu_mallocz(sizeof(ssys_state));
609: s->irq = irq;
610: s->board = board;
611: /* Most devices come preprogrammed with a MAC address in the user data. */
612: s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
613: s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
614:
1.1.1.3 root 615: iomemtype = cpu_register_io_memory(ssys_readfn,
1.1.1.6 root 616: ssys_writefn, s,
617: DEVICE_NATIVE_ENDIAN);
1.1 root 618: cpu_register_physical_memory(base, 0x00001000, iomemtype);
619: ssys_reset(s);
1.1.1.7 ! root 620: vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
1.1.1.4 root 621: return 0;
1.1 root 622: }
623:
624:
625: /* I2C controller. */
626:
627: typedef struct {
1.1.1.3 root 628: SysBusDevice busdev;
1.1 root 629: i2c_bus *bus;
630: qemu_irq irq;
631: uint32_t msa;
632: uint32_t mcs;
633: uint32_t mdr;
634: uint32_t mtpr;
635: uint32_t mimr;
636: uint32_t mris;
637: uint32_t mcr;
638: } stellaris_i2c_state;
639:
640: #define STELLARIS_I2C_MCS_BUSY 0x01
641: #define STELLARIS_I2C_MCS_ERROR 0x02
642: #define STELLARIS_I2C_MCS_ADRACK 0x04
643: #define STELLARIS_I2C_MCS_DATACK 0x08
644: #define STELLARIS_I2C_MCS_ARBLST 0x10
645: #define STELLARIS_I2C_MCS_IDLE 0x20
646: #define STELLARIS_I2C_MCS_BUSBSY 0x40
647:
648: static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
649: {
650: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
651:
652: switch (offset) {
653: case 0x00: /* MSA */
654: return s->msa;
655: case 0x04: /* MCS */
656: /* We don't emulate timing, so the controller is never busy. */
657: return s->mcs | STELLARIS_I2C_MCS_IDLE;
658: case 0x08: /* MDR */
659: return s->mdr;
660: case 0x0c: /* MTPR */
661: return s->mtpr;
662: case 0x10: /* MIMR */
663: return s->mimr;
664: case 0x14: /* MRIS */
665: return s->mris;
666: case 0x18: /* MMIS */
667: return s->mris & s->mimr;
668: case 0x20: /* MCR */
669: return s->mcr;
670: default:
1.1.1.3 root 671: hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
1.1 root 672: return 0;
673: }
674: }
675:
676: static void stellaris_i2c_update(stellaris_i2c_state *s)
677: {
678: int level;
679:
680: level = (s->mris & s->mimr) != 0;
681: qemu_set_irq(s->irq, level);
682: }
683:
684: static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
685: uint32_t value)
686: {
687: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
688:
689: switch (offset) {
690: case 0x00: /* MSA */
691: s->msa = value & 0xff;
692: break;
693: case 0x04: /* MCS */
694: if ((s->mcr & 0x10) == 0) {
695: /* Disabled. Do nothing. */
696: break;
697: }
698: /* Grab the bus if this is starting a transfer. */
699: if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
700: if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
701: s->mcs |= STELLARIS_I2C_MCS_ARBLST;
702: } else {
703: s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
704: s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
705: }
706: }
707: /* If we don't have the bus then indicate an error. */
708: if (!i2c_bus_busy(s->bus)
709: || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
710: s->mcs |= STELLARIS_I2C_MCS_ERROR;
711: break;
712: }
713: s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
714: if (value & 1) {
715: /* Transfer a byte. */
716: /* TODO: Handle errors. */
717: if (s->msa & 1) {
718: /* Recv */
719: s->mdr = i2c_recv(s->bus) & 0xff;
720: } else {
721: /* Send */
722: i2c_send(s->bus, s->mdr);
723: }
724: /* Raise an interrupt. */
725: s->mris |= 1;
726: }
727: if (value & 4) {
728: /* Finish transfer. */
729: i2c_end_transfer(s->bus);
730: s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
731: }
732: break;
733: case 0x08: /* MDR */
734: s->mdr = value & 0xff;
735: break;
736: case 0x0c: /* MTPR */
737: s->mtpr = value & 0xff;
738: break;
739: case 0x10: /* MIMR */
740: s->mimr = 1;
741: break;
742: case 0x1c: /* MICR */
743: s->mris &= ~value;
744: break;
745: case 0x20: /* MCR */
746: if (value & 1)
1.1.1.3 root 747: hw_error(
1.1 root 748: "stellaris_i2c_write: Loopback not implemented\n");
749: if (value & 0x20)
1.1.1.3 root 750: hw_error(
1.1 root 751: "stellaris_i2c_write: Slave mode not implemented\n");
752: s->mcr = value & 0x31;
753: break;
754: default:
1.1.1.3 root 755: hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
1.1 root 756: (int)offset);
757: }
758: stellaris_i2c_update(s);
759: }
760:
761: static void stellaris_i2c_reset(stellaris_i2c_state *s)
762: {
763: if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
764: i2c_end_transfer(s->bus);
765:
766: s->msa = 0;
767: s->mcs = 0;
768: s->mdr = 0;
769: s->mtpr = 1;
770: s->mimr = 0;
771: s->mris = 0;
772: s->mcr = 0;
773: stellaris_i2c_update(s);
774: }
775:
1.1.1.4 root 776: static CPUReadMemoryFunc * const stellaris_i2c_readfn[] = {
1.1 root 777: stellaris_i2c_read,
778: stellaris_i2c_read,
779: stellaris_i2c_read
780: };
781:
1.1.1.4 root 782: static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = {
1.1 root 783: stellaris_i2c_write,
784: stellaris_i2c_write,
785: stellaris_i2c_write
786: };
787:
1.1.1.7 ! root 788: static const VMStateDescription vmstate_stellaris_i2c = {
! 789: .name = "stellaris_i2c",
! 790: .version_id = 1,
! 791: .minimum_version_id = 1,
! 792: .minimum_version_id_old = 1,
! 793: .fields = (VMStateField[]) {
! 794: VMSTATE_UINT32(msa, stellaris_i2c_state),
! 795: VMSTATE_UINT32(mcs, stellaris_i2c_state),
! 796: VMSTATE_UINT32(mdr, stellaris_i2c_state),
! 797: VMSTATE_UINT32(mtpr, stellaris_i2c_state),
! 798: VMSTATE_UINT32(mimr, stellaris_i2c_state),
! 799: VMSTATE_UINT32(mris, stellaris_i2c_state),
! 800: VMSTATE_UINT32(mcr, stellaris_i2c_state),
! 801: VMSTATE_END_OF_LIST()
! 802: }
! 803: };
1.1.1.2 root 804:
1.1.1.4 root 805: static int stellaris_i2c_init(SysBusDevice * dev)
1.1 root 806: {
1.1.1.3 root 807: stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
808: i2c_bus *bus;
1.1 root 809: int iomemtype;
810:
1.1.1.3 root 811: sysbus_init_irq(dev, &s->irq);
812: bus = i2c_init_bus(&dev->qdev, "i2c");
1.1 root 813: s->bus = bus;
814:
1.1.1.3 root 815: iomemtype = cpu_register_io_memory(stellaris_i2c_readfn,
1.1.1.6 root 816: stellaris_i2c_writefn, s,
817: DEVICE_NATIVE_ENDIAN);
1.1.1.3 root 818: sysbus_init_mmio(dev, 0x1000, iomemtype);
1.1 root 819: /* ??? For now we only implement the master interface. */
820: stellaris_i2c_reset(s);
1.1.1.7 ! root 821: vmstate_register(&dev->qdev, -1, &vmstate_stellaris_i2c, s);
1.1.1.4 root 822: return 0;
1.1 root 823: }
824:
825: /* Analogue to Digital Converter. This is only partially implemented,
826: enough for applications that use a combined ADC and timer tick. */
827:
828: #define STELLARIS_ADC_EM_CONTROLLER 0
829: #define STELLARIS_ADC_EM_COMP 1
830: #define STELLARIS_ADC_EM_EXTERNAL 4
831: #define STELLARIS_ADC_EM_TIMER 5
832: #define STELLARIS_ADC_EM_PWM0 6
833: #define STELLARIS_ADC_EM_PWM1 7
834: #define STELLARIS_ADC_EM_PWM2 8
835:
836: #define STELLARIS_ADC_FIFO_EMPTY 0x0100
837: #define STELLARIS_ADC_FIFO_FULL 0x1000
838:
839: typedef struct
840: {
1.1.1.3 root 841: SysBusDevice busdev;
1.1 root 842: uint32_t actss;
843: uint32_t ris;
844: uint32_t im;
845: uint32_t emux;
846: uint32_t ostat;
847: uint32_t ustat;
848: uint32_t sspri;
849: uint32_t sac;
850: struct {
851: uint32_t state;
852: uint32_t data[16];
853: } fifo[4];
854: uint32_t ssmux[4];
855: uint32_t ssctl[4];
1.1.1.2 root 856: uint32_t noise;
1.1.1.3 root 857: qemu_irq irq[4];
1.1 root 858: } stellaris_adc_state;
859:
860: static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
861: {
862: int tail;
863:
864: tail = s->fifo[n].state & 0xf;
865: if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
866: s->ustat |= 1 << n;
867: } else {
868: s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
869: s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
870: if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
871: s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
872: }
873: return s->fifo[n].data[tail];
874: }
875:
876: static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
877: uint32_t value)
878: {
879: int head;
880:
1.1.1.3 root 881: /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
882: FIFO fir each sequencer. */
1.1 root 883: head = (s->fifo[n].state >> 4) & 0xf;
884: if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
885: s->ostat |= 1 << n;
886: return;
887: }
888: s->fifo[n].data[head] = value;
889: head = (head + 1) & 0xf;
890: s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
891: s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
892: if ((s->fifo[n].state & 0xf) == head)
893: s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
894: }
895:
896: static void stellaris_adc_update(stellaris_adc_state *s)
897: {
898: int level;
1.1.1.3 root 899: int n;
1.1 root 900:
1.1.1.3 root 901: for (n = 0; n < 4; n++) {
902: level = (s->ris & s->im & (1 << n)) != 0;
903: qemu_set_irq(s->irq[n], level);
904: }
1.1 root 905: }
906:
907: static void stellaris_adc_trigger(void *opaque, int irq, int level)
908: {
909: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1.1.1.3 root 910: int n;
1.1 root 911:
1.1.1.3 root 912: for (n = 0; n < 4; n++) {
913: if ((s->actss & (1 << n)) == 0) {
914: continue;
915: }
1.1 root 916:
1.1.1.3 root 917: if (((s->emux >> (n * 4)) & 0xff) != 5) {
918: continue;
919: }
920:
921: /* Some applications use the ADC as a random number source, so introduce
922: some variation into the signal. */
923: s->noise = s->noise * 314159 + 1;
924: /* ??? actual inputs not implemented. Return an arbitrary value. */
925: stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
926: s->ris |= (1 << n);
927: stellaris_adc_update(s);
928: }
1.1 root 929: }
930:
931: static void stellaris_adc_reset(stellaris_adc_state *s)
932: {
933: int n;
934:
935: for (n = 0; n < 4; n++) {
936: s->ssmux[n] = 0;
937: s->ssctl[n] = 0;
938: s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
939: }
940: }
941:
942: static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
943: {
944: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
945:
946: /* TODO: Implement this. */
947: if (offset >= 0x40 && offset < 0xc0) {
948: int n;
949: n = (offset - 0x40) >> 5;
950: switch (offset & 0x1f) {
951: case 0x00: /* SSMUX */
952: return s->ssmux[n];
953: case 0x04: /* SSCTL */
954: return s->ssctl[n];
955: case 0x08: /* SSFIFO */
956: return stellaris_adc_fifo_read(s, n);
957: case 0x0c: /* SSFSTAT */
958: return s->fifo[n].state;
959: default:
960: break;
961: }
962: }
963: switch (offset) {
964: case 0x00: /* ACTSS */
965: return s->actss;
966: case 0x04: /* RIS */
967: return s->ris;
968: case 0x08: /* IM */
969: return s->im;
970: case 0x0c: /* ISC */
971: return s->ris & s->im;
972: case 0x10: /* OSTAT */
973: return s->ostat;
974: case 0x14: /* EMUX */
975: return s->emux;
976: case 0x18: /* USTAT */
977: return s->ustat;
978: case 0x20: /* SSPRI */
979: return s->sspri;
980: case 0x30: /* SAC */
981: return s->sac;
982: default:
1.1.1.3 root 983: hw_error("strllaris_adc_read: Bad offset 0x%x\n",
1.1 root 984: (int)offset);
985: return 0;
986: }
987: }
988:
989: static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
990: uint32_t value)
991: {
992: stellaris_adc_state *s = (stellaris_adc_state *)opaque;
993:
994: /* TODO: Implement this. */
995: if (offset >= 0x40 && offset < 0xc0) {
996: int n;
997: n = (offset - 0x40) >> 5;
998: switch (offset & 0x1f) {
999: case 0x00: /* SSMUX */
1000: s->ssmux[n] = value & 0x33333333;
1001: return;
1002: case 0x04: /* SSCTL */
1003: if (value != 6) {
1.1.1.3 root 1004: hw_error("ADC: Unimplemented sequence %x\n",
1.1 root 1005: value);
1006: }
1007: s->ssctl[n] = value;
1008: return;
1009: default:
1010: break;
1011: }
1012: }
1013: switch (offset) {
1014: case 0x00: /* ACTSS */
1015: s->actss = value & 0xf;
1016: break;
1017: case 0x08: /* IM */
1018: s->im = value;
1019: break;
1020: case 0x0c: /* ISC */
1021: s->ris &= ~value;
1022: break;
1023: case 0x10: /* OSTAT */
1024: s->ostat &= ~value;
1025: break;
1026: case 0x14: /* EMUX */
1027: s->emux = value;
1028: break;
1029: case 0x18: /* USTAT */
1030: s->ustat &= ~value;
1031: break;
1032: case 0x20: /* SSPRI */
1033: s->sspri = value;
1034: break;
1035: case 0x28: /* PSSI */
1.1.1.3 root 1036: hw_error("Not implemented: ADC sample initiate\n");
1.1 root 1037: break;
1038: case 0x30: /* SAC */
1039: s->sac = value;
1040: break;
1041: default:
1.1.1.3 root 1042: hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
1.1 root 1043: }
1044: stellaris_adc_update(s);
1045: }
1046:
1.1.1.4 root 1047: static CPUReadMemoryFunc * const stellaris_adc_readfn[] = {
1.1 root 1048: stellaris_adc_read,
1049: stellaris_adc_read,
1050: stellaris_adc_read
1051: };
1052:
1.1.1.4 root 1053: static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = {
1.1 root 1054: stellaris_adc_write,
1055: stellaris_adc_write,
1056: stellaris_adc_write
1057: };
1058:
1.1.1.7 ! root 1059: static const VMStateDescription vmstate_stellaris_adc = {
! 1060: .name = "stellaris_adc",
! 1061: .version_id = 1,
! 1062: .minimum_version_id = 1,
! 1063: .minimum_version_id_old = 1,
! 1064: .fields = (VMStateField[]) {
! 1065: VMSTATE_UINT32(actss, stellaris_adc_state),
! 1066: VMSTATE_UINT32(ris, stellaris_adc_state),
! 1067: VMSTATE_UINT32(im, stellaris_adc_state),
! 1068: VMSTATE_UINT32(emux, stellaris_adc_state),
! 1069: VMSTATE_UINT32(ostat, stellaris_adc_state),
! 1070: VMSTATE_UINT32(ustat, stellaris_adc_state),
! 1071: VMSTATE_UINT32(sspri, stellaris_adc_state),
! 1072: VMSTATE_UINT32(sac, stellaris_adc_state),
! 1073: VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
! 1074: VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
! 1075: VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
! 1076: VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
! 1077: VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
! 1078: VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
! 1079: VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
! 1080: VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
! 1081: VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
! 1082: VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
! 1083: VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
! 1084: VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
! 1085: VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
! 1086: VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
! 1087: VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
! 1088: VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
! 1089: VMSTATE_UINT32(noise, stellaris_adc_state),
! 1090: VMSTATE_END_OF_LIST()
1.1.1.2 root 1091: }
1.1.1.7 ! root 1092: };
1.1.1.2 root 1093:
1.1.1.4 root 1094: static int stellaris_adc_init(SysBusDevice *dev)
1.1 root 1095: {
1.1.1.3 root 1096: stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
1.1 root 1097: int iomemtype;
1.1.1.3 root 1098: int n;
1.1 root 1099:
1.1.1.3 root 1100: for (n = 0; n < 4; n++) {
1101: sysbus_init_irq(dev, &s->irq[n]);
1102: }
1.1 root 1103:
1.1.1.3 root 1104: iomemtype = cpu_register_io_memory(stellaris_adc_readfn,
1.1.1.6 root 1105: stellaris_adc_writefn, s,
1106: DEVICE_NATIVE_ENDIAN);
1.1.1.3 root 1107: sysbus_init_mmio(dev, 0x1000, iomemtype);
1.1 root 1108: stellaris_adc_reset(s);
1.1.1.3 root 1109: qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
1.1.1.7 ! root 1110: vmstate_register(&dev->qdev, -1, &vmstate_stellaris_adc, s);
1.1.1.4 root 1111: return 0;
1.1 root 1112: }
1113:
1114: /* Some boards have both an OLED controller and SD card connected to
1115: the same SSI port, with the SD card chip select connected to a
1116: GPIO pin. Technically the OLED chip select is connected to the SSI
1117: Fss pin. We do not bother emulating that as both devices should
1118: never be selected simultaneously, and our OLED controller ignores stray
1119: 0xff commands that occur when deselecting the SD card. */
1120:
1121: typedef struct {
1.1.1.3 root 1122: SSISlave ssidev;
1.1 root 1123: qemu_irq irq;
1124: int current_dev;
1.1.1.3 root 1125: SSIBus *bus[2];
1.1 root 1126: } stellaris_ssi_bus_state;
1127:
1128: static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1129: {
1130: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1131:
1132: s->current_dev = level;
1133: }
1134:
1.1.1.3 root 1135: static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
1.1 root 1136: {
1.1.1.3 root 1137: stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1.1 root 1138:
1.1.1.3 root 1139: return ssi_transfer(s->bus[s->current_dev], val);
1.1 root 1140: }
1141:
1.1.1.7 ! root 1142: static const VMStateDescription vmstate_stellaris_ssi_bus = {
! 1143: .name = "stellaris_ssi_bus",
! 1144: .version_id = 1,
! 1145: .minimum_version_id = 1,
! 1146: .minimum_version_id_old = 1,
! 1147: .fields = (VMStateField[]) {
! 1148: VMSTATE_INT32(current_dev, stellaris_ssi_bus_state),
! 1149: VMSTATE_END_OF_LIST()
! 1150: }
! 1151: };
1.1.1.2 root 1152:
1.1.1.4 root 1153: static int stellaris_ssi_bus_init(SSISlave *dev)
1.1.1.3 root 1154: {
1155: stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1156:
1157: s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
1158: s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
1159: qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1160:
1.1.1.7 ! root 1161: vmstate_register(&dev->qdev, -1, &vmstate_stellaris_ssi_bus, s);
1.1.1.4 root 1162: return 0;
1.1 root 1163: }
1164:
1165: /* Board init. */
1166: static stellaris_board_info stellaris_boards[] = {
1167: { "LM3S811EVB",
1168: 0,
1169: 0x0032000e,
1170: 0x001f001f, /* dc0 */
1171: 0x001132bf,
1172: 0x01071013,
1173: 0x3f0f01ff,
1174: 0x0000001f,
1175: BP_OLED_I2C
1176: },
1177: { "LM3S6965EVB",
1178: 0x10010002,
1179: 0x1073402e,
1180: 0x00ff007f, /* dc0 */
1181: 0x001133ff,
1182: 0x030f5317,
1183: 0x0f0f87ff,
1184: 0x5000007f,
1185: BP_OLED_SSI | BP_GAMEPAD
1186: }
1187: };
1188:
1189: static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1.1.1.2 root 1190: stellaris_board_info *board)
1.1 root 1191: {
1192: static const int uart_irq[] = {5, 6, 33, 34};
1193: static const int timer_irq[] = {19, 21, 23, 35};
1194: static const uint32_t gpio_addr[7] =
1195: { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1196: 0x40024000, 0x40025000, 0x40026000};
1197: static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1198:
1199: qemu_irq *pic;
1.1.1.3 root 1200: DeviceState *gpio_dev[7];
1201: qemu_irq gpio_in[7][8];
1202: qemu_irq gpio_out[7][8];
1.1 root 1203: qemu_irq adc;
1204: int sram_size;
1205: int flash_size;
1206: i2c_bus *i2c;
1.1.1.3 root 1207: DeviceState *dev;
1.1 root 1208: int i;
1.1.1.3 root 1209: int j;
1.1 root 1210:
1211: flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1212: sram_size = (board->dc0 >> 18) + 1;
1213: pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1214:
1215: if (board->dc1 & (1 << 16)) {
1.1.1.3 root 1216: dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
1217: pic[14], pic[15], pic[16], pic[17], NULL);
1218: adc = qdev_get_gpio_in(dev, 0);
1.1 root 1219: } else {
1220: adc = NULL;
1221: }
1222: for (i = 0; i < 4; i++) {
1223: if (board->dc2 & (0x10000 << i)) {
1.1.1.3 root 1224: dev = sysbus_create_simple("stellaris-gptm",
1225: 0x40030000 + i * 0x1000,
1226: pic[timer_irq[i]]);
1227: /* TODO: This is incorrect, but we get away with it because
1228: the ADC output is only ever pulsed. */
1229: qdev_connect_gpio_out(dev, 0, adc);
1.1 root 1230: }
1231: }
1232:
1.1.1.7 ! root 1233: stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr.a);
1.1 root 1234:
1235: for (i = 0; i < 7; i++) {
1236: if (board->dc4 & (1 << i)) {
1.1.1.7 ! root 1237: gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
1.1.1.3 root 1238: pic[gpio_irq[i]]);
1239: for (j = 0; j < 8; j++) {
1240: gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
1241: gpio_out[i][j] = NULL;
1242: }
1.1 root 1243: }
1244: }
1245:
1246: if (board->dc2 & (1 << 12)) {
1.1.1.3 root 1247: dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
1248: i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
1.1 root 1249: if (board->peripherals & BP_OLED_I2C) {
1.1.1.3 root 1250: i2c_create_slave(i2c, "ssd0303", 0x3d);
1.1 root 1251: }
1252: }
1253:
1254: for (i = 0; i < 4; i++) {
1255: if (board->dc2 & (1 << i)) {
1.1.1.3 root 1256: sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1257: pic[uart_irq[i]]);
1.1 root 1258: }
1259: }
1260: if (board->dc2 & (1 << 4)) {
1.1.1.3 root 1261: dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
1.1 root 1262: if (board->peripherals & BP_OLED_SSI) {
1.1.1.3 root 1263: DeviceState *mux;
1264: void *bus;
1265:
1266: bus = qdev_get_child_bus(dev, "ssi");
1267: mux = ssi_create_slave(bus, "evb6965-ssi");
1268: gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
1269:
1270: bus = qdev_get_child_bus(mux, "ssi0");
1.1.1.5 root 1271: ssi_create_slave(bus, "ssi-sd");
1.1.1.3 root 1272:
1273: bus = qdev_get_child_bus(mux, "ssi1");
1274: dev = ssi_create_slave(bus, "ssd0323");
1275: gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0);
1.1 root 1276:
1277: /* Make sure the select pin is high. */
1278: qemu_irq_raise(gpio_out[GPIO_D][0]);
1279: }
1280: }
1.1.1.3 root 1281: if (board->dc4 & (1 << 28)) {
1282: DeviceState *enet;
1283:
1284: qemu_check_nic_model(&nd_table[0], "stellaris");
1285:
1286: enet = qdev_create(NULL, "stellaris_enet");
1.1.1.4 root 1287: qdev_set_nic_properties(enet, &nd_table[0]);
1288: qdev_init_nofail(enet);
1.1.1.3 root 1289: sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
1290: sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
1291: }
1.1 root 1292: if (board->peripherals & BP_GAMEPAD) {
1293: qemu_irq gpad_irq[5];
1294: static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1295:
1296: gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1297: gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1298: gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1299: gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1300: gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1301:
1302: stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1303: }
1.1.1.3 root 1304: for (i = 0; i < 7; i++) {
1305: if (board->dc4 & (1 << i)) {
1306: for (j = 0; j < 8; j++) {
1307: if (gpio_out[i][j]) {
1308: qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
1309: }
1310: }
1311: }
1312: }
1.1 root 1313: }
1314:
1315: /* FIXME: Figure out how to generate these from stellaris_boards. */
1.1.1.3 root 1316: static void lm3s811evb_init(ram_addr_t ram_size,
1.1.1.2 root 1317: const char *boot_device,
1.1 root 1318: const char *kernel_filename, const char *kernel_cmdline,
1319: const char *initrd_filename, const char *cpu_model)
1320: {
1.1.1.2 root 1321: stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
1.1 root 1322: }
1323:
1.1.1.3 root 1324: static void lm3s6965evb_init(ram_addr_t ram_size,
1.1.1.2 root 1325: const char *boot_device,
1.1 root 1326: const char *kernel_filename, const char *kernel_cmdline,
1327: const char *initrd_filename, const char *cpu_model)
1328: {
1.1.1.2 root 1329: stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
1.1 root 1330: }
1331:
1.1.1.3 root 1332: static QEMUMachine lm3s811evb_machine = {
1.1.1.2 root 1333: .name = "lm3s811evb",
1334: .desc = "Stellaris LM3S811EVB",
1335: .init = lm3s811evb_init,
1.1 root 1336: };
1337:
1.1.1.3 root 1338: static QEMUMachine lm3s6965evb_machine = {
1.1.1.2 root 1339: .name = "lm3s6965evb",
1340: .desc = "Stellaris LM3S6965EVB",
1341: .init = lm3s6965evb_init,
1.1 root 1342: };
1.1.1.3 root 1343:
1344: static void stellaris_machine_init(void)
1345: {
1346: qemu_register_machine(&lm3s811evb_machine);
1347: qemu_register_machine(&lm3s6965evb_machine);
1348: }
1349:
1350: machine_init(stellaris_machine_init);
1351:
1352: static SSISlaveInfo stellaris_ssi_bus_info = {
1353: .qdev.name = "evb6965-ssi",
1354: .qdev.size = sizeof(stellaris_ssi_bus_state),
1355: .init = stellaris_ssi_bus_init,
1356: .transfer = stellaris_ssi_bus_transfer
1357: };
1358:
1359: static void stellaris_register_devices(void)
1360: {
1361: sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
1362: stellaris_i2c_init);
1363: sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
1364: stellaris_gptm_init);
1365: sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
1366: stellaris_adc_init);
1367: ssi_register_slave(&stellaris_ssi_bus_info);
1368: }
1369:
1370: device_init(stellaris_register_devices)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.