Add statics and missing #includes for prototypes.
[qemu] / hw / stellaris.c
1 /*
2  * Luminary Micro Stellaris preipherals
3  *
4  * Copyright (c) 2006 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licenced under the GPL.
8  */
9
10 #include "hw.h"
11 #include "arm-misc.h"
12 #include "primecell.h"
13 #include "devices.h"
14 #include "qemu-timer.h"
15 #include "i2c.h"
16 #include "sysemu.h"
17 #include "boards.h"
18
19 typedef const struct {
20     const char *name;
21     uint32_t did0;
22     uint32_t did1;
23     uint32_t dc0;
24     uint32_t dc1;
25     uint32_t dc2;
26     uint32_t dc3;
27     uint32_t dc4;
28     enum {OLED_I2C, OLED_SSI} oled;
29 } stellaris_board_info;
30
31 /* General purpose timer module.  */
32
33 /* Multiplication factor to convert from GPTM timer ticks to qemu timer
34    ticks.  */
35 static int stellaris_clock_scale;
36
37 typedef struct gptm_state {
38     uint32_t config;
39     uint32_t mode[2];
40     uint32_t control;
41     uint32_t state;
42     uint32_t mask;
43     uint32_t load[2];
44     uint32_t match[2];
45     uint32_t prescale[2];
46     uint32_t match_prescale[2];
47     uint32_t rtc;
48     int64_t tick[2];
49     struct gptm_state *opaque[2];
50     uint32_t base;
51     QEMUTimer *timer[2];
52     /* The timers have an alternate output used to trigger the ADC.  */
53     qemu_irq trigger;
54     qemu_irq irq;
55 } gptm_state;
56
57 static void gptm_update_irq(gptm_state *s)
58 {
59     int level;
60     level = (s->state & s->mask) != 0;
61     qemu_set_irq(s->irq, level);
62 }
63
64 static void gptm_stop(gptm_state *s, int n)
65 {
66     qemu_del_timer(s->timer[n]);
67 }
68
69 static void gptm_reload(gptm_state *s, int n, int reset)
70 {
71     int64_t tick;
72     if (reset)
73         tick = qemu_get_clock(vm_clock);
74     else
75         tick = s->tick[n];
76
77     if (s->config == 0) {
78         /* 32-bit CountDown.  */
79         uint32_t count;
80         count = s->load[0] | (s->load[1] << 16);
81         tick += (int64_t)count * stellaris_clock_scale;
82     } else if (s->config == 1) {
83         /* 32-bit RTC.  1Hz tick.  */
84         tick += ticks_per_sec;
85     } else if (s->mode[n] == 0xa) {
86         /* PWM mode.  Not implemented.  */
87     } else {
88         cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n",
89                   s->mode[n]);
90     }
91     s->tick[n] = tick;
92     qemu_mod_timer(s->timer[n], tick);
93 }
94
95 static void gptm_tick(void *opaque)
96 {
97     gptm_state **p = (gptm_state **)opaque;
98     gptm_state *s;
99     int n;
100
101     s = *p;
102     n = p - s->opaque;
103     if (s->config == 0) {
104         s->state |= 1;
105         if ((s->control & 0x20)) {
106             /* Output trigger.  */
107             qemu_irq_raise(s->trigger);
108             qemu_irq_lower(s->trigger);
109         }
110         if (s->mode[0] & 1) {
111             /* One-shot.  */
112             s->control &= ~1;
113         } else {
114             /* Periodic.  */
115             gptm_reload(s, 0, 0);
116         }
117     } else if (s->config == 1) {
118         /* RTC.  */
119         uint32_t match;
120         s->rtc++;
121         match = s->match[0] | (s->match[1] << 16);
122         if (s->rtc > match)
123             s->rtc = 0;
124         if (s->rtc == 0) {
125             s->state |= 8;
126         }
127         gptm_reload(s, 0, 0);
128     } else if (s->mode[n] == 0xa) {
129         /* PWM mode.  Not implemented.  */
130     } else {
131         cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n",
132                   s->mode[n]);
133     }
134     gptm_update_irq(s);
135 }
136
137 static uint32_t gptm_read(void *opaque, target_phys_addr_t offset)
138 {
139     gptm_state *s = (gptm_state *)opaque;
140
141     offset -= s->base;
142     switch (offset) {
143     case 0x00: /* CFG */
144         return s->config;
145     case 0x04: /* TAMR */
146         return s->mode[0];
147     case 0x08: /* TBMR */
148         return s->mode[1];
149     case 0x0c: /* CTL */
150         return s->control;
151     case 0x18: /* IMR */
152         return s->mask;
153     case 0x1c: /* RIS */
154         return s->state;
155     case 0x20: /* MIS */
156         return s->state & s->mask;
157     case 0x24: /* CR */
158         return 0;
159     case 0x28: /* TAILR */
160         return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
161     case 0x2c: /* TBILR */
162         return s->load[1];
163     case 0x30: /* TAMARCHR */
164         return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
165     case 0x34: /* TBMATCHR */
166         return s->match[1];
167     case 0x38: /* TAPR */
168         return s->prescale[0];
169     case 0x3c: /* TBPR */
170         return s->prescale[1];
171     case 0x40: /* TAPMR */
172         return s->match_prescale[0];
173     case 0x44: /* TBPMR */
174         return s->match_prescale[1];
175     case 0x48: /* TAR */
176         if (s->control == 1)
177             return s->rtc;
178     case 0x4c: /* TBR */
179         cpu_abort(cpu_single_env, "TODO: Timer value read\n");
180     default:
181         cpu_abort(cpu_single_env, "gptm_read: Bad offset 0x%x\n", (int)offset);
182         return 0;
183     }
184 }
185
186 static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value)
187 {
188     gptm_state *s = (gptm_state *)opaque;
189     uint32_t oldval;
190
191     offset -= s->base;
192     /* The timers should be disabled before changing the configuration.
193        We take advantage of this and defer everything until the timer
194        is enabled.  */
195     switch (offset) {
196     case 0x00: /* CFG */
197         s->config = value;
198         break;
199     case 0x04: /* TAMR */
200         s->mode[0] = value;
201         break;
202     case 0x08: /* TBMR */
203         s->mode[1] = value;
204         break;
205     case 0x0c: /* CTL */
206         oldval = s->control;
207         s->control = value;
208         /* TODO: Implement pause.  */
209         if ((oldval ^ value) & 1) {
210             if (value & 1) {
211                 gptm_reload(s, 0, 1);
212             } else {
213                 gptm_stop(s, 0);
214             }
215         }
216         if (((oldval ^ value) & 0x100) && s->config >= 4) {
217             if (value & 0x100) {
218                 gptm_reload(s, 1, 1);
219             } else {
220                 gptm_stop(s, 1);
221             }
222         }
223         break;
224     case 0x18: /* IMR */
225         s->mask = value & 0x77;
226         gptm_update_irq(s);
227         break;
228     case 0x24: /* CR */
229         s->state &= ~value;
230         break;
231     case 0x28: /* TAILR */
232         s->load[0] = value & 0xffff;
233         if (s->config < 4) {
234             s->load[1] = value >> 16;
235         }
236         break;
237     case 0x2c: /* TBILR */
238         s->load[1] = value & 0xffff;
239         break;
240     case 0x30: /* TAMARCHR */
241         s->match[0] = value & 0xffff;
242         if (s->config < 4) {
243             s->match[1] = value >> 16;
244         }
245         break;
246     case 0x34: /* TBMATCHR */
247         s->match[1] = value >> 16;
248         break;
249     case 0x38: /* TAPR */
250         s->prescale[0] = value;
251         break;
252     case 0x3c: /* TBPR */
253         s->prescale[1] = value;
254         break;
255     case 0x40: /* TAPMR */
256         s->match_prescale[0] = value;
257         break;
258     case 0x44: /* TBPMR */
259         s->match_prescale[0] = value;
260         break;
261     default:
262         cpu_abort(cpu_single_env, "gptm_write: Bad offset 0x%x\n", (int)offset);
263     }
264     gptm_update_irq(s);
265 }
266
267 static CPUReadMemoryFunc *gptm_readfn[] = {
268    gptm_read,
269    gptm_read,
270    gptm_read
271 };
272
273 static CPUWriteMemoryFunc *gptm_writefn[] = {
274    gptm_write,
275    gptm_write,
276    gptm_write
277 };
278
279 static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger)
280 {
281     int iomemtype;
282     gptm_state *s;
283
284     s = (gptm_state *)qemu_mallocz(sizeof(gptm_state));
285     s->base = base;
286     s->irq = irq;
287     s->trigger = trigger;
288     s->opaque[0] = s->opaque[1] = s;
289
290     iomemtype = cpu_register_io_memory(0, gptm_readfn,
291                                        gptm_writefn, s);
292     cpu_register_physical_memory(base, 0x00001000, iomemtype);
293     s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);
294     s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]);
295     /* ??? Save/restore.  */
296 }
297
298
299 /* System controller.  */
300
301 typedef struct {
302     uint32_t base;
303     uint32_t pborctl;
304     uint32_t ldopctl;
305     uint32_t int_status;
306     uint32_t int_mask;
307     uint32_t resc;
308     uint32_t rcc;
309     uint32_t rcgc[3];
310     uint32_t scgc[3];
311     uint32_t dcgc[3];
312     uint32_t clkvclr;
313     uint32_t ldoarst;
314     qemu_irq irq;
315     stellaris_board_info *board;
316 } ssys_state;
317
318 static void ssys_update(ssys_state *s)
319 {
320   qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
321 }
322
323 static uint32_t pllcfg_sandstorm[16] = {
324     0x31c0, /* 1 Mhz */
325     0x1ae0, /* 1.8432 Mhz */
326     0x18c0, /* 2 Mhz */
327     0xd573, /* 2.4576 Mhz */
328     0x37a6, /* 3.57954 Mhz */
329     0x1ae2, /* 3.6864 Mhz */
330     0x0c40, /* 4 Mhz */
331     0x98bc, /* 4.906 Mhz */
332     0x935b, /* 4.9152 Mhz */
333     0x09c0, /* 5 Mhz */
334     0x4dee, /* 5.12 Mhz */
335     0x0c41, /* 6 Mhz */
336     0x75db, /* 6.144 Mhz */
337     0x1ae6, /* 7.3728 Mhz */
338     0x0600, /* 8 Mhz */
339     0x585b /* 8.192 Mhz */
340 };
341
342 static uint32_t pllcfg_fury[16] = {
343     0x3200, /* 1 Mhz */
344     0x1b20, /* 1.8432 Mhz */
345     0x1900, /* 2 Mhz */
346     0xf42b, /* 2.4576 Mhz */
347     0x37e3, /* 3.57954 Mhz */
348     0x1b21, /* 3.6864 Mhz */
349     0x0c80, /* 4 Mhz */
350     0x98ee, /* 4.906 Mhz */
351     0xd5b4, /* 4.9152 Mhz */
352     0x0a00, /* 5 Mhz */
353     0x4e27, /* 5.12 Mhz */
354     0x1902, /* 6 Mhz */
355     0xec1c, /* 6.144 Mhz */
356     0x1b23, /* 7.3728 Mhz */
357     0x0640, /* 8 Mhz */
358     0xb11c /* 8.192 Mhz */
359 };
360
361 static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
362 {
363     ssys_state *s = (ssys_state *)opaque;
364
365     offset -= s->base;
366     switch (offset) {
367     case 0x000: /* DID0 */
368         return s->board->did0;
369     case 0x004: /* DID1 */
370         return s->board->did1;
371     case 0x008: /* DC0 */
372         return s->board->dc0;
373     case 0x010: /* DC1 */
374         return s->board->dc1;
375     case 0x014: /* DC2 */
376         return s->board->dc2;
377     case 0x018: /* DC3 */
378         return s->board->dc3;
379     case 0x01c: /* DC4 */
380         return s->board->dc4;
381     case 0x030: /* PBORCTL */
382         return s->pborctl;
383     case 0x034: /* LDOPCTL */
384         return s->ldopctl;
385     case 0x040: /* SRCR0 */
386         return 0;
387     case 0x044: /* SRCR1 */
388         return 0;
389     case 0x048: /* SRCR2 */
390         return 0;
391     case 0x050: /* RIS */
392         return s->int_status;
393     case 0x054: /* IMC */
394         return s->int_mask;
395     case 0x058: /* MISC */
396         return s->int_status & s->int_mask;
397     case 0x05c: /* RESC */
398         return s->resc;
399     case 0x060: /* RCC */
400         return s->rcc;
401     case 0x064: /* PLLCFG */
402         {
403             int xtal;
404             xtal = (s->rcc >> 6) & 0xf;
405             if (s->board->did0 & (1 << 16)) {
406                 return pllcfg_fury[xtal];
407             } else {
408                 return pllcfg_sandstorm[xtal];
409             }
410         }
411     case 0x100: /* RCGC0 */
412         return s->rcgc[0];
413     case 0x104: /* RCGC1 */
414         return s->rcgc[1];
415     case 0x108: /* RCGC2 */
416         return s->rcgc[2];
417     case 0x110: /* SCGC0 */
418         return s->scgc[0];
419     case 0x114: /* SCGC1 */
420         return s->scgc[1];
421     case 0x118: /* SCGC2 */
422         return s->scgc[2];
423     case 0x120: /* DCGC0 */
424         return s->dcgc[0];
425     case 0x124: /* DCGC1 */
426         return s->dcgc[1];
427     case 0x128: /* DCGC2 */
428         return s->dcgc[2];
429     case 0x150: /* CLKVCLR */
430         return s->clkvclr;
431     case 0x160: /* LDOARST */
432         return s->ldoarst;
433     default:
434         cpu_abort(cpu_single_env, "gptm_read: Bad offset 0x%x\n", (int)offset);
435         return 0;
436     }
437 }
438
439 static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
440 {
441     ssys_state *s = (ssys_state *)opaque;
442
443     offset -= s->base;
444     switch (offset) {
445     case 0x030: /* PBORCTL */
446         s->pborctl = value & 0xffff;
447         break;
448     case 0x034: /* LDOPCTL */
449         s->ldopctl = value & 0x1f;
450         break;
451     case 0x040: /* SRCR0 */
452     case 0x044: /* SRCR1 */
453     case 0x048: /* SRCR2 */
454         fprintf(stderr, "Peripheral reset not implemented\n");
455         break;
456     case 0x054: /* IMC */
457         s->int_mask = value & 0x7f;
458         break;
459     case 0x058: /* MISC */
460         s->int_status &= ~value;
461         break;
462     case 0x05c: /* RESC */
463         s->resc = value & 0x3f;
464         break;
465     case 0x060: /* RCC */
466         if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
467             /* PLL enable.  */
468             s->int_status |= (1 << 6);
469         }
470         s->rcc = value;
471         stellaris_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
472         break;
473     case 0x100: /* RCGC0 */
474         s->rcgc[0] = value;
475         break;
476     case 0x104: /* RCGC1 */
477         s->rcgc[1] = value;
478         break;
479     case 0x108: /* RCGC2 */
480         s->rcgc[2] = value;
481         break;
482     case 0x110: /* SCGC0 */
483         s->scgc[0] = value;
484         break;
485     case 0x114: /* SCGC1 */
486         s->scgc[1] = value;
487         break;
488     case 0x118: /* SCGC2 */
489         s->scgc[2] = value;
490         break;
491     case 0x120: /* DCGC0 */
492         s->dcgc[0] = value;
493         break;
494     case 0x124: /* DCGC1 */
495         s->dcgc[1] = value;
496         break;
497     case 0x128: /* DCGC2 */
498         s->dcgc[2] = value;
499         break;
500     case 0x150: /* CLKVCLR */
501         s->clkvclr = value;
502         break;
503     case 0x160: /* LDOARST */
504         s->ldoarst = value;
505         break;
506     default:
507         cpu_abort(cpu_single_env, "gptm_write: Bad offset 0x%x\n", (int)offset);
508     }
509     ssys_update(s);
510 }
511
512 static CPUReadMemoryFunc *ssys_readfn[] = {
513    ssys_read,
514    ssys_read,
515    ssys_read
516 };
517
518 static CPUWriteMemoryFunc *ssys_writefn[] = {
519    ssys_write,
520    ssys_write,
521    ssys_write
522 };
523
524 static void ssys_reset(void *opaque)
525 {
526     ssys_state *s = (ssys_state *)opaque;
527
528     s->pborctl = 0x7ffd;
529     s->rcc = 0x078e3ac0;
530     s->rcgc[0] = 1;
531     s->scgc[0] = 1;
532     s->dcgc[0] = 1;
533 }
534
535 static void stellaris_sys_init(uint32_t base, qemu_irq irq,
536                                stellaris_board_info * board)
537 {
538     int iomemtype;
539     ssys_state *s;
540
541     s = (ssys_state *)qemu_mallocz(sizeof(ssys_state));
542     s->base = base;
543     s->irq = irq;
544     s->board = board;
545
546     iomemtype = cpu_register_io_memory(0, ssys_readfn,
547                                        ssys_writefn, s);
548     cpu_register_physical_memory(base, 0x00001000, iomemtype);
549     ssys_reset(s);
550     /* ??? Save/restore.  */
551 }
552
553
554 /* I2C controller.  */
555
556 typedef struct {
557     i2c_bus *bus;
558     qemu_irq irq;
559     uint32_t base;
560     uint32_t msa;
561     uint32_t mcs;
562     uint32_t mdr;
563     uint32_t mtpr;
564     uint32_t mimr;
565     uint32_t mris;
566     uint32_t mcr;
567 } stellaris_i2c_state;
568
569 #define STELLARIS_I2C_MCS_BUSY    0x01
570 #define STELLARIS_I2C_MCS_ERROR   0x02
571 #define STELLARIS_I2C_MCS_ADRACK  0x04
572 #define STELLARIS_I2C_MCS_DATACK  0x08
573 #define STELLARIS_I2C_MCS_ARBLST  0x10
574 #define STELLARIS_I2C_MCS_IDLE    0x20
575 #define STELLARIS_I2C_MCS_BUSBSY  0x40
576
577 static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
578 {
579     stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
580
581     offset -= s->base;
582     switch (offset) {
583     case 0x00: /* MSA */
584         return s->msa;
585     case 0x04: /* MCS */
586         /* We don't emulate timing, so the controller is never busy.  */
587         return s->mcs | STELLARIS_I2C_MCS_IDLE;
588     case 0x08: /* MDR */
589         return s->mdr;
590     case 0x0c: /* MTPR */
591         return s->mtpr;
592     case 0x10: /* MIMR */
593         return s->mimr;
594     case 0x14: /* MRIS */
595         return s->mris;
596     case 0x18: /* MMIS */
597         return s->mris & s->mimr;
598     case 0x20: /* MCR */
599         return s->mcr;
600     default:
601         cpu_abort(cpu_single_env, "strllaris_i2c_read: Bad offset 0x%x\n",
602                   (int)offset);
603         return 0;
604     }
605 }
606
607 static void stellaris_i2c_update(stellaris_i2c_state *s)
608 {
609     int level;
610
611     level = (s->mris & s->mimr) != 0;
612     qemu_set_irq(s->irq, level);
613 }
614
615 static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
616                                 uint32_t value)
617 {
618     stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
619
620     offset -= s->base;
621     switch (offset) {
622     case 0x00: /* MSA */
623         s->msa = value & 0xff;
624         break;
625     case 0x04: /* MCS */
626         if ((s->mcr & 0x10) == 0) {
627             /* Disabled.  Do nothing.  */
628             break;
629         }
630         /* Grab the bus if this is starting a transfer.  */
631         if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
632             if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
633                 s->mcs |= STELLARIS_I2C_MCS_ARBLST;
634             } else {
635                 s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
636                 s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
637             }
638         }
639         /* If we don't have the bus then indicate an error.  */
640         if (!i2c_bus_busy(s->bus)
641                 || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
642             s->mcs |= STELLARIS_I2C_MCS_ERROR;
643             break;
644         }
645         s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
646         if (value & 1) {
647             /* Transfer a byte.  */
648             /* TODO: Handle errors.  */
649             if (s->msa & 1) {
650                 /* Recv */
651                 s->mdr = i2c_recv(s->bus) & 0xff;
652             } else {
653                 /* Send */
654                 i2c_send(s->bus, s->mdr);
655             }
656             /* Raise an interrupt.  */
657             s->mris |= 1;
658         }
659         if (value & 4) {
660             /* Finish transfer.  */
661             i2c_end_transfer(s->bus);
662             s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
663         }
664         break;
665     case 0x08: /* MDR */
666         s->mdr = value & 0xff;
667         break;
668     case 0x0c: /* MTPR */
669         s->mtpr = value & 0xff;
670         break;
671     case 0x10: /* MIMR */
672         s->mimr = 1;
673         break;
674     case 0x1c: /* MICR */
675         s->mris &= ~value;
676         break;
677     case 0x20: /* MCR */
678         if (value & 1)
679             cpu_abort(cpu_single_env,
680                       "stellaris_i2c_write: Loopback not implemented\n");
681         if (value & 0x20)
682             cpu_abort(cpu_single_env,
683                       "stellaris_i2c_write: Slave mode not implemented\n");
684         s->mcr = value & 0x31;
685         break;
686     default:
687         cpu_abort(cpu_single_env, "stellaris_i2c_write: Bad offset 0x%x\n",
688                   (int)offset);
689     }
690     stellaris_i2c_update(s);
691 }
692
693 static void stellaris_i2c_reset(stellaris_i2c_state *s)
694 {
695     if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
696         i2c_end_transfer(s->bus);
697
698     s->msa = 0;
699     s->mcs = 0;
700     s->mdr = 0;
701     s->mtpr = 1;
702     s->mimr = 0;
703     s->mris = 0;
704     s->mcr = 0;
705     stellaris_i2c_update(s);
706 }
707
708 static CPUReadMemoryFunc *stellaris_i2c_readfn[] = {
709    stellaris_i2c_read,
710    stellaris_i2c_read,
711    stellaris_i2c_read
712 };
713
714 static CPUWriteMemoryFunc *stellaris_i2c_writefn[] = {
715    stellaris_i2c_write,
716    stellaris_i2c_write,
717    stellaris_i2c_write
718 };
719
720 static void stellaris_i2c_init(uint32_t base, qemu_irq irq, i2c_bus *bus)
721 {
722     stellaris_i2c_state *s;
723     int iomemtype;
724
725     s = (stellaris_i2c_state *)qemu_mallocz(sizeof(stellaris_i2c_state));
726     s->base = base;
727     s->irq = irq;
728     s->bus = bus;
729
730     iomemtype = cpu_register_io_memory(0, stellaris_i2c_readfn,
731                                        stellaris_i2c_writefn, s);
732     cpu_register_physical_memory(base, 0x00001000, iomemtype);
733     /* ??? For now we only implement the master interface.  */
734     stellaris_i2c_reset(s);
735 }
736
737 /* Analogue to Digital Converter.  This is only partially implemented,
738    enough for applications that use a combined ADC and timer tick.  */
739
740 #define STELLARIS_ADC_EM_CONTROLLER 0
741 #define STELLARIS_ADC_EM_COMP       1
742 #define STELLARIS_ADC_EM_EXTERNAL   4
743 #define STELLARIS_ADC_EM_TIMER      5
744 #define STELLARIS_ADC_EM_PWM0       6
745 #define STELLARIS_ADC_EM_PWM1       7
746 #define STELLARIS_ADC_EM_PWM2       8
747
748 #define STELLARIS_ADC_FIFO_EMPTY    0x0100
749 #define STELLARIS_ADC_FIFO_FULL     0x1000
750
751 typedef struct
752 {
753     uint32_t base;
754     uint32_t actss;
755     uint32_t ris;
756     uint32_t im;
757     uint32_t emux;
758     uint32_t ostat;
759     uint32_t ustat;
760     uint32_t sspri;
761     uint32_t sac;
762     struct {
763         uint32_t state;
764         uint32_t data[16];
765     } fifo[4];
766     uint32_t ssmux[4];
767     uint32_t ssctl[4];
768     qemu_irq irq;
769 } stellaris_adc_state;
770
771 static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
772 {
773     int tail;
774
775     tail = s->fifo[n].state & 0xf;
776     if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
777         s->ustat |= 1 << n;
778     } else {
779         s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
780         s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
781         if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
782             s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
783     }
784     return s->fifo[n].data[tail];
785 }
786
787 static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
788                                      uint32_t value)
789 {
790     int head;
791
792     head = (s->fifo[n].state >> 4) & 0xf;
793     if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
794         s->ostat |= 1 << n;
795         return;
796     }
797     s->fifo[n].data[head] = value;
798     head = (head + 1) & 0xf;
799     s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
800     s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
801     if ((s->fifo[n].state & 0xf) == head)
802         s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
803 }
804
805 static void stellaris_adc_update(stellaris_adc_state *s)
806 {
807     int level;
808
809     level = (s->ris & s->im) != 0;
810     qemu_set_irq(s->irq, level);
811 }
812
813 static void stellaris_adc_trigger(void *opaque, int irq, int level)
814 {
815     stellaris_adc_state *s = (stellaris_adc_state *)opaque;
816     /* Some applications use the ADC as a random number source, so introduce
817        some variation into the signal.  */
818     static uint32_t noise = 0;
819
820     if ((s->actss & 1) == 0) {
821         return;
822     }
823
824     noise = noise * 314159 + 1;
825     /* ??? actual inputs not implemented.  Return an arbitrary value.  */
826     stellaris_adc_fifo_write(s, 0, 0x200 + ((noise >> 16) & 7));
827     s->ris |= 1;
828     stellaris_adc_update(s);
829 }
830
831 static void stellaris_adc_reset(stellaris_adc_state *s)
832 {
833     int n;
834
835     for (n = 0; n < 4; n++) {
836         s->ssmux[n] = 0;
837         s->ssctl[n] = 0;
838         s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
839     }
840 }
841
842 static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
843 {
844     stellaris_adc_state *s = (stellaris_adc_state *)opaque;
845
846     /* TODO: Implement this.  */
847     offset -= s->base;
848     if (offset >= 0x40 && offset < 0xc0) {
849         int n;
850         n = (offset - 0x40) >> 5;
851         switch (offset & 0x1f) {
852         case 0x00: /* SSMUX */
853             return s->ssmux[n];
854         case 0x04: /* SSCTL */
855             return s->ssctl[n];
856         case 0x08: /* SSFIFO */
857             return stellaris_adc_fifo_read(s, n);
858         case 0x0c: /* SSFSTAT */
859             return s->fifo[n].state;
860         default:
861             break;
862         }
863     }
864     switch (offset) {
865     case 0x00: /* ACTSS */
866         return s->actss;
867     case 0x04: /* RIS */
868         return s->ris;
869     case 0x08: /* IM */
870         return s->im;
871     case 0x0c: /* ISC */
872         return s->ris & s->im;
873     case 0x10: /* OSTAT */
874         return s->ostat;
875     case 0x14: /* EMUX */
876         return s->emux;
877     case 0x18: /* USTAT */
878         return s->ustat;
879     case 0x20: /* SSPRI */
880         return s->sspri;
881     case 0x30: /* SAC */
882         return s->sac;
883     default:
884         cpu_abort(cpu_single_env, "strllaris_adc_read: Bad offset 0x%x\n",
885                   (int)offset);
886         return 0;
887     }
888 }
889
890 static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
891                                 uint32_t value)
892 {
893     stellaris_adc_state *s = (stellaris_adc_state *)opaque;
894
895     /* TODO: Implement this.  */
896     offset -= s->base;
897     if (offset >= 0x40 && offset < 0xc0) {
898         int n;
899         n = (offset - 0x40) >> 5;
900         switch (offset & 0x1f) {
901         case 0x00: /* SSMUX */
902             s->ssmux[n] = value & 0x33333333;
903             return;
904         case 0x04: /* SSCTL */
905             if (value != 6) {
906                 cpu_abort(cpu_single_env, "ADC: Unimplemented sequence %x\n",
907                           value);
908             }
909             s->ssctl[n] = value;
910             return;
911         default:
912             break;
913         }
914     }
915     switch (offset) {
916     case 0x00: /* ACTSS */
917         s->actss = value & 0xf;
918         if (value & 0xe) {
919             cpu_abort(cpu_single_env,
920                       "Not implemented:  ADC sequencers 1-3\n");
921         }
922         break;
923     case 0x08: /* IM */
924         s->im = value;
925         break;
926     case 0x0c: /* ISC */
927         s->ris &= ~value;
928         break;
929     case 0x10: /* OSTAT */
930         s->ostat &= ~value;
931         break;
932     case 0x14: /* EMUX */
933         s->emux = value;
934         break;
935     case 0x18: /* USTAT */
936         s->ustat &= ~value;
937         break;
938     case 0x20: /* SSPRI */
939         s->sspri = value;
940         break;
941     case 0x28: /* PSSI */
942         cpu_abort(cpu_single_env, "Not implemented:  ADC sample initiate\n");
943         break;
944     case 0x30: /* SAC */
945         s->sac = value;
946         break;
947     default:
948         cpu_abort(cpu_single_env, "stellaris_adc_write: Bad offset 0x%x\n",
949                   (int)offset);
950     }
951     stellaris_adc_update(s);
952 }
953
954 static CPUReadMemoryFunc *stellaris_adc_readfn[] = {
955    stellaris_adc_read,
956    stellaris_adc_read,
957    stellaris_adc_read
958 };
959
960 static CPUWriteMemoryFunc *stellaris_adc_writefn[] = {
961    stellaris_adc_write,
962    stellaris_adc_write,
963    stellaris_adc_write
964 };
965
966 static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq)
967 {
968     stellaris_adc_state *s;
969     int iomemtype;
970     qemu_irq *qi;
971
972     s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state));
973     s->base = base;
974     s->irq = irq;
975
976     iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn,
977                                        stellaris_adc_writefn, s);
978     cpu_register_physical_memory(base, 0x00001000, iomemtype);
979     stellaris_adc_reset(s);
980     qi = qemu_allocate_irqs(stellaris_adc_trigger, s, 1);
981     return qi[0];
982 }
983
984 /* Board init.  */
985 static stellaris_board_info stellaris_boards[] = {
986   { "LM3S811EVB",
987     0,
988     0x0032000e,
989     0x001f001f, /* dc0 */
990     0x001132bf,
991     0x01071013,
992     0x3f0f01ff,
993     0x0000001f,
994     OLED_I2C
995   },
996   { "LM3S6965EVB",
997     0x10010002,
998     0x1073402e,
999     0x00ff007f, /* dc0 */
1000     0x001133ff,
1001     0x030f5317,
1002     0x0f0f87ff,
1003     0x5000007f,
1004     OLED_SSI
1005   }
1006 };
1007
1008 static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1009                            DisplayState *ds, stellaris_board_info *board)
1010 {
1011     static const int uart_irq[] = {5, 6, 33, 34};
1012     static const int timer_irq[] = {19, 21, 23, 35};
1013     static const uint32_t gpio_addr[7] =
1014       { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1015         0x40024000, 0x40025000, 0x40026000};
1016     static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1017
1018     qemu_irq *pic;
1019     qemu_irq *gpio_in[5];
1020     qemu_irq *gpio_out[5];
1021     qemu_irq adc;
1022     int sram_size;
1023     int flash_size;
1024     i2c_bus *i2c;
1025     int i;
1026
1027     flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1028     sram_size = (board->dc0 >> 18) + 1;
1029     pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1030
1031     if (board->dc1 & (1 << 16)) {
1032         adc = stellaris_adc_init(0x40038000, pic[14]);
1033     } else {
1034         adc = NULL;
1035     }
1036     for (i = 0; i < 4; i++) {
1037         if (board->dc2 & (0x10000 << i)) {
1038             stellaris_gptm_init(0x40030000 + i * 0x1000,
1039                                 pic[timer_irq[i]], adc);
1040         }
1041     }
1042
1043     stellaris_sys_init(0x400fe000, pic[28], board);
1044
1045     for (i = 0; i < 7; i++) {
1046         if (board->dc4 & (1 << i)) {
1047             gpio_in[i] = pl061_init(gpio_addr[i], pic[gpio_irq[i]],
1048                                     &gpio_out[i]);
1049         }
1050     }
1051
1052     if (board->dc2 & (1 << 12)) {
1053         i2c = i2c_init_bus();
1054         stellaris_i2c_init(0x40020000, pic[8], i2c);
1055         if (board->oled == OLED_I2C) {
1056             ssd0303_init(ds, i2c, 0x3d);
1057         }
1058     }
1059
1060     for (i = 0; i < 4; i++) {
1061         if (board->dc2 & (1 << i)) {
1062             pl011_init(0x4000c000 + i * 0x1000, pic[uart_irq[i]],
1063                        serial_hds[i], PL011_LUMINARY);
1064         }
1065     }
1066     if (board->dc2 & (1 << 4)) {
1067         if (board->oled == OLED_SSI) {
1068             void * oled;
1069             /* FIXME: Implement chip select for OLED/MMC.  */
1070             oled = ssd0323_init(ds, &gpio_out[2][7]);
1071             pl022_init(0x40008000, pic[7], ssd0323_xfer_ssi, oled);
1072         } else {
1073             pl022_init(0x40008000, pic[7], NULL, NULL);
1074         }
1075     }
1076 }
1077
1078 /* FIXME: Figure out how to generate these from stellaris_boards.  */
1079 static void lm3s811evb_init(int ram_size, int vga_ram_size,
1080                      const char *boot_device, DisplayState *ds,
1081                      const char **fd_filename, int snapshot,
1082                      const char *kernel_filename, const char *kernel_cmdline,
1083                      const char *initrd_filename, const char *cpu_model)
1084 {
1085     stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[0]);
1086 }
1087
1088 static void lm3s6965evb_init(int ram_size, int vga_ram_size,
1089                      const char *boot_device, DisplayState *ds,
1090                      const char **fd_filename, int snapshot,
1091                      const char *kernel_filename, const char *kernel_cmdline,
1092                      const char *initrd_filename, const char *cpu_model)
1093 {
1094     stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[1]);
1095 }
1096
1097 QEMUMachine lm3s811evb_machine = {
1098     "lm3s811evb",
1099     "Stellaris LM3S811EVB",
1100     lm3s811evb_init,
1101 };
1102
1103 QEMUMachine lm3s6965evb_machine = {
1104     "lm3s6965evb",
1105     "Stellaris LM3S6965EVB",
1106     lm3s6965evb_init,
1107 };