Statistics
| Branch: | Revision:

root / hw / stellaris.c @ 8af7a3ab

History | View | Annotate | Download (39.2 kB)

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