Statistics
| Branch: | Revision:

root / hw / stellaris.c @ 93148aa5

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