Statistics
| Branch: | Revision:

root / hw / omap2.c @ 72af9170

History | View | Annotate | Download (142.1 kB)

1 827df9f3 balrog
/*
2 827df9f3 balrog
 * TI OMAP processors emulation.
3 827df9f3 balrog
 *
4 827df9f3 balrog
 * Copyright (C) 2007-2008 Nokia Corporation
5 827df9f3 balrog
 * Written by Andrzej Zaborowski <andrew@openedhand.com>
6 827df9f3 balrog
 *
7 827df9f3 balrog
 * This program is free software; you can redistribute it and/or
8 827df9f3 balrog
 * modify it under the terms of the GNU General Public License as
9 827df9f3 balrog
 * published by the Free Software Foundation; either version 2 or
10 827df9f3 balrog
 * (at your option) version 3 of the License.
11 827df9f3 balrog
 *
12 827df9f3 balrog
 * This program is distributed in the hope that it will be useful,
13 827df9f3 balrog
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 827df9f3 balrog
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 827df9f3 balrog
 * GNU General Public License for more details.
16 827df9f3 balrog
 *
17 fad6cb1a aurel32
 * You should have received a copy of the GNU General Public License along
18 fad6cb1a aurel32
 * with this program; if not, write to the Free Software Foundation, Inc.,
19 fad6cb1a aurel32
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 827df9f3 balrog
 */
21 827df9f3 balrog
#include "hw.h"
22 827df9f3 balrog
#include "arm-misc.h"
23 827df9f3 balrog
#include "omap.h"
24 827df9f3 balrog
#include "sysemu.h"
25 827df9f3 balrog
#include "qemu-timer.h"
26 827df9f3 balrog
#include "qemu-char.h"
27 827df9f3 balrog
#include "flash.h"
28 afbb5194 balrog
#include "soc_dma.h"
29 99570a40 balrog
#include "audio/audio.h"
30 827df9f3 balrog
31 827df9f3 balrog
/* GP timers */
32 827df9f3 balrog
struct omap_gp_timer_s {
33 827df9f3 balrog
    qemu_irq irq;
34 827df9f3 balrog
    qemu_irq wkup;
35 827df9f3 balrog
    qemu_irq in;
36 827df9f3 balrog
    qemu_irq out;
37 827df9f3 balrog
    omap_clk clk;
38 827df9f3 balrog
    QEMUTimer *timer;
39 827df9f3 balrog
    QEMUTimer *match;
40 827df9f3 balrog
    struct omap_target_agent_s *ta;
41 827df9f3 balrog
42 827df9f3 balrog
    int in_val;
43 827df9f3 balrog
    int out_val;
44 827df9f3 balrog
    int64_t time;
45 827df9f3 balrog
    int64_t rate;
46 827df9f3 balrog
    int64_t ticks_per_sec;
47 827df9f3 balrog
48 827df9f3 balrog
    int16_t config;
49 827df9f3 balrog
    int status;
50 827df9f3 balrog
    int it_ena;
51 827df9f3 balrog
    int wu_ena;
52 827df9f3 balrog
    int enable;
53 827df9f3 balrog
    int inout;
54 827df9f3 balrog
    int capt2;
55 827df9f3 balrog
    int pt;
56 827df9f3 balrog
    enum {
57 827df9f3 balrog
        gpt_trigger_none, gpt_trigger_overflow, gpt_trigger_both
58 827df9f3 balrog
    } trigger;
59 827df9f3 balrog
    enum {
60 827df9f3 balrog
        gpt_capture_none, gpt_capture_rising,
61 827df9f3 balrog
        gpt_capture_falling, gpt_capture_both
62 827df9f3 balrog
    } capture;
63 827df9f3 balrog
    int scpwm;
64 827df9f3 balrog
    int ce;
65 827df9f3 balrog
    int pre;
66 827df9f3 balrog
    int ptv;
67 827df9f3 balrog
    int ar;
68 827df9f3 balrog
    int st;
69 827df9f3 balrog
    int posted;
70 827df9f3 balrog
    uint32_t val;
71 827df9f3 balrog
    uint32_t load_val;
72 827df9f3 balrog
    uint32_t capture_val[2];
73 827df9f3 balrog
    uint32_t match_val;
74 827df9f3 balrog
    int capt_num;
75 827df9f3 balrog
76 827df9f3 balrog
    uint16_t writeh;        /* LSB */
77 827df9f3 balrog
    uint16_t readh;        /* MSB */
78 827df9f3 balrog
};
79 827df9f3 balrog
80 827df9f3 balrog
#define GPT_TCAR_IT        (1 << 2)
81 827df9f3 balrog
#define GPT_OVF_IT        (1 << 1)
82 827df9f3 balrog
#define GPT_MAT_IT        (1 << 0)
83 827df9f3 balrog
84 827df9f3 balrog
static inline void omap_gp_timer_intr(struct omap_gp_timer_s *timer, int it)
85 827df9f3 balrog
{
86 827df9f3 balrog
    if (timer->it_ena & it) {
87 827df9f3 balrog
        if (!timer->status)
88 827df9f3 balrog
            qemu_irq_raise(timer->irq);
89 827df9f3 balrog
90 827df9f3 balrog
        timer->status |= it;
91 827df9f3 balrog
        /* Or are the status bits set even when masked?
92 827df9f3 balrog
         * i.e. is masking applied before or after the status register?  */
93 827df9f3 balrog
    }
94 827df9f3 balrog
95 827df9f3 balrog
    if (timer->wu_ena & it)
96 827df9f3 balrog
        qemu_irq_pulse(timer->wkup);
97 827df9f3 balrog
}
98 827df9f3 balrog
99 827df9f3 balrog
static inline void omap_gp_timer_out(struct omap_gp_timer_s *timer, int level)
100 827df9f3 balrog
{
101 827df9f3 balrog
    if (!timer->inout && timer->out_val != level) {
102 827df9f3 balrog
        timer->out_val = level;
103 827df9f3 balrog
        qemu_set_irq(timer->out, level);
104 827df9f3 balrog
    }
105 827df9f3 balrog
}
106 827df9f3 balrog
107 827df9f3 balrog
static inline uint32_t omap_gp_timer_read(struct omap_gp_timer_s *timer)
108 827df9f3 balrog
{
109 827df9f3 balrog
    uint64_t distance;
110 827df9f3 balrog
111 827df9f3 balrog
    if (timer->st && timer->rate) {
112 827df9f3 balrog
        distance = qemu_get_clock(vm_clock) - timer->time;
113 827df9f3 balrog
        distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
114 827df9f3 balrog
115 827df9f3 balrog
        if (distance >= 0xffffffff - timer->val)
116 827df9f3 balrog
            return 0xffffffff;
117 827df9f3 balrog
        else
118 827df9f3 balrog
            return timer->val + distance;
119 827df9f3 balrog
    } else
120 827df9f3 balrog
        return timer->val;
121 827df9f3 balrog
}
122 827df9f3 balrog
123 827df9f3 balrog
static inline void omap_gp_timer_sync(struct omap_gp_timer_s *timer)
124 827df9f3 balrog
{
125 827df9f3 balrog
    if (timer->st) {
126 827df9f3 balrog
        timer->val = omap_gp_timer_read(timer);
127 827df9f3 balrog
        timer->time = qemu_get_clock(vm_clock);
128 827df9f3 balrog
    }
129 827df9f3 balrog
}
130 827df9f3 balrog
131 827df9f3 balrog
static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer)
132 827df9f3 balrog
{
133 827df9f3 balrog
    int64_t expires, matches;
134 827df9f3 balrog
135 827df9f3 balrog
    if (timer->st && timer->rate) {
136 827df9f3 balrog
        expires = muldiv64(0x100000000ll - timer->val,
137 827df9f3 balrog
                        timer->ticks_per_sec, timer->rate);
138 827df9f3 balrog
        qemu_mod_timer(timer->timer, timer->time + expires);
139 827df9f3 balrog
140 827df9f3 balrog
        if (timer->ce && timer->match_val >= timer->val) {
141 827df9f3 balrog
            matches = muldiv64(timer->match_val - timer->val,
142 827df9f3 balrog
                            timer->ticks_per_sec, timer->rate);
143 827df9f3 balrog
            qemu_mod_timer(timer->match, timer->time + matches);
144 827df9f3 balrog
        } else
145 827df9f3 balrog
            qemu_del_timer(timer->match);
146 827df9f3 balrog
    } else {
147 827df9f3 balrog
        qemu_del_timer(timer->timer);
148 827df9f3 balrog
        qemu_del_timer(timer->match);
149 827df9f3 balrog
        omap_gp_timer_out(timer, timer->scpwm);
150 827df9f3 balrog
    }
151 827df9f3 balrog
}
152 827df9f3 balrog
153 827df9f3 balrog
static inline void omap_gp_timer_trigger(struct omap_gp_timer_s *timer)
154 827df9f3 balrog
{
155 827df9f3 balrog
    if (timer->pt)
156 827df9f3 balrog
        /* TODO in overflow-and-match mode if the first event to
157 75554a3c balrog
         * occur is the match, don't toggle.  */
158 827df9f3 balrog
        omap_gp_timer_out(timer, !timer->out_val);
159 827df9f3 balrog
    else
160 827df9f3 balrog
        /* TODO inverted pulse on timer->out_val == 1?  */
161 827df9f3 balrog
        qemu_irq_pulse(timer->out);
162 827df9f3 balrog
}
163 827df9f3 balrog
164 827df9f3 balrog
static void omap_gp_timer_tick(void *opaque)
165 827df9f3 balrog
{
166 827df9f3 balrog
    struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
167 827df9f3 balrog
168 827df9f3 balrog
    if (!timer->ar) {
169 827df9f3 balrog
        timer->st = 0;
170 827df9f3 balrog
        timer->val = 0;
171 827df9f3 balrog
    } else {
172 827df9f3 balrog
        timer->val = timer->load_val;
173 827df9f3 balrog
        timer->time = qemu_get_clock(vm_clock);
174 827df9f3 balrog
    }
175 827df9f3 balrog
176 827df9f3 balrog
    if (timer->trigger == gpt_trigger_overflow ||
177 827df9f3 balrog
                    timer->trigger == gpt_trigger_both)
178 827df9f3 balrog
        omap_gp_timer_trigger(timer);
179 827df9f3 balrog
180 827df9f3 balrog
    omap_gp_timer_intr(timer, GPT_OVF_IT);
181 827df9f3 balrog
    omap_gp_timer_update(timer);
182 827df9f3 balrog
}
183 827df9f3 balrog
184 827df9f3 balrog
static void omap_gp_timer_match(void *opaque)
185 827df9f3 balrog
{
186 827df9f3 balrog
    struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
187 827df9f3 balrog
188 827df9f3 balrog
    if (timer->trigger == gpt_trigger_both)
189 827df9f3 balrog
        omap_gp_timer_trigger(timer);
190 827df9f3 balrog
191 827df9f3 balrog
    omap_gp_timer_intr(timer, GPT_MAT_IT);
192 827df9f3 balrog
}
193 827df9f3 balrog
194 827df9f3 balrog
static void omap_gp_timer_input(void *opaque, int line, int on)
195 827df9f3 balrog
{
196 827df9f3 balrog
    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
197 827df9f3 balrog
    int trigger;
198 827df9f3 balrog
199 827df9f3 balrog
    switch (s->capture) {
200 827df9f3 balrog
    default:
201 827df9f3 balrog
    case gpt_capture_none:
202 827df9f3 balrog
        trigger = 0;
203 827df9f3 balrog
        break;
204 827df9f3 balrog
    case gpt_capture_rising:
205 827df9f3 balrog
        trigger = !s->in_val && on;
206 827df9f3 balrog
        break;
207 827df9f3 balrog
    case gpt_capture_falling:
208 827df9f3 balrog
        trigger = s->in_val && !on;
209 827df9f3 balrog
        break;
210 827df9f3 balrog
    case gpt_capture_both:
211 827df9f3 balrog
        trigger = (s->in_val == !on);
212 827df9f3 balrog
        break;
213 827df9f3 balrog
    }
214 827df9f3 balrog
    s->in_val = on;
215 827df9f3 balrog
216 827df9f3 balrog
    if (s->inout && trigger && s->capt_num < 2) {
217 827df9f3 balrog
        s->capture_val[s->capt_num] = omap_gp_timer_read(s);
218 827df9f3 balrog
219 827df9f3 balrog
        if (s->capt2 == s->capt_num ++)
220 827df9f3 balrog
            omap_gp_timer_intr(s, GPT_TCAR_IT);
221 827df9f3 balrog
    }
222 827df9f3 balrog
}
223 827df9f3 balrog
224 827df9f3 balrog
static void omap_gp_timer_clk_update(void *opaque, int line, int on)
225 827df9f3 balrog
{
226 827df9f3 balrog
    struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
227 827df9f3 balrog
228 827df9f3 balrog
    omap_gp_timer_sync(timer);
229 827df9f3 balrog
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
230 827df9f3 balrog
    omap_gp_timer_update(timer);
231 827df9f3 balrog
}
232 827df9f3 balrog
233 827df9f3 balrog
static void omap_gp_timer_clk_setup(struct omap_gp_timer_s *timer)
234 827df9f3 balrog
{
235 827df9f3 balrog
    omap_clk_adduser(timer->clk,
236 827df9f3 balrog
                    qemu_allocate_irqs(omap_gp_timer_clk_update, timer, 1)[0]);
237 827df9f3 balrog
    timer->rate = omap_clk_getrate(timer->clk);
238 827df9f3 balrog
}
239 827df9f3 balrog
240 827df9f3 balrog
static void omap_gp_timer_reset(struct omap_gp_timer_s *s)
241 827df9f3 balrog
{
242 827df9f3 balrog
    s->config = 0x000;
243 827df9f3 balrog
    s->status = 0;
244 827df9f3 balrog
    s->it_ena = 0;
245 827df9f3 balrog
    s->wu_ena = 0;
246 827df9f3 balrog
    s->inout = 0;
247 827df9f3 balrog
    s->capt2 = 0;
248 827df9f3 balrog
    s->capt_num = 0;
249 827df9f3 balrog
    s->pt = 0;
250 827df9f3 balrog
    s->trigger = gpt_trigger_none;
251 827df9f3 balrog
    s->capture = gpt_capture_none;
252 827df9f3 balrog
    s->scpwm = 0;
253 827df9f3 balrog
    s->ce = 0;
254 827df9f3 balrog
    s->pre = 0;
255 827df9f3 balrog
    s->ptv = 0;
256 827df9f3 balrog
    s->ar = 0;
257 827df9f3 balrog
    s->st = 0;
258 827df9f3 balrog
    s->posted = 1;
259 827df9f3 balrog
    s->val = 0x00000000;
260 827df9f3 balrog
    s->load_val = 0x00000000;
261 827df9f3 balrog
    s->capture_val[0] = 0x00000000;
262 827df9f3 balrog
    s->capture_val[1] = 0x00000000;
263 827df9f3 balrog
    s->match_val = 0x00000000;
264 827df9f3 balrog
    omap_gp_timer_update(s);
265 827df9f3 balrog
}
266 827df9f3 balrog
267 827df9f3 balrog
static uint32_t omap_gp_timer_readw(void *opaque, target_phys_addr_t addr)
268 827df9f3 balrog
{
269 827df9f3 balrog
    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
270 827df9f3 balrog
271 8da3ff18 pbrook
    switch (addr) {
272 827df9f3 balrog
    case 0x00:        /* TIDR */
273 827df9f3 balrog
        return 0x21;
274 827df9f3 balrog
275 827df9f3 balrog
    case 0x10:        /* TIOCP_CFG */
276 827df9f3 balrog
        return s->config;
277 827df9f3 balrog
278 827df9f3 balrog
    case 0x14:        /* TISTAT */
279 827df9f3 balrog
        /* ??? When's this bit reset? */
280 827df9f3 balrog
        return 1;                                                /* RESETDONE */
281 827df9f3 balrog
282 827df9f3 balrog
    case 0x18:        /* TISR */
283 827df9f3 balrog
        return s->status;
284 827df9f3 balrog
285 827df9f3 balrog
    case 0x1c:        /* TIER */
286 827df9f3 balrog
        return s->it_ena;
287 827df9f3 balrog
288 827df9f3 balrog
    case 0x20:        /* TWER */
289 827df9f3 balrog
        return s->wu_ena;
290 827df9f3 balrog
291 827df9f3 balrog
    case 0x24:        /* TCLR */
292 827df9f3 balrog
        return (s->inout << 14) |
293 827df9f3 balrog
                (s->capt2 << 13) |
294 827df9f3 balrog
                (s->pt << 12) |
295 827df9f3 balrog
                (s->trigger << 10) |
296 827df9f3 balrog
                (s->capture << 8) |
297 827df9f3 balrog
                (s->scpwm << 7) |
298 827df9f3 balrog
                (s->ce << 6) |
299 827df9f3 balrog
                (s->pre << 5) |
300 827df9f3 balrog
                (s->ptv << 2) |
301 827df9f3 balrog
                (s->ar << 1) |
302 827df9f3 balrog
                (s->st << 0);
303 827df9f3 balrog
304 827df9f3 balrog
    case 0x28:        /* TCRR */
305 827df9f3 balrog
        return omap_gp_timer_read(s);
306 827df9f3 balrog
307 827df9f3 balrog
    case 0x2c:        /* TLDR */
308 827df9f3 balrog
        return s->load_val;
309 827df9f3 balrog
310 827df9f3 balrog
    case 0x30:        /* TTGR */
311 827df9f3 balrog
        return 0xffffffff;
312 827df9f3 balrog
313 827df9f3 balrog
    case 0x34:        /* TWPS */
314 827df9f3 balrog
        return 0x00000000;        /* No posted writes pending.  */
315 827df9f3 balrog
316 827df9f3 balrog
    case 0x38:        /* TMAR */
317 827df9f3 balrog
        return s->match_val;
318 827df9f3 balrog
319 827df9f3 balrog
    case 0x3c:        /* TCAR1 */
320 827df9f3 balrog
        return s->capture_val[0];
321 827df9f3 balrog
322 827df9f3 balrog
    case 0x40:        /* TSICR */
323 827df9f3 balrog
        return s->posted << 2;
324 827df9f3 balrog
325 827df9f3 balrog
    case 0x44:        /* TCAR2 */
326 827df9f3 balrog
        return s->capture_val[1];
327 827df9f3 balrog
    }
328 827df9f3 balrog
329 827df9f3 balrog
    OMAP_BAD_REG(addr);
330 827df9f3 balrog
    return 0;
331 827df9f3 balrog
}
332 827df9f3 balrog
333 827df9f3 balrog
static uint32_t omap_gp_timer_readh(void *opaque, target_phys_addr_t addr)
334 827df9f3 balrog
{
335 827df9f3 balrog
    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
336 827df9f3 balrog
    uint32_t ret;
337 827df9f3 balrog
338 827df9f3 balrog
    if (addr & 2)
339 827df9f3 balrog
        return s->readh;
340 827df9f3 balrog
    else {
341 827df9f3 balrog
        ret = omap_gp_timer_readw(opaque, addr);
342 827df9f3 balrog
        s->readh = ret >> 16;
343 827df9f3 balrog
        return ret & 0xffff;
344 827df9f3 balrog
    }
345 827df9f3 balrog
}
346 827df9f3 balrog
347 827df9f3 balrog
static CPUReadMemoryFunc *omap_gp_timer_readfn[] = {
348 827df9f3 balrog
    omap_badwidth_read32,
349 827df9f3 balrog
    omap_gp_timer_readh,
350 827df9f3 balrog
    omap_gp_timer_readw,
351 827df9f3 balrog
};
352 827df9f3 balrog
353 827df9f3 balrog
static void omap_gp_timer_write(void *opaque, target_phys_addr_t addr,
354 827df9f3 balrog
                uint32_t value)
355 827df9f3 balrog
{
356 827df9f3 balrog
    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
357 827df9f3 balrog
358 8da3ff18 pbrook
    switch (addr) {
359 827df9f3 balrog
    case 0x00:        /* TIDR */
360 827df9f3 balrog
    case 0x14:        /* TISTAT */
361 827df9f3 balrog
    case 0x34:        /* TWPS */
362 827df9f3 balrog
    case 0x3c:        /* TCAR1 */
363 827df9f3 balrog
    case 0x44:        /* TCAR2 */
364 827df9f3 balrog
        OMAP_RO_REG(addr);
365 827df9f3 balrog
        break;
366 827df9f3 balrog
367 827df9f3 balrog
    case 0x10:        /* TIOCP_CFG */
368 827df9f3 balrog
        s->config = value & 0x33d;
369 827df9f3 balrog
        if (((value >> 3) & 3) == 3)                                /* IDLEMODE */
370 827df9f3 balrog
            fprintf(stderr, "%s: illegal IDLEMODE value in TIOCP_CFG\n",
371 827df9f3 balrog
                            __FUNCTION__);
372 827df9f3 balrog
        if (value & 2)                                                /* SOFTRESET */
373 827df9f3 balrog
            omap_gp_timer_reset(s);
374 827df9f3 balrog
        break;
375 827df9f3 balrog
376 827df9f3 balrog
    case 0x18:        /* TISR */
377 827df9f3 balrog
        if (value & GPT_TCAR_IT)
378 827df9f3 balrog
            s->capt_num = 0;
379 827df9f3 balrog
        if (s->status && !(s->status &= ~value))
380 827df9f3 balrog
            qemu_irq_lower(s->irq);
381 827df9f3 balrog
        break;
382 827df9f3 balrog
383 827df9f3 balrog
    case 0x1c:        /* TIER */
384 827df9f3 balrog
        s->it_ena = value & 7;
385 827df9f3 balrog
        break;
386 827df9f3 balrog
387 827df9f3 balrog
    case 0x20:        /* TWER */
388 827df9f3 balrog
        s->wu_ena = value & 7;
389 827df9f3 balrog
        break;
390 827df9f3 balrog
391 827df9f3 balrog
    case 0x24:        /* TCLR */
392 827df9f3 balrog
        omap_gp_timer_sync(s);
393 827df9f3 balrog
        s->inout = (value >> 14) & 1;
394 827df9f3 balrog
        s->capt2 = (value >> 13) & 1;
395 827df9f3 balrog
        s->pt = (value >> 12) & 1;
396 827df9f3 balrog
        s->trigger = (value >> 10) & 3;
397 827df9f3 balrog
        if (s->capture == gpt_capture_none &&
398 827df9f3 balrog
                        ((value >> 8) & 3) != gpt_capture_none)
399 827df9f3 balrog
            s->capt_num = 0;
400 827df9f3 balrog
        s->capture = (value >> 8) & 3;
401 827df9f3 balrog
        s->scpwm = (value >> 7) & 1;
402 827df9f3 balrog
        s->ce = (value >> 6) & 1;
403 827df9f3 balrog
        s->pre = (value >> 5) & 1;
404 827df9f3 balrog
        s->ptv = (value >> 2) & 7;
405 827df9f3 balrog
        s->ar = (value >> 1) & 1;
406 827df9f3 balrog
        s->st = (value >> 0) & 1;
407 827df9f3 balrog
        if (s->inout && s->trigger != gpt_trigger_none)
408 827df9f3 balrog
            fprintf(stderr, "%s: GP timer pin must be an output "
409 827df9f3 balrog
                            "for this trigger mode\n", __FUNCTION__);
410 827df9f3 balrog
        if (!s->inout && s->capture != gpt_capture_none)
411 827df9f3 balrog
            fprintf(stderr, "%s: GP timer pin must be an input "
412 827df9f3 balrog
                            "for this capture mode\n", __FUNCTION__);
413 827df9f3 balrog
        if (s->trigger == gpt_trigger_none)
414 827df9f3 balrog
            omap_gp_timer_out(s, s->scpwm);
415 827df9f3 balrog
        /* TODO: make sure this doesn't overflow 32-bits */
416 827df9f3 balrog
        s->ticks_per_sec = ticks_per_sec << (s->pre ? s->ptv + 1 : 0);
417 827df9f3 balrog
        omap_gp_timer_update(s);
418 827df9f3 balrog
        break;
419 827df9f3 balrog
420 827df9f3 balrog
    case 0x28:        /* TCRR */
421 827df9f3 balrog
        s->time = qemu_get_clock(vm_clock);
422 827df9f3 balrog
        s->val = value;
423 827df9f3 balrog
        omap_gp_timer_update(s);
424 827df9f3 balrog
        break;
425 827df9f3 balrog
426 827df9f3 balrog
    case 0x2c:        /* TLDR */
427 827df9f3 balrog
        s->load_val = value;
428 827df9f3 balrog
        break;
429 827df9f3 balrog
430 827df9f3 balrog
    case 0x30:        /* TTGR */
431 827df9f3 balrog
        s->time = qemu_get_clock(vm_clock);
432 827df9f3 balrog
        s->val = s->load_val;
433 827df9f3 balrog
        omap_gp_timer_update(s);
434 827df9f3 balrog
        break;
435 827df9f3 balrog
436 827df9f3 balrog
    case 0x38:        /* TMAR */
437 827df9f3 balrog
        omap_gp_timer_sync(s);
438 827df9f3 balrog
        s->match_val = value;
439 827df9f3 balrog
        omap_gp_timer_update(s);
440 827df9f3 balrog
        break;
441 827df9f3 balrog
442 827df9f3 balrog
    case 0x40:        /* TSICR */
443 827df9f3 balrog
        s->posted = (value >> 2) & 1;
444 827df9f3 balrog
        if (value & 2)        /* How much exactly are we supposed to reset? */
445 827df9f3 balrog
            omap_gp_timer_reset(s);
446 827df9f3 balrog
        break;
447 827df9f3 balrog
448 827df9f3 balrog
    default:
449 827df9f3 balrog
        OMAP_BAD_REG(addr);
450 827df9f3 balrog
    }
451 827df9f3 balrog
}
452 827df9f3 balrog
453 827df9f3 balrog
static void omap_gp_timer_writeh(void *opaque, target_phys_addr_t addr,
454 827df9f3 balrog
                uint32_t value)
455 827df9f3 balrog
{
456 827df9f3 balrog
    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
457 827df9f3 balrog
458 827df9f3 balrog
    if (addr & 2)
459 827df9f3 balrog
        return omap_gp_timer_write(opaque, addr, (value << 16) | s->writeh);
460 827df9f3 balrog
    else
461 827df9f3 balrog
        s->writeh = (uint16_t) value;
462 827df9f3 balrog
}
463 827df9f3 balrog
464 827df9f3 balrog
static CPUWriteMemoryFunc *omap_gp_timer_writefn[] = {
465 827df9f3 balrog
    omap_badwidth_write32,
466 827df9f3 balrog
    omap_gp_timer_writeh,
467 827df9f3 balrog
    omap_gp_timer_write,
468 827df9f3 balrog
};
469 827df9f3 balrog
470 827df9f3 balrog
struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
471 827df9f3 balrog
                qemu_irq irq, omap_clk fclk, omap_clk iclk)
472 827df9f3 balrog
{
473 827df9f3 balrog
    int iomemtype;
474 827df9f3 balrog
    struct omap_gp_timer_s *s = (struct omap_gp_timer_s *)
475 827df9f3 balrog
            qemu_mallocz(sizeof(struct omap_gp_timer_s));
476 827df9f3 balrog
477 827df9f3 balrog
    s->ta = ta;
478 827df9f3 balrog
    s->irq = irq;
479 827df9f3 balrog
    s->clk = fclk;
480 827df9f3 balrog
    s->timer = qemu_new_timer(vm_clock, omap_gp_timer_tick, s);
481 827df9f3 balrog
    s->match = qemu_new_timer(vm_clock, omap_gp_timer_match, s);
482 827df9f3 balrog
    s->in = qemu_allocate_irqs(omap_gp_timer_input, s, 1)[0];
483 827df9f3 balrog
    omap_gp_timer_reset(s);
484 827df9f3 balrog
    omap_gp_timer_clk_setup(s);
485 827df9f3 balrog
486 c66fb5bc balrog
    iomemtype = l4_register_io_memory(0, omap_gp_timer_readfn,
487 827df9f3 balrog
                    omap_gp_timer_writefn, s);
488 8da3ff18 pbrook
    omap_l4_attach(ta, 0, iomemtype);
489 827df9f3 balrog
490 827df9f3 balrog
    return s;
491 827df9f3 balrog
}
492 827df9f3 balrog
493 827df9f3 balrog
/* 32-kHz Sync Timer of the OMAP2 */
494 827df9f3 balrog
static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
495 827df9f3 balrog
    return muldiv64(qemu_get_clock(vm_clock), 0x8000, ticks_per_sec);
496 827df9f3 balrog
}
497 827df9f3 balrog
498 827df9f3 balrog
static void omap_synctimer_reset(struct omap_synctimer_s *s)
499 827df9f3 balrog
{
500 827df9f3 balrog
    s->val = omap_synctimer_read(s);
501 827df9f3 balrog
}
502 827df9f3 balrog
503 827df9f3 balrog
static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr)
504 827df9f3 balrog
{
505 827df9f3 balrog
    struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
506 827df9f3 balrog
507 8da3ff18 pbrook
    switch (addr) {
508 827df9f3 balrog
    case 0x00:        /* 32KSYNCNT_REV */
509 827df9f3 balrog
        return 0x21;
510 827df9f3 balrog
511 827df9f3 balrog
    case 0x10:        /* CR */
512 827df9f3 balrog
        return omap_synctimer_read(s) - s->val;
513 827df9f3 balrog
    }
514 827df9f3 balrog
515 827df9f3 balrog
    OMAP_BAD_REG(addr);
516 827df9f3 balrog
    return 0;
517 827df9f3 balrog
}
518 827df9f3 balrog
519 827df9f3 balrog
static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr)
520 827df9f3 balrog
{
521 827df9f3 balrog
    struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
522 827df9f3 balrog
    uint32_t ret;
523 827df9f3 balrog
524 827df9f3 balrog
    if (addr & 2)
525 827df9f3 balrog
        return s->readh;
526 827df9f3 balrog
    else {
527 827df9f3 balrog
        ret = omap_synctimer_readw(opaque, addr);
528 827df9f3 balrog
        s->readh = ret >> 16;
529 827df9f3 balrog
        return ret & 0xffff;
530 827df9f3 balrog
    }
531 827df9f3 balrog
}
532 827df9f3 balrog
533 827df9f3 balrog
static CPUReadMemoryFunc *omap_synctimer_readfn[] = {
534 827df9f3 balrog
    omap_badwidth_read32,
535 827df9f3 balrog
    omap_synctimer_readh,
536 827df9f3 balrog
    omap_synctimer_readw,
537 827df9f3 balrog
};
538 827df9f3 balrog
539 827df9f3 balrog
static void omap_synctimer_write(void *opaque, target_phys_addr_t addr,
540 827df9f3 balrog
                uint32_t value)
541 827df9f3 balrog
{
542 827df9f3 balrog
    OMAP_BAD_REG(addr);
543 827df9f3 balrog
}
544 827df9f3 balrog
545 827df9f3 balrog
static CPUWriteMemoryFunc *omap_synctimer_writefn[] = {
546 827df9f3 balrog
    omap_badwidth_write32,
547 827df9f3 balrog
    omap_synctimer_write,
548 827df9f3 balrog
    omap_synctimer_write,
549 827df9f3 balrog
};
550 827df9f3 balrog
551 827df9f3 balrog
void omap_synctimer_init(struct omap_target_agent_s *ta,
552 827df9f3 balrog
                struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk)
553 827df9f3 balrog
{
554 827df9f3 balrog
    struct omap_synctimer_s *s = &mpu->synctimer;
555 827df9f3 balrog
556 827df9f3 balrog
    omap_synctimer_reset(s);
557 8da3ff18 pbrook
    omap_l4_attach(ta, 0, l4_register_io_memory(0,
558 8da3ff18 pbrook
                      omap_synctimer_readfn, omap_synctimer_writefn, s));
559 827df9f3 balrog
}
560 827df9f3 balrog
561 827df9f3 balrog
/* General-Purpose Interface of OMAP2 */
562 827df9f3 balrog
struct omap2_gpio_s {
563 827df9f3 balrog
    qemu_irq irq[2];
564 827df9f3 balrog
    qemu_irq wkup;
565 827df9f3 balrog
    qemu_irq *in;
566 827df9f3 balrog
    qemu_irq handler[32];
567 827df9f3 balrog
568 827df9f3 balrog
    uint8_t config[2];
569 827df9f3 balrog
    uint32_t inputs;
570 827df9f3 balrog
    uint32_t outputs;
571 827df9f3 balrog
    uint32_t dir;
572 827df9f3 balrog
    uint32_t level[2];
573 827df9f3 balrog
    uint32_t edge[2];
574 827df9f3 balrog
    uint32_t mask[2];
575 827df9f3 balrog
    uint32_t wumask;
576 827df9f3 balrog
    uint32_t ints[2];
577 827df9f3 balrog
    uint32_t debounce;
578 827df9f3 balrog
    uint8_t delay;
579 827df9f3 balrog
};
580 827df9f3 balrog
581 827df9f3 balrog
static inline void omap_gpio_module_int_update(struct omap2_gpio_s *s,
582 827df9f3 balrog
                int line)
583 827df9f3 balrog
{
584 827df9f3 balrog
    qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
585 827df9f3 balrog
}
586 827df9f3 balrog
587 827df9f3 balrog
static void omap_gpio_module_wake(struct omap2_gpio_s *s, int line)
588 827df9f3 balrog
{
589 827df9f3 balrog
    if (!(s->config[0] & (1 << 2)))                        /* ENAWAKEUP */
590 827df9f3 balrog
        return;
591 827df9f3 balrog
    if (!(s->config[0] & (3 << 3)))                        /* Force Idle */
592 827df9f3 balrog
        return;
593 827df9f3 balrog
    if (!(s->wumask & (1 << line)))
594 827df9f3 balrog
        return;
595 827df9f3 balrog
596 827df9f3 balrog
    qemu_irq_raise(s->wkup);
597 827df9f3 balrog
}
598 827df9f3 balrog
599 827df9f3 balrog
static inline void omap_gpio_module_out_update(struct omap2_gpio_s *s,
600 827df9f3 balrog
                uint32_t diff)
601 827df9f3 balrog
{
602 827df9f3 balrog
    int ln;
603 827df9f3 balrog
604 827df9f3 balrog
    s->outputs ^= diff;
605 827df9f3 balrog
    diff &= ~s->dir;
606 827df9f3 balrog
    while ((ln = ffs(diff))) {
607 827df9f3 balrog
        ln --;
608 827df9f3 balrog
        qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
609 827df9f3 balrog
        diff &= ~(1 << ln);
610 827df9f3 balrog
    }
611 827df9f3 balrog
}
612 827df9f3 balrog
613 827df9f3 balrog
static void omap_gpio_module_level_update(struct omap2_gpio_s *s, int line)
614 827df9f3 balrog
{
615 827df9f3 balrog
    s->ints[line] |= s->dir &
616 827df9f3 balrog
            ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
617 827df9f3 balrog
    omap_gpio_module_int_update(s, line);
618 827df9f3 balrog
}
619 827df9f3 balrog
620 827df9f3 balrog
static inline void omap_gpio_module_int(struct omap2_gpio_s *s, int line)
621 827df9f3 balrog
{
622 827df9f3 balrog
    s->ints[0] |= 1 << line;
623 827df9f3 balrog
    omap_gpio_module_int_update(s, 0);
624 827df9f3 balrog
    s->ints[1] |= 1 << line;
625 827df9f3 balrog
    omap_gpio_module_int_update(s, 1);
626 827df9f3 balrog
    omap_gpio_module_wake(s, line);
627 827df9f3 balrog
}
628 827df9f3 balrog
629 827df9f3 balrog
static void omap_gpio_module_set(void *opaque, int line, int level)
630 827df9f3 balrog
{
631 827df9f3 balrog
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
632 827df9f3 balrog
633 827df9f3 balrog
    if (level) {
634 827df9f3 balrog
        if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
635 827df9f3 balrog
            omap_gpio_module_int(s, line);
636 827df9f3 balrog
        s->inputs |= 1 << line;
637 827df9f3 balrog
    } else {
638 827df9f3 balrog
        if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
639 827df9f3 balrog
            omap_gpio_module_int(s, line);
640 827df9f3 balrog
        s->inputs &= ~(1 << line);
641 827df9f3 balrog
    }
642 827df9f3 balrog
}
643 827df9f3 balrog
644 827df9f3 balrog
static void omap_gpio_module_reset(struct omap2_gpio_s *s)
645 827df9f3 balrog
{
646 827df9f3 balrog
    s->config[0] = 0;
647 827df9f3 balrog
    s->config[1] = 2;
648 827df9f3 balrog
    s->ints[0] = 0;
649 827df9f3 balrog
    s->ints[1] = 0;
650 827df9f3 balrog
    s->mask[0] = 0;
651 827df9f3 balrog
    s->mask[1] = 0;
652 827df9f3 balrog
    s->wumask = 0;
653 827df9f3 balrog
    s->dir = ~0;
654 827df9f3 balrog
    s->level[0] = 0;
655 827df9f3 balrog
    s->level[1] = 0;
656 827df9f3 balrog
    s->edge[0] = 0;
657 827df9f3 balrog
    s->edge[1] = 0;
658 827df9f3 balrog
    s->debounce = 0;
659 827df9f3 balrog
    s->delay = 0;
660 827df9f3 balrog
}
661 827df9f3 balrog
662 827df9f3 balrog
static uint32_t omap_gpio_module_read(void *opaque, target_phys_addr_t addr)
663 827df9f3 balrog
{
664 827df9f3 balrog
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
665 827df9f3 balrog
666 8da3ff18 pbrook
    switch (addr) {
667 827df9f3 balrog
    case 0x00:        /* GPIO_REVISION */
668 827df9f3 balrog
        return 0x18;
669 827df9f3 balrog
670 827df9f3 balrog
    case 0x10:        /* GPIO_SYSCONFIG */
671 827df9f3 balrog
        return s->config[0];
672 827df9f3 balrog
673 827df9f3 balrog
    case 0x14:        /* GPIO_SYSSTATUS */
674 827df9f3 balrog
        return 0x01;
675 827df9f3 balrog
676 827df9f3 balrog
    case 0x18:        /* GPIO_IRQSTATUS1 */
677 827df9f3 balrog
        return s->ints[0];
678 827df9f3 balrog
679 827df9f3 balrog
    case 0x1c:        /* GPIO_IRQENABLE1 */
680 827df9f3 balrog
    case 0x60:        /* GPIO_CLEARIRQENABLE1 */
681 827df9f3 balrog
    case 0x64:        /* GPIO_SETIRQENABLE1 */
682 827df9f3 balrog
        return s->mask[0];
683 827df9f3 balrog
684 827df9f3 balrog
    case 0x20:        /* GPIO_WAKEUPENABLE */
685 827df9f3 balrog
    case 0x80:        /* GPIO_CLEARWKUENA */
686 827df9f3 balrog
    case 0x84:        /* GPIO_SETWKUENA */
687 827df9f3 balrog
        return s->wumask;
688 827df9f3 balrog
689 827df9f3 balrog
    case 0x28:        /* GPIO_IRQSTATUS2 */
690 827df9f3 balrog
        return s->ints[1];
691 827df9f3 balrog
692 827df9f3 balrog
    case 0x2c:        /* GPIO_IRQENABLE2 */
693 827df9f3 balrog
    case 0x70:        /* GPIO_CLEARIRQENABLE2 */
694 827df9f3 balrog
    case 0x74:        /* GPIO_SETIREQNEABLE2 */
695 827df9f3 balrog
        return s->mask[1];
696 827df9f3 balrog
697 827df9f3 balrog
    case 0x30:        /* GPIO_CTRL */
698 827df9f3 balrog
        return s->config[1];
699 827df9f3 balrog
700 827df9f3 balrog
    case 0x34:        /* GPIO_OE */
701 827df9f3 balrog
        return s->dir;
702 827df9f3 balrog
703 827df9f3 balrog
    case 0x38:        /* GPIO_DATAIN */
704 827df9f3 balrog
        return s->inputs;
705 827df9f3 balrog
706 827df9f3 balrog
    case 0x3c:        /* GPIO_DATAOUT */
707 827df9f3 balrog
    case 0x90:        /* GPIO_CLEARDATAOUT */
708 827df9f3 balrog
    case 0x94:        /* GPIO_SETDATAOUT */
709 827df9f3 balrog
        return s->outputs;
710 827df9f3 balrog
711 827df9f3 balrog
    case 0x40:        /* GPIO_LEVELDETECT0 */
712 827df9f3 balrog
        return s->level[0];
713 827df9f3 balrog
714 827df9f3 balrog
    case 0x44:        /* GPIO_LEVELDETECT1 */
715 827df9f3 balrog
        return s->level[1];
716 827df9f3 balrog
717 827df9f3 balrog
    case 0x48:        /* GPIO_RISINGDETECT */
718 827df9f3 balrog
        return s->edge[0];
719 827df9f3 balrog
720 827df9f3 balrog
    case 0x4c:        /* GPIO_FALLINGDETECT */
721 827df9f3 balrog
        return s->edge[1];
722 827df9f3 balrog
723 827df9f3 balrog
    case 0x50:        /* GPIO_DEBOUNCENABLE */
724 827df9f3 balrog
        return s->debounce;
725 827df9f3 balrog
726 827df9f3 balrog
    case 0x54:        /* GPIO_DEBOUNCINGTIME */
727 827df9f3 balrog
        return s->delay;
728 827df9f3 balrog
    }
729 827df9f3 balrog
730 827df9f3 balrog
    OMAP_BAD_REG(addr);
731 827df9f3 balrog
    return 0;
732 827df9f3 balrog
}
733 827df9f3 balrog
734 827df9f3 balrog
static void omap_gpio_module_write(void *opaque, target_phys_addr_t addr,
735 827df9f3 balrog
                uint32_t value)
736 827df9f3 balrog
{
737 827df9f3 balrog
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
738 827df9f3 balrog
    uint32_t diff;
739 827df9f3 balrog
    int ln;
740 827df9f3 balrog
741 8da3ff18 pbrook
    switch (addr) {
742 827df9f3 balrog
    case 0x00:        /* GPIO_REVISION */
743 827df9f3 balrog
    case 0x14:        /* GPIO_SYSSTATUS */
744 827df9f3 balrog
    case 0x38:        /* GPIO_DATAIN */
745 827df9f3 balrog
        OMAP_RO_REG(addr);
746 827df9f3 balrog
        break;
747 827df9f3 balrog
748 827df9f3 balrog
    case 0x10:        /* GPIO_SYSCONFIG */
749 827df9f3 balrog
        if (((value >> 3) & 3) == 3)
750 827df9f3 balrog
            fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
751 827df9f3 balrog
        if (value & 2)
752 827df9f3 balrog
            omap_gpio_module_reset(s);
753 827df9f3 balrog
        s->config[0] = value & 0x1d;
754 827df9f3 balrog
        break;
755 827df9f3 balrog
756 827df9f3 balrog
    case 0x18:        /* GPIO_IRQSTATUS1 */
757 827df9f3 balrog
        if (s->ints[0] & value) {
758 827df9f3 balrog
            s->ints[0] &= ~value;
759 827df9f3 balrog
            omap_gpio_module_level_update(s, 0);
760 827df9f3 balrog
        }
761 827df9f3 balrog
        break;
762 827df9f3 balrog
763 827df9f3 balrog
    case 0x1c:        /* GPIO_IRQENABLE1 */
764 827df9f3 balrog
        s->mask[0] = value;
765 827df9f3 balrog
        omap_gpio_module_int_update(s, 0);
766 827df9f3 balrog
        break;
767 827df9f3 balrog
768 827df9f3 balrog
    case 0x20:        /* GPIO_WAKEUPENABLE */
769 827df9f3 balrog
        s->wumask = value;
770 827df9f3 balrog
        break;
771 827df9f3 balrog
772 827df9f3 balrog
    case 0x28:        /* GPIO_IRQSTATUS2 */
773 827df9f3 balrog
        if (s->ints[1] & value) {
774 827df9f3 balrog
            s->ints[1] &= ~value;
775 827df9f3 balrog
            omap_gpio_module_level_update(s, 1);
776 827df9f3 balrog
        }
777 827df9f3 balrog
        break;
778 827df9f3 balrog
779 827df9f3 balrog
    case 0x2c:        /* GPIO_IRQENABLE2 */
780 827df9f3 balrog
        s->mask[1] = value;
781 827df9f3 balrog
        omap_gpio_module_int_update(s, 1);
782 827df9f3 balrog
        break;
783 827df9f3 balrog
784 827df9f3 balrog
    case 0x30:        /* GPIO_CTRL */
785 827df9f3 balrog
        s->config[1] = value & 7;
786 827df9f3 balrog
        break;
787 827df9f3 balrog
788 827df9f3 balrog
    case 0x34:        /* GPIO_OE */
789 827df9f3 balrog
        diff = s->outputs & (s->dir ^ value);
790 827df9f3 balrog
        s->dir = value;
791 827df9f3 balrog
792 827df9f3 balrog
        value = s->outputs & ~s->dir;
793 827df9f3 balrog
        while ((ln = ffs(diff))) {
794 827df9f3 balrog
            diff &= ~(1 <<-- ln);
795 827df9f3 balrog
            qemu_set_irq(s->handler[ln], (value >> ln) & 1);
796 827df9f3 balrog
        }
797 827df9f3 balrog
798 827df9f3 balrog
        omap_gpio_module_level_update(s, 0);
799 827df9f3 balrog
        omap_gpio_module_level_update(s, 1);
800 827df9f3 balrog
        break;
801 827df9f3 balrog
802 827df9f3 balrog
    case 0x3c:        /* GPIO_DATAOUT */
803 827df9f3 balrog
        omap_gpio_module_out_update(s, s->outputs ^ value);
804 827df9f3 balrog
        break;
805 827df9f3 balrog
806 827df9f3 balrog
    case 0x40:        /* GPIO_LEVELDETECT0 */
807 827df9f3 balrog
        s->level[0] = value;
808 827df9f3 balrog
        omap_gpio_module_level_update(s, 0);
809 827df9f3 balrog
        omap_gpio_module_level_update(s, 1);
810 827df9f3 balrog
        break;
811 827df9f3 balrog
812 827df9f3 balrog
    case 0x44:        /* GPIO_LEVELDETECT1 */
813 827df9f3 balrog
        s->level[1] = value;
814 827df9f3 balrog
        omap_gpio_module_level_update(s, 0);
815 827df9f3 balrog
        omap_gpio_module_level_update(s, 1);
816 827df9f3 balrog
        break;
817 827df9f3 balrog
818 827df9f3 balrog
    case 0x48:        /* GPIO_RISINGDETECT */
819 827df9f3 balrog
        s->edge[0] = value;
820 827df9f3 balrog
        break;
821 827df9f3 balrog
822 827df9f3 balrog
    case 0x4c:        /* GPIO_FALLINGDETECT */
823 827df9f3 balrog
        s->edge[1] = value;
824 827df9f3 balrog
        break;
825 827df9f3 balrog
826 827df9f3 balrog
    case 0x50:        /* GPIO_DEBOUNCENABLE */
827 827df9f3 balrog
        s->debounce = value;
828 827df9f3 balrog
        break;
829 827df9f3 balrog
830 827df9f3 balrog
    case 0x54:        /* GPIO_DEBOUNCINGTIME */
831 827df9f3 balrog
        s->delay = value;
832 827df9f3 balrog
        break;
833 827df9f3 balrog
834 827df9f3 balrog
    case 0x60:        /* GPIO_CLEARIRQENABLE1 */
835 827df9f3 balrog
        s->mask[0] &= ~value;
836 827df9f3 balrog
        omap_gpio_module_int_update(s, 0);
837 827df9f3 balrog
        break;
838 827df9f3 balrog
839 827df9f3 balrog
    case 0x64:        /* GPIO_SETIRQENABLE1 */
840 827df9f3 balrog
        s->mask[0] |= value;
841 827df9f3 balrog
        omap_gpio_module_int_update(s, 0);
842 827df9f3 balrog
        break;
843 827df9f3 balrog
844 827df9f3 balrog
    case 0x70:        /* GPIO_CLEARIRQENABLE2 */
845 827df9f3 balrog
        s->mask[1] &= ~value;
846 827df9f3 balrog
        omap_gpio_module_int_update(s, 1);
847 827df9f3 balrog
        break;
848 827df9f3 balrog
849 827df9f3 balrog
    case 0x74:        /* GPIO_SETIREQNEABLE2 */
850 827df9f3 balrog
        s->mask[1] |= value;
851 827df9f3 balrog
        omap_gpio_module_int_update(s, 1);
852 827df9f3 balrog
        break;
853 827df9f3 balrog
854 827df9f3 balrog
    case 0x80:        /* GPIO_CLEARWKUENA */
855 827df9f3 balrog
        s->wumask &= ~value;
856 827df9f3 balrog
        break;
857 827df9f3 balrog
858 827df9f3 balrog
    case 0x84:        /* GPIO_SETWKUENA */
859 827df9f3 balrog
        s->wumask |= value;
860 827df9f3 balrog
        break;
861 827df9f3 balrog
862 827df9f3 balrog
    case 0x90:        /* GPIO_CLEARDATAOUT */
863 827df9f3 balrog
        omap_gpio_module_out_update(s, s->outputs & value);
864 827df9f3 balrog
        break;
865 827df9f3 balrog
866 827df9f3 balrog
    case 0x94:        /* GPIO_SETDATAOUT */
867 827df9f3 balrog
        omap_gpio_module_out_update(s, ~s->outputs & value);
868 827df9f3 balrog
        break;
869 827df9f3 balrog
870 827df9f3 balrog
    default:
871 827df9f3 balrog
        OMAP_BAD_REG(addr);
872 827df9f3 balrog
        return;
873 827df9f3 balrog
    }
874 827df9f3 balrog
}
875 827df9f3 balrog
876 827df9f3 balrog
static uint32_t omap_gpio_module_readp(void *opaque, target_phys_addr_t addr)
877 827df9f3 balrog
{
878 827df9f3 balrog
    return omap_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);
879 827df9f3 balrog
}
880 827df9f3 balrog
881 827df9f3 balrog
static void omap_gpio_module_writep(void *opaque, target_phys_addr_t addr,
882 827df9f3 balrog
                uint32_t value)
883 827df9f3 balrog
{
884 827df9f3 balrog
    uint32_t cur = 0;
885 827df9f3 balrog
    uint32_t mask = 0xffff;
886 827df9f3 balrog
887 8da3ff18 pbrook
    switch (addr & ~3) {
888 827df9f3 balrog
    case 0x00:        /* GPIO_REVISION */
889 827df9f3 balrog
    case 0x14:        /* GPIO_SYSSTATUS */
890 827df9f3 balrog
    case 0x38:        /* GPIO_DATAIN */
891 827df9f3 balrog
        OMAP_RO_REG(addr);
892 827df9f3 balrog
        break;
893 827df9f3 balrog
894 827df9f3 balrog
    case 0x10:        /* GPIO_SYSCONFIG */
895 827df9f3 balrog
    case 0x1c:        /* GPIO_IRQENABLE1 */
896 827df9f3 balrog
    case 0x20:        /* GPIO_WAKEUPENABLE */
897 827df9f3 balrog
    case 0x2c:        /* GPIO_IRQENABLE2 */
898 827df9f3 balrog
    case 0x30:        /* GPIO_CTRL */
899 827df9f3 balrog
    case 0x34:        /* GPIO_OE */
900 827df9f3 balrog
    case 0x3c:        /* GPIO_DATAOUT */
901 827df9f3 balrog
    case 0x40:        /* GPIO_LEVELDETECT0 */
902 827df9f3 balrog
    case 0x44:        /* GPIO_LEVELDETECT1 */
903 827df9f3 balrog
    case 0x48:        /* GPIO_RISINGDETECT */
904 827df9f3 balrog
    case 0x4c:        /* GPIO_FALLINGDETECT */
905 827df9f3 balrog
    case 0x50:        /* GPIO_DEBOUNCENABLE */
906 827df9f3 balrog
    case 0x54:        /* GPIO_DEBOUNCINGTIME */
907 827df9f3 balrog
        cur = omap_gpio_module_read(opaque, addr & ~3) &
908 827df9f3 balrog
                ~(mask << ((addr & 3) << 3));
909 827df9f3 balrog
910 827df9f3 balrog
        /* Fall through.  */
911 827df9f3 balrog
    case 0x18:        /* GPIO_IRQSTATUS1 */
912 827df9f3 balrog
    case 0x28:        /* GPIO_IRQSTATUS2 */
913 827df9f3 balrog
    case 0x60:        /* GPIO_CLEARIRQENABLE1 */
914 827df9f3 balrog
    case 0x64:        /* GPIO_SETIRQENABLE1 */
915 827df9f3 balrog
    case 0x70:        /* GPIO_CLEARIRQENABLE2 */
916 827df9f3 balrog
    case 0x74:        /* GPIO_SETIREQNEABLE2 */
917 827df9f3 balrog
    case 0x80:        /* GPIO_CLEARWKUENA */
918 827df9f3 balrog
    case 0x84:        /* GPIO_SETWKUENA */
919 827df9f3 balrog
    case 0x90:        /* GPIO_CLEARDATAOUT */
920 827df9f3 balrog
    case 0x94:        /* GPIO_SETDATAOUT */
921 827df9f3 balrog
        value <<= (addr & 3) << 3;
922 827df9f3 balrog
        omap_gpio_module_write(opaque, addr, cur | value);
923 827df9f3 balrog
        break;
924 827df9f3 balrog
925 827df9f3 balrog
    default:
926 827df9f3 balrog
        OMAP_BAD_REG(addr);
927 827df9f3 balrog
        return;
928 827df9f3 balrog
    }
929 827df9f3 balrog
}
930 827df9f3 balrog
931 827df9f3 balrog
static CPUReadMemoryFunc *omap_gpio_module_readfn[] = {
932 827df9f3 balrog
    omap_gpio_module_readp,
933 827df9f3 balrog
    omap_gpio_module_readp,
934 827df9f3 balrog
    omap_gpio_module_read,
935 827df9f3 balrog
};
936 827df9f3 balrog
937 827df9f3 balrog
static CPUWriteMemoryFunc *omap_gpio_module_writefn[] = {
938 827df9f3 balrog
    omap_gpio_module_writep,
939 827df9f3 balrog
    omap_gpio_module_writep,
940 827df9f3 balrog
    omap_gpio_module_write,
941 827df9f3 balrog
};
942 827df9f3 balrog
943 827df9f3 balrog
static void omap_gpio_module_init(struct omap2_gpio_s *s,
944 827df9f3 balrog
                struct omap_target_agent_s *ta, int region,
945 827df9f3 balrog
                qemu_irq mpu, qemu_irq dsp, qemu_irq wkup,
946 827df9f3 balrog
                omap_clk fclk, omap_clk iclk)
947 827df9f3 balrog
{
948 827df9f3 balrog
    int iomemtype;
949 827df9f3 balrog
950 827df9f3 balrog
    s->irq[0] = mpu;
951 827df9f3 balrog
    s->irq[1] = dsp;
952 827df9f3 balrog
    s->wkup = wkup;
953 827df9f3 balrog
    s->in = qemu_allocate_irqs(omap_gpio_module_set, s, 32);
954 827df9f3 balrog
955 c66fb5bc balrog
    iomemtype = l4_register_io_memory(0, omap_gpio_module_readfn,
956 827df9f3 balrog
                    omap_gpio_module_writefn, s);
957 8da3ff18 pbrook
    omap_l4_attach(ta, region, iomemtype);
958 827df9f3 balrog
}
959 827df9f3 balrog
960 827df9f3 balrog
struct omap_gpif_s {
961 827df9f3 balrog
    struct omap2_gpio_s module[5];
962 827df9f3 balrog
    int modules;
963 827df9f3 balrog
964 827df9f3 balrog
    int autoidle;
965 827df9f3 balrog
    int gpo;
966 827df9f3 balrog
};
967 827df9f3 balrog
968 827df9f3 balrog
static void omap_gpif_reset(struct omap_gpif_s *s)
969 827df9f3 balrog
{
970 827df9f3 balrog
    int i;
971 827df9f3 balrog
972 827df9f3 balrog
    for (i = 0; i < s->modules; i ++)
973 827df9f3 balrog
        omap_gpio_module_reset(s->module + i);
974 827df9f3 balrog
975 827df9f3 balrog
    s->autoidle = 0;
976 827df9f3 balrog
    s->gpo = 0;
977 827df9f3 balrog
}
978 827df9f3 balrog
979 827df9f3 balrog
static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
980 827df9f3 balrog
{
981 827df9f3 balrog
    struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
982 827df9f3 balrog
983 8da3ff18 pbrook
    switch (addr) {
984 827df9f3 balrog
    case 0x00:        /* IPGENERICOCPSPL_REVISION */
985 827df9f3 balrog
        return 0x18;
986 827df9f3 balrog
987 827df9f3 balrog
    case 0x10:        /* IPGENERICOCPSPL_SYSCONFIG */
988 827df9f3 balrog
        return s->autoidle;
989 827df9f3 balrog
990 827df9f3 balrog
    case 0x14:        /* IPGENERICOCPSPL_SYSSTATUS */
991 827df9f3 balrog
        return 0x01;
992 827df9f3 balrog
993 827df9f3 balrog
    case 0x18:        /* IPGENERICOCPSPL_IRQSTATUS */
994 827df9f3 balrog
        return 0x00;
995 827df9f3 balrog
996 827df9f3 balrog
    case 0x40:        /* IPGENERICOCPSPL_GPO */
997 827df9f3 balrog
        return s->gpo;
998 827df9f3 balrog
999 827df9f3 balrog
    case 0x50:        /* IPGENERICOCPSPL_GPI */
1000 827df9f3 balrog
        return 0x00;
1001 827df9f3 balrog
    }
1002 827df9f3 balrog
1003 827df9f3 balrog
    OMAP_BAD_REG(addr);
1004 827df9f3 balrog
    return 0;
1005 827df9f3 balrog
}
1006 827df9f3 balrog
1007 827df9f3 balrog
static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
1008 827df9f3 balrog
                uint32_t value)
1009 827df9f3 balrog
{
1010 827df9f3 balrog
    struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
1011 827df9f3 balrog
1012 8da3ff18 pbrook
    switch (addr) {
1013 827df9f3 balrog
    case 0x00:        /* IPGENERICOCPSPL_REVISION */
1014 827df9f3 balrog
    case 0x14:        /* IPGENERICOCPSPL_SYSSTATUS */
1015 827df9f3 balrog
    case 0x18:        /* IPGENERICOCPSPL_IRQSTATUS */
1016 827df9f3 balrog
    case 0x50:        /* IPGENERICOCPSPL_GPI */
1017 827df9f3 balrog
        OMAP_RO_REG(addr);
1018 827df9f3 balrog
        break;
1019 827df9f3 balrog
1020 827df9f3 balrog
    case 0x10:        /* IPGENERICOCPSPL_SYSCONFIG */
1021 827df9f3 balrog
        if (value & (1 << 1))                                        /* SOFTRESET */
1022 827df9f3 balrog
            omap_gpif_reset(s);
1023 827df9f3 balrog
        s->autoidle = value & 1;
1024 827df9f3 balrog
        break;
1025 827df9f3 balrog
1026 827df9f3 balrog
    case 0x40:        /* IPGENERICOCPSPL_GPO */
1027 827df9f3 balrog
        s->gpo = value & 1;
1028 827df9f3 balrog
        break;
1029 827df9f3 balrog
1030 827df9f3 balrog
    default:
1031 827df9f3 balrog
        OMAP_BAD_REG(addr);
1032 827df9f3 balrog
        return;
1033 827df9f3 balrog
    }
1034 827df9f3 balrog
}
1035 827df9f3 balrog
1036 827df9f3 balrog
static CPUReadMemoryFunc *omap_gpif_top_readfn[] = {
1037 827df9f3 balrog
    omap_gpif_top_read,
1038 827df9f3 balrog
    omap_gpif_top_read,
1039 827df9f3 balrog
    omap_gpif_top_read,
1040 827df9f3 balrog
};
1041 827df9f3 balrog
1042 827df9f3 balrog
static CPUWriteMemoryFunc *omap_gpif_top_writefn[] = {
1043 827df9f3 balrog
    omap_gpif_top_write,
1044 827df9f3 balrog
    omap_gpif_top_write,
1045 827df9f3 balrog
    omap_gpif_top_write,
1046 827df9f3 balrog
};
1047 827df9f3 balrog
1048 827df9f3 balrog
struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
1049 827df9f3 balrog
                qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
1050 827df9f3 balrog
{
1051 827df9f3 balrog
    int iomemtype, i;
1052 827df9f3 balrog
    struct omap_gpif_s *s = (struct omap_gpif_s *)
1053 827df9f3 balrog
            qemu_mallocz(sizeof(struct omap_gpif_s));
1054 827df9f3 balrog
    int region[4] = { 0, 2, 4, 5 };
1055 827df9f3 balrog
1056 827df9f3 balrog
    s->modules = modules;
1057 827df9f3 balrog
    for (i = 0; i < modules; i ++)
1058 827df9f3 balrog
        omap_gpio_module_init(s->module + i, ta, region[i],
1059 827df9f3 balrog
                        irq[i], 0, 0, fclk[i], iclk);
1060 827df9f3 balrog
1061 827df9f3 balrog
    omap_gpif_reset(s);
1062 827df9f3 balrog
1063 c66fb5bc balrog
    iomemtype = l4_register_io_memory(0, omap_gpif_top_readfn,
1064 827df9f3 balrog
                    omap_gpif_top_writefn, s);
1065 8da3ff18 pbrook
    omap_l4_attach(ta, 1, iomemtype);
1066 827df9f3 balrog
1067 827df9f3 balrog
    return s;
1068 827df9f3 balrog
}
1069 827df9f3 balrog
1070 827df9f3 balrog
qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
1071 827df9f3 balrog
{
1072 827df9f3 balrog
    if (start >= s->modules * 32 || start < 0)
1073 827df9f3 balrog
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n",
1074 827df9f3 balrog
                        __FUNCTION__, start);
1075 827df9f3 balrog
    return s->module[start >> 5].in + (start & 31);
1076 827df9f3 balrog
}
1077 827df9f3 balrog
1078 827df9f3 balrog
void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
1079 827df9f3 balrog
{
1080 827df9f3 balrog
    if (line >= s->modules * 32 || line < 0)
1081 827df9f3 balrog
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
1082 827df9f3 balrog
    s->module[line >> 5].handler[line & 31] = handler;
1083 827df9f3 balrog
}
1084 827df9f3 balrog
1085 827df9f3 balrog
/* Multichannel SPI */
1086 827df9f3 balrog
struct omap_mcspi_s {
1087 827df9f3 balrog
    qemu_irq irq;
1088 827df9f3 balrog
    int chnum;
1089 827df9f3 balrog
1090 827df9f3 balrog
    uint32_t sysconfig;
1091 827df9f3 balrog
    uint32_t systest;
1092 827df9f3 balrog
    uint32_t irqst;
1093 827df9f3 balrog
    uint32_t irqen;
1094 827df9f3 balrog
    uint32_t wken;
1095 827df9f3 balrog
    uint32_t control;
1096 827df9f3 balrog
1097 827df9f3 balrog
    struct omap_mcspi_ch_s {
1098 827df9f3 balrog
        qemu_irq txdrq;
1099 827df9f3 balrog
        qemu_irq rxdrq;
1100 e927bb00 balrog
        uint32_t (*txrx)(void *opaque, uint32_t, int);
1101 827df9f3 balrog
        void *opaque;
1102 827df9f3 balrog
1103 827df9f3 balrog
        uint32_t tx;
1104 827df9f3 balrog
        uint32_t rx;
1105 827df9f3 balrog
1106 827df9f3 balrog
        uint32_t config;
1107 827df9f3 balrog
        uint32_t status;
1108 827df9f3 balrog
        uint32_t control;
1109 827df9f3 balrog
    } ch[4];
1110 827df9f3 balrog
};
1111 827df9f3 balrog
1112 827df9f3 balrog
static inline void omap_mcspi_interrupt_update(struct omap_mcspi_s *s)
1113 827df9f3 balrog
{
1114 827df9f3 balrog
    qemu_set_irq(s->irq, s->irqst & s->irqen);
1115 827df9f3 balrog
}
1116 827df9f3 balrog
1117 827df9f3 balrog
static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_ch_s *ch)
1118 827df9f3 balrog
{
1119 827df9f3 balrog
    qemu_set_irq(ch->txdrq,
1120 827df9f3 balrog
                    (ch->control & 1) &&                /* EN */
1121 827df9f3 balrog
                    (ch->config & (1 << 14)) &&                /* DMAW */
1122 827df9f3 balrog
                    (ch->status & (1 << 1)) &&                /* TXS */
1123 827df9f3 balrog
                    ((ch->config >> 12) & 3) != 1);        /* TRM */
1124 827df9f3 balrog
    qemu_set_irq(ch->rxdrq,
1125 827df9f3 balrog
                    (ch->control & 1) &&                /* EN */
1126 827df9f3 balrog
                    (ch->config & (1 << 15)) &&                /* DMAW */
1127 827df9f3 balrog
                    (ch->status & (1 << 0)) &&                /* RXS */
1128 827df9f3 balrog
                    ((ch->config >> 12) & 3) != 2);        /* TRM */
1129 827df9f3 balrog
}
1130 827df9f3 balrog
1131 827df9f3 balrog
static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
1132 827df9f3 balrog
{
1133 827df9f3 balrog
    struct omap_mcspi_ch_s *ch = s->ch + chnum;
1134 827df9f3 balrog
1135 827df9f3 balrog
    if (!(ch->control & 1))                                /* EN */
1136 827df9f3 balrog
        return;
1137 827df9f3 balrog
    if ((ch->status & (1 << 0)) &&                        /* RXS */
1138 827df9f3 balrog
                    ((ch->config >> 12) & 3) != 2 &&        /* TRM */
1139 827df9f3 balrog
                    !(ch->config & (1 << 19)))                /* TURBO */
1140 827df9f3 balrog
        goto intr_update;
1141 827df9f3 balrog
    if ((ch->status & (1 << 1)) &&                        /* TXS */
1142 827df9f3 balrog
                    ((ch->config >> 12) & 3) != 1)        /* TRM */
1143 827df9f3 balrog
        goto intr_update;
1144 827df9f3 balrog
1145 827df9f3 balrog
    if (!(s->control & 1) ||                                /* SINGLE */
1146 827df9f3 balrog
                    (ch->config & (1 << 20))) {                /* FORCE */
1147 827df9f3 balrog
        if (ch->txrx)
1148 e927bb00 balrog
            ch->rx = ch->txrx(ch->opaque, ch->tx,        /* WL */
1149 e927bb00 balrog
                            1 + (0x1f & (ch->config >> 7)));
1150 827df9f3 balrog
    }
1151 827df9f3 balrog
1152 827df9f3 balrog
    ch->tx = 0;
1153 827df9f3 balrog
    ch->status |= 1 << 2;                                /* EOT */
1154 827df9f3 balrog
    ch->status |= 1 << 1;                                /* TXS */
1155 827df9f3 balrog
    if (((ch->config >> 12) & 3) != 2)                        /* TRM */
1156 827df9f3 balrog
        ch->status |= 1 << 0;                                /* RXS */
1157 827df9f3 balrog
1158 827df9f3 balrog
intr_update:
1159 827df9f3 balrog
    if ((ch->status & (1 << 0)) &&                        /* RXS */
1160 827df9f3 balrog
                    ((ch->config >> 12) & 3) != 2 &&        /* TRM */
1161 827df9f3 balrog
                    !(ch->config & (1 << 19)))                /* TURBO */
1162 827df9f3 balrog
        s->irqst |= 1 << (2 + 4 * chnum);                /* RX_FULL */
1163 827df9f3 balrog
    if ((ch->status & (1 << 1)) &&                        /* TXS */
1164 827df9f3 balrog
                    ((ch->config >> 12) & 3) != 1)        /* TRM */
1165 827df9f3 balrog
        s->irqst |= 1 << (0 + 4 * chnum);                /* TX_EMPTY */
1166 827df9f3 balrog
    omap_mcspi_interrupt_update(s);
1167 827df9f3 balrog
    omap_mcspi_dmarequest_update(ch);
1168 827df9f3 balrog
}
1169 827df9f3 balrog
1170 827df9f3 balrog
static void omap_mcspi_reset(struct omap_mcspi_s *s)
1171 827df9f3 balrog
{
1172 827df9f3 balrog
    int ch;
1173 827df9f3 balrog
1174 827df9f3 balrog
    s->sysconfig = 0;
1175 827df9f3 balrog
    s->systest = 0;
1176 827df9f3 balrog
    s->irqst = 0;
1177 827df9f3 balrog
    s->irqen = 0;
1178 827df9f3 balrog
    s->wken = 0;
1179 827df9f3 balrog
    s->control = 4;
1180 827df9f3 balrog
1181 827df9f3 balrog
    for (ch = 0; ch < 4; ch ++) {
1182 827df9f3 balrog
        s->ch[ch].config = 0x060000;
1183 827df9f3 balrog
        s->ch[ch].status = 2;                                /* TXS */
1184 827df9f3 balrog
        s->ch[ch].control = 0;
1185 827df9f3 balrog
1186 827df9f3 balrog
        omap_mcspi_dmarequest_update(s->ch + ch);
1187 827df9f3 balrog
    }
1188 827df9f3 balrog
1189 827df9f3 balrog
    omap_mcspi_interrupt_update(s);
1190 827df9f3 balrog
}
1191 827df9f3 balrog
1192 827df9f3 balrog
static uint32_t omap_mcspi_read(void *opaque, target_phys_addr_t addr)
1193 827df9f3 balrog
{
1194 827df9f3 balrog
    struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1195 827df9f3 balrog
    int ch = 0;
1196 827df9f3 balrog
    uint32_t ret;
1197 827df9f3 balrog
1198 8da3ff18 pbrook
    switch (addr) {
1199 827df9f3 balrog
    case 0x00:        /* MCSPI_REVISION */
1200 827df9f3 balrog
        return 0x91;
1201 827df9f3 balrog
1202 827df9f3 balrog
    case 0x10:        /* MCSPI_SYSCONFIG */
1203 827df9f3 balrog
        return s->sysconfig;
1204 827df9f3 balrog
1205 827df9f3 balrog
    case 0x14:        /* MCSPI_SYSSTATUS */
1206 827df9f3 balrog
        return 1;                                        /* RESETDONE */
1207 827df9f3 balrog
1208 827df9f3 balrog
    case 0x18:        /* MCSPI_IRQSTATUS */
1209 827df9f3 balrog
        return s->irqst;
1210 827df9f3 balrog
1211 827df9f3 balrog
    case 0x1c:        /* MCSPI_IRQENABLE */
1212 827df9f3 balrog
        return s->irqen;
1213 827df9f3 balrog
1214 827df9f3 balrog
    case 0x20:        /* MCSPI_WAKEUPENABLE */
1215 827df9f3 balrog
        return s->wken;
1216 827df9f3 balrog
1217 827df9f3 balrog
    case 0x24:        /* MCSPI_SYST */
1218 827df9f3 balrog
        return s->systest;
1219 827df9f3 balrog
1220 827df9f3 balrog
    case 0x28:        /* MCSPI_MODULCTRL */
1221 827df9f3 balrog
        return s->control;
1222 827df9f3 balrog
1223 827df9f3 balrog
    case 0x68: ch ++;
1224 827df9f3 balrog
    case 0x54: ch ++;
1225 827df9f3 balrog
    case 0x40: ch ++;
1226 827df9f3 balrog
    case 0x2c:        /* MCSPI_CHCONF */
1227 827df9f3 balrog
        return s->ch[ch].config;
1228 827df9f3 balrog
1229 827df9f3 balrog
    case 0x6c: ch ++;
1230 827df9f3 balrog
    case 0x58: ch ++;
1231 827df9f3 balrog
    case 0x44: ch ++;
1232 827df9f3 balrog
    case 0x30:        /* MCSPI_CHSTAT */
1233 827df9f3 balrog
        return s->ch[ch].status;
1234 827df9f3 balrog
1235 827df9f3 balrog
    case 0x70: ch ++;
1236 827df9f3 balrog
    case 0x5c: ch ++;
1237 827df9f3 balrog
    case 0x48: ch ++;
1238 827df9f3 balrog
    case 0x34:        /* MCSPI_CHCTRL */
1239 827df9f3 balrog
        return s->ch[ch].control;
1240 827df9f3 balrog
1241 827df9f3 balrog
    case 0x74: ch ++;
1242 827df9f3 balrog
    case 0x60: ch ++;
1243 827df9f3 balrog
    case 0x4c: ch ++;
1244 827df9f3 balrog
    case 0x38:        /* MCSPI_TX */
1245 827df9f3 balrog
        return s->ch[ch].tx;
1246 827df9f3 balrog
1247 827df9f3 balrog
    case 0x78: ch ++;
1248 827df9f3 balrog
    case 0x64: ch ++;
1249 827df9f3 balrog
    case 0x50: ch ++;
1250 827df9f3 balrog
    case 0x3c:        /* MCSPI_RX */
1251 827df9f3 balrog
        s->ch[ch].status &= ~(1 << 0);                        /* RXS */
1252 827df9f3 balrog
        ret = s->ch[ch].rx;
1253 827df9f3 balrog
        omap_mcspi_transfer_run(s, ch);
1254 827df9f3 balrog
        return ret;
1255 827df9f3 balrog
    }
1256 827df9f3 balrog
1257 827df9f3 balrog
    OMAP_BAD_REG(addr);
1258 827df9f3 balrog
    return 0;
1259 827df9f3 balrog
}
1260 827df9f3 balrog
1261 827df9f3 balrog
static void omap_mcspi_write(void *opaque, target_phys_addr_t addr,
1262 827df9f3 balrog
                uint32_t value)
1263 827df9f3 balrog
{
1264 827df9f3 balrog
    struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1265 827df9f3 balrog
    int ch = 0;
1266 827df9f3 balrog
1267 8da3ff18 pbrook
    switch (addr) {
1268 827df9f3 balrog
    case 0x00:        /* MCSPI_REVISION */
1269 827df9f3 balrog
    case 0x14:        /* MCSPI_SYSSTATUS */
1270 827df9f3 balrog
    case 0x30:        /* MCSPI_CHSTAT0 */
1271 827df9f3 balrog
    case 0x3c:        /* MCSPI_RX0 */
1272 827df9f3 balrog
    case 0x44:        /* MCSPI_CHSTAT1 */
1273 827df9f3 balrog
    case 0x50:        /* MCSPI_RX1 */
1274 827df9f3 balrog
    case 0x58:        /* MCSPI_CHSTAT2 */
1275 827df9f3 balrog
    case 0x64:        /* MCSPI_RX2 */
1276 827df9f3 balrog
    case 0x6c:        /* MCSPI_CHSTAT3 */
1277 827df9f3 balrog
    case 0x78:        /* MCSPI_RX3 */
1278 827df9f3 balrog
        OMAP_RO_REG(addr);
1279 827df9f3 balrog
        return;
1280 827df9f3 balrog
1281 827df9f3 balrog
    case 0x10:        /* MCSPI_SYSCONFIG */
1282 827df9f3 balrog
        if (value & (1 << 1))                                /* SOFTRESET */
1283 827df9f3 balrog
            omap_mcspi_reset(s);
1284 827df9f3 balrog
        s->sysconfig = value & 0x31d;
1285 827df9f3 balrog
        break;
1286 827df9f3 balrog
1287 827df9f3 balrog
    case 0x18:        /* MCSPI_IRQSTATUS */
1288 827df9f3 balrog
        if (!((s->control & (1 << 3)) && (s->systest & (1 << 11)))) {
1289 827df9f3 balrog
            s->irqst &= ~value;
1290 827df9f3 balrog
            omap_mcspi_interrupt_update(s);
1291 827df9f3 balrog
        }
1292 827df9f3 balrog
        break;
1293 827df9f3 balrog
1294 827df9f3 balrog
    case 0x1c:        /* MCSPI_IRQENABLE */
1295 827df9f3 balrog
        s->irqen = value & 0x1777f;
1296 827df9f3 balrog
        omap_mcspi_interrupt_update(s);
1297 827df9f3 balrog
        break;
1298 827df9f3 balrog
1299 827df9f3 balrog
    case 0x20:        /* MCSPI_WAKEUPENABLE */
1300 827df9f3 balrog
        s->wken = value & 1;
1301 827df9f3 balrog
        break;
1302 827df9f3 balrog
1303 827df9f3 balrog
    case 0x24:        /* MCSPI_SYST */
1304 827df9f3 balrog
        if (s->control & (1 << 3))                        /* SYSTEM_TEST */
1305 827df9f3 balrog
            if (value & (1 << 11)) {                        /* SSB */
1306 827df9f3 balrog
                s->irqst |= 0x1777f;
1307 827df9f3 balrog
                omap_mcspi_interrupt_update(s);
1308 827df9f3 balrog
            }
1309 827df9f3 balrog
        s->systest = value & 0xfff;
1310 827df9f3 balrog
        break;
1311 827df9f3 balrog
1312 827df9f3 balrog
    case 0x28:        /* MCSPI_MODULCTRL */
1313 827df9f3 balrog
        if (value & (1 << 3))                                /* SYSTEM_TEST */
1314 827df9f3 balrog
            if (s->systest & (1 << 11)) {                /* SSB */
1315 827df9f3 balrog
                s->irqst |= 0x1777f;
1316 827df9f3 balrog
                omap_mcspi_interrupt_update(s);
1317 827df9f3 balrog
            }
1318 827df9f3 balrog
        s->control = value & 0xf;
1319 827df9f3 balrog
        break;
1320 827df9f3 balrog
1321 827df9f3 balrog
    case 0x68: ch ++;
1322 827df9f3 balrog
    case 0x54: ch ++;
1323 827df9f3 balrog
    case 0x40: ch ++;
1324 827df9f3 balrog
    case 0x2c:        /* MCSPI_CHCONF */
1325 827df9f3 balrog
        if ((value ^ s->ch[ch].config) & (3 << 14))        /* DMAR | DMAW */
1326 827df9f3 balrog
            omap_mcspi_dmarequest_update(s->ch + ch);
1327 827df9f3 balrog
        if (((value >> 12) & 3) == 3)                        /* TRM */
1328 827df9f3 balrog
            fprintf(stderr, "%s: invalid TRM value (3)\n", __FUNCTION__);
1329 827df9f3 balrog
        if (((value >> 7) & 0x1f) < 3)                        /* WL */
1330 827df9f3 balrog
            fprintf(stderr, "%s: invalid WL value (%i)\n",
1331 827df9f3 balrog
                            __FUNCTION__, (value >> 7) & 0x1f);
1332 827df9f3 balrog
        s->ch[ch].config = value & 0x7fffff;
1333 827df9f3 balrog
        break;
1334 827df9f3 balrog
1335 827df9f3 balrog
    case 0x70: ch ++;
1336 827df9f3 balrog
    case 0x5c: ch ++;
1337 827df9f3 balrog
    case 0x48: ch ++;
1338 827df9f3 balrog
    case 0x34:        /* MCSPI_CHCTRL */
1339 827df9f3 balrog
        if (value & ~s->ch[ch].control & 1) {                /* EN */
1340 827df9f3 balrog
            s->ch[ch].control |= 1;
1341 827df9f3 balrog
            omap_mcspi_transfer_run(s, ch);
1342 827df9f3 balrog
        } else
1343 827df9f3 balrog
            s->ch[ch].control = value & 1;
1344 827df9f3 balrog
        break;
1345 827df9f3 balrog
1346 827df9f3 balrog
    case 0x74: ch ++;
1347 827df9f3 balrog
    case 0x60: ch ++;
1348 827df9f3 balrog
    case 0x4c: ch ++;
1349 827df9f3 balrog
    case 0x38:        /* MCSPI_TX */
1350 827df9f3 balrog
        s->ch[ch].tx = value;
1351 827df9f3 balrog
        s->ch[ch].status &= ~(1 << 1);                        /* TXS */
1352 827df9f3 balrog
        omap_mcspi_transfer_run(s, ch);
1353 827df9f3 balrog
        break;
1354 827df9f3 balrog
1355 827df9f3 balrog
    default:
1356 827df9f3 balrog
        OMAP_BAD_REG(addr);
1357 827df9f3 balrog
        return;
1358 827df9f3 balrog
    }
1359 827df9f3 balrog
}
1360 827df9f3 balrog
1361 827df9f3 balrog
static CPUReadMemoryFunc *omap_mcspi_readfn[] = {
1362 827df9f3 balrog
    omap_badwidth_read32,
1363 827df9f3 balrog
    omap_badwidth_read32,
1364 827df9f3 balrog
    omap_mcspi_read,
1365 827df9f3 balrog
};
1366 827df9f3 balrog
1367 827df9f3 balrog
static CPUWriteMemoryFunc *omap_mcspi_writefn[] = {
1368 827df9f3 balrog
    omap_badwidth_write32,
1369 827df9f3 balrog
    omap_badwidth_write32,
1370 827df9f3 balrog
    omap_mcspi_write,
1371 827df9f3 balrog
};
1372 827df9f3 balrog
1373 827df9f3 balrog
struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
1374 827df9f3 balrog
                qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
1375 827df9f3 balrog
{
1376 827df9f3 balrog
    int iomemtype;
1377 827df9f3 balrog
    struct omap_mcspi_s *s = (struct omap_mcspi_s *)
1378 827df9f3 balrog
            qemu_mallocz(sizeof(struct omap_mcspi_s));
1379 827df9f3 balrog
    struct omap_mcspi_ch_s *ch = s->ch;
1380 827df9f3 balrog
1381 827df9f3 balrog
    s->irq = irq;
1382 827df9f3 balrog
    s->chnum = chnum;
1383 827df9f3 balrog
    while (chnum --) {
1384 827df9f3 balrog
        ch->txdrq = *drq ++;
1385 827df9f3 balrog
        ch->rxdrq = *drq ++;
1386 827df9f3 balrog
        ch ++;
1387 827df9f3 balrog
    }
1388 827df9f3 balrog
    omap_mcspi_reset(s);
1389 827df9f3 balrog
1390 c66fb5bc balrog
    iomemtype = l4_register_io_memory(0, omap_mcspi_readfn,
1391 827df9f3 balrog
                    omap_mcspi_writefn, s);
1392 8da3ff18 pbrook
    omap_l4_attach(ta, 0, iomemtype);
1393 827df9f3 balrog
1394 827df9f3 balrog
    return s;
1395 827df9f3 balrog
}
1396 827df9f3 balrog
1397 827df9f3 balrog
void omap_mcspi_attach(struct omap_mcspi_s *s,
1398 e927bb00 balrog
                uint32_t (*txrx)(void *opaque, uint32_t, int), void *opaque,
1399 827df9f3 balrog
                int chipselect)
1400 827df9f3 balrog
{
1401 827df9f3 balrog
    if (chipselect < 0 || chipselect >= s->chnum)
1402 827df9f3 balrog
        cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n",
1403 827df9f3 balrog
                        __FUNCTION__, chipselect);
1404 827df9f3 balrog
1405 827df9f3 balrog
    s->ch[chipselect].txrx = txrx;
1406 827df9f3 balrog
    s->ch[chipselect].opaque = opaque;
1407 827df9f3 balrog
}
1408 827df9f3 balrog
1409 99570a40 balrog
/* Enhanced Audio Controller (CODEC only) */
1410 99570a40 balrog
struct omap_eac_s {
1411 99570a40 balrog
    qemu_irq irq;
1412 99570a40 balrog
1413 99570a40 balrog
    uint16_t sysconfig;
1414 99570a40 balrog
    uint8_t config[4];
1415 99570a40 balrog
    uint8_t control;
1416 99570a40 balrog
    uint8_t address;
1417 99570a40 balrog
    uint16_t data;
1418 99570a40 balrog
    uint8_t vtol;
1419 99570a40 balrog
    uint8_t vtsl;
1420 99570a40 balrog
    uint16_t mixer;
1421 99570a40 balrog
    uint16_t gain[4];
1422 99570a40 balrog
    uint8_t att;
1423 99570a40 balrog
    uint16_t max[7];
1424 99570a40 balrog
1425 99570a40 balrog
    struct {
1426 99570a40 balrog
        qemu_irq txdrq;
1427 99570a40 balrog
        qemu_irq rxdrq;
1428 99570a40 balrog
        uint32_t (*txrx)(void *opaque, uint32_t, int);
1429 99570a40 balrog
        void *opaque;
1430 99570a40 balrog
1431 99570a40 balrog
#define EAC_BUF_LEN 1024
1432 99570a40 balrog
        uint32_t rxbuf[EAC_BUF_LEN];
1433 ab17b46d balrog
        int rxoff;
1434 99570a40 balrog
        int rxlen;
1435 99570a40 balrog
        int rxavail;
1436 99570a40 balrog
        uint32_t txbuf[EAC_BUF_LEN];
1437 99570a40 balrog
        int txlen;
1438 99570a40 balrog
        int txavail;
1439 99570a40 balrog
1440 99570a40 balrog
        int enable;
1441 99570a40 balrog
        int rate;
1442 99570a40 balrog
1443 99570a40 balrog
        uint16_t config[4];
1444 99570a40 balrog
1445 99570a40 balrog
        /* These need to be moved to the actual codec */
1446 99570a40 balrog
        QEMUSoundCard card;
1447 99570a40 balrog
        SWVoiceIn *in_voice;
1448 99570a40 balrog
        SWVoiceOut *out_voice;
1449 99570a40 balrog
        int hw_enable;
1450 99570a40 balrog
    } codec;
1451 99570a40 balrog
1452 99570a40 balrog
    struct {
1453 99570a40 balrog
        uint8_t control;
1454 99570a40 balrog
        uint16_t config;
1455 99570a40 balrog
    } modem, bt;
1456 99570a40 balrog
};
1457 99570a40 balrog
1458 99570a40 balrog
static inline void omap_eac_interrupt_update(struct omap_eac_s *s)
1459 99570a40 balrog
{
1460 99570a40 balrog
    qemu_set_irq(s->irq, (s->codec.config[1] >> 14) & 1);        /* AURDI */
1461 99570a40 balrog
}
1462 99570a40 balrog
1463 99570a40 balrog
static inline void omap_eac_in_dmarequest_update(struct omap_eac_s *s)
1464 99570a40 balrog
{
1465 ab17b46d balrog
    qemu_set_irq(s->codec.rxdrq, (s->codec.rxavail || s->codec.rxlen) &&
1466 99570a40 balrog
                    ((s->codec.config[1] >> 12) & 1));                /* DMAREN */
1467 99570a40 balrog
}
1468 99570a40 balrog
1469 99570a40 balrog
static inline void omap_eac_out_dmarequest_update(struct omap_eac_s *s)
1470 99570a40 balrog
{
1471 99570a40 balrog
    qemu_set_irq(s->codec.txdrq, s->codec.txlen < s->codec.txavail &&
1472 99570a40 balrog
                    ((s->codec.config[1] >> 11) & 1));                /* DMAWEN */
1473 99570a40 balrog
}
1474 99570a40 balrog
1475 99570a40 balrog
static inline void omap_eac_in_refill(struct omap_eac_s *s)
1476 99570a40 balrog
{
1477 ab17b46d balrog
    int left = MIN(EAC_BUF_LEN - s->codec.rxlen, s->codec.rxavail) << 2;
1478 ab17b46d balrog
    int start = ((s->codec.rxoff + s->codec.rxlen) & (EAC_BUF_LEN - 1)) << 2;
1479 ab17b46d balrog
    int leftwrap = MIN(left, (EAC_BUF_LEN << 2) - start);
1480 ab17b46d balrog
    int recv = 1;
1481 ab17b46d balrog
    uint8_t *buf = (uint8_t *) s->codec.rxbuf + start;
1482 ab17b46d balrog
1483 ab17b46d balrog
    left -= leftwrap;
1484 ab17b46d balrog
    start = 0;
1485 ab17b46d balrog
    while (leftwrap && (recv = AUD_read(s->codec.in_voice, buf + start,
1486 ab17b46d balrog
                                    leftwrap)) > 0) {        /* Be defensive */
1487 ab17b46d balrog
        start += recv;
1488 ab17b46d balrog
        leftwrap -= recv;
1489 ab17b46d balrog
    }
1490 ab17b46d balrog
    if (recv <= 0)
1491 ab17b46d balrog
        s->codec.rxavail = 0;
1492 ab17b46d balrog
    else
1493 ab17b46d balrog
        s->codec.rxavail -= start >> 2;
1494 ab17b46d balrog
    s->codec.rxlen += start >> 2;
1495 ab17b46d balrog
1496 ab17b46d balrog
    if (recv > 0 && left > 0) {
1497 ab17b46d balrog
        start = 0;
1498 ab17b46d balrog
        while (left && (recv = AUD_read(s->codec.in_voice,
1499 ab17b46d balrog
                                        (uint8_t *) s->codec.rxbuf + start,
1500 ab17b46d balrog
                                        left)) > 0) {        /* Be defensive */
1501 ab17b46d balrog
            start += recv;
1502 ab17b46d balrog
            left -= recv;
1503 ab17b46d balrog
        }
1504 ab17b46d balrog
        if (recv <= 0)
1505 ab17b46d balrog
            s->codec.rxavail = 0;
1506 ab17b46d balrog
        else
1507 ab17b46d balrog
            s->codec.rxavail -= start >> 2;
1508 ab17b46d balrog
        s->codec.rxlen += start >> 2;
1509 ab17b46d balrog
    }
1510 99570a40 balrog
}
1511 99570a40 balrog
1512 99570a40 balrog
static inline void omap_eac_out_empty(struct omap_eac_s *s)
1513 99570a40 balrog
{
1514 ab17b46d balrog
    int left = s->codec.txlen << 2;
1515 ab17b46d balrog
    int start = 0;
1516 ab17b46d balrog
    int sent = 1;
1517 ab17b46d balrog
1518 ab17b46d balrog
    while (left && (sent = AUD_write(s->codec.out_voice,
1519 ab17b46d balrog
                                    (uint8_t *) s->codec.txbuf + start,
1520 ab17b46d balrog
                                    left)) > 0) {        /* Be defensive */
1521 ab17b46d balrog
        start += sent;
1522 ab17b46d balrog
        left -= sent;
1523 ab17b46d balrog
    }
1524 99570a40 balrog
1525 ab17b46d balrog
    if (!sent) {
1526 ab17b46d balrog
        s->codec.txavail = 0;
1527 ab17b46d balrog
        omap_eac_out_dmarequest_update(s);
1528 ab17b46d balrog
    }
1529 99570a40 balrog
1530 ab17b46d balrog
    if (start)
1531 ab17b46d balrog
        s->codec.txlen = 0;
1532 99570a40 balrog
}
1533 99570a40 balrog
1534 99570a40 balrog
static void omap_eac_in_cb(void *opaque, int avail_b)
1535 99570a40 balrog
{
1536 99570a40 balrog
    struct omap_eac_s *s = (struct omap_eac_s *) opaque;
1537 99570a40 balrog
1538 99570a40 balrog
    s->codec.rxavail = avail_b >> 2;
1539 ab17b46d balrog
    omap_eac_in_refill(s);
1540 99570a40 balrog
    /* TODO: possibly discard current buffer if overrun */
1541 ab17b46d balrog
    omap_eac_in_dmarequest_update(s);
1542 99570a40 balrog
}
1543 99570a40 balrog
1544 99570a40 balrog
static void omap_eac_out_cb(void *opaque, int free_b)
1545 99570a40 balrog
{
1546 99570a40 balrog
    struct omap_eac_s *s = (struct omap_eac_s *) opaque;
1547 99570a40 balrog
1548 99570a40 balrog
    s->codec.txavail = free_b >> 2;
1549 ab17b46d balrog
    if (s->codec.txlen)
1550 ab17b46d balrog
        omap_eac_out_empty(s);
1551 ab17b46d balrog
    else
1552 ab17b46d balrog
        omap_eac_out_dmarequest_update(s);
1553 99570a40 balrog
}
1554 99570a40 balrog
1555 99570a40 balrog
static void omap_eac_enable_update(struct omap_eac_s *s)
1556 99570a40 balrog
{
1557 99570a40 balrog
    s->codec.enable = !(s->codec.config[1] & 1) &&                /* EACPWD */
1558 99570a40 balrog
            (s->codec.config[1] & 2) &&                                /* AUDEN */
1559 99570a40 balrog
            s->codec.hw_enable;
1560 99570a40 balrog
}
1561 99570a40 balrog
1562 99570a40 balrog
static const int omap_eac_fsint[4] = {
1563 99570a40 balrog
    8000,
1564 99570a40 balrog
    11025,
1565 99570a40 balrog
    22050,
1566 99570a40 balrog
    44100,
1567 99570a40 balrog
};
1568 99570a40 balrog
1569 99570a40 balrog
static const int omap_eac_fsint2[8] = {
1570 99570a40 balrog
    8000,
1571 99570a40 balrog
    11025,
1572 99570a40 balrog
    22050,
1573 99570a40 balrog
    44100,
1574 99570a40 balrog
    48000,
1575 99570a40 balrog
    0, 0, 0,
1576 99570a40 balrog
};
1577 99570a40 balrog
1578 99570a40 balrog
static const int omap_eac_fsint3[16] = {
1579 99570a40 balrog
    8000,
1580 99570a40 balrog
    11025,
1581 99570a40 balrog
    16000,
1582 99570a40 balrog
    22050,
1583 99570a40 balrog
    24000,
1584 99570a40 balrog
    32000,
1585 99570a40 balrog
    44100,
1586 99570a40 balrog
    48000,
1587 99570a40 balrog
    0, 0, 0, 0, 0, 0, 0, 0,
1588 99570a40 balrog
};
1589 99570a40 balrog
1590 99570a40 balrog
static void omap_eac_rate_update(struct omap_eac_s *s)
1591 99570a40 balrog
{
1592 99570a40 balrog
    int fsint[3];
1593 99570a40 balrog
1594 99570a40 balrog
    fsint[2] = (s->codec.config[3] >> 9) & 0xf;
1595 99570a40 balrog
    fsint[1] = (s->codec.config[2] >> 0) & 0x7;
1596 99570a40 balrog
    fsint[0] = (s->codec.config[0] >> 6) & 0x3;
1597 99570a40 balrog
    if (fsint[2] < 0xf)
1598 99570a40 balrog
        s->codec.rate = omap_eac_fsint3[fsint[2]];
1599 99570a40 balrog
    else if (fsint[1] < 0x7)
1600 99570a40 balrog
        s->codec.rate = omap_eac_fsint2[fsint[1]];
1601 99570a40 balrog
    else
1602 99570a40 balrog
        s->codec.rate = omap_eac_fsint[fsint[0]];
1603 99570a40 balrog
}
1604 99570a40 balrog
1605 99570a40 balrog
static void omap_eac_volume_update(struct omap_eac_s *s)
1606 99570a40 balrog
{
1607 99570a40 balrog
    /* TODO */
1608 99570a40 balrog
}
1609 99570a40 balrog
1610 99570a40 balrog
static void omap_eac_format_update(struct omap_eac_s *s)
1611 99570a40 balrog
{
1612 1ea879e5 malc
    struct audsettings fmt;
1613 99570a40 balrog
1614 ab17b46d balrog
    /* The hardware buffers at most one sample */
1615 ab17b46d balrog
    if (s->codec.rxlen)
1616 ab17b46d balrog
        s->codec.rxlen = 1;
1617 99570a40 balrog
1618 99570a40 balrog
    if (s->codec.in_voice) {
1619 99570a40 balrog
        AUD_set_active_in(s->codec.in_voice, 0);
1620 99570a40 balrog
        AUD_close_in(&s->codec.card, s->codec.in_voice);
1621 99570a40 balrog
        s->codec.in_voice = 0;
1622 99570a40 balrog
    }
1623 99570a40 balrog
    if (s->codec.out_voice) {
1624 ab17b46d balrog
        omap_eac_out_empty(s);
1625 99570a40 balrog
        AUD_set_active_out(s->codec.out_voice, 0);
1626 99570a40 balrog
        AUD_close_out(&s->codec.card, s->codec.out_voice);
1627 99570a40 balrog
        s->codec.out_voice = 0;
1628 ab17b46d balrog
        s->codec.txavail = 0;
1629 99570a40 balrog
    }
1630 ab17b46d balrog
    /* Discard what couldn't be written */
1631 ab17b46d balrog
    s->codec.txlen = 0;
1632 99570a40 balrog
1633 99570a40 balrog
    omap_eac_enable_update(s);
1634 99570a40 balrog
    if (!s->codec.enable)
1635 99570a40 balrog
        return;
1636 99570a40 balrog
1637 99570a40 balrog
    omap_eac_rate_update(s);
1638 99570a40 balrog
    fmt.endianness = ((s->codec.config[0] >> 8) & 1);                /* LI_BI */
1639 99570a40 balrog
    fmt.nchannels = ((s->codec.config[0] >> 10) & 1) ? 2 : 1;        /* MN_ST */
1640 99570a40 balrog
    fmt.freq = s->codec.rate;
1641 99570a40 balrog
    /* TODO: signedness possibly depends on the CODEC hardware - or
1642 99570a40 balrog
     * does I2S specify it?  */
1643 99570a40 balrog
    /* All register writes are 16 bits so we we store 16-bit samples
1644 99570a40 balrog
     * in the buffers regardless of AGCFR[B8_16] value.  */
1645 99570a40 balrog
    fmt.fmt = AUD_FMT_U16;
1646 99570a40 balrog
1647 99570a40 balrog
    s->codec.in_voice = AUD_open_in(&s->codec.card, s->codec.in_voice,
1648 99570a40 balrog
                    "eac.codec.in", s, omap_eac_in_cb, &fmt);
1649 99570a40 balrog
    s->codec.out_voice = AUD_open_out(&s->codec.card, s->codec.out_voice,
1650 99570a40 balrog
                    "eac.codec.out", s, omap_eac_out_cb, &fmt);
1651 99570a40 balrog
1652 99570a40 balrog
    omap_eac_volume_update(s);
1653 99570a40 balrog
1654 99570a40 balrog
    AUD_set_active_in(s->codec.in_voice, 1);
1655 99570a40 balrog
    AUD_set_active_out(s->codec.out_voice, 1);
1656 99570a40 balrog
}
1657 99570a40 balrog
1658 99570a40 balrog
static void omap_eac_reset(struct omap_eac_s *s)
1659 99570a40 balrog
{
1660 99570a40 balrog
    s->sysconfig = 0;
1661 99570a40 balrog
    s->config[0] = 0x0c;
1662 99570a40 balrog
    s->config[1] = 0x09;
1663 99570a40 balrog
    s->config[2] = 0xab;
1664 99570a40 balrog
    s->config[3] = 0x03;
1665 99570a40 balrog
    s->control = 0x00;
1666 99570a40 balrog
    s->address = 0x00;
1667 99570a40 balrog
    s->data = 0x0000;
1668 99570a40 balrog
    s->vtol = 0x00;
1669 99570a40 balrog
    s->vtsl = 0x00;
1670 99570a40 balrog
    s->mixer = 0x0000;
1671 99570a40 balrog
    s->gain[0] = 0xe7e7;
1672 99570a40 balrog
    s->gain[1] = 0x6767;
1673 99570a40 balrog
    s->gain[2] = 0x6767;
1674 99570a40 balrog
    s->gain[3] = 0x6767;
1675 99570a40 balrog
    s->att = 0xce;
1676 99570a40 balrog
    s->max[0] = 0;
1677 99570a40 balrog
    s->max[1] = 0;
1678 99570a40 balrog
    s->max[2] = 0;
1679 99570a40 balrog
    s->max[3] = 0;
1680 99570a40 balrog
    s->max[4] = 0;
1681 99570a40 balrog
    s->max[5] = 0;
1682 99570a40 balrog
    s->max[6] = 0;
1683 99570a40 balrog
1684 99570a40 balrog
    s->modem.control = 0x00;
1685 99570a40 balrog
    s->modem.config = 0x0000;
1686 99570a40 balrog
    s->bt.control = 0x00;
1687 99570a40 balrog
    s->bt.config = 0x0000;
1688 99570a40 balrog
    s->codec.config[0] = 0x0649;
1689 99570a40 balrog
    s->codec.config[1] = 0x0000;
1690 99570a40 balrog
    s->codec.config[2] = 0x0007;
1691 99570a40 balrog
    s->codec.config[3] = 0x1ffc;
1692 ab17b46d balrog
    s->codec.rxoff = 0;
1693 99570a40 balrog
    s->codec.rxlen = 0;
1694 99570a40 balrog
    s->codec.txlen = 0;
1695 99570a40 balrog
    s->codec.rxavail = 0;
1696 99570a40 balrog
    s->codec.txavail = 0;
1697 99570a40 balrog
1698 99570a40 balrog
    omap_eac_format_update(s);
1699 99570a40 balrog
    omap_eac_interrupt_update(s);
1700 99570a40 balrog
}
1701 99570a40 balrog
1702 99570a40 balrog
static uint32_t omap_eac_read(void *opaque, target_phys_addr_t addr)
1703 99570a40 balrog
{
1704 99570a40 balrog
    struct omap_eac_s *s = (struct omap_eac_s *) opaque;
1705 ab17b46d balrog
    uint32_t ret;
1706 99570a40 balrog
1707 8da3ff18 pbrook
    switch (addr) {
1708 99570a40 balrog
    case 0x000:        /* CPCFR1 */
1709 99570a40 balrog
        return s->config[0];
1710 99570a40 balrog
    case 0x004:        /* CPCFR2 */
1711 99570a40 balrog
        return s->config[1];
1712 99570a40 balrog
    case 0x008:        /* CPCFR3 */
1713 99570a40 balrog
        return s->config[2];
1714 99570a40 balrog
    case 0x00c:        /* CPCFR4 */
1715 99570a40 balrog
        return s->config[3];
1716 99570a40 balrog
1717 99570a40 balrog
    case 0x010:        /* CPTCTL */
1718 99570a40 balrog
        return s->control | ((s->codec.rxavail + s->codec.rxlen > 0) << 7) |
1719 99570a40 balrog
                ((s->codec.txlen < s->codec.txavail) << 5);
1720 99570a40 balrog
1721 99570a40 balrog
    case 0x014:        /* CPTTADR */
1722 99570a40 balrog
        return s->address;
1723 99570a40 balrog
    case 0x018:        /* CPTDATL */
1724 99570a40 balrog
        return s->data & 0xff;
1725 99570a40 balrog
    case 0x01c:        /* CPTDATH */
1726 99570a40 balrog
        return s->data >> 8;
1727 99570a40 balrog
    case 0x020:        /* CPTVSLL */
1728 99570a40 balrog
        return s->vtol;
1729 99570a40 balrog
    case 0x024:        /* CPTVSLH */
1730 99570a40 balrog
        return s->vtsl | (3 << 5);        /* CRDY1 | CRDY2 */
1731 99570a40 balrog
    case 0x040:        /* MPCTR */
1732 99570a40 balrog
        return s->modem.control;
1733 99570a40 balrog
    case 0x044:        /* MPMCCFR */
1734 99570a40 balrog
        return s->modem.config;
1735 99570a40 balrog
    case 0x060:        /* BPCTR */
1736 99570a40 balrog
        return s->bt.control;
1737 99570a40 balrog
    case 0x064:        /* BPMCCFR */
1738 99570a40 balrog
        return s->bt.config;
1739 99570a40 balrog
    case 0x080:        /* AMSCFR */
1740 99570a40 balrog
        return s->mixer;
1741 99570a40 balrog
    case 0x084:        /* AMVCTR */
1742 99570a40 balrog
        return s->gain[0];
1743 99570a40 balrog
    case 0x088:        /* AM1VCTR */
1744 99570a40 balrog
        return s->gain[1];
1745 99570a40 balrog
    case 0x08c:        /* AM2VCTR */
1746 99570a40 balrog
        return s->gain[2];
1747 99570a40 balrog
    case 0x090:        /* AM3VCTR */
1748 99570a40 balrog
        return s->gain[3];
1749 99570a40 balrog
    case 0x094:        /* ASTCTR */
1750 99570a40 balrog
        return s->att;
1751 99570a40 balrog
    case 0x098:        /* APD1LCR */
1752 99570a40 balrog
        return s->max[0];
1753 99570a40 balrog
    case 0x09c:        /* APD1RCR */
1754 99570a40 balrog
        return s->max[1];
1755 99570a40 balrog
    case 0x0a0:        /* APD2LCR */
1756 99570a40 balrog
        return s->max[2];
1757 99570a40 balrog
    case 0x0a4:        /* APD2RCR */
1758 99570a40 balrog
        return s->max[3];
1759 99570a40 balrog
    case 0x0a8:        /* APD3LCR */
1760 99570a40 balrog
        return s->max[4];
1761 99570a40 balrog
    case 0x0ac:        /* APD3RCR */
1762 99570a40 balrog
        return s->max[5];
1763 99570a40 balrog
    case 0x0b0:        /* APD4R */
1764 99570a40 balrog
        return s->max[6];
1765 99570a40 balrog
    case 0x0b4:        /* ADWR */
1766 99570a40 balrog
        /* This should be write-only?  Docs list it as read-only.  */
1767 99570a40 balrog
        return 0x0000;
1768 99570a40 balrog
    case 0x0b8:        /* ADRDR */
1769 ab17b46d balrog
        if (likely(s->codec.rxlen > 1)) {
1770 ab17b46d balrog
            ret = s->codec.rxbuf[s->codec.rxoff ++];
1771 ab17b46d balrog
            s->codec.rxlen --;
1772 ab17b46d balrog
            s->codec.rxoff &= EAC_BUF_LEN - 1;
1773 ab17b46d balrog
            return ret;
1774 ab17b46d balrog
        } else if (s->codec.rxlen) {
1775 ab17b46d balrog
            ret = s->codec.rxbuf[s->codec.rxoff ++];
1776 ab17b46d balrog
            s->codec.rxlen --;
1777 ab17b46d balrog
            s->codec.rxoff &= EAC_BUF_LEN - 1;
1778 99570a40 balrog
            if (s->codec.rxavail)
1779 99570a40 balrog
                omap_eac_in_refill(s);
1780 ab17b46d balrog
            omap_eac_in_dmarequest_update(s);
1781 ab17b46d balrog
            return ret;
1782 99570a40 balrog
        }
1783 99570a40 balrog
        return 0x0000;
1784 99570a40 balrog
    case 0x0bc:        /* AGCFR */
1785 99570a40 balrog
        return s->codec.config[0];
1786 99570a40 balrog
    case 0x0c0:        /* AGCTR */
1787 99570a40 balrog
        return s->codec.config[1] | ((s->codec.config[1] & 2) << 14);
1788 99570a40 balrog
    case 0x0c4:        /* AGCFR2 */
1789 99570a40 balrog
        return s->codec.config[2];
1790 99570a40 balrog
    case 0x0c8:        /* AGCFR3 */
1791 99570a40 balrog
        return s->codec.config[3];
1792 99570a40 balrog
    case 0x0cc:        /* MBPDMACTR */
1793 99570a40 balrog
    case 0x0d0:        /* MPDDMARR */
1794 99570a40 balrog
    case 0x0d8:        /* MPUDMARR */
1795 99570a40 balrog
    case 0x0e4:        /* BPDDMARR */
1796 99570a40 balrog
    case 0x0ec:        /* BPUDMARR */
1797 99570a40 balrog
        return 0x0000;
1798 99570a40 balrog
1799 99570a40 balrog
    case 0x100:        /* VERSION_NUMBER */
1800 99570a40 balrog
        return 0x0010;
1801 99570a40 balrog
1802 99570a40 balrog
    case 0x104:        /* SYSCONFIG */
1803 99570a40 balrog
        return s->sysconfig;
1804 99570a40 balrog
1805 99570a40 balrog
    case 0x108:        /* SYSSTATUS */
1806 99570a40 balrog
        return 1 | 0xe;                                        /* RESETDONE | stuff */
1807 99570a40 balrog
    }
1808 99570a40 balrog
1809 99570a40 balrog
    OMAP_BAD_REG(addr);
1810 99570a40 balrog
    return 0;
1811 99570a40 balrog
}
1812 99570a40 balrog
1813 99570a40 balrog
static void omap_eac_write(void *opaque, target_phys_addr_t addr,
1814 99570a40 balrog
                uint32_t value)
1815 99570a40 balrog
{
1816 99570a40 balrog
    struct omap_eac_s *s = (struct omap_eac_s *) opaque;
1817 99570a40 balrog
1818 8da3ff18 pbrook
    switch (addr) {
1819 99570a40 balrog
    case 0x098:        /* APD1LCR */
1820 99570a40 balrog
    case 0x09c:        /* APD1RCR */
1821 99570a40 balrog
    case 0x0a0:        /* APD2LCR */
1822 99570a40 balrog
    case 0x0a4:        /* APD2RCR */
1823 99570a40 balrog
    case 0x0a8:        /* APD3LCR */
1824 99570a40 balrog
    case 0x0ac:        /* APD3RCR */
1825 99570a40 balrog
    case 0x0b0:        /* APD4R */
1826 99570a40 balrog
    case 0x0b8:        /* ADRDR */
1827 99570a40 balrog
    case 0x0d0:        /* MPDDMARR */
1828 99570a40 balrog
    case 0x0d8:        /* MPUDMARR */
1829 99570a40 balrog
    case 0x0e4:        /* BPDDMARR */
1830 99570a40 balrog
    case 0x0ec:        /* BPUDMARR */
1831 99570a40 balrog
    case 0x100:        /* VERSION_NUMBER */
1832 99570a40 balrog
    case 0x108:        /* SYSSTATUS */
1833 99570a40 balrog
        OMAP_RO_REG(addr);
1834 99570a40 balrog
        return;
1835 99570a40 balrog
1836 99570a40 balrog
    case 0x000:        /* CPCFR1 */
1837 99570a40 balrog
        s->config[0] = value & 0xff;
1838 99570a40 balrog
        omap_eac_format_update(s);
1839 99570a40 balrog
        break;
1840 99570a40 balrog
    case 0x004:        /* CPCFR2 */
1841 99570a40 balrog
        s->config[1] = value & 0xff;
1842 99570a40 balrog
        omap_eac_format_update(s);
1843 99570a40 balrog
        break;
1844 99570a40 balrog
    case 0x008:        /* CPCFR3 */
1845 99570a40 balrog
        s->config[2] = value & 0xff;
1846 99570a40 balrog
        omap_eac_format_update(s);
1847 99570a40 balrog
        break;
1848 99570a40 balrog
    case 0x00c:        /* CPCFR4 */
1849 99570a40 balrog
        s->config[3] = value & 0xff;
1850 99570a40 balrog
        omap_eac_format_update(s);
1851 99570a40 balrog
        break;
1852 99570a40 balrog
1853 99570a40 balrog
    case 0x010:        /* CPTCTL */
1854 99570a40 balrog
        /* Assuming TXF and TXE bits are read-only... */
1855 99570a40 balrog
        s->control = value & 0x5f;
1856 99570a40 balrog
        omap_eac_interrupt_update(s);
1857 99570a40 balrog
        break;
1858 99570a40 balrog
1859 99570a40 balrog
    case 0x014:        /* CPTTADR */
1860 99570a40 balrog
        s->address = value & 0xff;
1861 99570a40 balrog
        break;
1862 99570a40 balrog
    case 0x018:        /* CPTDATL */
1863 99570a40 balrog
        s->data &= 0xff00;
1864 99570a40 balrog
        s->data |= value & 0xff;
1865 99570a40 balrog
        break;
1866 99570a40 balrog
    case 0x01c:        /* CPTDATH */
1867 99570a40 balrog
        s->data &= 0x00ff;
1868 99570a40 balrog
        s->data |= value << 8;
1869 99570a40 balrog
        break;
1870 99570a40 balrog
    case 0x020:        /* CPTVSLL */
1871 99570a40 balrog
        s->vtol = value & 0xf8;
1872 99570a40 balrog
        break;
1873 99570a40 balrog
    case 0x024:        /* CPTVSLH */
1874 99570a40 balrog
        s->vtsl = value & 0x9f;
1875 99570a40 balrog
        break;
1876 99570a40 balrog
    case 0x040:        /* MPCTR */
1877 99570a40 balrog
        s->modem.control = value & 0x8f;
1878 99570a40 balrog
        break;
1879 99570a40 balrog
    case 0x044:        /* MPMCCFR */
1880 99570a40 balrog
        s->modem.config = value & 0x7fff;
1881 99570a40 balrog
        break;
1882 99570a40 balrog
    case 0x060:        /* BPCTR */
1883 99570a40 balrog
        s->bt.control = value & 0x8f;
1884 99570a40 balrog
        break;
1885 99570a40 balrog
    case 0x064:        /* BPMCCFR */
1886 99570a40 balrog
        s->bt.config = value & 0x7fff;
1887 99570a40 balrog
        break;
1888 99570a40 balrog
    case 0x080:        /* AMSCFR */
1889 99570a40 balrog
        s->mixer = value & 0x0fff;
1890 99570a40 balrog
        break;
1891 99570a40 balrog
    case 0x084:        /* AMVCTR */
1892 99570a40 balrog
        s->gain[0] = value & 0xffff;
1893 99570a40 balrog
        break;
1894 99570a40 balrog
    case 0x088:        /* AM1VCTR */
1895 99570a40 balrog
        s->gain[1] = value & 0xff7f;
1896 99570a40 balrog
        break;
1897 99570a40 balrog
    case 0x08c:        /* AM2VCTR */
1898 99570a40 balrog
        s->gain[2] = value & 0xff7f;
1899 99570a40 balrog
        break;
1900 99570a40 balrog
    case 0x090:        /* AM3VCTR */
1901 99570a40 balrog
        s->gain[3] = value & 0xff7f;
1902 99570a40 balrog
        break;
1903 99570a40 balrog
    case 0x094:        /* ASTCTR */
1904 99570a40 balrog
        s->att = value & 0xff;
1905 99570a40 balrog
        break;
1906 99570a40 balrog
1907 99570a40 balrog
    case 0x0b4:        /* ADWR */
1908 99570a40 balrog
        s->codec.txbuf[s->codec.txlen ++] = value;
1909 99570a40 balrog
        if (unlikely(s->codec.txlen == EAC_BUF_LEN ||
1910 99570a40 balrog
                                s->codec.txlen == s->codec.txavail)) {
1911 99570a40 balrog
            if (s->codec.txavail)
1912 99570a40 balrog
                omap_eac_out_empty(s);
1913 ab17b46d balrog
            /* Discard what couldn't be written */
1914 ab17b46d balrog
            s->codec.txlen = 0;
1915 99570a40 balrog
        }
1916 99570a40 balrog
        break;
1917 99570a40 balrog
1918 99570a40 balrog
    case 0x0bc:        /* AGCFR */
1919 99570a40 balrog
        s->codec.config[0] = value & 0x07ff;
1920 99570a40 balrog
        omap_eac_format_update(s);
1921 99570a40 balrog
        break;
1922 99570a40 balrog
    case 0x0c0:        /* AGCTR */
1923 99570a40 balrog
        s->codec.config[1] = value & 0x780f;
1924 99570a40 balrog
        omap_eac_format_update(s);
1925 99570a40 balrog
        break;
1926 99570a40 balrog
    case 0x0c4:        /* AGCFR2 */
1927 99570a40 balrog
        s->codec.config[2] = value & 0x003f;
1928 99570a40 balrog
        omap_eac_format_update(s);
1929 99570a40 balrog
        break;
1930 99570a40 balrog
    case 0x0c8:        /* AGCFR3 */
1931 99570a40 balrog
        s->codec.config[3] = value & 0xffff;
1932 99570a40 balrog
        omap_eac_format_update(s);
1933 99570a40 balrog
        break;
1934 99570a40 balrog
    case 0x0cc:        /* MBPDMACTR */
1935 99570a40 balrog
    case 0x0d4:        /* MPDDMAWR */
1936 99570a40 balrog
    case 0x0e0:        /* MPUDMAWR */
1937 99570a40 balrog
    case 0x0e8:        /* BPDDMAWR */
1938 99570a40 balrog
    case 0x0f0:        /* BPUDMAWR */
1939 99570a40 balrog
        break;
1940 99570a40 balrog
1941 99570a40 balrog
    case 0x104:        /* SYSCONFIG */
1942 99570a40 balrog
        if (value & (1 << 1))                                /* SOFTRESET */
1943 99570a40 balrog
            omap_eac_reset(s);
1944 99570a40 balrog
        s->sysconfig = value & 0x31d;
1945 99570a40 balrog
        break;
1946 99570a40 balrog
1947 99570a40 balrog
    default:
1948 99570a40 balrog
        OMAP_BAD_REG(addr);
1949 99570a40 balrog
        return;
1950 99570a40 balrog
    }
1951 99570a40 balrog
}
1952 99570a40 balrog
1953 99570a40 balrog
static CPUReadMemoryFunc *omap_eac_readfn[] = {
1954 99570a40 balrog
    omap_badwidth_read16,
1955 99570a40 balrog
    omap_eac_read,
1956 99570a40 balrog
    omap_badwidth_read16,
1957 99570a40 balrog
};
1958 99570a40 balrog
1959 99570a40 balrog
static CPUWriteMemoryFunc *omap_eac_writefn[] = {
1960 99570a40 balrog
    omap_badwidth_write16,
1961 99570a40 balrog
    omap_eac_write,
1962 99570a40 balrog
    omap_badwidth_write16,
1963 99570a40 balrog
};
1964 99570a40 balrog
1965 99570a40 balrog
struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
1966 99570a40 balrog
                qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
1967 99570a40 balrog
{
1968 99570a40 balrog
    int iomemtype;
1969 99570a40 balrog
    struct omap_eac_s *s = (struct omap_eac_s *)
1970 99570a40 balrog
            qemu_mallocz(sizeof(struct omap_eac_s));
1971 99570a40 balrog
1972 99570a40 balrog
    s->irq = irq;
1973 99570a40 balrog
    s->codec.rxdrq = *drq ++;
1974 99570a40 balrog
    s->codec.txdrq = *drq ++;
1975 99570a40 balrog
    omap_eac_reset(s);
1976 99570a40 balrog
1977 99570a40 balrog
#ifdef HAS_AUDIO
1978 99570a40 balrog
    /* TODO: do AUD_init globally for machine */
1979 99570a40 balrog
    AUD_register_card(AUD_init(), "OMAP EAC", &s->codec.card);
1980 99570a40 balrog
1981 99570a40 balrog
    iomemtype = cpu_register_io_memory(0, omap_eac_readfn,
1982 99570a40 balrog
                    omap_eac_writefn, s);
1983 8da3ff18 pbrook
    omap_l4_attach(ta, 0, iomemtype);
1984 99570a40 balrog
#endif
1985 99570a40 balrog
1986 99570a40 balrog
    return s;
1987 99570a40 balrog
}
1988 99570a40 balrog
1989 54585ffe balrog
/* STI/XTI (emulation interface) console - reverse engineered only */
1990 54585ffe balrog
struct omap_sti_s {
1991 54585ffe balrog
    qemu_irq irq;
1992 54585ffe balrog
    CharDriverState *chr;
1993 54585ffe balrog
1994 54585ffe balrog
    uint32_t sysconfig;
1995 54585ffe balrog
    uint32_t systest;
1996 54585ffe balrog
    uint32_t irqst;
1997 54585ffe balrog
    uint32_t irqen;
1998 54585ffe balrog
    uint32_t clkcontrol;
1999 54585ffe balrog
    uint32_t serial_config;
2000 54585ffe balrog
};
2001 54585ffe balrog
2002 54585ffe balrog
#define STI_TRACE_CONSOLE_CHANNEL        239
2003 54585ffe balrog
#define STI_TRACE_CONTROL_CHANNEL        253
2004 54585ffe balrog
2005 54585ffe balrog
static inline void omap_sti_interrupt_update(struct omap_sti_s *s)
2006 54585ffe balrog
{
2007 54585ffe balrog
    qemu_set_irq(s->irq, s->irqst & s->irqen);
2008 54585ffe balrog
}
2009 54585ffe balrog
2010 54585ffe balrog
static void omap_sti_reset(struct omap_sti_s *s)
2011 54585ffe balrog
{
2012 54585ffe balrog
    s->sysconfig = 0;
2013 54585ffe balrog
    s->irqst = 0;
2014 54585ffe balrog
    s->irqen = 0;
2015 54585ffe balrog
    s->clkcontrol = 0;
2016 54585ffe balrog
    s->serial_config = 0;
2017 54585ffe balrog
2018 54585ffe balrog
    omap_sti_interrupt_update(s);
2019 54585ffe balrog
}
2020 54585ffe balrog
2021 54585ffe balrog
static uint32_t omap_sti_read(void *opaque, target_phys_addr_t addr)
2022 54585ffe balrog
{
2023 54585ffe balrog
    struct omap_sti_s *s = (struct omap_sti_s *) opaque;
2024 54585ffe balrog
2025 8da3ff18 pbrook
    switch (addr) {
2026 54585ffe balrog
    case 0x00:        /* STI_REVISION */
2027 54585ffe balrog
        return 0x10;
2028 54585ffe balrog
2029 54585ffe balrog
    case 0x10:        /* STI_SYSCONFIG */
2030 54585ffe balrog
        return s->sysconfig;
2031 54585ffe balrog
2032 54585ffe balrog
    case 0x14:        /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
2033 54585ffe balrog
        return 0x00;
2034 54585ffe balrog
2035 54585ffe balrog
    case 0x18:        /* STI_IRQSTATUS */
2036 54585ffe balrog
        return s->irqst;
2037 54585ffe balrog
2038 54585ffe balrog
    case 0x1c:        /* STI_IRQSETEN / STI_IRQCLREN */
2039 54585ffe balrog
        return s->irqen;
2040 54585ffe balrog
2041 54585ffe balrog
    case 0x24:        /* STI_ER / STI_DR / XTI_TRACESELECT */
2042 54585ffe balrog
    case 0x28:        /* STI_RX_DR / XTI_RXDATA */
2043 e927bb00 balrog
        /* TODO */
2044 e927bb00 balrog
        return 0;
2045 54585ffe balrog
2046 54585ffe balrog
    case 0x2c:        /* STI_CLK_CTRL / XTI_SCLKCRTL */
2047 54585ffe balrog
        return s->clkcontrol;
2048 54585ffe balrog
2049 54585ffe balrog
    case 0x30:        /* STI_SERIAL_CFG / XTI_SCONFIG */
2050 54585ffe balrog
        return s->serial_config;
2051 54585ffe balrog
    }
2052 54585ffe balrog
2053 54585ffe balrog
    OMAP_BAD_REG(addr);
2054 54585ffe balrog
    return 0;
2055 54585ffe balrog
}
2056 54585ffe balrog
2057 54585ffe balrog
static void omap_sti_write(void *opaque, target_phys_addr_t addr,
2058 54585ffe balrog
                uint32_t value)
2059 54585ffe balrog
{
2060 54585ffe balrog
    struct omap_sti_s *s = (struct omap_sti_s *) opaque;
2061 54585ffe balrog
2062 8da3ff18 pbrook
    switch (addr) {
2063 54585ffe balrog
    case 0x00:        /* STI_REVISION */
2064 54585ffe balrog
    case 0x14:        /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
2065 54585ffe balrog
        OMAP_RO_REG(addr);
2066 54585ffe balrog
        return;
2067 54585ffe balrog
2068 54585ffe balrog
    case 0x10:        /* STI_SYSCONFIG */
2069 54585ffe balrog
        if (value & (1 << 1))                                /* SOFTRESET */
2070 54585ffe balrog
            omap_sti_reset(s);
2071 54585ffe balrog
        s->sysconfig = value & 0xfe;
2072 54585ffe balrog
        break;
2073 54585ffe balrog
2074 54585ffe balrog
    case 0x18:        /* STI_IRQSTATUS */
2075 54585ffe balrog
        s->irqst &= ~value;
2076 54585ffe balrog
        omap_sti_interrupt_update(s);
2077 54585ffe balrog
        break;
2078 54585ffe balrog
2079 54585ffe balrog
    case 0x1c:        /* STI_IRQSETEN / STI_IRQCLREN */
2080 54585ffe balrog
        s->irqen = value & 0xffff;
2081 54585ffe balrog
        omap_sti_interrupt_update(s);
2082 54585ffe balrog
        break;
2083 54585ffe balrog
2084 54585ffe balrog
    case 0x2c:        /* STI_CLK_CTRL / XTI_SCLKCRTL */
2085 54585ffe balrog
        s->clkcontrol = value & 0xff;
2086 54585ffe balrog
        break;
2087 54585ffe balrog
2088 54585ffe balrog
    case 0x30:        /* STI_SERIAL_CFG / XTI_SCONFIG */
2089 54585ffe balrog
        s->serial_config = value & 0xff;
2090 54585ffe balrog
        break;
2091 54585ffe balrog
2092 54585ffe balrog
    case 0x24:        /* STI_ER / STI_DR / XTI_TRACESELECT */
2093 54585ffe balrog
    case 0x28:        /* STI_RX_DR / XTI_RXDATA */
2094 e927bb00 balrog
        /* TODO */
2095 e927bb00 balrog
        return;
2096 e927bb00 balrog
2097 54585ffe balrog
    default:
2098 54585ffe balrog
        OMAP_BAD_REG(addr);
2099 54585ffe balrog
        return;
2100 54585ffe balrog
    }
2101 54585ffe balrog
}
2102 54585ffe balrog
2103 54585ffe balrog
static CPUReadMemoryFunc *omap_sti_readfn[] = {
2104 54585ffe balrog
    omap_badwidth_read32,
2105 54585ffe balrog
    omap_badwidth_read32,
2106 54585ffe balrog
    omap_sti_read,
2107 54585ffe balrog
};
2108 54585ffe balrog
2109 54585ffe balrog
static CPUWriteMemoryFunc *omap_sti_writefn[] = {
2110 54585ffe balrog
    omap_badwidth_write32,
2111 54585ffe balrog
    omap_badwidth_write32,
2112 54585ffe balrog
    omap_sti_write,
2113 54585ffe balrog
};
2114 54585ffe balrog
2115 54585ffe balrog
static uint32_t omap_sti_fifo_read(void *opaque, target_phys_addr_t addr)
2116 54585ffe balrog
{
2117 54585ffe balrog
    OMAP_BAD_REG(addr);
2118 54585ffe balrog
    return 0;
2119 54585ffe balrog
}
2120 54585ffe balrog
2121 54585ffe balrog
static void omap_sti_fifo_write(void *opaque, target_phys_addr_t addr,
2122 54585ffe balrog
                uint32_t value)
2123 54585ffe balrog
{
2124 54585ffe balrog
    struct omap_sti_s *s = (struct omap_sti_s *) opaque;
2125 8da3ff18 pbrook
    int ch = addr >> 6;
2126 54585ffe balrog
    uint8_t byte = value;
2127 54585ffe balrog
2128 54585ffe balrog
    if (ch == STI_TRACE_CONTROL_CHANNEL) {
2129 54585ffe balrog
        /* Flush channel <i>value</i>.  */
2130 75554a3c balrog
        qemu_chr_write(s->chr, (const uint8_t *) "\r", 1);
2131 54585ffe balrog
    } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
2132 54585ffe balrog
        if (value == 0xc0 || value == 0xc3) {
2133 54585ffe balrog
            /* Open channel <i>ch</i>.  */
2134 54585ffe balrog
        } else if (value == 0x00)
2135 75554a3c balrog
            qemu_chr_write(s->chr, (const uint8_t *) "\n", 1);
2136 54585ffe balrog
        else
2137 54585ffe balrog
            qemu_chr_write(s->chr, &byte, 1);
2138 54585ffe balrog
    }
2139 54585ffe balrog
}
2140 54585ffe balrog
2141 54585ffe balrog
static CPUReadMemoryFunc *omap_sti_fifo_readfn[] = {
2142 54585ffe balrog
    omap_sti_fifo_read,
2143 54585ffe balrog
    omap_badwidth_read8,
2144 54585ffe balrog
    omap_badwidth_read8,
2145 54585ffe balrog
};
2146 54585ffe balrog
2147 54585ffe balrog
static CPUWriteMemoryFunc *omap_sti_fifo_writefn[] = {
2148 54585ffe balrog
    omap_sti_fifo_write,
2149 54585ffe balrog
    omap_badwidth_write8,
2150 54585ffe balrog
    omap_badwidth_write8,
2151 54585ffe balrog
};
2152 54585ffe balrog
2153 b1d8e52e blueswir1
static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
2154 54585ffe balrog
                target_phys_addr_t channel_base, qemu_irq irq, omap_clk clk,
2155 54585ffe balrog
                CharDriverState *chr)
2156 54585ffe balrog
{
2157 54585ffe balrog
    int iomemtype;
2158 54585ffe balrog
    struct omap_sti_s *s = (struct omap_sti_s *)
2159 54585ffe balrog
            qemu_mallocz(sizeof(struct omap_sti_s));
2160 54585ffe balrog
2161 54585ffe balrog
    s->irq = irq;
2162 54585ffe balrog
    omap_sti_reset(s);
2163 54585ffe balrog
2164 ceecf1d1 aurel32
    s->chr = chr ?: qemu_chr_open("null", "null", NULL);
2165 54585ffe balrog
2166 c66fb5bc balrog
    iomemtype = l4_register_io_memory(0, omap_sti_readfn,
2167 54585ffe balrog
                    omap_sti_writefn, s);
2168 8da3ff18 pbrook
    omap_l4_attach(ta, 0, iomemtype);
2169 54585ffe balrog
2170 54585ffe balrog
    iomemtype = cpu_register_io_memory(0, omap_sti_fifo_readfn,
2171 54585ffe balrog
                    omap_sti_fifo_writefn, s);
2172 8da3ff18 pbrook
    cpu_register_physical_memory(channel_base, 0x10000, iomemtype);
2173 54585ffe balrog
2174 54585ffe balrog
    return s;
2175 54585ffe balrog
}
2176 54585ffe balrog
2177 827df9f3 balrog
/* L4 Interconnect */
2178 827df9f3 balrog
struct omap_target_agent_s {
2179 827df9f3 balrog
    struct omap_l4_s *bus;
2180 827df9f3 balrog
    int regions;
2181 827df9f3 balrog
    struct omap_l4_region_s *start;
2182 827df9f3 balrog
    target_phys_addr_t base;
2183 827df9f3 balrog
    uint32_t component;
2184 827df9f3 balrog
    uint32_t control;
2185 827df9f3 balrog
    uint32_t status;
2186 827df9f3 balrog
};
2187 827df9f3 balrog
2188 827df9f3 balrog
struct omap_l4_s {
2189 827df9f3 balrog
    target_phys_addr_t base;
2190 827df9f3 balrog
    int ta_num;
2191 827df9f3 balrog
    struct omap_target_agent_s ta[0];
2192 827df9f3 balrog
};
2193 827df9f3 balrog
2194 c66fb5bc balrog
#ifdef L4_MUX_HACK
2195 c66fb5bc balrog
static int omap_l4_io_entries;
2196 c66fb5bc balrog
static int omap_cpu_io_entry;
2197 c66fb5bc balrog
static struct omap_l4_entry {
2198 c66fb5bc balrog
        CPUReadMemoryFunc **mem_read;
2199 c66fb5bc balrog
        CPUWriteMemoryFunc **mem_write;
2200 c66fb5bc balrog
        void *opaque;
2201 c66fb5bc balrog
} *omap_l4_io_entry;
2202 c66fb5bc balrog
static CPUReadMemoryFunc **omap_l4_io_readb_fn;
2203 c66fb5bc balrog
static CPUReadMemoryFunc **omap_l4_io_readh_fn;
2204 c66fb5bc balrog
static CPUReadMemoryFunc **omap_l4_io_readw_fn;
2205 c66fb5bc balrog
static CPUWriteMemoryFunc **omap_l4_io_writeb_fn;
2206 c66fb5bc balrog
static CPUWriteMemoryFunc **omap_l4_io_writeh_fn;
2207 c66fb5bc balrog
static CPUWriteMemoryFunc **omap_l4_io_writew_fn;
2208 c66fb5bc balrog
static void **omap_l4_io_opaque;
2209 c66fb5bc balrog
2210 c66fb5bc balrog
int l4_register_io_memory(int io_index, CPUReadMemoryFunc **mem_read,
2211 c66fb5bc balrog
                CPUWriteMemoryFunc **mem_write, void *opaque)
2212 c66fb5bc balrog
{
2213 c66fb5bc balrog
    omap_l4_io_entry[omap_l4_io_entries].mem_read = mem_read;
2214 c66fb5bc balrog
    omap_l4_io_entry[omap_l4_io_entries].mem_write = mem_write;
2215 c66fb5bc balrog
    omap_l4_io_entry[omap_l4_io_entries].opaque = opaque;
2216 c66fb5bc balrog
2217 c66fb5bc balrog
    return omap_l4_io_entries ++;
2218 c66fb5bc balrog
}
2219 c66fb5bc balrog
2220 c66fb5bc balrog
static uint32_t omap_l4_io_readb(void *opaque, target_phys_addr_t addr)
2221 c66fb5bc balrog
{
2222 c66fb5bc balrog
    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2223 c66fb5bc balrog
2224 c66fb5bc balrog
    return omap_l4_io_readb_fn[i](omap_l4_io_opaque[i], addr);
2225 c66fb5bc balrog
}
2226 c66fb5bc balrog
2227 c66fb5bc balrog
static uint32_t omap_l4_io_readh(void *opaque, target_phys_addr_t addr)
2228 c66fb5bc balrog
{
2229 c66fb5bc balrog
    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2230 c66fb5bc balrog
2231 c66fb5bc balrog
    return omap_l4_io_readh_fn[i](omap_l4_io_opaque[i], addr);
2232 c66fb5bc balrog
}
2233 c66fb5bc balrog
2234 c66fb5bc balrog
static uint32_t omap_l4_io_readw(void *opaque, target_phys_addr_t addr)
2235 c66fb5bc balrog
{
2236 c66fb5bc balrog
    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2237 c66fb5bc balrog
2238 c66fb5bc balrog
    return omap_l4_io_readw_fn[i](omap_l4_io_opaque[i], addr);
2239 c66fb5bc balrog
}
2240 c66fb5bc balrog
2241 c66fb5bc balrog
static void omap_l4_io_writeb(void *opaque, target_phys_addr_t addr,
2242 c66fb5bc balrog
                uint32_t value)
2243 c66fb5bc balrog
{
2244 c66fb5bc balrog
    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2245 c66fb5bc balrog
2246 c66fb5bc balrog
    return omap_l4_io_writeb_fn[i](omap_l4_io_opaque[i], addr, value);
2247 c66fb5bc balrog
}
2248 c66fb5bc balrog
2249 c66fb5bc balrog
static void omap_l4_io_writeh(void *opaque, target_phys_addr_t addr,
2250 c66fb5bc balrog
                uint32_t value)
2251 c66fb5bc balrog
{
2252 c66fb5bc balrog
    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2253 c66fb5bc balrog
2254 c66fb5bc balrog
    return omap_l4_io_writeh_fn[i](omap_l4_io_opaque[i], addr, value);
2255 c66fb5bc balrog
}
2256 c66fb5bc balrog
2257 c66fb5bc balrog
static void omap_l4_io_writew(void *opaque, target_phys_addr_t addr,
2258 c66fb5bc balrog
                uint32_t value)
2259 c66fb5bc balrog
{
2260 c66fb5bc balrog
    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2261 c66fb5bc balrog
2262 c66fb5bc balrog
    return omap_l4_io_writew_fn[i](omap_l4_io_opaque[i], addr, value);
2263 c66fb5bc balrog
}
2264 c66fb5bc balrog
2265 c66fb5bc balrog
static CPUReadMemoryFunc *omap_l4_io_readfn[] = {
2266 c66fb5bc balrog
    omap_l4_io_readb,
2267 c66fb5bc balrog
    omap_l4_io_readh,
2268 c66fb5bc balrog
    omap_l4_io_readw,
2269 c66fb5bc balrog
};
2270 c66fb5bc balrog
2271 c66fb5bc balrog
static CPUWriteMemoryFunc *omap_l4_io_writefn[] = {
2272 c66fb5bc balrog
    omap_l4_io_writeb,
2273 c66fb5bc balrog
    omap_l4_io_writeh,
2274 c66fb5bc balrog
    omap_l4_io_writew,
2275 c66fb5bc balrog
};
2276 c66fb5bc balrog
#endif
2277 c66fb5bc balrog
2278 827df9f3 balrog
struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num)
2279 827df9f3 balrog
{
2280 827df9f3 balrog
    struct omap_l4_s *bus = qemu_mallocz(
2281 827df9f3 balrog
                    sizeof(*bus) + ta_num * sizeof(*bus->ta));
2282 827df9f3 balrog
2283 827df9f3 balrog
    bus->ta_num = ta_num;
2284 827df9f3 balrog
    bus->base = base;
2285 827df9f3 balrog
2286 c66fb5bc balrog
#ifdef L4_MUX_HACK
2287 c66fb5bc balrog
    omap_l4_io_entries = 1;
2288 c66fb5bc balrog
    omap_l4_io_entry = qemu_mallocz(125 * sizeof(*omap_l4_io_entry));
2289 c66fb5bc balrog
2290 c66fb5bc balrog
    omap_cpu_io_entry =
2291 c66fb5bc balrog
            cpu_register_io_memory(0, omap_l4_io_readfn,
2292 c66fb5bc balrog
                            omap_l4_io_writefn, bus);
2293 c66fb5bc balrog
# define L4_PAGES        (0xb4000 / TARGET_PAGE_SIZE)
2294 c66fb5bc balrog
    omap_l4_io_readb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2295 c66fb5bc balrog
    omap_l4_io_readh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2296 c66fb5bc balrog
    omap_l4_io_readw_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2297 c66fb5bc balrog
    omap_l4_io_writeb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2298 c66fb5bc balrog
    omap_l4_io_writeh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2299 c66fb5bc balrog
    omap_l4_io_writew_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2300 c66fb5bc balrog
    omap_l4_io_opaque = qemu_mallocz(sizeof(void *) * L4_PAGES);
2301 c66fb5bc balrog
#endif
2302 c66fb5bc balrog
2303 827df9f3 balrog
    return bus;
2304 827df9f3 balrog
}
2305 827df9f3 balrog
2306 827df9f3 balrog
static uint32_t omap_l4ta_read(void *opaque, target_phys_addr_t addr)
2307 827df9f3 balrog
{
2308 827df9f3 balrog
    struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
2309 827df9f3 balrog
2310 8da3ff18 pbrook
    switch (addr) {
2311 827df9f3 balrog
    case 0x00:        /* COMPONENT */
2312 827df9f3 balrog
        return s->component;
2313 827df9f3 balrog
2314 827df9f3 balrog
    case 0x20:        /* AGENT_CONTROL */
2315 827df9f3 balrog
        return s->control;
2316 827df9f3 balrog
2317 827df9f3 balrog
    case 0x28:        /* AGENT_STATUS */
2318 827df9f3 balrog
        return s->status;
2319 827df9f3 balrog
    }
2320 827df9f3 balrog
2321 827df9f3 balrog
    OMAP_BAD_REG(addr);
2322 827df9f3 balrog
    return 0;
2323 827df9f3 balrog
}
2324 827df9f3 balrog
2325 827df9f3 balrog
static void omap_l4ta_write(void *opaque, target_phys_addr_t addr,
2326 827df9f3 balrog
                uint32_t value)
2327 827df9f3 balrog
{
2328 827df9f3 balrog
    struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
2329 827df9f3 balrog
2330 8da3ff18 pbrook
    switch (addr) {
2331 827df9f3 balrog
    case 0x00:        /* COMPONENT */
2332 827df9f3 balrog
    case 0x28:        /* AGENT_STATUS */
2333 827df9f3 balrog
        OMAP_RO_REG(addr);
2334 827df9f3 balrog
        break;
2335 827df9f3 balrog
2336 827df9f3 balrog
    case 0x20:        /* AGENT_CONTROL */
2337 827df9f3 balrog
        s->control = value & 0x01000700;
2338 827df9f3 balrog
        if (value & 1)                                        /* OCP_RESET */
2339 827df9f3 balrog
            s->status &= ~1;                                /* REQ_TIMEOUT */
2340 827df9f3 balrog
        break;
2341 827df9f3 balrog
2342 827df9f3 balrog
    default:
2343 827df9f3 balrog
        OMAP_BAD_REG(addr);
2344 827df9f3 balrog
    }
2345 827df9f3 balrog
}
2346 827df9f3 balrog
2347 827df9f3 balrog
static CPUReadMemoryFunc *omap_l4ta_readfn[] = {
2348 827df9f3 balrog
    omap_badwidth_read16,
2349 827df9f3 balrog
    omap_l4ta_read,
2350 827df9f3 balrog
    omap_badwidth_read16,
2351 827df9f3 balrog
};
2352 827df9f3 balrog
2353 827df9f3 balrog
static CPUWriteMemoryFunc *omap_l4ta_writefn[] = {
2354 827df9f3 balrog
    omap_badwidth_write32,
2355 827df9f3 balrog
    omap_badwidth_write32,
2356 827df9f3 balrog
    omap_l4ta_write,
2357 827df9f3 balrog
};
2358 827df9f3 balrog
2359 827df9f3 balrog
#define L4TA(n)                (n)
2360 827df9f3 balrog
#define L4TAO(n)        ((n) + 39)
2361 827df9f3 balrog
2362 827df9f3 balrog
static struct omap_l4_region_s {
2363 827df9f3 balrog
    target_phys_addr_t offset;
2364 827df9f3 balrog
    size_t size;
2365 827df9f3 balrog
    int access;
2366 827df9f3 balrog
} omap_l4_region[125] = {
2367 827df9f3 balrog
    [  1] = { 0x40800,  0x800, 32          }, /* Initiator agent */
2368 827df9f3 balrog
    [  2] = { 0x41000, 0x1000, 32          }, /* Link agent */
2369 827df9f3 balrog
    [  0] = { 0x40000,  0x800, 32          }, /* Address and protection */
2370 827df9f3 balrog
    [  3] = { 0x00000, 0x1000, 32 | 16 | 8 }, /* System Control and Pinout */
2371 827df9f3 balrog
    [  4] = { 0x01000, 0x1000, 32 | 16 | 8 }, /* L4TAO1 */
2372 827df9f3 balrog
    [  5] = { 0x04000, 0x1000, 32 | 16     }, /* 32K Timer */
2373 827df9f3 balrog
    [  6] = { 0x05000, 0x1000, 32 | 16 | 8 }, /* L4TAO2 */
2374 827df9f3 balrog
    [  7] = { 0x08000,  0x800, 32          }, /* PRCM Region A */
2375 827df9f3 balrog
    [  8] = { 0x08800,  0x800, 32          }, /* PRCM Region B */
2376 827df9f3 balrog
    [  9] = { 0x09000, 0x1000, 32 | 16 | 8 }, /* L4TAO */
2377 827df9f3 balrog
    [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 }, /* Test (BCM) */
2378 827df9f3 balrog
    [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 }, /* L4TA1 */
2379 827df9f3 balrog
    [ 12] = { 0x14000, 0x1000, 32          }, /* Test/emulation (TAP) */
2380 827df9f3 balrog
    [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 }, /* L4TA2 */
2381 827df9f3 balrog
    [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 }, /* GPIO1 */
2382 827df9f3 balrog
    [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 }, /* GPIO2 */
2383 827df9f3 balrog
    [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 }, /* GPIO3 */
2384 827df9f3 balrog
    [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 }, /* GPIO4 */
2385 827df9f3 balrog
    [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 }, /* Quad GPIO TOP */
2386 827df9f3 balrog
    [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 }, /* L4TA3 */
2387 827df9f3 balrog
    [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 }, /* WD Timer 1 (Secure) */
2388 827df9f3 balrog
    [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 }, /* WD Timer 2 (OMAP) */
2389 827df9f3 balrog
    [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 }, /* Dual WD timer TOP */
2390 827df9f3 balrog
    [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 }, /* L4TA4 */
2391 827df9f3 balrog
    [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 }, /* GP Timer 1 */
2392 827df9f3 balrog
    [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 }, /* L4TA7 */
2393 827df9f3 balrog
    [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 }, /* Emulation (ARM11ETB) */
2394 827df9f3 balrog
    [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 }, /* L4TA9 */
2395 827df9f3 balrog
    [ 28] = { 0x50000,  0x400, 32 | 16 | 8 }, /* Display top */
2396 827df9f3 balrog
    [ 29] = { 0x50400,  0x400, 32 | 16 | 8 }, /* Display control */
2397 827df9f3 balrog
    [ 30] = { 0x50800,  0x400, 32 | 16 | 8 }, /* Display RFBI */
2398 827df9f3 balrog
    [ 31] = { 0x50c00,  0x400, 32 | 16 | 8 }, /* Display encoder */
2399 827df9f3 balrog
    [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 }, /* L4TA10 */
2400 827df9f3 balrog
    [ 33] = { 0x52000,  0x400, 32 | 16 | 8 }, /* Camera top */
2401 827df9f3 balrog
    [ 34] = { 0x52400,  0x400, 32 | 16 | 8 }, /* Camera core */
2402 827df9f3 balrog
    [ 35] = { 0x52800,  0x400, 32 | 16 | 8 }, /* Camera DMA */
2403 827df9f3 balrog
    [ 36] = { 0x52c00,  0x400, 32 | 16 | 8 }, /* Camera MMU */
2404 827df9f3 balrog
    [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 }, /* L4TA11 */
2405 827df9f3 balrog
    [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 }, /* sDMA */
2406 827df9f3 balrog
    [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 }, /* L4TA12 */
2407 827df9f3 balrog
    [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 }, /* SSI top */
2408 827df9f3 balrog
    [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 }, /* SSI GDD */
2409 827df9f3 balrog
    [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 }, /* SSI Port1 */
2410 827df9f3 balrog
    [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 }, /* SSI Port2 */
2411 827df9f3 balrog
    [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 }, /* L4TA13 */
2412 827df9f3 balrog
    [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 }, /* USB OTG */
2413 827df9f3 balrog
    [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 }, /* L4TAO4 */
2414 827df9f3 balrog
    [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER1SDRC) */
2415 827df9f3 balrog
    [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 }, /* L4TA14 */
2416 827df9f3 balrog
    [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER2GPMC) */
2417 827df9f3 balrog
    [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 }, /* L4TA15 */
2418 827df9f3 balrog
    [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER3OCM) */
2419 827df9f3 balrog
    [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 }, /* L4TA16 */
2420 827df9f3 balrog
    [ 53] = { 0x66000,  0x300, 32 | 16 | 8 }, /* Emulation (WIN_TRACER4L4) */
2421 827df9f3 balrog
    [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 }, /* L4TA17 */
2422 827df9f3 balrog
    [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 }, /* Emulation (XTI) */
2423 827df9f3 balrog
    [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 }, /* L4TA18 */
2424 827df9f3 balrog
    [ 57] = { 0x6a000, 0x1000,      16 | 8 }, /* UART1 */
2425 827df9f3 balrog
    [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 }, /* L4TA19 */
2426 827df9f3 balrog
    [ 59] = { 0x6c000, 0x1000,      16 | 8 }, /* UART2 */
2427 827df9f3 balrog
    [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 }, /* L4TA20 */
2428 827df9f3 balrog
    [ 61] = { 0x6e000, 0x1000,      16 | 8 }, /* UART3 */
2429 827df9f3 balrog
    [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 }, /* L4TA21 */
2430 827df9f3 balrog
    [ 63] = { 0x70000, 0x1000,      16     }, /* I2C1 */
2431 827df9f3 balrog
    [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 }, /* L4TAO5 */
2432 827df9f3 balrog
    [ 65] = { 0x72000, 0x1000,      16     }, /* I2C2 */
2433 827df9f3 balrog
    [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 }, /* L4TAO6 */
2434 827df9f3 balrog
    [ 67] = { 0x74000, 0x1000,      16     }, /* McBSP1 */
2435 827df9f3 balrog
    [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 }, /* L4TAO7 */
2436 827df9f3 balrog
    [ 69] = { 0x76000, 0x1000,      16     }, /* McBSP2 */
2437 827df9f3 balrog
    [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 }, /* L4TAO8 */
2438 827df9f3 balrog
    [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 }, /* WD Timer 3 (DSP) */
2439 827df9f3 balrog
    [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 }, /* L4TA5 */
2440 827df9f3 balrog
    [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 }, /* WD Timer 4 (IVA) */
2441 827df9f3 balrog
    [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 }, /* L4TA6 */
2442 827df9f3 balrog
    [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 2 */
2443 827df9f3 balrog
    [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 }, /* L4TA8 */
2444 827df9f3 balrog
    [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 }, /* GP Timer 3 */
2445 827df9f3 balrog
    [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 }, /* L4TA22 */
2446 827df9f3 balrog
    [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 4 */
2447 827df9f3 balrog
    [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 }, /* L4TA23 */
2448 827df9f3 balrog
    [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 }, /* GP Timer 5 */
2449 827df9f3 balrog
    [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 }, /* L4TA24 */
2450 827df9f3 balrog
    [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 }, /* GP Timer 6 */
2451 827df9f3 balrog
    [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 }, /* L4TA25 */
2452 827df9f3 balrog
    [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 }, /* GP Timer 7 */
2453 827df9f3 balrog
    [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 }, /* L4TA26 */
2454 827df9f3 balrog
    [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 }, /* GP Timer 8 */
2455 827df9f3 balrog
    [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 }, /* L4TA27 */
2456 827df9f3 balrog
    [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 }, /* GP Timer 9 */
2457 827df9f3 balrog
    [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 }, /* L4TA28 */
2458 827df9f3 balrog
    [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 }, /* GP Timer 10 */
2459 827df9f3 balrog
    [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 }, /* L4TA29 */
2460 827df9f3 balrog
    [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 }, /* GP Timer 11 */
2461 827df9f3 balrog
    [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 }, /* L4TA30 */
2462 827df9f3 balrog
    [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 12 */
2463 827df9f3 balrog
    [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 }, /* L4TA31 */
2464 827df9f3 balrog
    [ 97] = { 0x90000, 0x1000,      16     }, /* EAC */
2465 827df9f3 balrog
    [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 }, /* L4TA32 */
2466 827df9f3 balrog
    [ 99] = { 0x92000, 0x1000,      16     }, /* FAC */
2467 827df9f3 balrog
    [100] = { 0x93000, 0x1000, 32 | 16 | 8 }, /* L4TA33 */
2468 827df9f3 balrog
    [101] = { 0x94000, 0x1000, 32 | 16 | 8 }, /* IPC (MAILBOX) */
2469 827df9f3 balrog
    [102] = { 0x95000, 0x1000, 32 | 16 | 8 }, /* L4TA34 */
2470 827df9f3 balrog
    [103] = { 0x98000, 0x1000, 32 | 16 | 8 }, /* SPI1 */
2471 827df9f3 balrog
    [104] = { 0x99000, 0x1000, 32 | 16 | 8 }, /* L4TA35 */
2472 827df9f3 balrog
    [105] = { 0x9a000, 0x1000, 32 | 16 | 8 }, /* SPI2 */
2473 827df9f3 balrog
    [106] = { 0x9b000, 0x1000, 32 | 16 | 8 }, /* L4TA36 */
2474 827df9f3 balrog
    [107] = { 0x9c000, 0x1000,      16 | 8 }, /* MMC SDIO */
2475 827df9f3 balrog
    [108] = { 0x9d000, 0x1000, 32 | 16 | 8 }, /* L4TAO9 */
2476 827df9f3 balrog
    [109] = { 0x9e000, 0x1000, 32 | 16 | 8 }, /* MS_PRO */
2477 827df9f3 balrog
    [110] = { 0x9f000, 0x1000, 32 | 16 | 8 }, /* L4TAO10 */
2478 827df9f3 balrog
    [111] = { 0xa0000, 0x1000, 32          }, /* RNG */
2479 827df9f3 balrog
    [112] = { 0xa1000, 0x1000, 32 | 16 | 8 }, /* L4TAO11 */
2480 827df9f3 balrog
    [113] = { 0xa2000, 0x1000, 32          }, /* DES3DES */
2481 827df9f3 balrog
    [114] = { 0xa3000, 0x1000, 32 | 16 | 8 }, /* L4TAO12 */
2482 827df9f3 balrog
    [115] = { 0xa4000, 0x1000, 32          }, /* SHA1MD5 */
2483 827df9f3 balrog
    [116] = { 0xa5000, 0x1000, 32 | 16 | 8 }, /* L4TAO13 */
2484 827df9f3 balrog
    [117] = { 0xa6000, 0x1000, 32          }, /* AES */
2485 827df9f3 balrog
    [118] = { 0xa7000, 0x1000, 32 | 16 | 8 }, /* L4TA37 */
2486 827df9f3 balrog
    [119] = { 0xa8000, 0x2000, 32          }, /* PKA */
2487 827df9f3 balrog
    [120] = { 0xaa000, 0x1000, 32 | 16 | 8 }, /* L4TA38 */
2488 827df9f3 balrog
    [121] = { 0xb0000, 0x1000, 32          }, /* MG */
2489 827df9f3 balrog
    [122] = { 0xb1000, 0x1000, 32 | 16 | 8 },
2490 827df9f3 balrog
    [123] = { 0xb2000, 0x1000, 32          }, /* HDQ/1-Wire */
2491 827df9f3 balrog
    [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */
2492 827df9f3 balrog
};
2493 827df9f3 balrog
2494 827df9f3 balrog
static struct omap_l4_agent_info_s {
2495 827df9f3 balrog
    int ta;
2496 827df9f3 balrog
    int region;
2497 827df9f3 balrog
    int regions;
2498 827df9f3 balrog
    int ta_region;
2499 827df9f3 balrog
} omap_l4_agent_info[54] = {
2500 827df9f3 balrog
    { 0,           0, 3, 2 }, /* L4IA initiatior agent */
2501 827df9f3 balrog
    { L4TAO(1),    3, 2, 1 }, /* Control and pinout module */
2502 827df9f3 balrog
    { L4TAO(2),    5, 2, 1 }, /* 32K timer */
2503 827df9f3 balrog
    { L4TAO(3),    7, 3, 2 }, /* PRCM */
2504 827df9f3 balrog
    { L4TA(1),    10, 2, 1 }, /* BCM */
2505 827df9f3 balrog
    { L4TA(2),    12, 2, 1 }, /* Test JTAG */
2506 827df9f3 balrog
    { L4TA(3),    14, 6, 3 }, /* Quad GPIO */
2507 827df9f3 balrog
    { L4TA(4),    20, 4, 3 }, /* WD timer 1/2 */
2508 827df9f3 balrog
    { L4TA(7),    24, 2, 1 }, /* GP timer 1 */
2509 827df9f3 balrog
    { L4TA(9),    26, 2, 1 }, /* ATM11 ETB */
2510 827df9f3 balrog
    { L4TA(10),   28, 5, 4 }, /* Display subsystem */
2511 827df9f3 balrog
    { L4TA(11),   33, 5, 4 }, /* Camera subsystem */
2512 827df9f3 balrog
    { L4TA(12),   38, 2, 1 }, /* sDMA */
2513 827df9f3 balrog
    { L4TA(13),   40, 5, 4 }, /* SSI */
2514 827df9f3 balrog
    { L4TAO(4),   45, 2, 1 }, /* USB */
2515 827df9f3 balrog
    { L4TA(14),   47, 2, 1 }, /* Win Tracer1 */
2516 827df9f3 balrog
    { L4TA(15),   49, 2, 1 }, /* Win Tracer2 */
2517 827df9f3 balrog
    { L4TA(16),   51, 2, 1 }, /* Win Tracer3 */
2518 827df9f3 balrog
    { L4TA(17),   53, 2, 1 }, /* Win Tracer4 */
2519 827df9f3 balrog
    { L4TA(18),   55, 2, 1 }, /* XTI */
2520 827df9f3 balrog
    { L4TA(19),   57, 2, 1 }, /* UART1 */
2521 827df9f3 balrog
    { L4TA(20),   59, 2, 1 }, /* UART2 */
2522 827df9f3 balrog
    { L4TA(21),   61, 2, 1 }, /* UART3 */
2523 827df9f3 balrog
    { L4TAO(5),   63, 2, 1 }, /* I2C1 */
2524 827df9f3 balrog
    { L4TAO(6),   65, 2, 1 }, /* I2C2 */
2525 827df9f3 balrog
    { L4TAO(7),   67, 2, 1 }, /* McBSP1 */
2526 827df9f3 balrog
    { L4TAO(8),   69, 2, 1 }, /* McBSP2 */
2527 827df9f3 balrog
    { L4TA(5),    71, 2, 1 }, /* WD Timer 3 (DSP) */
2528 827df9f3 balrog
    { L4TA(6),    73, 2, 1 }, /* WD Timer 4 (IVA) */
2529 827df9f3 balrog
    { L4TA(8),    75, 2, 1 }, /* GP Timer 2 */
2530 827df9f3 balrog
    { L4TA(22),   77, 2, 1 }, /* GP Timer 3 */
2531 827df9f3 balrog
    { L4TA(23),   79, 2, 1 }, /* GP Timer 4 */
2532 827df9f3 balrog
    { L4TA(24),   81, 2, 1 }, /* GP Timer 5 */
2533 827df9f3 balrog
    { L4TA(25),   83, 2, 1 }, /* GP Timer 6 */
2534 827df9f3 balrog
    { L4TA(26),   85, 2, 1 }, /* GP Timer 7 */
2535 827df9f3 balrog
    { L4TA(27),   87, 2, 1 }, /* GP Timer 8 */
2536 827df9f3 balrog
    { L4TA(28),   89, 2, 1 }, /* GP Timer 9 */
2537 827df9f3 balrog
    { L4TA(29),   91, 2, 1 }, /* GP Timer 10 */
2538 827df9f3 balrog
    { L4TA(30),   93, 2, 1 }, /* GP Timer 11 */
2539 827df9f3 balrog
    { L4TA(31),   95, 2, 1 }, /* GP Timer 12 */
2540 827df9f3 balrog
    { L4TA(32),   97, 2, 1 }, /* EAC */
2541 827df9f3 balrog
    { L4TA(33),   99, 2, 1 }, /* FAC */
2542 827df9f3 balrog
    { L4TA(34),  101, 2, 1 }, /* IPC */
2543 827df9f3 balrog
    { L4TA(35),  103, 2, 1 }, /* SPI1 */
2544 827df9f3 balrog
    { L4TA(36),  105, 2, 1 }, /* SPI2 */
2545 827df9f3 balrog
    { L4TAO(9),  107, 2, 1 }, /* MMC SDIO */
2546 827df9f3 balrog
    { L4TAO(10), 109, 2, 1 },
2547 827df9f3 balrog
    { L4TAO(11), 111, 2, 1 }, /* RNG */
2548 827df9f3 balrog
    { L4TAO(12), 113, 2, 1 }, /* DES3DES */
2549 827df9f3 balrog
    { L4TAO(13), 115, 2, 1 }, /* SHA1MD5 */
2550 827df9f3 balrog
    { L4TA(37),  117, 2, 1 }, /* AES */
2551 827df9f3 balrog
    { L4TA(38),  119, 2, 1 }, /* PKA */
2552 827df9f3 balrog
    { -1,        121, 2, 1 },
2553 827df9f3 balrog
    { L4TA(39),  123, 2, 1 }, /* HDQ/1-Wire */
2554 827df9f3 balrog
};
2555 827df9f3 balrog
2556 827df9f3 balrog
#define omap_l4ta(bus, cs)        omap_l4ta_get(bus, L4TA(cs))
2557 827df9f3 balrog
#define omap_l4tao(bus, cs)        omap_l4ta_get(bus, L4TAO(cs))
2558 827df9f3 balrog
2559 827df9f3 balrog
struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs)
2560 827df9f3 balrog
{
2561 827df9f3 balrog
    int i, iomemtype;
2562 827df9f3 balrog
    struct omap_target_agent_s *ta = 0;
2563 827df9f3 balrog
    struct omap_l4_agent_info_s *info = 0;
2564 827df9f3 balrog
2565 827df9f3 balrog
    for (i = 0; i < bus->ta_num; i ++)
2566 827df9f3 balrog
        if (omap_l4_agent_info[i].ta == cs) {
2567 827df9f3 balrog
            ta = &bus->ta[i];
2568 827df9f3 balrog
            info = &omap_l4_agent_info[i];
2569 827df9f3 balrog
            break;
2570 827df9f3 balrog
        }
2571 827df9f3 balrog
    if (!ta) {
2572 827df9f3 balrog
        fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs);
2573 827df9f3 balrog
        exit(-1);
2574 827df9f3 balrog
    }
2575 827df9f3 balrog
2576 827df9f3 balrog
    ta->bus = bus;
2577 827df9f3 balrog
    ta->start = &omap_l4_region[info->region];
2578 827df9f3 balrog
    ta->regions = info->regions;
2579 827df9f3 balrog
2580 827df9f3 balrog
    ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2581 827df9f3 balrog
    ta->status = 0x00000000;
2582 827df9f3 balrog
    ta->control = 0x00000200;        /* XXX 01000200 for L4TAO */
2583 827df9f3 balrog
2584 c66fb5bc balrog
    iomemtype = l4_register_io_memory(0, omap_l4ta_readfn,
2585 827df9f3 balrog
                    omap_l4ta_writefn, ta);
2586 c66fb5bc balrog
    ta->base = omap_l4_attach(ta, info->ta_region, iomemtype);
2587 827df9f3 balrog
2588 827df9f3 balrog
    return ta;
2589 827df9f3 balrog
}
2590 827df9f3 balrog
2591 827df9f3 balrog
target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
2592 827df9f3 balrog
                int iotype)
2593 827df9f3 balrog
{
2594 827df9f3 balrog
    target_phys_addr_t base;
2595 c66fb5bc balrog
    ssize_t size;
2596 c66fb5bc balrog
#ifdef L4_MUX_HACK
2597 c66fb5bc balrog
    int i;
2598 c66fb5bc balrog
#endif
2599 827df9f3 balrog
2600 827df9f3 balrog
    if (region < 0 || region >= ta->regions) {
2601 827df9f3 balrog
        fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region);
2602 827df9f3 balrog
        exit(-1);
2603 827df9f3 balrog
    }
2604 827df9f3 balrog
2605 827df9f3 balrog
    base = ta->bus->base + ta->start[region].offset;
2606 827df9f3 balrog
    size = ta->start[region].size;
2607 c66fb5bc balrog
    if (iotype) {
2608 c66fb5bc balrog
#ifndef L4_MUX_HACK
2609 827df9f3 balrog
        cpu_register_physical_memory(base, size, iotype);
2610 c66fb5bc balrog
#else
2611 c66fb5bc balrog
        cpu_register_physical_memory(base, size, omap_cpu_io_entry);
2612 c66fb5bc balrog
        i = (base - ta->bus->base) / TARGET_PAGE_SIZE;
2613 c66fb5bc balrog
        for (; size > 0; size -= TARGET_PAGE_SIZE, i ++) {
2614 c66fb5bc balrog
            omap_l4_io_readb_fn[i] = omap_l4_io_entry[iotype].mem_read[0];
2615 c66fb5bc balrog
            omap_l4_io_readh_fn[i] = omap_l4_io_entry[iotype].mem_read[1];
2616 c66fb5bc balrog
            omap_l4_io_readw_fn[i] = omap_l4_io_entry[iotype].mem_read[2];
2617 c66fb5bc balrog
            omap_l4_io_writeb_fn[i] = omap_l4_io_entry[iotype].mem_write[0];
2618 c66fb5bc balrog
            omap_l4_io_writeh_fn[i] = omap_l4_io_entry[iotype].mem_write[1];
2619 c66fb5bc balrog
            omap_l4_io_writew_fn[i] = omap_l4_io_entry[iotype].mem_write[2];
2620 c66fb5bc balrog
            omap_l4_io_opaque[i] = omap_l4_io_entry[iotype].opaque;
2621 c66fb5bc balrog
        }
2622 c66fb5bc balrog
#endif
2623 c66fb5bc balrog
    }
2624 827df9f3 balrog
2625 827df9f3 balrog
    return base;
2626 827df9f3 balrog
}
2627 827df9f3 balrog
2628 827df9f3 balrog
/* TEST-Chip-level TAP */
2629 827df9f3 balrog
static uint32_t omap_tap_read(void *opaque, target_phys_addr_t addr)
2630 827df9f3 balrog
{
2631 827df9f3 balrog
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2632 827df9f3 balrog
2633 8da3ff18 pbrook
    switch (addr) {
2634 827df9f3 balrog
    case 0x204:        /* IDCODE_reg */
2635 827df9f3 balrog
        switch (s->mpu_model) {
2636 827df9f3 balrog
        case omap2420:
2637 827df9f3 balrog
        case omap2422:
2638 827df9f3 balrog
        case omap2423:
2639 827df9f3 balrog
            return 0x5b5d902f;        /* ES 2.2 */
2640 827df9f3 balrog
        case omap2430:
2641 827df9f3 balrog
            return 0x5b68a02f;        /* ES 2.2 */
2642 827df9f3 balrog
        case omap3430:
2643 827df9f3 balrog
            return 0x1b7ae02f;        /* ES 2 */
2644 827df9f3 balrog
        default:
2645 827df9f3 balrog
            cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
2646 827df9f3 balrog
        }
2647 827df9f3 balrog
2648 827df9f3 balrog
    case 0x208:        /* PRODUCTION_ID_reg for OMAP2 */
2649 827df9f3 balrog
    case 0x210:        /* PRODUCTION_ID_reg for OMAP3 */
2650 827df9f3 balrog
        switch (s->mpu_model) {
2651 827df9f3 balrog
        case omap2420:
2652 827df9f3 balrog
            return 0x000254f0;        /* POP ESHS2.1.1 in N91/93/95, ES2 in N800 */
2653 827df9f3 balrog
        case omap2422:
2654 827df9f3 balrog
            return 0x000400f0;
2655 827df9f3 balrog
        case omap2423:
2656 827df9f3 balrog
            return 0x000800f0;
2657 827df9f3 balrog
        case omap2430:
2658 827df9f3 balrog
            return 0x000000f0;
2659 827df9f3 balrog
        case omap3430:
2660 827df9f3 balrog
            return 0x000000f0;
2661 827df9f3 balrog
        default:
2662 827df9f3 balrog
            cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
2663 827df9f3 balrog
        }
2664 827df9f3 balrog
2665 827df9f3 balrog
    case 0x20c:
2666 827df9f3 balrog
        switch (s->mpu_model) {
2667 827df9f3 balrog
        case omap2420:
2668 827df9f3 balrog
        case omap2422:
2669 827df9f3 balrog
        case omap2423:
2670 827df9f3 balrog
            return 0xcafeb5d9;        /* ES 2.2 */
2671 827df9f3 balrog
        case omap2430:
2672 827df9f3 balrog
            return 0xcafeb68a;        /* ES 2.2 */
2673 827df9f3 balrog
        case omap3430:
2674 827df9f3 balrog
            return 0xcafeb7ae;        /* ES 2 */
2675 827df9f3 balrog
        default:
2676 827df9f3 balrog
            cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
2677 827df9f3 balrog
        }
2678 827df9f3 balrog
2679 827df9f3 balrog
    case 0x218:        /* DIE_ID_reg */
2680 827df9f3 balrog
        return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2681 827df9f3 balrog
    case 0x21c:        /* DIE_ID_reg */
2682 827df9f3 balrog
        return 0x54 << 24;
2683 827df9f3 balrog
    case 0x220:        /* DIE_ID_reg */
2684 827df9f3 balrog
        return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2685 827df9f3 balrog
    case 0x224:        /* DIE_ID_reg */
2686 827df9f3 balrog
        return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2687 827df9f3 balrog
    }
2688 827df9f3 balrog
2689 827df9f3 balrog
    OMAP_BAD_REG(addr);
2690 827df9f3 balrog
    return 0;
2691 827df9f3 balrog
}
2692 827df9f3 balrog
2693 827df9f3 balrog
static void omap_tap_write(void *opaque, target_phys_addr_t addr,
2694 827df9f3 balrog
                uint32_t value)
2695 827df9f3 balrog
{
2696 827df9f3 balrog
    OMAP_BAD_REG(addr);
2697 827df9f3 balrog
}
2698 827df9f3 balrog
2699 827df9f3 balrog
static CPUReadMemoryFunc *omap_tap_readfn[] = {
2700 827df9f3 balrog
    omap_badwidth_read32,
2701 827df9f3 balrog
    omap_badwidth_read32,
2702 827df9f3 balrog
    omap_tap_read,
2703 827df9f3 balrog
};
2704 827df9f3 balrog
2705 827df9f3 balrog
static CPUWriteMemoryFunc *omap_tap_writefn[] = {
2706 827df9f3 balrog
    omap_badwidth_write32,
2707 827df9f3 balrog
    omap_badwidth_write32,
2708 827df9f3 balrog
    omap_tap_write,
2709 827df9f3 balrog
};
2710 827df9f3 balrog
2711 827df9f3 balrog
void omap_tap_init(struct omap_target_agent_s *ta,
2712 827df9f3 balrog
                struct omap_mpu_state_s *mpu)
2713 827df9f3 balrog
{
2714 8da3ff18 pbrook
    omap_l4_attach(ta, 0, l4_register_io_memory(0,
2715 827df9f3 balrog
                            omap_tap_readfn, omap_tap_writefn, mpu));
2716 827df9f3 balrog
}
2717 827df9f3 balrog
2718 827df9f3 balrog
/* Power, Reset, and Clock Management */
2719 827df9f3 balrog
struct omap_prcm_s {
2720 827df9f3 balrog
    qemu_irq irq[3];
2721 827df9f3 balrog
    struct omap_mpu_state_s *mpu;
2722 827df9f3 balrog
2723 827df9f3 balrog
    uint32_t irqst[3];
2724 827df9f3 balrog
    uint32_t irqen[3];
2725 827df9f3 balrog
2726 827df9f3 balrog
    uint32_t sysconfig;
2727 827df9f3 balrog
    uint32_t voltctrl;
2728 827df9f3 balrog
    uint32_t scratch[20];
2729 827df9f3 balrog
2730 827df9f3 balrog
    uint32_t clksrc[1];
2731 827df9f3 balrog
    uint32_t clkout[1];
2732 827df9f3 balrog
    uint32_t clkemul[1];
2733 827df9f3 balrog
    uint32_t clkpol[1];
2734 827df9f3 balrog
    uint32_t clksel[8];
2735 827df9f3 balrog
    uint32_t clken[12];
2736 827df9f3 balrog
    uint32_t clkctrl[4];
2737 827df9f3 balrog
    uint32_t clkidle[7];
2738 827df9f3 balrog
    uint32_t setuptime[2];
2739 827df9f3 balrog
2740 827df9f3 balrog
    uint32_t wkup[3];
2741 827df9f3 balrog
    uint32_t wken[3];
2742 827df9f3 balrog
    uint32_t wkst[3];
2743 827df9f3 balrog
    uint32_t rst[4];
2744 827df9f3 balrog
    uint32_t rstctrl[1];
2745 827df9f3 balrog
    uint32_t power[4];
2746 827df9f3 balrog
    uint32_t rsttime_wkup;
2747 827df9f3 balrog
2748 827df9f3 balrog
    uint32_t ev;
2749 827df9f3 balrog
    uint32_t evtime[2];
2750 51fec3cc balrog
2751 51fec3cc balrog
    int dpll_lock, apll_lock[2];
2752 827df9f3 balrog
};
2753 827df9f3 balrog
2754 827df9f3 balrog
static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
2755 827df9f3 balrog
{
2756 827df9f3 balrog
    qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]);
2757 827df9f3 balrog
    /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */
2758 827df9f3 balrog
}
2759 827df9f3 balrog
2760 827df9f3 balrog
static uint32_t omap_prcm_read(void *opaque, target_phys_addr_t addr)
2761 827df9f3 balrog
{
2762 827df9f3 balrog
    struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
2763 51fec3cc balrog
    uint32_t ret;
2764 827df9f3 balrog
2765 8da3ff18 pbrook
    switch (addr) {
2766 827df9f3 balrog
    case 0x000:        /* PRCM_REVISION */
2767 827df9f3 balrog
        return 0x10;
2768 827df9f3 balrog
2769 827df9f3 balrog
    case 0x010:        /* PRCM_SYSCONFIG */
2770 827df9f3 balrog
        return s->sysconfig;
2771 827df9f3 balrog
2772 827df9f3 balrog
    case 0x018:        /* PRCM_IRQSTATUS_MPU */
2773 827df9f3 balrog
        return s->irqst[0];
2774 827df9f3 balrog
2775 827df9f3 balrog
    case 0x01c:        /* PRCM_IRQENABLE_MPU */
2776 827df9f3 balrog
        return s->irqen[0];
2777 827df9f3 balrog
2778 827df9f3 balrog
    case 0x050:        /* PRCM_VOLTCTRL */
2779 827df9f3 balrog
        return s->voltctrl;
2780 827df9f3 balrog
    case 0x054:        /* PRCM_VOLTST */
2781 827df9f3 balrog
        return s->voltctrl & 3;
2782 827df9f3 balrog
2783 827df9f3 balrog
    case 0x060:        /* PRCM_CLKSRC_CTRL */
2784 827df9f3 balrog
        return s->clksrc[0];
2785 827df9f3 balrog
    case 0x070:        /* PRCM_CLKOUT_CTRL */
2786 827df9f3 balrog
        return s->clkout[0];
2787 827df9f3 balrog
    case 0x078:        /* PRCM_CLKEMUL_CTRL */
2788 827df9f3 balrog
        return s->clkemul[0];
2789 827df9f3 balrog
    case 0x080:        /* PRCM_CLKCFG_CTRL */
2790 827df9f3 balrog
    case 0x084:        /* PRCM_CLKCFG_STATUS */
2791 827df9f3 balrog
        return 0;
2792 827df9f3 balrog
2793 827df9f3 balrog
    case 0x090:        /* PRCM_VOLTSETUP */
2794 827df9f3 balrog
        return s->setuptime[0];
2795 827df9f3 balrog
2796 827df9f3 balrog
    case 0x094:        /* PRCM_CLKSSETUP */
2797 827df9f3 balrog
        return s->setuptime[1];
2798 827df9f3 balrog
2799 827df9f3 balrog
    case 0x098:        /* PRCM_POLCTRL */
2800 827df9f3 balrog
        return s->clkpol[0];
2801 827df9f3 balrog
2802 827df9f3 balrog
    case 0x0b0:        /* GENERAL_PURPOSE1 */
2803 827df9f3 balrog
    case 0x0b4:        /* GENERAL_PURPOSE2 */
2804 827df9f3 balrog
    case 0x0b8:        /* GENERAL_PURPOSE3 */
2805 827df9f3 balrog
    case 0x0bc:        /* GENERAL_PURPOSE4 */
2806 827df9f3 balrog
    case 0x0c0:        /* GENERAL_PURPOSE5 */
2807 827df9f3 balrog
    case 0x0c4:        /* GENERAL_PURPOSE6 */
2808 827df9f3 balrog
    case 0x0c8:        /* GENERAL_PURPOSE7 */
2809 827df9f3 balrog
    case 0x0cc:        /* GENERAL_PURPOSE8 */
2810 827df9f3 balrog
    case 0x0d0:        /* GENERAL_PURPOSE9 */
2811 827df9f3 balrog
    case 0x0d4:        /* GENERAL_PURPOSE10 */
2812 827df9f3 balrog
    case 0x0d8:        /* GENERAL_PURPOSE11 */
2813 827df9f3 balrog
    case 0x0dc:        /* GENERAL_PURPOSE12 */
2814 827df9f3 balrog
    case 0x0e0:        /* GENERAL_PURPOSE13 */
2815 827df9f3 balrog
    case 0x0e4:        /* GENERAL_PURPOSE14 */
2816 827df9f3 balrog
    case 0x0e8:        /* GENERAL_PURPOSE15 */
2817 827df9f3 balrog
    case 0x0ec:        /* GENERAL_PURPOSE16 */
2818 827df9f3 balrog
    case 0x0f0:        /* GENERAL_PURPOSE17 */
2819 827df9f3 balrog
    case 0x0f4:        /* GENERAL_PURPOSE18 */
2820 827df9f3 balrog
    case 0x0f8:        /* GENERAL_PURPOSE19 */
2821 827df9f3 balrog
    case 0x0fc:        /* GENERAL_PURPOSE20 */
2822 8da3ff18 pbrook
        return s->scratch[(addr - 0xb0) >> 2];
2823 827df9f3 balrog
2824 827df9f3 balrog
    case 0x140:        /* CM_CLKSEL_MPU */
2825 827df9f3 balrog
        return s->clksel[0];
2826 827df9f3 balrog
    case 0x148:        /* CM_CLKSTCTRL_MPU */
2827 827df9f3 balrog
        return s->clkctrl[0];
2828 827df9f3 balrog
2829 827df9f3 balrog
    case 0x158:        /* RM_RSTST_MPU */
2830 827df9f3 balrog
        return s->rst[0];
2831 827df9f3 balrog
    case 0x1c8:        /* PM_WKDEP_MPU */
2832 827df9f3 balrog
        return s->wkup[0];
2833 827df9f3 balrog
    case 0x1d4:        /* PM_EVGENCTRL_MPU */
2834 827df9f3 balrog
        return s->ev;
2835 827df9f3 balrog
    case 0x1d8:        /* PM_EVEGENONTIM_MPU */
2836 827df9f3 balrog
        return s->evtime[0];
2837 827df9f3 balrog
    case 0x1dc:        /* PM_EVEGENOFFTIM_MPU */
2838 827df9f3 balrog
        return s->evtime[1];
2839 827df9f3 balrog
    case 0x1e0:        /* PM_PWSTCTRL_MPU */
2840 827df9f3 balrog
        return s->power[0];
2841 827df9f3 balrog
    case 0x1e4:        /* PM_PWSTST_MPU */
2842 827df9f3 balrog
        return 0;
2843 827df9f3 balrog
2844 827df9f3 balrog
    case 0x200:        /* CM_FCLKEN1_CORE */
2845 827df9f3 balrog
        return s->clken[0];
2846 827df9f3 balrog
    case 0x204:        /* CM_FCLKEN2_CORE */
2847 827df9f3 balrog
        return s->clken[1];
2848 827df9f3 balrog
    case 0x210:        /* CM_ICLKEN1_CORE */
2849 827df9f3 balrog
        return s->clken[2];
2850 827df9f3 balrog
    case 0x214:        /* CM_ICLKEN2_CORE */
2851 827df9f3 balrog
        return s->clken[3];
2852 827df9f3 balrog
    case 0x21c:        /* CM_ICLKEN4_CORE */
2853 827df9f3 balrog
        return s->clken[4];
2854 827df9f3 balrog
2855 827df9f3 balrog
    case 0x220:        /* CM_IDLEST1_CORE */
2856 827df9f3 balrog
        /* TODO: check the actual iclk status */
2857 827df9f3 balrog
        return 0x7ffffff9;
2858 827df9f3 balrog
    case 0x224:        /* CM_IDLEST2_CORE */
2859 827df9f3 balrog
        /* TODO: check the actual iclk status */
2860 827df9f3 balrog
        return 0x00000007;
2861 827df9f3 balrog
    case 0x22c:        /* CM_IDLEST4_CORE */
2862 827df9f3 balrog
        /* TODO: check the actual iclk status */
2863 827df9f3 balrog
        return 0x0000001f;
2864 827df9f3 balrog
2865 827df9f3 balrog
    case 0x230:        /* CM_AUTOIDLE1_CORE */
2866 827df9f3 balrog
        return s->clkidle[0];
2867 827df9f3 balrog
    case 0x234:        /* CM_AUTOIDLE2_CORE */
2868 827df9f3 balrog
        return s->clkidle[1];
2869 827df9f3 balrog
    case 0x238:        /* CM_AUTOIDLE3_CORE */
2870 827df9f3 balrog
        return s->clkidle[2];
2871 827df9f3 balrog
    case 0x23c:        /* CM_AUTOIDLE4_CORE */
2872 827df9f3 balrog
        return s->clkidle[3];
2873 827df9f3 balrog
2874 827df9f3 balrog
    case 0x240:        /* CM_CLKSEL1_CORE */
2875 827df9f3 balrog
        return s->clksel[1];
2876 827df9f3 balrog
    case 0x244:        /* CM_CLKSEL2_CORE */
2877 827df9f3 balrog
        return s->clksel[2];
2878 827df9f3 balrog
2879 827df9f3 balrog
    case 0x248:        /* CM_CLKSTCTRL_CORE */
2880 827df9f3 balrog
        return s->clkctrl[1];
2881 827df9f3 balrog
2882 827df9f3 balrog
    case 0x2a0:        /* PM_WKEN1_CORE */
2883 827df9f3 balrog
        return s->wken[0];
2884 827df9f3 balrog
    case 0x2a4:        /* PM_WKEN2_CORE */
2885 827df9f3 balrog
        return s->wken[1];
2886 827df9f3 balrog
2887 827df9f3 balrog
    case 0x2b0:        /* PM_WKST1_CORE */
2888 827df9f3 balrog
        return s->wkst[0];
2889 827df9f3 balrog
    case 0x2b4:        /* PM_WKST2_CORE */
2890 827df9f3 balrog
        return s->wkst[1];
2891 827df9f3 balrog
    case 0x2c8:        /* PM_WKDEP_CORE */
2892 827df9f3 balrog
        return 0x1e;
2893 827df9f3 balrog
2894 827df9f3 balrog
    case 0x2e0:        /* PM_PWSTCTRL_CORE */
2895 827df9f3 balrog
        return s->power[1];
2896 827df9f3 balrog
    case 0x2e4:        /* PM_PWSTST_CORE */
2897 827df9f3 balrog
        return 0x000030 | (s->power[1] & 0xfc00);
2898 827df9f3 balrog
2899 827df9f3 balrog
    case 0x300:        /* CM_FCLKEN_GFX */
2900 827df9f3 balrog
        return s->clken[5];
2901 827df9f3 balrog
    case 0x310:        /* CM_ICLKEN_GFX */
2902 827df9f3 balrog
        return s->clken[6];
2903 827df9f3 balrog
    case 0x320:        /* CM_IDLEST_GFX */
2904 827df9f3 balrog
        /* TODO: check the actual iclk status */
2905 827df9f3 balrog
        return 0x00000001;
2906 827df9f3 balrog
    case 0x340:        /* CM_CLKSEL_GFX */
2907 827df9f3 balrog
        return s->clksel[3];
2908 827df9f3 balrog
    case 0x348:        /* CM_CLKSTCTRL_GFX */
2909 827df9f3 balrog
        return s->clkctrl[2];
2910 827df9f3 balrog
    case 0x350:        /* RM_RSTCTRL_GFX */
2911 827df9f3 balrog
        return s->rstctrl[0];
2912 827df9f3 balrog
    case 0x358:        /* RM_RSTST_GFX */
2913 827df9f3 balrog
        return s->rst[1];
2914 827df9f3 balrog
    case 0x3c8:        /* PM_WKDEP_GFX */
2915 827df9f3 balrog
        return s->wkup[1];
2916 827df9f3 balrog
2917 827df9f3 balrog
    case 0x3e0:        /* PM_PWSTCTRL_GFX */
2918 827df9f3 balrog
        return s->power[2];
2919 827df9f3 balrog
    case 0x3e4:        /* PM_PWSTST_GFX */
2920 827df9f3 balrog
        return s->power[2] & 3;
2921 827df9f3 balrog
2922 827df9f3 balrog
    case 0x400:        /* CM_FCLKEN_WKUP */
2923 827df9f3 balrog
        return s->clken[7];
2924 827df9f3 balrog
    case 0x410:        /* CM_ICLKEN_WKUP */
2925 827df9f3 balrog
        return s->clken[8];
2926 827df9f3 balrog
    case 0x420:        /* CM_IDLEST_WKUP */
2927 827df9f3 balrog
        /* TODO: check the actual iclk status */
2928 827df9f3 balrog
        return 0x0000003f;
2929 827df9f3 balrog
    case 0x430:        /* CM_AUTOIDLE_WKUP */
2930 827df9f3 balrog
        return s->clkidle[4];
2931 827df9f3 balrog
    case 0x440:        /* CM_CLKSEL_WKUP */
2932 827df9f3 balrog
        return s->clksel[4];
2933 827df9f3 balrog
    case 0x450:        /* RM_RSTCTRL_WKUP */
2934 827df9f3 balrog
        return 0;
2935 827df9f3 balrog
    case 0x454:        /* RM_RSTTIME_WKUP */
2936 827df9f3 balrog
        return s->rsttime_wkup;
2937 827df9f3 balrog
    case 0x458:        /* RM_RSTST_WKUP */
2938 827df9f3 balrog
        return s->rst[2];
2939 827df9f3 balrog
    case 0x4a0:        /* PM_WKEN_WKUP */
2940 827df9f3 balrog
        return s->wken[2];
2941 827df9f3 balrog
    case 0x4b0:        /* PM_WKST_WKUP */
2942 827df9f3 balrog
        return s->wkst[2];
2943 827df9f3 balrog
2944 827df9f3 balrog
    case 0x500:        /* CM_CLKEN_PLL */
2945 827df9f3 balrog
        return s->clken[9];
2946 827df9f3 balrog
    case 0x520:        /* CM_IDLEST_CKGEN */
2947 51fec3cc balrog
        ret = 0x0000070 | (s->apll_lock[0] << 9) | (s->apll_lock[1] << 8);
2948 827df9f3 balrog
        if (!(s->clksel[6] & 3))
2949 51fec3cc balrog
            /* Core uses 32-kHz clock */
2950 51fec3cc balrog
            ret |= 3 << 0;
2951 51fec3cc balrog
        else if (!s->dpll_lock)
2952 51fec3cc balrog
            /* DPLL not locked, core uses ref_clk */
2953 51fec3cc balrog
            ret |= 1 << 0;
2954 51fec3cc balrog
        else
2955 51fec3cc balrog
            /* Core uses DPLL */
2956 51fec3cc balrog
            ret |= 2 << 0;
2957 51fec3cc balrog
        return ret;
2958 827df9f3 balrog
    case 0x530:        /* CM_AUTOIDLE_PLL */
2959 827df9f3 balrog
        return s->clkidle[5];
2960 827df9f3 balrog
    case 0x540:        /* CM_CLKSEL1_PLL */
2961 827df9f3 balrog
        return s->clksel[5];
2962 827df9f3 balrog
    case 0x544:        /* CM_CLKSEL2_PLL */
2963 827df9f3 balrog
        return s->clksel[6];
2964 827df9f3 balrog
2965 827df9f3 balrog
    case 0x800:        /* CM_FCLKEN_DSP */
2966 827df9f3 balrog
        return s->clken[10];
2967 827df9f3 balrog
    case 0x810:        /* CM_ICLKEN_DSP */
2968 827df9f3 balrog
        return s->clken[11];
2969 827df9f3 balrog
    case 0x820:        /* CM_IDLEST_DSP */
2970 827df9f3 balrog
        /* TODO: check the actual iclk status */
2971 827df9f3 balrog
        return 0x00000103;
2972 827df9f3 balrog
    case 0x830:        /* CM_AUTOIDLE_DSP */
2973 827df9f3 balrog
        return s->clkidle[6];
2974 827df9f3 balrog
    case 0x840:        /* CM_CLKSEL_DSP */
2975 827df9f3 balrog
        return s->clksel[7];
2976 827df9f3 balrog
    case 0x848:        /* CM_CLKSTCTRL_DSP */
2977 827df9f3 balrog
        return s->clkctrl[3];
2978 827df9f3 balrog
    case 0x850:        /* RM_RSTCTRL_DSP */
2979 827df9f3 balrog
        return 0;
2980 827df9f3 balrog
    case 0x858:        /* RM_RSTST_DSP */
2981 827df9f3 balrog
        return s->rst[3];
2982 827df9f3 balrog
    case 0x8c8:        /* PM_WKDEP_DSP */
2983 827df9f3 balrog
        return s->wkup[2];
2984 827df9f3 balrog
    case 0x8e0:        /* PM_PWSTCTRL_DSP */
2985 827df9f3 balrog
        return s->power[3];
2986 827df9f3 balrog
    case 0x8e4:        /* PM_PWSTST_DSP */
2987 827df9f3 balrog
        return 0x008030 | (s->power[3] & 0x3003);
2988 827df9f3 balrog
2989 827df9f3 balrog
    case 0x8f0:        /* PRCM_IRQSTATUS_DSP */
2990 827df9f3 balrog
        return s->irqst[1];
2991 827df9f3 balrog
    case 0x8f4:        /* PRCM_IRQENABLE_DSP */
2992 827df9f3 balrog
        return s->irqen[1];
2993 827df9f3 balrog
2994 827df9f3 balrog
    case 0x8f8:        /* PRCM_IRQSTATUS_IVA */
2995 827df9f3 balrog
        return s->irqst[2];
2996 827df9f3 balrog
    case 0x8fc:        /* PRCM_IRQENABLE_IVA */
2997 827df9f3 balrog
        return s->irqen[2];
2998 827df9f3 balrog
    }
2999 827df9f3 balrog
3000 827df9f3 balrog
    OMAP_BAD_REG(addr);
3001 827df9f3 balrog
    return 0;
3002 827df9f3 balrog
}
3003 827df9f3 balrog
3004 51fec3cc balrog
static void omap_prcm_apll_update(struct omap_prcm_s *s)
3005 51fec3cc balrog
{
3006 51fec3cc balrog
    int mode[2];
3007 51fec3cc balrog
3008 51fec3cc balrog
    mode[0] = (s->clken[9] >> 6) & 3;
3009 51fec3cc balrog
    s->apll_lock[0] = (mode[0] == 3);
3010 51fec3cc balrog
    mode[1] = (s->clken[9] >> 2) & 3;
3011 51fec3cc balrog
    s->apll_lock[1] = (mode[1] == 3);
3012 51fec3cc balrog
    /* TODO: update clocks */
3013 51fec3cc balrog
3014 51fec3cc balrog
    if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[2] == 2)
3015 51fec3cc balrog
        fprintf(stderr, "%s: bad EN_54M_PLL or bad EN_96M_PLL\n",
3016 51fec3cc balrog
                        __FUNCTION__);
3017 51fec3cc balrog
}
3018 51fec3cc balrog
3019 51fec3cc balrog
static void omap_prcm_dpll_update(struct omap_prcm_s *s)
3020 51fec3cc balrog
{
3021 51fec3cc balrog
    omap_clk dpll = omap_findclk(s->mpu, "dpll");
3022 51fec3cc balrog
    omap_clk dpll_x2 = omap_findclk(s->mpu, "dpll");
3023 51fec3cc balrog
    omap_clk core = omap_findclk(s->mpu, "core_clk");
3024 51fec3cc balrog
    int mode = (s->clken[9] >> 0) & 3;
3025 51fec3cc balrog
    int mult, div;
3026 51fec3cc balrog
3027 51fec3cc balrog
    mult = (s->clksel[5] >> 12) & 0x3ff;
3028 51fec3cc balrog
    div = (s->clksel[5] >> 8) & 0xf;
3029 51fec3cc balrog
    if (mult == 0 || mult == 1)
3030 51fec3cc balrog
        mode = 1;        /* Bypass */
3031 51fec3cc balrog
3032 51fec3cc balrog
    s->dpll_lock = 0;
3033 51fec3cc balrog
    switch (mode) {
3034 51fec3cc balrog
    case 0:
3035 51fec3cc balrog
        fprintf(stderr, "%s: bad EN_DPLL\n", __FUNCTION__);
3036 51fec3cc balrog
        break;
3037 51fec3cc balrog
    case 1:        /* Low-power bypass mode (Default) */
3038 51fec3cc balrog
    case 2:        /* Fast-relock bypass mode */
3039 51fec3cc balrog
        omap_clk_setrate(dpll, 1, 1);
3040 51fec3cc balrog
        omap_clk_setrate(dpll_x2, 1, 1);
3041 51fec3cc balrog
        break;
3042 51fec3cc balrog
    case 3:        /* Lock mode */
3043 51fec3cc balrog
        s->dpll_lock = 1; /* After 20 FINT cycles (ref_clk / (div + 1)).  */
3044 51fec3cc balrog
3045 51fec3cc balrog
        omap_clk_setrate(dpll, div + 1, mult);
3046 51fec3cc balrog
        omap_clk_setrate(dpll_x2, div + 1, mult * 2);
3047 51fec3cc balrog
        break;
3048 51fec3cc balrog
    }
3049 51fec3cc balrog
3050 51fec3cc balrog
    switch ((s->clksel[6] >> 0) & 3) {
3051 51fec3cc balrog
    case 0:
3052 51fec3cc balrog
        omap_clk_reparent(core, omap_findclk(s->mpu, "clk32-kHz"));
3053 51fec3cc balrog
        break;
3054 51fec3cc balrog
    case 1:
3055 51fec3cc balrog
        omap_clk_reparent(core, dpll);
3056 51fec3cc balrog
        break;
3057 51fec3cc balrog
    case 2:
3058 51fec3cc balrog
        /* Default */
3059 51fec3cc balrog
        omap_clk_reparent(core, dpll_x2);
3060 51fec3cc balrog
        break;
3061 51fec3cc balrog
    case 3:
3062 51fec3cc balrog
        fprintf(stderr, "%s: bad CORE_CLK_SRC\n", __FUNCTION__);
3063 51fec3cc balrog
        break;
3064 51fec3cc balrog
    }
3065 51fec3cc balrog
}
3066 51fec3cc balrog
3067 827df9f3 balrog
static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
3068 827df9f3 balrog
                uint32_t value)
3069 827df9f3 balrog
{
3070 827df9f3 balrog
    struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
3071 827df9f3 balrog
3072 8da3ff18 pbrook
    switch (addr) {
3073 827df9f3 balrog
    case 0x000:        /* PRCM_REVISION */
3074 827df9f3 balrog
    case 0x054:        /* PRCM_VOLTST */
3075 827df9f3 balrog
    case 0x084:        /* PRCM_CLKCFG_STATUS */
3076 827df9f3 balrog
    case 0x1e4:        /* PM_PWSTST_MPU */
3077 827df9f3 balrog
    case 0x220:        /* CM_IDLEST1_CORE */
3078 827df9f3 balrog
    case 0x224:        /* CM_IDLEST2_CORE */
3079 827df9f3 balrog
    case 0x22c:        /* CM_IDLEST4_CORE */
3080 827df9f3 balrog
    case 0x2c8:        /* PM_WKDEP_CORE */
3081 827df9f3 balrog
    case 0x2e4:        /* PM_PWSTST_CORE */
3082 827df9f3 balrog
    case 0x320:        /* CM_IDLEST_GFX */
3083 827df9f3 balrog
    case 0x3e4:        /* PM_PWSTST_GFX */
3084 827df9f3 balrog
    case 0x420:        /* CM_IDLEST_WKUP */
3085 827df9f3 balrog
    case 0x520:        /* CM_IDLEST_CKGEN */
3086 827df9f3 balrog
    case 0x820:        /* CM_IDLEST_DSP */
3087 827df9f3 balrog
    case 0x8e4:        /* PM_PWSTST_DSP */
3088 827df9f3 balrog
        OMAP_RO_REG(addr);
3089 827df9f3 balrog
        return;
3090 827df9f3 balrog
3091 827df9f3 balrog
    case 0x010:        /* PRCM_SYSCONFIG */
3092 827df9f3 balrog
        s->sysconfig = value & 1;
3093 827df9f3 balrog
        break;
3094 827df9f3 balrog
3095 827df9f3 balrog
    case 0x018:        /* PRCM_IRQSTATUS_MPU */
3096 827df9f3 balrog
        s->irqst[0] &= ~value;
3097 827df9f3 balrog
        omap_prcm_int_update(s, 0);
3098 827df9f3 balrog
        break;
3099 827df9f3 balrog
    case 0x01c:        /* PRCM_IRQENABLE_MPU */
3100 827df9f3 balrog
        s->irqen[0] = value & 0x3f;
3101 827df9f3 balrog
        omap_prcm_int_update(s, 0);
3102 827df9f3 balrog
        break;
3103 827df9f3 balrog
3104 827df9f3 balrog
    case 0x050:        /* PRCM_VOLTCTRL */
3105 827df9f3 balrog
        s->voltctrl = value & 0xf1c3;
3106 827df9f3 balrog
        break;
3107 827df9f3 balrog
3108 827df9f3 balrog
    case 0x060:        /* PRCM_CLKSRC_CTRL */
3109 827df9f3 balrog
        s->clksrc[0] = value & 0xdb;
3110 827df9f3 balrog
        /* TODO update clocks */
3111 827df9f3 balrog
        break;
3112 827df9f3 balrog
3113 827df9f3 balrog
    case 0x070:        /* PRCM_CLKOUT_CTRL */
3114 827df9f3 balrog
        s->clkout[0] = value & 0xbbbb;
3115 827df9f3 balrog
        /* TODO update clocks */
3116 827df9f3 balrog
        break;
3117 827df9f3 balrog
3118 827df9f3 balrog
    case 0x078:        /* PRCM_CLKEMUL_CTRL */
3119 827df9f3 balrog
        s->clkemul[0] = value & 1;
3120 827df9f3 balrog
        /* TODO update clocks */
3121 827df9f3 balrog
        break;
3122 827df9f3 balrog
3123 827df9f3 balrog
    case 0x080:        /* PRCM_CLKCFG_CTRL */
3124 827df9f3 balrog
        break;
3125 827df9f3 balrog
3126 827df9f3 balrog
    case 0x090:        /* PRCM_VOLTSETUP */
3127 827df9f3 balrog
        s->setuptime[0] = value & 0xffff;
3128 827df9f3 balrog
        break;
3129 827df9f3 balrog
    case 0x094:        /* PRCM_CLKSSETUP */
3130 827df9f3 balrog
        s->setuptime[1] = value & 0xffff;
3131 827df9f3 balrog
        break;
3132 827df9f3 balrog
3133 827df9f3 balrog
    case 0x098:        /* PRCM_POLCTRL */
3134 827df9f3 balrog
        s->clkpol[0] = value & 0x701;
3135 827df9f3 balrog
        break;
3136 827df9f3 balrog
3137 827df9f3 balrog
    case 0x0b0:        /* GENERAL_PURPOSE1 */
3138 827df9f3 balrog
    case 0x0b4:        /* GENERAL_PURPOSE2 */
3139 827df9f3 balrog
    case 0x0b8:        /* GENERAL_PURPOSE3 */
3140 827df9f3 balrog
    case 0x0bc:        /* GENERAL_PURPOSE4 */
3141 827df9f3 balrog
    case 0x0c0:        /* GENERAL_PURPOSE5 */
3142 827df9f3 balrog
    case 0x0c4:        /* GENERAL_PURPOSE6 */
3143 827df9f3 balrog
    case 0x0c8:        /* GENERAL_PURPOSE7 */
3144 827df9f3 balrog
    case 0x0cc:        /* GENERAL_PURPOSE8 */
3145 827df9f3 balrog
    case 0x0d0:        /* GENERAL_PURPOSE9 */
3146 827df9f3 balrog
    case 0x0d4:        /* GENERAL_PURPOSE10 */
3147 827df9f3 balrog
    case 0x0d8:        /* GENERAL_PURPOSE11 */
3148 827df9f3 balrog
    case 0x0dc:        /* GENERAL_PURPOSE12 */
3149 827df9f3 balrog
    case 0x0e0:        /* GENERAL_PURPOSE13 */
3150 827df9f3 balrog
    case 0x0e4:        /* GENERAL_PURPOSE14 */
3151 827df9f3 balrog
    case 0x0e8:        /* GENERAL_PURPOSE15 */
3152 827df9f3 balrog
    case 0x0ec:        /* GENERAL_PURPOSE16 */
3153 827df9f3 balrog
    case 0x0f0:        /* GENERAL_PURPOSE17 */
3154 827df9f3 balrog
    case 0x0f4:        /* GENERAL_PURPOSE18 */
3155 827df9f3 balrog
    case 0x0f8:        /* GENERAL_PURPOSE19 */
3156 827df9f3 balrog
    case 0x0fc:        /* GENERAL_PURPOSE20 */
3157 8da3ff18 pbrook
        s->scratch[(addr - 0xb0) >> 2] = value;
3158 827df9f3 balrog
        break;
3159 827df9f3 balrog
3160 827df9f3 balrog
    case 0x140:        /* CM_CLKSEL_MPU */
3161 827df9f3 balrog
        s->clksel[0] = value & 0x1f;
3162 827df9f3 balrog
        /* TODO update clocks */
3163 827df9f3 balrog
        break;
3164 827df9f3 balrog
    case 0x148:        /* CM_CLKSTCTRL_MPU */
3165 827df9f3 balrog
        s->clkctrl[0] = value & 0x1f;
3166 827df9f3 balrog
        break;
3167 827df9f3 balrog
3168 827df9f3 balrog
    case 0x158:        /* RM_RSTST_MPU */
3169 827df9f3 balrog
        s->rst[0] &= ~value;
3170 827df9f3 balrog
        break;
3171 827df9f3 balrog
    case 0x1c8:        /* PM_WKDEP_MPU */
3172 827df9f3 balrog
        s->wkup[0] = value & 0x15;
3173 827df9f3 balrog
        break;
3174 827df9f3 balrog
3175 827df9f3 balrog
    case 0x1d4:        /* PM_EVGENCTRL_MPU */
3176 827df9f3 balrog
        s->ev = value & 0x1f;
3177 827df9f3 balrog
        break;
3178 827df9f3 balrog
    case 0x1d8:        /* PM_EVEGENONTIM_MPU */
3179 827df9f3 balrog
        s->evtime[0] = value;
3180 827df9f3 balrog
        break;
3181 827df9f3 balrog
    case 0x1dc:        /* PM_EVEGENOFFTIM_MPU */
3182 827df9f3 balrog
        s->evtime[1] = value;
3183 827df9f3 balrog
        break;
3184 827df9f3 balrog
3185 827df9f3 balrog
    case 0x1e0:        /* PM_PWSTCTRL_MPU */
3186 827df9f3 balrog
        s->power[0] = value & 0xc0f;
3187 827df9f3 balrog
        break;
3188 827df9f3 balrog
3189 827df9f3 balrog
    case 0x200:        /* CM_FCLKEN1_CORE */
3190 827df9f3 balrog
        s->clken[0] = value & 0xbfffffff;
3191 827df9f3 balrog
        /* TODO update clocks */
3192 99570a40 balrog
        /* The EN_EAC bit only gets/puts func_96m_clk.  */
3193 827df9f3 balrog
        break;
3194 827df9f3 balrog
    case 0x204:        /* CM_FCLKEN2_CORE */
3195 827df9f3 balrog
        s->clken[1] = value & 0x00000007;
3196 827df9f3 balrog
        /* TODO update clocks */
3197 827df9f3 balrog
        break;
3198 827df9f3 balrog
    case 0x210:        /* CM_ICLKEN1_CORE */
3199 827df9f3 balrog
        s->clken[2] = value & 0xfffffff9;
3200 827df9f3 balrog
        /* TODO update clocks */
3201 99570a40 balrog
        /* The EN_EAC bit only gets/puts core_l4_iclk.  */
3202 827df9f3 balrog
        break;
3203 827df9f3 balrog
    case 0x214:        /* CM_ICLKEN2_CORE */
3204 827df9f3 balrog
        s->clken[3] = value & 0x00000007;
3205 827df9f3 balrog
        /* TODO update clocks */
3206 827df9f3 balrog
        break;
3207 827df9f3 balrog
    case 0x21c:        /* CM_ICLKEN4_CORE */
3208 827df9f3 balrog
        s->clken[4] = value & 0x0000001f;
3209 827df9f3 balrog
        /* TODO update clocks */
3210 827df9f3 balrog
        break;
3211 827df9f3 balrog
3212 827df9f3 balrog
    case 0x230:        /* CM_AUTOIDLE1_CORE */
3213 827df9f3 balrog
        s->clkidle[0] = value & 0xfffffff9;
3214 827df9f3 balrog
        /* TODO update clocks */
3215 827df9f3 balrog
        break;
3216 827df9f3 balrog
    case 0x234:        /* CM_AUTOIDLE2_CORE */
3217 827df9f3 balrog
        s->clkidle[1] = value & 0x00000007;
3218 827df9f3 balrog
        /* TODO update clocks */
3219 827df9f3 balrog
        break;
3220 827df9f3 balrog
    case 0x238:        /* CM_AUTOIDLE3_CORE */
3221 827df9f3 balrog
        s->clkidle[2] = value & 0x00000007;
3222 827df9f3 balrog
        /* TODO update clocks */
3223 827df9f3 balrog
        break;
3224 827df9f3 balrog
    case 0x23c:        /* CM_AUTOIDLE4_CORE */
3225 827df9f3 balrog
        s->clkidle[3] = value & 0x0000001f;
3226 827df9f3 balrog
        /* TODO update clocks */
3227 827df9f3 balrog
        break;
3228 827df9f3 balrog
3229 827df9f3 balrog
    case 0x240:        /* CM_CLKSEL1_CORE */
3230 827df9f3 balrog
        s->clksel[1] = value & 0x0fffbf7f;
3231 827df9f3 balrog
        /* TODO update clocks */
3232 827df9f3 balrog
        break;
3233 827df9f3 balrog
3234 827df9f3 balrog
    case 0x244:        /* CM_CLKSEL2_CORE */
3235 827df9f3 balrog
        s->clksel[2] = value & 0x00fffffc;
3236 827df9f3 balrog
        /* TODO update clocks */
3237 827df9f3 balrog
        break;
3238 827df9f3 balrog
3239 827df9f3 balrog
    case 0x248:        /* CM_CLKSTCTRL_CORE */
3240 827df9f3 balrog
        s->clkctrl[1] = value & 0x7;
3241 827df9f3 balrog
        break;
3242 827df9f3 balrog
3243 827df9f3 balrog
    case 0x2a0:        /* PM_WKEN1_CORE */
3244 827df9f3 balrog
        s->wken[0] = value & 0x04667ff8;
3245 827df9f3 balrog
        break;
3246 827df9f3 balrog
    case 0x2a4:        /* PM_WKEN2_CORE */
3247 827df9f3 balrog
        s->wken[1] = value & 0x00000005;
3248 827df9f3 balrog
        break;
3249 827df9f3 balrog
3250 827df9f3 balrog
    case 0x2b0:        /* PM_WKST1_CORE */
3251 827df9f3 balrog
        s->wkst[0] &= ~value;
3252 827df9f3 balrog
        break;
3253 827df9f3 balrog
    case 0x2b4:        /* PM_WKST2_CORE */
3254 827df9f3 balrog
        s->wkst[1] &= ~value;
3255 827df9f3 balrog
        break;
3256 827df9f3 balrog
3257 827df9f3 balrog
    case 0x2e0:        /* PM_PWSTCTRL_CORE */
3258 827df9f3 balrog
        s->power[1] = (value & 0x00fc3f) | (1 << 2);
3259 827df9f3 balrog
        break;
3260 827df9f3 balrog
3261 827df9f3 balrog
    case 0x300:        /* CM_FCLKEN_GFX */
3262 827df9f3 balrog
        s->clken[5] = value & 6;
3263 827df9f3 balrog
        /* TODO update clocks */
3264 827df9f3 balrog
        break;
3265 827df9f3 balrog
    case 0x310:        /* CM_ICLKEN_GFX */
3266 827df9f3 balrog
        s->clken[6] = value & 1;
3267 827df9f3 balrog
        /* TODO update clocks */
3268 827df9f3 balrog
        break;
3269 827df9f3 balrog
    case 0x340:        /* CM_CLKSEL_GFX */
3270 827df9f3 balrog
        s->clksel[3] = value & 7;
3271 827df9f3 balrog
        /* TODO update clocks */
3272 827df9f3 balrog
        break;
3273 827df9f3 balrog
    case 0x348:        /* CM_CLKSTCTRL_GFX */
3274 827df9f3 balrog
        s->clkctrl[2] = value & 1;
3275 827df9f3 balrog
        break;
3276 827df9f3 balrog
    case 0x350:        /* RM_RSTCTRL_GFX */
3277 827df9f3 balrog
        s->rstctrl[0] = value & 1;
3278 827df9f3 balrog
        /* TODO: reset */
3279 827df9f3 balrog
        break;
3280 827df9f3 balrog
    case 0x358:        /* RM_RSTST_GFX */
3281 827df9f3 balrog
        s->rst[1] &= ~value;
3282 827df9f3 balrog
        break;
3283 827df9f3 balrog
    case 0x3c8:        /* PM_WKDEP_GFX */
3284 827df9f3 balrog
        s->wkup[1] = value & 0x13;
3285 827df9f3 balrog
        break;
3286 827df9f3 balrog
    case 0x3e0:        /* PM_PWSTCTRL_GFX */
3287 827df9f3 balrog
        s->power[2] = (value & 0x00c0f) | (3 << 2);
3288 827df9f3 balrog
        break;
3289 827df9f3 balrog
3290 827df9f3 balrog
    case 0x400:        /* CM_FCLKEN_WKUP */
3291 827df9f3 balrog
        s->clken[7] = value & 0xd;
3292 827df9f3 balrog
        /* TODO update clocks */
3293 827df9f3 balrog
        break;
3294 827df9f3 balrog
    case 0x410:        /* CM_ICLKEN_WKUP */
3295 827df9f3 balrog
        s->clken[8] = value & 0x3f;
3296 827df9f3 balrog
        /* TODO update clocks */
3297 827df9f3 balrog
        break;
3298 827df9f3 balrog
    case 0x430:        /* CM_AUTOIDLE_WKUP */
3299 827df9f3 balrog
        s->clkidle[4] = value & 0x0000003f;
3300 827df9f3 balrog
        /* TODO update clocks */
3301 827df9f3 balrog
        break;
3302 827df9f3 balrog
    case 0x440:        /* CM_CLKSEL_WKUP */
3303 827df9f3 balrog
        s->clksel[4] = value & 3;
3304 827df9f3 balrog
        /* TODO update clocks */
3305 827df9f3 balrog
        break;
3306 827df9f3 balrog
    case 0x450:        /* RM_RSTCTRL_WKUP */
3307 827df9f3 balrog
        /* TODO: reset */
3308 827df9f3 balrog
        if (value & 2)
3309 827df9f3 balrog
            qemu_system_reset_request();
3310 827df9f3 balrog
        break;
3311 827df9f3 balrog
    case 0x454:        /* RM_RSTTIME_WKUP */
3312 827df9f3 balrog
        s->rsttime_wkup = value & 0x1fff;
3313 827df9f3 balrog
        break;
3314 827df9f3 balrog
    case 0x458:        /* RM_RSTST_WKUP */
3315 827df9f3 balrog
        s->rst[2] &= ~value;
3316 827df9f3 balrog
        break;
3317 827df9f3 balrog
    case 0x4a0:        /* PM_WKEN_WKUP */
3318 827df9f3 balrog
        s->wken[2] = value & 0x00000005;
3319 827df9f3 balrog
        break;
3320 827df9f3 balrog
    case 0x4b0:        /* PM_WKST_WKUP */
3321 827df9f3 balrog
        s->wkst[2] &= ~value;
3322 827df9f3 balrog
        break;
3323 827df9f3 balrog
3324 827df9f3 balrog
    case 0x500:        /* CM_CLKEN_PLL */
3325 51fec3cc balrog
        if (value & 0xffffff30)
3326 51fec3cc balrog
            fprintf(stderr, "%s: write 0s in CM_CLKEN_PLL for "
3327 51fec3cc balrog
                            "future compatiblity\n", __FUNCTION__);
3328 51fec3cc balrog
        if ((s->clken[9] ^ value) & 0xcc) {
3329 51fec3cc balrog
            s->clken[9] &= ~0xcc;
3330 51fec3cc balrog
            s->clken[9] |= value & 0xcc;
3331 51fec3cc balrog
            omap_prcm_apll_update(s);
3332 51fec3cc balrog
        }
3333 51fec3cc balrog
        if ((s->clken[9] ^ value) & 3) {
3334 51fec3cc balrog
            s->clken[9] &= ~3;
3335 51fec3cc balrog
            s->clken[9] |= value & 3;
3336 51fec3cc balrog
            omap_prcm_dpll_update(s);
3337 51fec3cc balrog
        }
3338 827df9f3 balrog
        break;
3339 827df9f3 balrog
    case 0x530:        /* CM_AUTOIDLE_PLL */
3340 827df9f3 balrog
        s->clkidle[5] = value & 0x000000cf;
3341 827df9f3 balrog
        /* TODO update clocks */
3342 827df9f3 balrog
        break;
3343 827df9f3 balrog
    case 0x540:        /* CM_CLKSEL1_PLL */
3344 51fec3cc balrog
        if (value & 0xfc4000d7)
3345 51fec3cc balrog
            fprintf(stderr, "%s: write 0s in CM_CLKSEL1_PLL for "
3346 51fec3cc balrog
                            "future compatiblity\n", __FUNCTION__);
3347 51fec3cc balrog
        if ((s->clksel[5] ^ value) & 0x003fff00) {
3348 51fec3cc balrog
            s->clksel[5] = value & 0x03bfff28;
3349 51fec3cc balrog
            omap_prcm_dpll_update(s);
3350 51fec3cc balrog
        }
3351 51fec3cc balrog
        /* TODO update the other clocks */
3352 51fec3cc balrog
3353 827df9f3 balrog
        s->clksel[5] = value & 0x03bfff28;
3354 827df9f3 balrog
        break;
3355 827df9f3 balrog
    case 0x544:        /* CM_CLKSEL2_PLL */
3356 51fec3cc balrog
        if (value & ~3)
3357 51fec3cc balrog
            fprintf(stderr, "%s: write 0s in CM_CLKSEL2_PLL[31:2] for "
3358 51fec3cc balrog
                            "future compatiblity\n", __FUNCTION__);
3359 51fec3cc balrog
        if (s->clksel[6] != (value & 3)) {
3360 51fec3cc balrog
            s->clksel[6] = value & 3;
3361 51fec3cc balrog
            omap_prcm_dpll_update(s);
3362 51fec3cc balrog
        }
3363 827df9f3 balrog
        break;
3364 827df9f3 balrog
3365 827df9f3 balrog
    case 0x800:        /* CM_FCLKEN_DSP */
3366 827df9f3 balrog
        s->clken[10] = value & 0x501;
3367 827df9f3 balrog
        /* TODO update clocks */
3368 827df9f3 balrog
        break;
3369 827df9f3 balrog
    case 0x810:        /* CM_ICLKEN_DSP */
3370 827df9f3 balrog
        s->clken[11] = value & 0x2;
3371 827df9f3 balrog
        /* TODO update clocks */
3372 827df9f3 balrog
        break;
3373 827df9f3 balrog
    case 0x830:        /* CM_AUTOIDLE_DSP */
3374 827df9f3 balrog
        s->clkidle[6] = value & 0x2;
3375 827df9f3 balrog
        /* TODO update clocks */
3376 827df9f3 balrog
        break;
3377 827df9f3 balrog
    case 0x840:        /* CM_CLKSEL_DSP */
3378 827df9f3 balrog
        s->clksel[7] = value & 0x3fff;
3379 827df9f3 balrog
        /* TODO update clocks */
3380 827df9f3 balrog
        break;
3381 827df9f3 balrog
    case 0x848:        /* CM_CLKSTCTRL_DSP */
3382 827df9f3 balrog
        s->clkctrl[3] = value & 0x101;
3383 827df9f3 balrog
        break;
3384 827df9f3 balrog
    case 0x850:        /* RM_RSTCTRL_DSP */
3385 827df9f3 balrog
        /* TODO: reset */
3386 827df9f3 balrog
        break;
3387 827df9f3 balrog
    case 0x858:        /* RM_RSTST_DSP */
3388 827df9f3 balrog
        s->rst[3] &= ~value;
3389 827df9f3 balrog
        break;
3390 827df9f3 balrog
    case 0x8c8:        /* PM_WKDEP_DSP */
3391 827df9f3 balrog
        s->wkup[2] = value & 0x13;
3392 827df9f3 balrog
        break;
3393 827df9f3 balrog
    case 0x8e0:        /* PM_PWSTCTRL_DSP */
3394 827df9f3 balrog
        s->power[3] = (value & 0x03017) | (3 << 2);
3395 827df9f3 balrog
        break;
3396 827df9f3 balrog
3397 827df9f3 balrog
    case 0x8f0:        /* PRCM_IRQSTATUS_DSP */
3398 827df9f3 balrog
        s->irqst[1] &= ~value;
3399 827df9f3 balrog
        omap_prcm_int_update(s, 1);
3400 827df9f3 balrog
        break;
3401 827df9f3 balrog
    case 0x8f4:        /* PRCM_IRQENABLE_DSP */
3402 827df9f3 balrog
        s->irqen[1] = value & 0x7;
3403 827df9f3 balrog
        omap_prcm_int_update(s, 1);
3404 827df9f3 balrog
        break;
3405 827df9f3 balrog
3406 827df9f3 balrog
    case 0x8f8:        /* PRCM_IRQSTATUS_IVA */
3407 827df9f3 balrog
        s->irqst[2] &= ~value;
3408 827df9f3 balrog
        omap_prcm_int_update(s, 2);
3409 827df9f3 balrog
        break;
3410 827df9f3 balrog
    case 0x8fc:        /* PRCM_IRQENABLE_IVA */
3411 827df9f3 balrog
        s->irqen[2] = value & 0x7;
3412 827df9f3 balrog
        omap_prcm_int_update(s, 2);
3413 827df9f3 balrog
        break;
3414 827df9f3 balrog
3415 827df9f3 balrog
    default:
3416 827df9f3 balrog
        OMAP_BAD_REG(addr);
3417 827df9f3 balrog
        return;
3418 827df9f3 balrog
    }
3419 827df9f3 balrog
}
3420 827df9f3 balrog
3421 827df9f3 balrog
static CPUReadMemoryFunc *omap_prcm_readfn[] = {
3422 827df9f3 balrog
    omap_badwidth_read32,
3423 827df9f3 balrog
    omap_badwidth_read32,
3424 827df9f3 balrog
    omap_prcm_read,
3425 827df9f3 balrog
};
3426 827df9f3 balrog
3427 827df9f3 balrog
static CPUWriteMemoryFunc *omap_prcm_writefn[] = {
3428 827df9f3 balrog
    omap_badwidth_write32,
3429 827df9f3 balrog
    omap_badwidth_write32,
3430 827df9f3 balrog
    omap_prcm_write,
3431 827df9f3 balrog
};
3432 827df9f3 balrog
3433 827df9f3 balrog
static void omap_prcm_reset(struct omap_prcm_s *s)
3434 827df9f3 balrog
{
3435 827df9f3 balrog
    s->sysconfig = 0;
3436 827df9f3 balrog
    s->irqst[0] = 0;
3437 827df9f3 balrog
    s->irqst[1] = 0;
3438 827df9f3 balrog
    s->irqst[2] = 0;
3439 827df9f3 balrog
    s->irqen[0] = 0;
3440 827df9f3 balrog
    s->irqen[1] = 0;
3441 827df9f3 balrog
    s->irqen[2] = 0;
3442 827df9f3 balrog
    s->voltctrl = 0x1040;
3443 827df9f3 balrog
    s->ev = 0x14;
3444 827df9f3 balrog
    s->evtime[0] = 0;
3445 827df9f3 balrog
    s->evtime[1] = 0;
3446 827df9f3 balrog
    s->clkctrl[0] = 0;
3447 827df9f3 balrog
    s->clkctrl[1] = 0;
3448 827df9f3 balrog
    s->clkctrl[2] = 0;
3449 827df9f3 balrog
    s->clkctrl[3] = 0;
3450 827df9f3 balrog
    s->clken[1] = 7;
3451 827df9f3 balrog
    s->clken[3] = 7;
3452 827df9f3 balrog
    s->clken[4] = 0;
3453 827df9f3 balrog
    s->clken[5] = 0;
3454 827df9f3 balrog
    s->clken[6] = 0;
3455 827df9f3 balrog
    s->clken[7] = 0xc;
3456 827df9f3 balrog
    s->clken[8] = 0x3e;
3457 827df9f3 balrog
    s->clken[9] = 0x0d;
3458 827df9f3 balrog
    s->clken[10] = 0;
3459 827df9f3 balrog
    s->clken[11] = 0;
3460 827df9f3 balrog
    s->clkidle[0] = 0;
3461 827df9f3 balrog
    s->clkidle[2] = 7;
3462 827df9f3 balrog
    s->clkidle[3] = 0;
3463 827df9f3 balrog
    s->clkidle[4] = 0;
3464 827df9f3 balrog
    s->clkidle[5] = 0x0c;
3465 827df9f3 balrog
    s->clkidle[6] = 0;
3466 827df9f3 balrog
    s->clksel[0] = 0x01;
3467 827df9f3 balrog
    s->clksel[1] = 0x02100121;
3468 827df9f3 balrog
    s->clksel[2] = 0x00000000;
3469 827df9f3 balrog
    s->clksel[3] = 0x01;
3470 827df9f3 balrog
    s->clksel[4] = 0;
3471 827df9f3 balrog
    s->clksel[7] = 0x0121;
3472 827df9f3 balrog
    s->wkup[0] = 0x15;
3473 827df9f3 balrog
    s->wkup[1] = 0x13;
3474 827df9f3 balrog
    s->wkup[2] = 0x13;
3475 827df9f3 balrog
    s->wken[0] = 0x04667ff8;
3476 827df9f3 balrog
    s->wken[1] = 0x00000005;
3477 827df9f3 balrog
    s->wken[2] = 5;
3478 827df9f3 balrog
    s->wkst[0] = 0;
3479 827df9f3 balrog
    s->wkst[1] = 0;
3480 827df9f3 balrog
    s->wkst[2] = 0;
3481 827df9f3 balrog
    s->power[0] = 0x00c;
3482 827df9f3 balrog
    s->power[1] = 4;
3483 827df9f3 balrog
    s->power[2] = 0x0000c;
3484 827df9f3 balrog
    s->power[3] = 0x14;
3485 827df9f3 balrog
    s->rstctrl[0] = 1;
3486 827df9f3 balrog
    s->rst[3] = 1;
3487 51fec3cc balrog
    omap_prcm_apll_update(s);
3488 51fec3cc balrog
    omap_prcm_dpll_update(s);
3489 827df9f3 balrog
}
3490 827df9f3 balrog
3491 827df9f3 balrog
static void omap_prcm_coldreset(struct omap_prcm_s *s)
3492 827df9f3 balrog
{
3493 827df9f3 balrog
    s->setuptime[0] = 0;
3494 827df9f3 balrog
    s->setuptime[1] = 0;
3495 827df9f3 balrog
    memset(&s->scratch, 0, sizeof(s->scratch));
3496 827df9f3 balrog
    s->rst[0] = 0x01;
3497 827df9f3 balrog
    s->rst[1] = 0x00;
3498 827df9f3 balrog
    s->rst[2] = 0x01;
3499 827df9f3 balrog
    s->clken[0] = 0;
3500 827df9f3 balrog
    s->clken[2] = 0;
3501 827df9f3 balrog
    s->clkidle[1] = 0;
3502 827df9f3 balrog
    s->clksel[5] = 0;
3503 827df9f3 balrog
    s->clksel[6] = 2;
3504 827df9f3 balrog
    s->clksrc[0] = 0x43;
3505 827df9f3 balrog
    s->clkout[0] = 0x0303;
3506 827df9f3 balrog
    s->clkemul[0] = 0;
3507 827df9f3 balrog
    s->clkpol[0] = 0x100;
3508 827df9f3 balrog
    s->rsttime_wkup = 0x1002;
3509 827df9f3 balrog
3510 827df9f3 balrog
    omap_prcm_reset(s);
3511 827df9f3 balrog
}
3512 827df9f3 balrog
3513 827df9f3 balrog
struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
3514 827df9f3 balrog
                qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
3515 827df9f3 balrog
                struct omap_mpu_state_s *mpu)
3516 827df9f3 balrog
{
3517 827df9f3 balrog
    int iomemtype;
3518 827df9f3 balrog
    struct omap_prcm_s *s = (struct omap_prcm_s *)
3519 827df9f3 balrog
            qemu_mallocz(sizeof(struct omap_prcm_s));
3520 827df9f3 balrog
3521 827df9f3 balrog
    s->irq[0] = mpu_int;
3522 827df9f3 balrog
    s->irq[1] = dsp_int;
3523 827df9f3 balrog
    s->irq[2] = iva_int;
3524 827df9f3 balrog
    s->mpu = mpu;
3525 827df9f3 balrog
    omap_prcm_coldreset(s);
3526 827df9f3 balrog
3527 c66fb5bc balrog
    iomemtype = l4_register_io_memory(0, omap_prcm_readfn,
3528 827df9f3 balrog
                    omap_prcm_writefn, s);
3529 8da3ff18 pbrook
    omap_l4_attach(ta, 0, iomemtype);
3530 827df9f3 balrog
    omap_l4_attach(ta, 1, iomemtype);
3531 827df9f3 balrog
3532 827df9f3 balrog
    return s;
3533 827df9f3 balrog
}
3534 827df9f3 balrog
3535 827df9f3 balrog
/* System and Pinout control */
3536 827df9f3 balrog
struct omap_sysctl_s {
3537 827df9f3 balrog
    struct omap_mpu_state_s *mpu;
3538 827df9f3 balrog
3539 827df9f3 balrog
    uint32_t sysconfig;
3540 827df9f3 balrog
    uint32_t devconfig;
3541 827df9f3 balrog
    uint32_t psaconfig;
3542 827df9f3 balrog
    uint32_t padconf[0x45];
3543 827df9f3 balrog
    uint8_t obs;
3544 827df9f3 balrog
    uint32_t msuspendmux[5];
3545 827df9f3 balrog
};
3546 827df9f3 balrog
3547 f451387a balrog
static uint32_t omap_sysctl_read8(void *opaque, target_phys_addr_t addr)
3548 f451387a balrog
{
3549 f451387a balrog
3550 f451387a balrog
    struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
3551 f451387a balrog
    int pad_offset, byte_offset;
3552 f451387a balrog
    int value;
3553 f451387a balrog
3554 8da3ff18 pbrook
    switch (addr) {
3555 f451387a balrog
    case 0x030 ... 0x140:        /* CONTROL_PADCONF - only used in the POP */
3556 8da3ff18 pbrook
        pad_offset = (addr - 0x30) >> 2;
3557 8da3ff18 pbrook
        byte_offset = (addr - 0x30) & (4 - 1);
3558 f451387a balrog
3559 f451387a balrog
        value = s->padconf[pad_offset];
3560 f451387a balrog
        value = (value >> (byte_offset * 8)) & 0xff;
3561 f451387a balrog
3562 f451387a balrog
        return value;
3563 f451387a balrog
3564 f451387a balrog
    default:
3565 f451387a balrog
        break;
3566 f451387a balrog
    }
3567 f451387a balrog
3568 f451387a balrog
    OMAP_BAD_REG(addr);
3569 f451387a balrog
    return 0;
3570 f451387a balrog
}
3571 f451387a balrog
3572 827df9f3 balrog
static uint32_t omap_sysctl_read(void *opaque, target_phys_addr_t addr)
3573 827df9f3 balrog
{
3574 827df9f3 balrog
    struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
3575 827df9f3 balrog
3576 8da3ff18 pbrook
    switch (addr) {
3577 827df9f3 balrog
    case 0x000:        /* CONTROL_REVISION */
3578 827df9f3 balrog
        return 0x20;
3579 827df9f3 balrog
3580 827df9f3 balrog
    case 0x010:        /* CONTROL_SYSCONFIG */
3581 827df9f3 balrog
        return s->sysconfig;
3582 827df9f3 balrog
3583 827df9f3 balrog
    case 0x030 ... 0x140:        /* CONTROL_PADCONF - only used in the POP */
3584 8da3ff18 pbrook
        return s->padconf[(addr - 0x30) >> 2];
3585 827df9f3 balrog
3586 827df9f3 balrog
    case 0x270:        /* CONTROL_DEBOBS */
3587 827df9f3 balrog
        return s->obs;
3588 827df9f3 balrog
3589 827df9f3 balrog
    case 0x274:        /* CONTROL_DEVCONF */
3590 827df9f3 balrog
        return s->devconfig;
3591 827df9f3 balrog
3592 827df9f3 balrog
    case 0x28c:        /* CONTROL_EMU_SUPPORT */
3593 827df9f3 balrog
        return 0;
3594 827df9f3 balrog
3595 827df9f3 balrog
    case 0x290:        /* CONTROL_MSUSPENDMUX_0 */
3596 827df9f3 balrog
        return s->msuspendmux[0];
3597 827df9f3 balrog
    case 0x294:        /* CONTROL_MSUSPENDMUX_1 */
3598 827df9f3 balrog
        return s->msuspendmux[1];
3599 827df9f3 balrog
    case 0x298:        /* CONTROL_MSUSPENDMUX_2 */
3600 827df9f3 balrog
        return s->msuspendmux[2];
3601 827df9f3 balrog
    case 0x29c:        /* CONTROL_MSUSPENDMUX_3 */
3602 827df9f3 balrog
        return s->msuspendmux[3];
3603 827df9f3 balrog
    case 0x2a0:        /* CONTROL_MSUSPENDMUX_4 */
3604 827df9f3 balrog
        return s->msuspendmux[4];
3605 827df9f3 balrog
    case 0x2a4:        /* CONTROL_MSUSPENDMUX_5 */
3606 827df9f3 balrog
        return 0;
3607 827df9f3 balrog
3608 827df9f3 balrog
    case 0x2b8:        /* CONTROL_PSA_CTRL */
3609 827df9f3 balrog
        return s->psaconfig;
3610 827df9f3 balrog
    case 0x2bc:        /* CONTROL_PSA_CMD */
3611 827df9f3 balrog
    case 0x2c0:        /* CONTROL_PSA_VALUE */
3612 827df9f3 balrog
        return 0;
3613 827df9f3 balrog
3614 827df9f3 balrog
    case 0x2b0:        /* CONTROL_SEC_CTRL */
3615 827df9f3 balrog
        return 0x800000f1;
3616 827df9f3 balrog
    case 0x2d0:        /* CONTROL_SEC_EMU */
3617 827df9f3 balrog
        return 0x80000015;
3618 827df9f3 balrog
    case 0x2d4:        /* CONTROL_SEC_TAP */
3619 827df9f3 balrog
        return 0x8000007f;
3620 827df9f3 balrog
    case 0x2b4:        /* CONTROL_SEC_TEST */
3621 827df9f3 balrog
    case 0x2f0:        /* CONTROL_SEC_STATUS */
3622 827df9f3 balrog
    case 0x2f4:        /* CONTROL_SEC_ERR_STATUS */
3623 827df9f3 balrog
        /* Secure mode is not present on general-pusrpose device.  Outside
3624 827df9f3 balrog
         * secure mode these values cannot be read or written.  */
3625 827df9f3 balrog
        return 0;
3626 827df9f3 balrog
3627 827df9f3 balrog
    case 0x2d8:        /* CONTROL_OCM_RAM_PERM */
3628 827df9f3 balrog
        return 0xff;
3629 827df9f3 balrog
    case 0x2dc:        /* CONTROL_OCM_PUB_RAM_ADD */
3630 827df9f3 balrog
    case 0x2e0:        /* CONTROL_EXT_SEC_RAM_START_ADD */
3631 827df9f3 balrog
    case 0x2e4:        /* CONTROL_EXT_SEC_RAM_STOP_ADD */
3632 827df9f3 balrog
        /* No secure mode so no Extended Secure RAM present.  */
3633 827df9f3 balrog
        return 0;
3634 827df9f3 balrog
3635 827df9f3 balrog
    case 0x2f8:        /* CONTROL_STATUS */
3636 827df9f3 balrog
        /* Device Type => General-purpose */
3637 827df9f3 balrog
        return 0x0300;
3638 827df9f3 balrog
    case 0x2fc:        /* CONTROL_GENERAL_PURPOSE_STATUS */
3639 827df9f3 balrog
3640 827df9f3 balrog
    case 0x300:        /* CONTROL_RPUB_KEY_H_0 */
3641 827df9f3 balrog
    case 0x304:        /* CONTROL_RPUB_KEY_H_1 */
3642 827df9f3 balrog
    case 0x308:        /* CONTROL_RPUB_KEY_H_2 */
3643 827df9f3 balrog
    case 0x30c:        /* CONTROL_RPUB_KEY_H_3 */
3644 827df9f3 balrog
        return 0xdecafbad;
3645 827df9f3 balrog
3646 827df9f3 balrog
    case 0x310:        /* CONTROL_RAND_KEY_0 */
3647 827df9f3 balrog
    case 0x314:        /* CONTROL_RAND_KEY_1 */
3648 827df9f3 balrog
    case 0x318:        /* CONTROL_RAND_KEY_2 */
3649 827df9f3 balrog
    case 0x31c:        /* CONTROL_RAND_KEY_3 */
3650 827df9f3 balrog
    case 0x320:        /* CONTROL_CUST_KEY_0 */
3651 827df9f3 balrog
    case 0x324:        /* CONTROL_CUST_KEY_1 */
3652 827df9f3 balrog
    case 0x330:        /* CONTROL_TEST_KEY_0 */
3653 827df9f3 balrog
    case 0x334:        /* CONTROL_TEST_KEY_1 */
3654 827df9f3 balrog
    case 0x338:        /* CONTROL_TEST_KEY_2 */
3655 827df9f3 balrog
    case 0x33c:        /* CONTROL_TEST_KEY_3 */
3656 827df9f3 balrog
    case 0x340:        /* CONTROL_TEST_KEY_4 */
3657 827df9f3 balrog
    case 0x344:        /* CONTROL_TEST_KEY_5 */
3658 827df9f3 balrog
    case 0x348:        /* CONTROL_TEST_KEY_6 */
3659 827df9f3 balrog
    case 0x34c:        /* CONTROL_TEST_KEY_7 */
3660 827df9f3 balrog
    case 0x350:        /* CONTROL_TEST_KEY_8 */
3661 827df9f3 balrog
    case 0x354:        /* CONTROL_TEST_KEY_9 */
3662 827df9f3 balrog
        /* Can only be accessed in secure mode and when C_FieldAccEnable
3663 827df9f3 balrog
         * bit is set in CONTROL_SEC_CTRL.
3664 827df9f3 balrog
         * TODO: otherwise an interconnect access error is generated.  */
3665 827df9f3 balrog
        return 0;
3666 827df9f3 balrog
    }
3667 827df9f3 balrog
3668 827df9f3 balrog
    OMAP_BAD_REG(addr);
3669 827df9f3 balrog
    return 0;
3670 827df9f3 balrog
}
3671 827df9f3 balrog
3672 f451387a balrog
static void omap_sysctl_write8(void *opaque, target_phys_addr_t addr,
3673 f451387a balrog
                uint32_t value)
3674 f451387a balrog
{
3675 f451387a balrog
    struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
3676 f451387a balrog
    int pad_offset, byte_offset;
3677 f451387a balrog
    int prev_value;
3678 f451387a balrog
3679 8da3ff18 pbrook
    switch (addr) {
3680 f451387a balrog
    case 0x030 ... 0x140:        /* CONTROL_PADCONF - only used in the POP */
3681 8da3ff18 pbrook
        pad_offset = (addr - 0x30) >> 2;
3682 8da3ff18 pbrook
        byte_offset = (addr - 0x30) & (4 - 1);
3683 f451387a balrog
3684 f451387a balrog
        prev_value = s->padconf[pad_offset];
3685 f451387a balrog
        prev_value &= ~(0xff << (byte_offset * 8));
3686 f451387a balrog
        prev_value |= ((value & 0x1f1f1f1f) << (byte_offset * 8)) & 0x1f1f1f1f;
3687 f451387a balrog
        s->padconf[pad_offset] = prev_value;
3688 f451387a balrog
        break;
3689 f451387a balrog
3690 f451387a balrog
    default:
3691 f451387a balrog
        OMAP_BAD_REG(addr);
3692 f451387a balrog
        break;
3693 f451387a balrog
    }
3694 f451387a balrog
}
3695 f451387a balrog
3696 827df9f3 balrog
static void omap_sysctl_write(void *opaque, target_phys_addr_t addr,
3697 827df9f3 balrog
                uint32_t value)
3698 827df9f3 balrog
{
3699 827df9f3 balrog
    struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
3700 827df9f3 balrog
3701 8da3ff18 pbrook
    switch (addr) {
3702 827df9f3 balrog
    case 0x000:        /* CONTROL_REVISION */
3703 827df9f3 balrog
    case 0x2a4:        /* CONTROL_MSUSPENDMUX_5 */
3704 827df9f3 balrog
    case 0x2c0:        /* CONTROL_PSA_VALUE */
3705 827df9f3 balrog
    case 0x2f8:        /* CONTROL_STATUS */
3706 827df9f3 balrog
    case 0x2fc:        /* CONTROL_GENERAL_PURPOSE_STATUS */
3707 827df9f3 balrog
    case 0x300:        /* CONTROL_RPUB_KEY_H_0 */
3708 827df9f3 balrog
    case 0x304:        /* CONTROL_RPUB_KEY_H_1 */
3709 827df9f3 balrog
    case 0x308:        /* CONTROL_RPUB_KEY_H_2 */
3710 827df9f3 balrog
    case 0x30c:        /* CONTROL_RPUB_KEY_H_3 */
3711 827df9f3 balrog
    case 0x310:        /* CONTROL_RAND_KEY_0 */
3712 827df9f3 balrog
    case 0x314:        /* CONTROL_RAND_KEY_1 */
3713 827df9f3 balrog
    case 0x318:        /* CONTROL_RAND_KEY_2 */
3714 827df9f3 balrog
    case 0x31c:        /* CONTROL_RAND_KEY_3 */
3715 827df9f3 balrog
    case 0x320:        /* CONTROL_CUST_KEY_0 */
3716 827df9f3 balrog
    case 0x324:        /* CONTROL_CUST_KEY_1 */
3717 827df9f3 balrog
    case 0x330:        /* CONTROL_TEST_KEY_0 */
3718 827df9f3 balrog
    case 0x334:        /* CONTROL_TEST_KEY_1 */
3719 827df9f3 balrog
    case 0x338:        /* CONTROL_TEST_KEY_2 */
3720 827df9f3 balrog
    case 0x33c:        /* CONTROL_TEST_KEY_3 */
3721 827df9f3 balrog
    case 0x340:        /* CONTROL_TEST_KEY_4 */
3722 827df9f3 balrog
    case 0x344:        /* CONTROL_TEST_KEY_5 */
3723 827df9f3 balrog
    case 0x348:        /* CONTROL_TEST_KEY_6 */
3724 827df9f3 balrog
    case 0x34c:        /* CONTROL_TEST_KEY_7 */
3725 827df9f3 balrog
    case 0x350:        /* CONTROL_TEST_KEY_8 */
3726 827df9f3 balrog
    case 0x354:        /* CONTROL_TEST_KEY_9 */
3727 827df9f3 balrog
        OMAP_RO_REG(addr);
3728 827df9f3 balrog
        return;
3729 827df9f3 balrog
3730 827df9f3 balrog
    case 0x010:        /* CONTROL_SYSCONFIG */
3731 827df9f3 balrog
        s->sysconfig = value & 0x1e;
3732 827df9f3 balrog
        break;
3733 827df9f3 balrog
3734 827df9f3 balrog
    case 0x030 ... 0x140:        /* CONTROL_PADCONF - only used in the POP */
3735 827df9f3 balrog
        /* XXX: should check constant bits */
3736 8da3ff18 pbrook
        s->padconf[(addr - 0x30) >> 2] = value & 0x1f1f1f1f;
3737 827df9f3 balrog
        break;
3738 827df9f3 balrog
3739 827df9f3 balrog
    case 0x270:        /* CONTROL_DEBOBS */
3740 827df9f3 balrog
        s->obs = value & 0xff;
3741 827df9f3 balrog
        break;
3742 827df9f3 balrog
3743 827df9f3 balrog
    case 0x274:        /* CONTROL_DEVCONF */
3744 827df9f3 balrog
        s->devconfig = value & 0xffffc7ff;
3745 827df9f3 balrog
        break;
3746 827df9f3 balrog
3747 827df9f3 balrog
    case 0x28c:        /* CONTROL_EMU_SUPPORT */
3748 827df9f3 balrog
        break;
3749 827df9f3 balrog
3750 827df9f3 balrog
    case 0x290:        /* CONTROL_MSUSPENDMUX_0 */
3751 827df9f3 balrog
        s->msuspendmux[0] = value & 0x3fffffff;
3752 827df9f3 balrog
        break;
3753 827df9f3 balrog
    case 0x294:        /* CONTROL_MSUSPENDMUX_1 */
3754 827df9f3 balrog
        s->msuspendmux[1] = value & 0x3fffffff;
3755 827df9f3 balrog
        break;
3756 827df9f3 balrog
    case 0x298:        /* CONTROL_MSUSPENDMUX_2 */
3757 827df9f3 balrog
        s->msuspendmux[2] = value & 0x3fffffff;
3758 827df9f3 balrog
        break;
3759 827df9f3 balrog
    case 0x29c:        /* CONTROL_MSUSPENDMUX_3 */
3760 827df9f3 balrog
        s->msuspendmux[3] = value & 0x3fffffff;
3761 827df9f3 balrog
        break;
3762 827df9f3 balrog
    case 0x2a0:        /* CONTROL_MSUSPENDMUX_4 */
3763 827df9f3 balrog
        s->msuspendmux[4] = value & 0x3fffffff;
3764 827df9f3 balrog
        break;
3765 827df9f3 balrog
3766 827df9f3 balrog
    case 0x2b8:        /* CONTROL_PSA_CTRL */
3767 827df9f3 balrog
        s->psaconfig = value & 0x1c;
3768 827df9f3 balrog
        s->psaconfig |= (value & 0x20) ? 2 : 1;
3769 827df9f3 balrog
        break;
3770 827df9f3 balrog
    case 0x2bc:        /* CONTROL_PSA_CMD */
3771 827df9f3 balrog
        break;
3772 827df9f3 balrog
3773 827df9f3 balrog
    case 0x2b0:        /* CONTROL_SEC_CTRL */
3774 827df9f3 balrog
    case 0x2b4:        /* CONTROL_SEC_TEST */
3775 827df9f3 balrog
    case 0x2d0:        /* CONTROL_SEC_EMU */
3776 827df9f3 balrog
    case 0x2d4:        /* CONTROL_SEC_TAP */
3777 827df9f3 balrog
    case 0x2d8:        /* CONTROL_OCM_RAM_PERM */
3778 827df9f3 balrog
    case 0x2dc:        /* CONTROL_OCM_PUB_RAM_ADD */
3779 827df9f3 balrog
    case 0x2e0:        /* CONTROL_EXT_SEC_RAM_START_ADD */
3780 827df9f3 balrog
    case 0x2e4:        /* CONTROL_EXT_SEC_RAM_STOP_ADD */
3781 827df9f3 balrog
    case 0x2f0:        /* CONTROL_SEC_STATUS */
3782 827df9f3 balrog
    case 0x2f4:        /* CONTROL_SEC_ERR_STATUS */
3783 827df9f3 balrog
        break;
3784 827df9f3 balrog
3785 827df9f3 balrog
    default:
3786 827df9f3 balrog
        OMAP_BAD_REG(addr);
3787 827df9f3 balrog
        return;
3788 827df9f3 balrog
    }
3789 827df9f3 balrog
}
3790 827df9f3 balrog
3791 827df9f3 balrog
static CPUReadMemoryFunc *omap_sysctl_readfn[] = {
3792 f451387a balrog
    omap_sysctl_read8,
3793 827df9f3 balrog
    omap_badwidth_read32,        /* TODO */
3794 827df9f3 balrog
    omap_sysctl_read,
3795 827df9f3 balrog
};
3796 827df9f3 balrog
3797 827df9f3 balrog
static CPUWriteMemoryFunc *omap_sysctl_writefn[] = {
3798 f451387a balrog
    omap_sysctl_write8,
3799 827df9f3 balrog
    omap_badwidth_write32,        /* TODO */
3800 827df9f3 balrog
    omap_sysctl_write,
3801 827df9f3 balrog
};
3802 827df9f3 balrog
3803 827df9f3 balrog
static void omap_sysctl_reset(struct omap_sysctl_s *s)
3804 827df9f3 balrog
{
3805 827df9f3 balrog
    /* (power-on reset) */
3806 827df9f3 balrog
    s->sysconfig = 0;
3807 827df9f3 balrog
    s->obs = 0;
3808 827df9f3 balrog
    s->devconfig = 0x0c000000;
3809 827df9f3 balrog
    s->msuspendmux[0] = 0x00000000;
3810 827df9f3 balrog
    s->msuspendmux[1] = 0x00000000;
3811 827df9f3 balrog
    s->msuspendmux[2] = 0x00000000;
3812 827df9f3 balrog
    s->msuspendmux[3] = 0x00000000;
3813 827df9f3 balrog
    s->msuspendmux[4] = 0x00000000;
3814 827df9f3 balrog
    s->psaconfig = 1;
3815 827df9f3 balrog
3816 827df9f3 balrog
    s->padconf[0x00] = 0x000f0f0f;
3817 827df9f3 balrog
    s->padconf[0x01] = 0x00000000;
3818 827df9f3 balrog
    s->padconf[0x02] = 0x00000000;
3819 827df9f3 balrog
    s->padconf[0x03] = 0x00000000;
3820 827df9f3 balrog
    s->padconf[0x04] = 0x00000000;
3821 827df9f3 balrog
    s->padconf[0x05] = 0x00000000;
3822 827df9f3 balrog
    s->padconf[0x06] = 0x00000000;
3823 827df9f3 balrog
    s->padconf[0x07] = 0x00000000;
3824 827df9f3 balrog
    s->padconf[0x08] = 0x08080800;
3825 827df9f3 balrog
    s->padconf[0x09] = 0x08080808;
3826 827df9f3 balrog
    s->padconf[0x0a] = 0x08080808;
3827 827df9f3 balrog
    s->padconf[0x0b] = 0x08080808;
3828 827df9f3 balrog
    s->padconf[0x0c] = 0x08080808;
3829 827df9f3 balrog
    s->padconf[0x0d] = 0x08080800;
3830 827df9f3 balrog
    s->padconf[0x0e] = 0x08080808;
3831 827df9f3 balrog
    s->padconf[0x0f] = 0x08080808;
3832 827df9f3 balrog
    s->padconf[0x10] = 0x18181808;        /* | 0x07070700 if SBoot3 */
3833 827df9f3 balrog
    s->padconf[0x11] = 0x18181818;        /* | 0x07070707 if SBoot3 */
3834 827df9f3 balrog
    s->padconf[0x12] = 0x18181818;        /* | 0x07070707 if SBoot3 */
3835 827df9f3 balrog
    s->padconf[0x13] = 0x18181818;        /* | 0x07070707 if SBoot3 */
3836 827df9f3 balrog
    s->padconf[0x14] = 0x18181818;        /* | 0x00070707 if SBoot3 */
3837 827df9f3 balrog
    s->padconf[0x15] = 0x18181818;
3838 827df9f3 balrog
    s->padconf[0x16] = 0x18181818;        /* | 0x07000000 if SBoot3 */
3839 827df9f3 balrog
    s->padconf[0x17] = 0x1f001f00;
3840 827df9f3 balrog
    s->padconf[0x18] = 0x1f1f1f1f;
3841 827df9f3 balrog
    s->padconf[0x19] = 0x00000000;
3842 827df9f3 balrog
    s->padconf[0x1a] = 0x1f180000;
3843 827df9f3 balrog
    s->padconf[0x1b] = 0x00001f1f;
3844 827df9f3 balrog
    s->padconf[0x1c] = 0x1f001f00;
3845 827df9f3 balrog
    s->padconf[0x1d] = 0x00000000;
3846 827df9f3 balrog
    s->padconf[0x1e] = 0x00000000;
3847 827df9f3 balrog
    s->padconf[0x1f] = 0x08000000;
3848 827df9f3 balrog
    s->padconf[0x20] = 0x08080808;
3849 827df9f3 balrog
    s->padconf[0x21] = 0x08080808;
3850 827df9f3 balrog
    s->padconf[0x22] = 0x0f080808;
3851 827df9f3 balrog
    s->padconf[0x23] = 0x0f0f0f0f;
3852 827df9f3 balrog
    s->padconf[0x24] = 0x000f0f0f;
3853 827df9f3 balrog
    s->padconf[0x25] = 0x1f1f1f0f;
3854 827df9f3 balrog
    s->padconf[0x26] = 0x080f0f1f;
3855 827df9f3 balrog
    s->padconf[0x27] = 0x070f1808;
3856 827df9f3 balrog
    s->padconf[0x28] = 0x0f070707;
3857 827df9f3 balrog
    s->padconf[0x29] = 0x000f0f1f;
3858 827df9f3 balrog
    s->padconf[0x2a] = 0x0f0f0f1f;
3859 827df9f3 balrog
    s->padconf[0x2b] = 0x08000000;
3860 827df9f3 balrog
    s->padconf[0x2c] = 0x0000001f;
3861 827df9f3 balrog
    s->padconf[0x2d] = 0x0f0f1f00;
3862 827df9f3 balrog
    s->padconf[0x2e] = 0x1f1f0f0f;
3863 827df9f3 balrog
    s->padconf[0x2f] = 0x0f1f1f1f;
3864 827df9f3 balrog
    s->padconf[0x30] = 0x0f0f0f0f;
3865 827df9f3 balrog
    s->padconf[0x31] = 0x0f1f0f1f;
3866 827df9f3 balrog
    s->padconf[0x32] = 0x0f0f0f0f;
3867 827df9f3 balrog
    s->padconf[0x33] = 0x0f1f0f1f;
3868 827df9f3 balrog
    s->padconf[0x34] = 0x1f1f0f0f;
3869 827df9f3 balrog
    s->padconf[0x35] = 0x0f0f1f1f;
3870 827df9f3 balrog
    s->padconf[0x36] = 0x0f0f1f0f;
3871 827df9f3 balrog
    s->padconf[0x37] = 0x0f0f0f0f;
3872 827df9f3 balrog
    s->padconf[0x38] = 0x1f18180f;
3873 827df9f3 balrog
    s->padconf[0x39] = 0x1f1f1f1f;
3874 827df9f3 balrog
    s->padconf[0x3a] = 0x00001f1f;
3875 827df9f3 balrog
    s->padconf[0x3b] = 0x00000000;
3876 827df9f3 balrog
    s->padconf[0x3c] = 0x00000000;
3877 827df9f3 balrog
    s->padconf[0x3d] = 0x0f0f0f0f;
3878 827df9f3 balrog
    s->padconf[0x3e] = 0x18000f0f;
3879 827df9f3 balrog
    s->padconf[0x3f] = 0x00070000;
3880 827df9f3 balrog
    s->padconf[0x40] = 0x00000707;
3881 827df9f3 balrog
    s->padconf[0x41] = 0x0f1f0700;
3882 827df9f3 balrog
    s->padconf[0x42] = 0x1f1f070f;
3883 827df9f3 balrog
    s->padconf[0x43] = 0x0008081f;
3884 827df9f3 balrog
    s->padconf[0x44] = 0x00000800;
3885 827df9f3 balrog
}
3886 827df9f3 balrog
3887 827df9f3 balrog
struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
3888 827df9f3 balrog
                omap_clk iclk, struct omap_mpu_state_s *mpu)
3889 827df9f3 balrog
{
3890 827df9f3 balrog
    int iomemtype;
3891 827df9f3 balrog
    struct omap_sysctl_s *s = (struct omap_sysctl_s *)
3892 827df9f3 balrog
            qemu_mallocz(sizeof(struct omap_sysctl_s));
3893 827df9f3 balrog
3894 827df9f3 balrog
    s->mpu = mpu;
3895 827df9f3 balrog
    omap_sysctl_reset(s);
3896 827df9f3 balrog
3897 c66fb5bc balrog
    iomemtype = l4_register_io_memory(0, omap_sysctl_readfn,
3898 827df9f3 balrog
                    omap_sysctl_writefn, s);
3899 8da3ff18 pbrook
    omap_l4_attach(ta, 0, iomemtype);
3900 827df9f3 balrog
3901 827df9f3 balrog
    return s;
3902 827df9f3 balrog
}
3903 827df9f3 balrog
3904 827df9f3 balrog
/* SDRAM Controller Subsystem */
3905 827df9f3 balrog
struct omap_sdrc_s {
3906 827df9f3 balrog
    uint8_t config;
3907 827df9f3 balrog
};
3908 827df9f3 balrog
3909 827df9f3 balrog
static void omap_sdrc_reset(struct omap_sdrc_s *s)
3910 827df9f3 balrog
{
3911 827df9f3 balrog
    s->config = 0x10;
3912 827df9f3 balrog
}
3913 827df9f3 balrog
3914 827df9f3 balrog
static uint32_t omap_sdrc_read(void *opaque, target_phys_addr_t addr)
3915 827df9f3 balrog
{
3916 827df9f3 balrog
    struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
3917 827df9f3 balrog
3918 8da3ff18 pbrook
    switch (addr) {
3919 827df9f3 balrog
    case 0x00:        /* SDRC_REVISION */
3920 827df9f3 balrog
        return 0x20;
3921 827df9f3 balrog
3922 827df9f3 balrog
    case 0x10:        /* SDRC_SYSCONFIG */
3923 827df9f3 balrog
        return s->config;
3924 827df9f3 balrog
3925 827df9f3 balrog
    case 0x14:        /* SDRC_SYSSTATUS */
3926 827df9f3 balrog
        return 1;                                                /* RESETDONE */
3927 827df9f3 balrog
3928 827df9f3 balrog
    case 0x40:        /* SDRC_CS_CFG */
3929 827df9f3 balrog
    case 0x44:        /* SDRC_SHARING */
3930 827df9f3 balrog
    case 0x48:        /* SDRC_ERR_ADDR */
3931 827df9f3 balrog
    case 0x4c:        /* SDRC_ERR_TYPE */
3932 827df9f3 balrog
    case 0x60:        /* SDRC_DLLA_SCTRL */
3933 827df9f3 balrog
    case 0x64:        /* SDRC_DLLA_STATUS */
3934 827df9f3 balrog
    case 0x68:        /* SDRC_DLLB_CTRL */
3935 827df9f3 balrog
    case 0x6c:        /* SDRC_DLLB_STATUS */
3936 827df9f3 balrog
    case 0x70:        /* SDRC_POWER */
3937 827df9f3 balrog
    case 0x80:        /* SDRC_MCFG_0 */
3938 827df9f3 balrog
    case 0x84:        /* SDRC_MR_0 */
3939 827df9f3 balrog
    case 0x88:        /* SDRC_EMR1_0 */
3940 827df9f3 balrog
    case 0x8c:        /* SDRC_EMR2_0 */
3941 827df9f3 balrog
    case 0x90:        /* SDRC_EMR3_0 */
3942 827df9f3 balrog
    case 0x94:        /* SDRC_DCDL1_CTRL */
3943 827df9f3 balrog
    case 0x98:        /* SDRC_DCDL2_CTRL */
3944 827df9f3 balrog
    case 0x9c:        /* SDRC_ACTIM_CTRLA_0 */
3945 827df9f3 balrog
    case 0xa0:        /* SDRC_ACTIM_CTRLB_0 */
3946 827df9f3 balrog
    case 0xa4:        /* SDRC_RFR_CTRL_0 */
3947 827df9f3 balrog
    case 0xa8:        /* SDRC_MANUAL_0 */
3948 827df9f3 balrog
    case 0xb0:        /* SDRC_MCFG_1 */
3949 827df9f3 balrog
    case 0xb4:        /* SDRC_MR_1 */
3950 827df9f3 balrog
    case 0xb8:        /* SDRC_EMR1_1 */
3951 827df9f3 balrog
    case 0xbc:        /* SDRC_EMR2_1 */
3952 827df9f3 balrog
    case 0xc0:        /* SDRC_EMR3_1 */
3953 827df9f3 balrog
    case 0xc4:        /* SDRC_ACTIM_CTRLA_1 */
3954 827df9f3 balrog
    case 0xc8:        /* SDRC_ACTIM_CTRLB_1 */
3955 827df9f3 balrog
    case 0xd4:        /* SDRC_RFR_CTRL_1 */
3956 827df9f3 balrog
    case 0xd8:        /* SDRC_MANUAL_1 */
3957 827df9f3 balrog
        return 0x00;
3958 827df9f3 balrog
    }
3959 827df9f3 balrog
3960 827df9f3 balrog
    OMAP_BAD_REG(addr);
3961 827df9f3 balrog
    return 0;
3962 827df9f3 balrog
}
3963 827df9f3 balrog
3964 827df9f3 balrog
static void omap_sdrc_write(void *opaque, target_phys_addr_t addr,
3965 827df9f3 balrog
                uint32_t value)
3966 827df9f3 balrog
{
3967 827df9f3 balrog
    struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
3968 827df9f3 balrog
3969 8da3ff18 pbrook
    switch (addr) {
3970 827df9f3 balrog
    case 0x00:        /* SDRC_REVISION */
3971 827df9f3 balrog
    case 0x14:        /* SDRC_SYSSTATUS */
3972 827df9f3 balrog
    case 0x48:        /* SDRC_ERR_ADDR */
3973 827df9f3 balrog
    case 0x64:        /* SDRC_DLLA_STATUS */
3974 827df9f3 balrog
    case 0x6c:        /* SDRC_DLLB_STATUS */
3975 827df9f3 balrog
        OMAP_RO_REG(addr);
3976 827df9f3 balrog
        return;
3977 827df9f3 balrog
3978 827df9f3 balrog
    case 0x10:        /* SDRC_SYSCONFIG */
3979 827df9f3 balrog
        if ((value >> 3) != 0x2)
3980 827df9f3 balrog
            fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
3981 827df9f3 balrog
                            __FUNCTION__, value >> 3);
3982 827df9f3 balrog
        if (value & 2)
3983 827df9f3 balrog
            omap_sdrc_reset(s);
3984 827df9f3 balrog
        s->config = value & 0x18;
3985 827df9f3 balrog
        break;
3986 827df9f3 balrog
3987 827df9f3 balrog
    case 0x40:        /* SDRC_CS_CFG */
3988 827df9f3 balrog
    case 0x44:        /* SDRC_SHARING */
3989 827df9f3 balrog
    case 0x4c:        /* SDRC_ERR_TYPE */
3990 827df9f3 balrog
    case 0x60:        /* SDRC_DLLA_SCTRL */
3991 827df9f3 balrog
    case 0x68:        /* SDRC_DLLB_CTRL */
3992 827df9f3 balrog
    case 0x70:        /* SDRC_POWER */
3993 827df9f3 balrog
    case 0x80:        /* SDRC_MCFG_0 */
3994 827df9f3 balrog
    case 0x84:        /* SDRC_MR_0 */
3995 827df9f3 balrog
    case 0x88:        /* SDRC_EMR1_0 */
3996 827df9f3 balrog
    case 0x8c:        /* SDRC_EMR2_0 */
3997 827df9f3 balrog
    case 0x90:        /* SDRC_EMR3_0 */
3998 827df9f3 balrog
    case 0x94:        /* SDRC_DCDL1_CTRL */
3999 827df9f3 balrog
    case 0x98:        /* SDRC_DCDL2_CTRL */
4000 827df9f3 balrog
    case 0x9c:        /* SDRC_ACTIM_CTRLA_0 */
4001 827df9f3 balrog
    case 0xa0:        /* SDRC_ACTIM_CTRLB_0 */
4002 827df9f3 balrog
    case 0xa4:        /* SDRC_RFR_CTRL_0 */
4003 827df9f3 balrog
    case 0xa8:        /* SDRC_MANUAL_0 */
4004 827df9f3 balrog
    case 0xb0:        /* SDRC_MCFG_1 */
4005 827df9f3 balrog
    case 0xb4:        /* SDRC_MR_1 */
4006 827df9f3 balrog
    case 0xb8:        /* SDRC_EMR1_1 */
4007 827df9f3 balrog
    case 0xbc:        /* SDRC_EMR2_1 */
4008 827df9f3 balrog
    case 0xc0:        /* SDRC_EMR3_1 */
4009 827df9f3 balrog
    case 0xc4:        /* SDRC_ACTIM_CTRLA_1 */
4010 827df9f3 balrog
    case 0xc8:        /* SDRC_ACTIM_CTRLB_1 */
4011 827df9f3 balrog
    case 0xd4:        /* SDRC_RFR_CTRL_1 */
4012 827df9f3 balrog
    case 0xd8:        /* SDRC_MANUAL_1 */
4013 827df9f3 balrog
        break;
4014 827df9f3 balrog
4015 827df9f3 balrog
    default:
4016 827df9f3 balrog
        OMAP_BAD_REG(addr);
4017 827df9f3 balrog
        return;
4018 827df9f3 balrog
    }
4019 827df9f3 balrog
}
4020 827df9f3 balrog
4021 827df9f3 balrog
static CPUReadMemoryFunc *omap_sdrc_readfn[] = {
4022 827df9f3 balrog
    omap_badwidth_read32,
4023 827df9f3 balrog
    omap_badwidth_read32,
4024 827df9f3 balrog
    omap_sdrc_read,
4025 827df9f3 balrog
};
4026 827df9f3 balrog
4027 827df9f3 balrog
static CPUWriteMemoryFunc *omap_sdrc_writefn[] = {
4028 827df9f3 balrog
    omap_badwidth_write32,
4029 827df9f3 balrog
    omap_badwidth_write32,
4030 827df9f3 balrog
    omap_sdrc_write,
4031 827df9f3 balrog
};
4032 827df9f3 balrog
4033 827df9f3 balrog
struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base)
4034 827df9f3 balrog
{
4035 827df9f3 balrog
    int iomemtype;
4036 827df9f3 balrog
    struct omap_sdrc_s *s = (struct omap_sdrc_s *)
4037 827df9f3 balrog
            qemu_mallocz(sizeof(struct omap_sdrc_s));
4038 827df9f3 balrog
4039 827df9f3 balrog
    omap_sdrc_reset(s);
4040 827df9f3 balrog
4041 827df9f3 balrog
    iomemtype = cpu_register_io_memory(0, omap_sdrc_readfn,
4042 827df9f3 balrog
                    omap_sdrc_writefn, s);
4043 8da3ff18 pbrook
    cpu_register_physical_memory(base, 0x1000, iomemtype);
4044 827df9f3 balrog
4045 827df9f3 balrog
    return s;
4046 827df9f3 balrog
}
4047 827df9f3 balrog
4048 827df9f3 balrog
/* General-Purpose Memory Controller */
4049 827df9f3 balrog
struct omap_gpmc_s {
4050 827df9f3 balrog
    qemu_irq irq;
4051 827df9f3 balrog
4052 827df9f3 balrog
    uint8_t sysconfig;
4053 827df9f3 balrog
    uint16_t irqst;
4054 827df9f3 balrog
    uint16_t irqen;
4055 827df9f3 balrog
    uint16_t timeout;
4056 827df9f3 balrog
    uint16_t config;
4057 827df9f3 balrog
    uint32_t prefconfig[2];
4058 827df9f3 balrog
    int prefcontrol;
4059 827df9f3 balrog
    int preffifo;
4060 827df9f3 balrog
    int prefcount;
4061 827df9f3 balrog
    struct omap_gpmc_cs_file_s {
4062 827df9f3 balrog
        uint32_t config[7];
4063 827df9f3 balrog
        target_phys_addr_t base;
4064 827df9f3 balrog
        size_t size;
4065 827df9f3 balrog
        int iomemtype;
4066 827df9f3 balrog
        void (*base_update)(void *opaque, target_phys_addr_t new);
4067 827df9f3 balrog
        void (*unmap)(void *opaque);
4068 827df9f3 balrog
        void *opaque;
4069 827df9f3 balrog
    } cs_file[8];
4070 827df9f3 balrog
    int ecc_cs;
4071 827df9f3 balrog
    int ecc_ptr;
4072 827df9f3 balrog
    uint32_t ecc_cfg;
4073 827df9f3 balrog
    struct ecc_state_s ecc[9];
4074 827df9f3 balrog
};
4075 827df9f3 balrog
4076 827df9f3 balrog
static void omap_gpmc_int_update(struct omap_gpmc_s *s)
4077 827df9f3 balrog
{
4078 827df9f3 balrog
    qemu_set_irq(s->irq, s->irqen & s->irqst);
4079 827df9f3 balrog
}
4080 827df9f3 balrog
4081 827df9f3 balrog
static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
4082 827df9f3 balrog
{
4083 827df9f3 balrog
    /* TODO: check for overlapping regions and report access errors */
4084 827df9f3 balrog
    if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
4085 827df9f3 balrog
                    (base < 0 || base >= 0x40) ||
4086 827df9f3 balrog
                    (base & 0x0f & ~mask)) {
4087 827df9f3 balrog
        fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
4088 827df9f3 balrog
                        __FUNCTION__);
4089 827df9f3 balrog
        return;
4090 827df9f3 balrog
    }
4091 827df9f3 balrog
4092 827df9f3 balrog
    if (!f->opaque)
4093 827df9f3 balrog
        return;
4094 827df9f3 balrog
4095 827df9f3 balrog
    f->base = base << 24;
4096 827df9f3 balrog
    f->size = (0x0fffffff & ~(mask << 24)) + 1;
4097 827df9f3 balrog
    /* TODO: rather than setting the size of the mapping (which should be
4098 827df9f3 balrog
     * constant), the mask should cause wrapping of the address space, so
4099 827df9f3 balrog
     * that the same memory becomes accessible at every <i>size</i> bytes
4100 827df9f3 balrog
     * starting from <i>base</i>.  */
4101 827df9f3 balrog
    if (f->iomemtype)
4102 827df9f3 balrog
        cpu_register_physical_memory(f->base, f->size, f->iomemtype);
4103 827df9f3 balrog
4104 827df9f3 balrog
    if (f->base_update)
4105 827df9f3 balrog
        f->base_update(f->opaque, f->base);
4106 827df9f3 balrog
}
4107 827df9f3 balrog
4108 827df9f3 balrog
static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
4109 827df9f3 balrog
{
4110 827df9f3 balrog
    if (f->size) {
4111 827df9f3 balrog
        if (f->unmap)
4112 827df9f3 balrog
            f->unmap(f->opaque);
4113 827df9f3 balrog
        if (f->iomemtype)
4114 827df9f3 balrog
            cpu_register_physical_memory(f->base, f->size, IO_MEM_UNASSIGNED);
4115 827df9f3 balrog
        f->base = 0;
4116 827df9f3 balrog
        f->size = 0;
4117 827df9f3 balrog
    }
4118 827df9f3 balrog
}
4119 827df9f3 balrog
4120 827df9f3 balrog
static void omap_gpmc_reset(struct omap_gpmc_s *s)
4121 827df9f3 balrog
{
4122 827df9f3 balrog
    int i;
4123 827df9f3 balrog
4124 827df9f3 balrog
    s->sysconfig = 0;
4125 827df9f3 balrog
    s->irqst = 0;
4126 827df9f3 balrog
    s->irqen = 0;
4127 827df9f3 balrog
    omap_gpmc_int_update(s);
4128 827df9f3 balrog
    s->timeout = 0;
4129 827df9f3 balrog
    s->config = 0xa00;
4130 827df9f3 balrog
    s->prefconfig[0] = 0x00004000;
4131 827df9f3 balrog
    s->prefconfig[1] = 0x00000000;
4132 827df9f3 balrog
    s->prefcontrol = 0;
4133 827df9f3 balrog
    s->preffifo = 0;
4134 827df9f3 balrog
    s->prefcount = 0;
4135 827df9f3 balrog
    for (i = 0; i < 8; i ++) {
4136 827df9f3 balrog
        if (s->cs_file[i].config[6] & (1 << 6))                        /* CSVALID */
4137 827df9f3 balrog
            omap_gpmc_cs_unmap(s->cs_file + i);
4138 827df9f3 balrog
        s->cs_file[i].config[0] = i ? 1 << 12 : 0;
4139 827df9f3 balrog
        s->cs_file[i].config[1] = 0x101001;
4140 827df9f3 balrog
        s->cs_file[i].config[2] = 0x020201;
4141 827df9f3 balrog
        s->cs_file[i].config[3] = 0x10031003;
4142 827df9f3 balrog
        s->cs_file[i].config[4] = 0x10f1111;
4143 827df9f3 balrog
        s->cs_file[i].config[5] = 0;
4144 827df9f3 balrog
        s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
4145 827df9f3 balrog
        if (s->cs_file[i].config[6] & (1 << 6))                        /* CSVALID */
4146 827df9f3 balrog
            omap_gpmc_cs_map(&s->cs_file[i],
4147 827df9f3 balrog
                            s->cs_file[i].config[6] & 0x1f,        /* MASKADDR */
4148 827df9f3 balrog
                        (s->cs_file[i].config[6] >> 8 & 0xf));        /* BASEADDR */
4149 827df9f3 balrog
    }
4150 827df9f3 balrog
    omap_gpmc_cs_map(s->cs_file, 0, 0xf);
4151 827df9f3 balrog
    s->ecc_cs = 0;
4152 827df9f3 balrog
    s->ecc_ptr = 0;
4153 827df9f3 balrog
    s->ecc_cfg = 0x3fcff000;
4154 827df9f3 balrog
    for (i = 0; i < 9; i ++)
4155 827df9f3 balrog
        ecc_reset(&s->ecc[i]);
4156 827df9f3 balrog
}
4157 827df9f3 balrog
4158 827df9f3 balrog
static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr)
4159 827df9f3 balrog
{
4160 827df9f3 balrog
    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
4161 827df9f3 balrog
    int cs;
4162 827df9f3 balrog
    struct omap_gpmc_cs_file_s *f;
4163 827df9f3 balrog
4164 8da3ff18 pbrook
    switch (addr) {
4165 827df9f3 balrog
    case 0x000:        /* GPMC_REVISION */
4166 827df9f3 balrog
        return 0x20;
4167 827df9f3 balrog
4168 827df9f3 balrog
    case 0x010:        /* GPMC_SYSCONFIG */
4169 827df9f3 balrog
        return s->sysconfig;
4170 827df9f3 balrog
4171 827df9f3 balrog
    case 0x014:        /* GPMC_SYSSTATUS */
4172 827df9f3 balrog
        return 1;                                                /* RESETDONE */
4173 827df9f3 balrog
4174 827df9f3 balrog
    case 0x018:        /* GPMC_IRQSTATUS */
4175 827df9f3 balrog
        return s->irqst;
4176 827df9f3 balrog
4177 827df9f3 balrog
    case 0x01c:        /* GPMC_IRQENABLE */
4178 827df9f3 balrog
        return s->irqen;
4179 827df9f3 balrog
4180 827df9f3 balrog
    case 0x040:        /* GPMC_TIMEOUT_CONTROL */
4181 827df9f3 balrog
        return s->timeout;
4182 827df9f3 balrog
4183 827df9f3 balrog
    case 0x044:        /* GPMC_ERR_ADDRESS */
4184 827df9f3 balrog
    case 0x048:        /* GPMC_ERR_TYPE */
4185 827df9f3 balrog
        return 0;
4186 827df9f3 balrog
4187 827df9f3 balrog
    case 0x050:        /* GPMC_CONFIG */
4188 827df9f3 balrog
        return s->config;
4189 827df9f3 balrog
4190 827df9f3 balrog
    case 0x054:        /* GPMC_STATUS */
4191 827df9f3 balrog
        return 0x001;
4192 827df9f3 balrog
4193 827df9f3 balrog
    case 0x060 ... 0x1d4:
4194 8da3ff18 pbrook
        cs = (addr - 0x060) / 0x30;
4195 8da3ff18 pbrook
        addr -= cs * 0x30;
4196 827df9f3 balrog
        f = s->cs_file + cs;
4197 8da3ff18 pbrook
        switch (addr) {
4198 827df9f3 balrog
            case 0x60:        /* GPMC_CONFIG1 */
4199 827df9f3 balrog
                return f->config[0];
4200 827df9f3 balrog
            case 0x64:        /* GPMC_CONFIG2 */
4201 827df9f3 balrog
                return f->config[1];
4202 827df9f3 balrog
            case 0x68:        /* GPMC_CONFIG3 */
4203 827df9f3 balrog
                return f->config[2];
4204 827df9f3 balrog
            case 0x6c:        /* GPMC_CONFIG4 */
4205 827df9f3 balrog
                return f->config[3];
4206 827df9f3 balrog
            case 0x70:        /* GPMC_CONFIG5 */
4207 827df9f3 balrog
                return f->config[4];
4208 827df9f3 balrog
            case 0x74:        /* GPMC_CONFIG6 */
4209 827df9f3 balrog
                return f->config[5];
4210 827df9f3 balrog
            case 0x78:        /* GPMC_CONFIG7 */
4211 827df9f3 balrog
                return f->config[6];
4212 827df9f3 balrog
            case 0x84:        /* GPMC_NAND_DATA */
4213 827df9f3 balrog
                return 0;
4214 827df9f3 balrog
        }
4215 827df9f3 balrog
        break;
4216 827df9f3 balrog
4217 827df9f3 balrog
    case 0x1e0:        /* GPMC_PREFETCH_CONFIG1 */
4218 827df9f3 balrog
        return s->prefconfig[0];
4219 827df9f3 balrog
    case 0x1e4:        /* GPMC_PREFETCH_CONFIG2 */
4220 827df9f3 balrog
        return s->prefconfig[1];
4221 827df9f3 balrog
    case 0x1ec:        /* GPMC_PREFETCH_CONTROL */
4222 827df9f3 balrog
        return s->prefcontrol;
4223 827df9f3 balrog
    case 0x1f0:        /* GPMC_PREFETCH_STATUS */
4224 827df9f3 balrog
        return (s->preffifo << 24) |
4225 827df9f3 balrog
                ((s->preffifo >
4226 827df9f3 balrog
                  ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) |
4227 827df9f3 balrog
                s->prefcount;
4228 827df9f3 balrog
4229 827df9f3 balrog
    case 0x1f4:        /* GPMC_ECC_CONFIG */
4230 827df9f3 balrog
        return s->ecc_cs;
4231 827df9f3 balrog
    case 0x1f8:        /* GPMC_ECC_CONTROL */
4232 827df9f3 balrog
        return s->ecc_ptr;
4233 827df9f3 balrog
    case 0x1fc:        /* GPMC_ECC_SIZE_CONFIG */
4234 827df9f3 balrog
        return s->ecc_cfg;
4235 827df9f3 balrog
    case 0x200 ... 0x220:        /* GPMC_ECC_RESULT */
4236 8da3ff18 pbrook
        cs = (addr & 0x1f) >> 2;
4237 827df9f3 balrog
        /* TODO: check correctness */
4238 827df9f3 balrog
        return
4239 827df9f3 balrog
                ((s->ecc[cs].cp    &  0x07) <<  0) |
4240 827df9f3 balrog
                ((s->ecc[cs].cp    &  0x38) << 13) |
4241 827df9f3 balrog
                ((s->ecc[cs].lp[0] & 0x1ff) <<  3) |
4242 827df9f3 balrog
                ((s->ecc[cs].lp[1] & 0x1ff) << 19);
4243 827df9f3 balrog
4244 827df9f3 balrog
    case 0x230:        /* GPMC_TESTMODE_CTRL */
4245 827df9f3 balrog
        return 0;
4246 827df9f3 balrog
    case 0x234:        /* GPMC_PSA_LSB */
4247 827df9f3 balrog
    case 0x238:        /* GPMC_PSA_MSB */
4248 827df9f3 balrog
        return 0x00000000;
4249 827df9f3 balrog
    }
4250 827df9f3 balrog
4251 827df9f3 balrog
    OMAP_BAD_REG(addr);
4252 827df9f3 balrog
    return 0;
4253 827df9f3 balrog
}
4254 827df9f3 balrog
4255 827df9f3 balrog
static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
4256 827df9f3 balrog
                uint32_t value)
4257 827df9f3 balrog
{
4258 827df9f3 balrog
    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
4259 827df9f3 balrog
    int cs;
4260 827df9f3 balrog
    struct omap_gpmc_cs_file_s *f;
4261 827df9f3 balrog
4262 8da3ff18 pbrook
    switch (addr) {
4263 827df9f3 balrog
    case 0x000:        /* GPMC_REVISION */
4264 827df9f3 balrog
    case 0x014:        /* GPMC_SYSSTATUS */
4265 827df9f3 balrog
    case 0x054:        /* GPMC_STATUS */
4266 827df9f3 balrog
    case 0x1f0:        /* GPMC_PREFETCH_STATUS */
4267 827df9f3 balrog
    case 0x200 ... 0x220:        /* GPMC_ECC_RESULT */
4268 827df9f3 balrog
    case 0x234:        /* GPMC_PSA_LSB */
4269 827df9f3 balrog
    case 0x238:        /* GPMC_PSA_MSB */
4270 827df9f3 balrog
        OMAP_RO_REG(addr);
4271 827df9f3 balrog
        break;
4272 827df9f3 balrog
4273 827df9f3 balrog
    case 0x010:        /* GPMC_SYSCONFIG */
4274 827df9f3 balrog
        if ((value >> 3) == 0x3)
4275 827df9f3 balrog
            fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
4276 827df9f3 balrog
                            __FUNCTION__, value >> 3);
4277 827df9f3 balrog
        if (value & 2)
4278 827df9f3 balrog
            omap_gpmc_reset(s);
4279 827df9f3 balrog
        s->sysconfig = value & 0x19;
4280 827df9f3 balrog
        break;
4281 827df9f3 balrog
4282 827df9f3 balrog
    case 0x018:        /* GPMC_IRQSTATUS */
4283 827df9f3 balrog
        s->irqen = ~value;
4284 827df9f3 balrog
        omap_gpmc_int_update(s);
4285 827df9f3 balrog
        break;
4286 827df9f3 balrog
4287 827df9f3 balrog
    case 0x01c:        /* GPMC_IRQENABLE */
4288 827df9f3 balrog
        s->irqen = value & 0xf03;
4289 827df9f3 balrog
        omap_gpmc_int_update(s);
4290 827df9f3 balrog
        break;
4291 827df9f3 balrog
4292 827df9f3 balrog
    case 0x040:        /* GPMC_TIMEOUT_CONTROL */
4293 827df9f3 balrog
        s->timeout = value & 0x1ff1;
4294 827df9f3 balrog
        break;
4295 827df9f3 balrog
4296 827df9f3 balrog
    case 0x044:        /* GPMC_ERR_ADDRESS */
4297 827df9f3 balrog
    case 0x048:        /* GPMC_ERR_TYPE */
4298 827df9f3 balrog
        break;
4299 827df9f3 balrog
4300 827df9f3 balrog
    case 0x050:        /* GPMC_CONFIG */
4301 827df9f3 balrog
        s->config = value & 0xf13;
4302 827df9f3 balrog
        break;
4303 827df9f3 balrog
4304 827df9f3 balrog
    case 0x060 ... 0x1d4:
4305 8da3ff18 pbrook
        cs = (addr - 0x060) / 0x30;
4306 8da3ff18 pbrook
        addr -= cs * 0x30;
4307 827df9f3 balrog
        f = s->cs_file + cs;
4308 8da3ff18 pbrook
        switch (addr) {
4309 827df9f3 balrog
            case 0x60:        /* GPMC_CONFIG1 */
4310 827df9f3 balrog
                f->config[0] = value & 0xffef3e13;
4311 827df9f3 balrog
                break;
4312 827df9f3 balrog
            case 0x64:        /* GPMC_CONFIG2 */
4313 827df9f3 balrog
                f->config[1] = value & 0x001f1f8f;
4314 827df9f3 balrog
                break;
4315 827df9f3 balrog
            case 0x68:        /* GPMC_CONFIG3 */
4316 827df9f3 balrog
                f->config[2] = value & 0x001f1f8f;
4317 827df9f3 balrog
                break;
4318 827df9f3 balrog
            case 0x6c:        /* GPMC_CONFIG4 */
4319 827df9f3 balrog
                f->config[3] = value & 0x1f8f1f8f;
4320 827df9f3 balrog
                break;
4321 827df9f3 balrog
            case 0x70:        /* GPMC_CONFIG5 */
4322 827df9f3 balrog
                f->config[4] = value & 0x0f1f1f1f;
4323 827df9f3 balrog
                break;
4324 827df9f3 balrog
            case 0x74:        /* GPMC_CONFIG6 */
4325 827df9f3 balrog
                f->config[5] = value & 0x00000fcf;
4326 827df9f3 balrog
                break;
4327 827df9f3 balrog
            case 0x78:        /* GPMC_CONFIG7 */
4328 827df9f3 balrog
                if ((f->config[6] ^ value) & 0xf7f) {
4329 827df9f3 balrog
                    if (f->config[6] & (1 << 6))                /* CSVALID */
4330 827df9f3 balrog
                        omap_gpmc_cs_unmap(f);
4331 827df9f3 balrog
                    if (value & (1 << 6))                        /* CSVALID */
4332 827df9f3 balrog
                        omap_gpmc_cs_map(f, value & 0x1f,        /* MASKADDR */
4333 827df9f3 balrog
                                        (value >> 8 & 0xf));        /* BASEADDR */
4334 827df9f3 balrog
                }
4335 827df9f3 balrog
                f->config[6] = value & 0x00000f7f;
4336 827df9f3 balrog
                break;
4337 827df9f3 balrog
            case 0x7c:        /* GPMC_NAND_COMMAND */
4338 827df9f3 balrog
            case 0x80:        /* GPMC_NAND_ADDRESS */
4339 827df9f3 balrog
            case 0x84:        /* GPMC_NAND_DATA */
4340 827df9f3 balrog
                break;
4341 827df9f3 balrog
4342 827df9f3 balrog
            default:
4343 827df9f3 balrog
                goto bad_reg;
4344 827df9f3 balrog
        }
4345 827df9f3 balrog
        break;
4346 827df9f3 balrog
4347 827df9f3 balrog
    case 0x1e0:        /* GPMC_PREFETCH_CONFIG1 */
4348 827df9f3 balrog
        s->prefconfig[0] = value & 0x7f8f7fbf;
4349 827df9f3 balrog
        /* TODO: update interrupts, fifos, dmas */
4350 827df9f3 balrog
        break;
4351 827df9f3 balrog
4352 827df9f3 balrog
    case 0x1e4:        /* GPMC_PREFETCH_CONFIG2 */
4353 827df9f3 balrog
        s->prefconfig[1] = value & 0x3fff;
4354 827df9f3 balrog
        break;
4355 827df9f3 balrog
4356 827df9f3 balrog
    case 0x1ec:        /* GPMC_PREFETCH_CONTROL */
4357 827df9f3 balrog
        s->prefcontrol = value & 1;
4358 827df9f3 balrog
        if (s->prefcontrol) {
4359 827df9f3 balrog
            if (s->prefconfig[0] & 1)
4360 827df9f3 balrog
                s->preffifo = 0x40;
4361 827df9f3 balrog
            else
4362 827df9f3 balrog
                s->preffifo = 0x00;
4363 827df9f3 balrog
        }
4364 827df9f3 balrog
        /* TODO: start */
4365 827df9f3 balrog
        break;
4366 827df9f3 balrog
4367 827df9f3 balrog
    case 0x1f4:        /* GPMC_ECC_CONFIG */
4368 827df9f3 balrog
        s->ecc_cs = 0x8f;
4369 827df9f3 balrog
        break;
4370 827df9f3 balrog
    case 0x1f8:        /* GPMC_ECC_CONTROL */
4371 827df9f3 balrog
        if (value & (1 << 8))
4372 827df9f3 balrog
            for (cs = 0; cs < 9; cs ++)
4373 827df9f3 balrog
                ecc_reset(&s->ecc[cs]);
4374 827df9f3 balrog
        s->ecc_ptr = value & 0xf;
4375 827df9f3 balrog
        if (s->ecc_ptr == 0 || s->ecc_ptr > 9) {
4376 827df9f3 balrog
            s->ecc_ptr = 0;
4377 827df9f3 balrog
            s->ecc_cs &= ~1;
4378 827df9f3 balrog
        }
4379 827df9f3 balrog
        break;
4380 827df9f3 balrog
    case 0x1fc:        /* GPMC_ECC_SIZE_CONFIG */
4381 827df9f3 balrog
        s->ecc_cfg = value & 0x3fcff1ff;
4382 827df9f3 balrog
        break;
4383 827df9f3 balrog
    case 0x230:        /* GPMC_TESTMODE_CTRL */
4384 827df9f3 balrog
        if (value & 7)
4385 827df9f3 balrog
            fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__);
4386 827df9f3 balrog
        break;
4387 827df9f3 balrog
4388 827df9f3 balrog
    default:
4389 827df9f3 balrog
    bad_reg:
4390 827df9f3 balrog
        OMAP_BAD_REG(addr);
4391 827df9f3 balrog
        return;
4392 827df9f3 balrog
    }
4393 827df9f3 balrog
}
4394 827df9f3 balrog
4395 827df9f3 balrog
static CPUReadMemoryFunc *omap_gpmc_readfn[] = {
4396 827df9f3 balrog
    omap_badwidth_read32,        /* TODO */
4397 827df9f3 balrog
    omap_badwidth_read32,        /* TODO */
4398 827df9f3 balrog
    omap_gpmc_read,
4399 827df9f3 balrog
};
4400 827df9f3 balrog
4401 827df9f3 balrog
static CPUWriteMemoryFunc *omap_gpmc_writefn[] = {
4402 827df9f3 balrog
    omap_badwidth_write32,        /* TODO */
4403 827df9f3 balrog
    omap_badwidth_write32,        /* TODO */
4404 827df9f3 balrog
    omap_gpmc_write,
4405 827df9f3 balrog
};
4406 827df9f3 balrog
4407 827df9f3 balrog
struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
4408 827df9f3 balrog
{
4409 827df9f3 balrog
    int iomemtype;
4410 827df9f3 balrog
    struct omap_gpmc_s *s = (struct omap_gpmc_s *)
4411 827df9f3 balrog
            qemu_mallocz(sizeof(struct omap_gpmc_s));
4412 827df9f3 balrog
4413 827df9f3 balrog
    omap_gpmc_reset(s);
4414 827df9f3 balrog
4415 827df9f3 balrog
    iomemtype = cpu_register_io_memory(0, omap_gpmc_readfn,
4416 827df9f3 balrog
                    omap_gpmc_writefn, s);
4417 8da3ff18 pbrook
    cpu_register_physical_memory(base, 0x1000, iomemtype);
4418 827df9f3 balrog
4419 827df9f3 balrog
    return s;
4420 827df9f3 balrog
}
4421 827df9f3 balrog
4422 827df9f3 balrog
void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
4423 827df9f3 balrog
                void (*base_upd)(void *opaque, target_phys_addr_t new),
4424 827df9f3 balrog
                void (*unmap)(void *opaque), void *opaque)
4425 827df9f3 balrog
{
4426 827df9f3 balrog
    struct omap_gpmc_cs_file_s *f;
4427 827df9f3 balrog
4428 827df9f3 balrog
    if (cs < 0 || cs >= 8) {
4429 827df9f3 balrog
        fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
4430 827df9f3 balrog
        exit(-1);
4431 827df9f3 balrog
    }
4432 827df9f3 balrog
    f = &s->cs_file[cs];
4433 827df9f3 balrog
4434 827df9f3 balrog
    f->iomemtype = iomemtype;
4435 827df9f3 balrog
    f->base_update = base_upd;
4436 827df9f3 balrog
    f->unmap = unmap;
4437 827df9f3 balrog
    f->opaque = opaque;
4438 827df9f3 balrog
4439 827df9f3 balrog
    if (f->config[6] & (1 << 6))                                /* CSVALID */
4440 827df9f3 balrog
        omap_gpmc_cs_map(f, f->config[6] & 0x1f,                /* MASKADDR */
4441 827df9f3 balrog
                        (f->config[6] >> 8 & 0xf));                /* BASEADDR */
4442 827df9f3 balrog
}
4443 827df9f3 balrog
4444 827df9f3 balrog
/* General chip reset */
4445 827df9f3 balrog
static void omap2_mpu_reset(void *opaque)
4446 827df9f3 balrog
{
4447 827df9f3 balrog
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4448 827df9f3 balrog
4449 827df9f3 balrog
    omap_inth_reset(mpu->ih[0]);
4450 827df9f3 balrog
    omap_dma_reset(mpu->dma);
4451 827df9f3 balrog
    omap_prcm_reset(mpu->prcm);
4452 827df9f3 balrog
    omap_sysctl_reset(mpu->sysc);
4453 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[0]);
4454 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[1]);
4455 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[2]);
4456 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[3]);
4457 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[4]);
4458 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[5]);
4459 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[6]);
4460 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[7]);
4461 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[8]);
4462 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[9]);
4463 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[10]);
4464 827df9f3 balrog
    omap_gp_timer_reset(mpu->gptimer[11]);
4465 827df9f3 balrog
    omap_synctimer_reset(&mpu->synctimer);
4466 827df9f3 balrog
    omap_sdrc_reset(mpu->sdrc);
4467 827df9f3 balrog
    omap_gpmc_reset(mpu->gpmc);
4468 827df9f3 balrog
    omap_dss_reset(mpu->dss);
4469 827df9f3 balrog
    omap_uart_reset(mpu->uart[0]);
4470 827df9f3 balrog
    omap_uart_reset(mpu->uart[1]);
4471 827df9f3 balrog
    omap_uart_reset(mpu->uart[2]);
4472 827df9f3 balrog
    omap_mmc_reset(mpu->mmc);
4473 827df9f3 balrog
    omap_gpif_reset(mpu->gpif);
4474 827df9f3 balrog
    omap_mcspi_reset(mpu->mcspi[0]);
4475 827df9f3 balrog
    omap_mcspi_reset(mpu->mcspi[1]);
4476 827df9f3 balrog
    omap_i2c_reset(mpu->i2c[0]);
4477 827df9f3 balrog
    omap_i2c_reset(mpu->i2c[1]);
4478 827df9f3 balrog
    cpu_reset(mpu->env);
4479 827df9f3 balrog
}
4480 827df9f3 balrog
4481 827df9f3 balrog
static int omap2_validate_addr(struct omap_mpu_state_s *s,
4482 827df9f3 balrog
                target_phys_addr_t addr)
4483 827df9f3 balrog
{
4484 827df9f3 balrog
    return 1;
4485 827df9f3 balrog
}
4486 827df9f3 balrog
4487 827df9f3 balrog
static const struct dma_irq_map omap2_dma_irq_map[] = {
4488 827df9f3 balrog
    { 0, OMAP_INT_24XX_SDMA_IRQ0 },
4489 827df9f3 balrog
    { 0, OMAP_INT_24XX_SDMA_IRQ1 },
4490 827df9f3 balrog
    { 0, OMAP_INT_24XX_SDMA_IRQ2 },
4491 827df9f3 balrog
    { 0, OMAP_INT_24XX_SDMA_IRQ3 },
4492 827df9f3 balrog
};
4493 827df9f3 balrog
4494 827df9f3 balrog
struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
4495 3023f332 aliguori
                const char *core)
4496 827df9f3 balrog
{
4497 827df9f3 balrog
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4498 827df9f3 balrog
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4499 7e7c5e4c balrog
    ram_addr_t sram_base, q2_base;
4500 827df9f3 balrog
    qemu_irq *cpu_irq;
4501 827df9f3 balrog
    qemu_irq dma_irqs[4];
4502 827df9f3 balrog
    omap_clk gpio_clks[4];
4503 827df9f3 balrog
    int sdindex;
4504 827df9f3 balrog
    int i;
4505 827df9f3 balrog
4506 827df9f3 balrog
    /* Core */
4507 827df9f3 balrog
    s->mpu_model = omap2420;
4508 827df9f3 balrog
    s->env = cpu_init(core ?: "arm1136-r2");
4509 827df9f3 balrog
    if (!s->env) {
4510 827df9f3 balrog
        fprintf(stderr, "Unable to find CPU definition\n");
4511 827df9f3 balrog
        exit(1);
4512 827df9f3 balrog
    }
4513 827df9f3 balrog
    s->sdram_size = sdram_size;
4514 827df9f3 balrog
    s->sram_size = OMAP242X_SRAM_SIZE;
4515 827df9f3 balrog
4516 827df9f3 balrog
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4517 827df9f3 balrog
4518 827df9f3 balrog
    /* Clocks */
4519 827df9f3 balrog
    omap_clk_init(s);
4520 827df9f3 balrog
4521 827df9f3 balrog
    /* Memory-mapped stuff */
4522 827df9f3 balrog
    cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size,
4523 7e7c5e4c balrog
                    (q2_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4524 827df9f3 balrog
    cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size,
4525 827df9f3 balrog
                    (sram_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4526 827df9f3 balrog
4527 827df9f3 balrog
    s->l4 = omap_l4_init(OMAP2_L4_BASE, 54);
4528 827df9f3 balrog
4529 827df9f3 balrog
    /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
4530 827df9f3 balrog
    cpu_irq = arm_pic_init_cpu(s->env);
4531 827df9f3 balrog
    s->ih[0] = omap2_inth_init(0x480fe000, 0x1000, 3, &s->irq[0],
4532 827df9f3 balrog
                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
4533 827df9f3 balrog
                    omap_findclk(s, "mpu_intc_fclk"),
4534 827df9f3 balrog
                    omap_findclk(s, "mpu_intc_iclk"));
4535 827df9f3 balrog
4536 827df9f3 balrog
    s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
4537 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_PRCM_MPU_IRQ], NULL, NULL, s);
4538 827df9f3 balrog
4539 827df9f3 balrog
    s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
4540 827df9f3 balrog
                    omap_findclk(s, "omapctrl_iclk"), s);
4541 827df9f3 balrog
4542 827df9f3 balrog
    for (i = 0; i < 4; i ++)
4543 827df9f3 balrog
        dma_irqs[i] =
4544 827df9f3 balrog
                s->irq[omap2_dma_irq_map[i].ih][omap2_dma_irq_map[i].intr];
4545 827df9f3 balrog
    s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
4546 827df9f3 balrog
                    omap_findclk(s, "sdma_iclk"),
4547 827df9f3 balrog
                    omap_findclk(s, "sdma_fclk"));
4548 827df9f3 balrog
    s->port->addr_valid = omap2_validate_addr;
4549 827df9f3 balrog
4550 afbb5194 balrog
    /* Register SDRAM and SRAM ports for fast DMA transfers.  */
4551 afbb5194 balrog
    soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
4552 afbb5194 balrog
    soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
4553 afbb5194 balrog
4554 827df9f3 balrog
    s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19),
4555 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_UART1_IRQ],
4556 827df9f3 balrog
                    omap_findclk(s, "uart1_fclk"),
4557 827df9f3 balrog
                    omap_findclk(s, "uart1_iclk"),
4558 827df9f3 balrog
                    s->drq[OMAP24XX_DMA_UART1_TX],
4559 827df9f3 balrog
                    s->drq[OMAP24XX_DMA_UART1_RX], serial_hds[0]);
4560 827df9f3 balrog
    s->uart[1] = omap2_uart_init(omap_l4ta(s->l4, 20),
4561 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_UART2_IRQ],
4562 827df9f3 balrog
                    omap_findclk(s, "uart2_fclk"),
4563 827df9f3 balrog
                    omap_findclk(s, "uart2_iclk"),
4564 827df9f3 balrog
                    s->drq[OMAP24XX_DMA_UART2_TX],
4565 827df9f3 balrog
                    s->drq[OMAP24XX_DMA_UART2_RX],
4566 827df9f3 balrog
                    serial_hds[0] ? serial_hds[1] : 0);
4567 827df9f3 balrog
    s->uart[2] = omap2_uart_init(omap_l4ta(s->l4, 21),
4568 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_UART3_IRQ],
4569 827df9f3 balrog
                    omap_findclk(s, "uart3_fclk"),
4570 827df9f3 balrog
                    omap_findclk(s, "uart3_iclk"),
4571 827df9f3 balrog
                    s->drq[OMAP24XX_DMA_UART3_TX],
4572 827df9f3 balrog
                    s->drq[OMAP24XX_DMA_UART3_RX],
4573 827df9f3 balrog
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4574 827df9f3 balrog
4575 827df9f3 balrog
    s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
4576 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER1],
4577 827df9f3 balrog
                    omap_findclk(s, "wu_gpt1_clk"),
4578 827df9f3 balrog
                    omap_findclk(s, "wu_l4_iclk"));
4579 827df9f3 balrog
    s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
4580 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER2],
4581 827df9f3 balrog
                    omap_findclk(s, "core_gpt2_clk"),
4582 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4583 827df9f3 balrog
    s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
4584 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER3],
4585 827df9f3 balrog
                    omap_findclk(s, "core_gpt3_clk"),
4586 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4587 827df9f3 balrog
    s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
4588 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER4],
4589 827df9f3 balrog
                    omap_findclk(s, "core_gpt4_clk"),
4590 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4591 827df9f3 balrog
    s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
4592 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER5],
4593 827df9f3 balrog
                    omap_findclk(s, "core_gpt5_clk"),
4594 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4595 827df9f3 balrog
    s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
4596 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER6],
4597 827df9f3 balrog
                    omap_findclk(s, "core_gpt6_clk"),
4598 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4599 827df9f3 balrog
    s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
4600 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER7],
4601 827df9f3 balrog
                    omap_findclk(s, "core_gpt7_clk"),
4602 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4603 827df9f3 balrog
    s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
4604 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER8],
4605 827df9f3 balrog
                    omap_findclk(s, "core_gpt8_clk"),
4606 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4607 827df9f3 balrog
    s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
4608 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER9],
4609 827df9f3 balrog
                    omap_findclk(s, "core_gpt9_clk"),
4610 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4611 827df9f3 balrog
    s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
4612 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER10],
4613 827df9f3 balrog
                    omap_findclk(s, "core_gpt10_clk"),
4614 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4615 827df9f3 balrog
    s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
4616 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER11],
4617 827df9f3 balrog
                    omap_findclk(s, "core_gpt11_clk"),
4618 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4619 827df9f3 balrog
    s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
4620 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_GPTIMER12],
4621 827df9f3 balrog
                    omap_findclk(s, "core_gpt12_clk"),
4622 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4623 827df9f3 balrog
4624 827df9f3 balrog
    omap_tap_init(omap_l4ta(s->l4, 2), s);
4625 827df9f3 balrog
4626 827df9f3 balrog
    omap_synctimer_init(omap_l4tao(s->l4, 2), s,
4627 827df9f3 balrog
                    omap_findclk(s, "clk32-kHz"),
4628 827df9f3 balrog
                    omap_findclk(s, "core_l4_iclk"));
4629 827df9f3 balrog
4630 827df9f3 balrog
    s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5),
4631 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_I2C1_IRQ],
4632 827df9f3 balrog
                    &s->drq[OMAP24XX_DMA_I2C1_TX],
4633 827df9f3 balrog
                    omap_findclk(s, "i2c1.fclk"),
4634 827df9f3 balrog
                    omap_findclk(s, "i2c1.iclk"));
4635 827df9f3 balrog
    s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6),
4636 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_I2C2_IRQ],
4637 827df9f3 balrog
                    &s->drq[OMAP24XX_DMA_I2C2_TX],
4638 827df9f3 balrog
                    omap_findclk(s, "i2c2.fclk"),
4639 827df9f3 balrog
                    omap_findclk(s, "i2c2.iclk"));
4640 827df9f3 balrog
4641 827df9f3 balrog
    gpio_clks[0] = omap_findclk(s, "gpio1_dbclk");
4642 827df9f3 balrog
    gpio_clks[1] = omap_findclk(s, "gpio2_dbclk");
4643 827df9f3 balrog
    gpio_clks[2] = omap_findclk(s, "gpio3_dbclk");
4644 827df9f3 balrog
    gpio_clks[3] = omap_findclk(s, "gpio4_dbclk");
4645 827df9f3 balrog
    s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3),
4646 827df9f3 balrog
                    &s->irq[0][OMAP_INT_24XX_GPIO_BANK1],
4647 827df9f3 balrog
                    gpio_clks, omap_findclk(s, "gpio_iclk"), 4);
4648 827df9f3 balrog
4649 827df9f3 balrog
    s->sdrc = omap_sdrc_init(0x68009000);
4650 827df9f3 balrog
    s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
4651 827df9f3 balrog
4652 827df9f3 balrog
    sdindex = drive_get_index(IF_SD, 0, 0);
4653 827df9f3 balrog
    if (sdindex == -1) {
4654 827df9f3 balrog
        fprintf(stderr, "qemu: missing SecureDigital device\n");
4655 827df9f3 balrog
        exit(1);
4656 827df9f3 balrog
    }
4657 827df9f3 balrog
    s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), drives_table[sdindex].bdrv,
4658 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_MMC_IRQ],
4659 827df9f3 balrog
                    &s->drq[OMAP24XX_DMA_MMC1_TX],
4660 827df9f3 balrog
                    omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
4661 827df9f3 balrog
4662 827df9f3 balrog
    s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
4663 99570a40 balrog
                    s->irq[0][OMAP_INT_24XX_MCSPI1_IRQ],
4664 827df9f3 balrog
                    &s->drq[OMAP24XX_DMA_SPI1_TX0],
4665 827df9f3 balrog
                    omap_findclk(s, "spi1_fclk"),
4666 827df9f3 balrog
                    omap_findclk(s, "spi1_iclk"));
4667 827df9f3 balrog
    s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
4668 99570a40 balrog
                    s->irq[0][OMAP_INT_24XX_MCSPI2_IRQ],
4669 827df9f3 balrog
                    &s->drq[OMAP24XX_DMA_SPI2_TX0],
4670 827df9f3 balrog
                    omap_findclk(s, "spi2_fclk"),
4671 827df9f3 balrog
                    omap_findclk(s, "spi2_iclk"));
4672 827df9f3 balrog
4673 3023f332 aliguori
    s->dss = omap_dss_init(omap_l4ta(s->l4, 10), 0x68000800,
4674 827df9f3 balrog
                    /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
4675 827df9f3 balrog
                    s->irq[0][OMAP_INT_24XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
4676 827df9f3 balrog
                    omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
4677 827df9f3 balrog
                    omap_findclk(s, "dss_54m_clk"),
4678 827df9f3 balrog
                    omap_findclk(s, "dss_l3_iclk"),
4679 827df9f3 balrog
                    omap_findclk(s, "dss_l4_iclk"));
4680 827df9f3 balrog
4681 54585ffe balrog
    omap_sti_init(omap_l4ta(s->l4, 18), 0x54000000,
4682 54585ffe balrog
                    s->irq[0][OMAP_INT_24XX_STI], omap_findclk(s, "emul_ck"),
4683 54585ffe balrog
                    serial_hds[0] && serial_hds[1] && serial_hds[2] ?
4684 54585ffe balrog
                    serial_hds[3] : 0);
4685 54585ffe balrog
4686 99570a40 balrog
    s->eac = omap_eac_init(omap_l4ta(s->l4, 32),
4687 99570a40 balrog
                    s->irq[0][OMAP_INT_24XX_EAC_IRQ],
4688 99570a40 balrog
                    /* Ten consecutive lines */
4689 99570a40 balrog
                    &s->drq[OMAP24XX_DMA_EAC_AC_RD],
4690 99570a40 balrog
                    omap_findclk(s, "func_96m_clk"),
4691 99570a40 balrog
                    omap_findclk(s, "core_l4_iclk"));
4692 99570a40 balrog
4693 827df9f3 balrog
    /* All register mappings (includin those not currenlty implemented):
4694 827df9f3 balrog
     * SystemControlMod        48000000 - 48000fff
4695 827df9f3 balrog
     * SystemControlL4        48001000 - 48001fff
4696 827df9f3 balrog
     * 32kHz Timer Mod        48004000 - 48004fff
4697 827df9f3 balrog
     * 32kHz Timer L4        48005000 - 48005fff
4698 827df9f3 balrog
     * PRCM ModA        48008000 - 480087ff
4699 827df9f3 balrog
     * PRCM ModB        48008800 - 48008fff
4700 827df9f3 balrog
     * PRCM L4                48009000 - 48009fff
4701 827df9f3 balrog
     * TEST-BCM Mod        48012000 - 48012fff
4702 827df9f3 balrog
     * TEST-BCM L4        48013000 - 48013fff
4703 827df9f3 balrog
     * TEST-TAP Mod        48014000 - 48014fff
4704 827df9f3 balrog
     * TEST-TAP L4        48015000 - 48015fff
4705 827df9f3 balrog
     * GPIO1 Mod        48018000 - 48018fff
4706 827df9f3 balrog
     * GPIO Top                48019000 - 48019fff
4707 827df9f3 balrog
     * GPIO2 Mod        4801a000 - 4801afff
4708 827df9f3 balrog
     * GPIO L4                4801b000 - 4801bfff
4709 827df9f3 balrog
     * GPIO3 Mod        4801c000 - 4801cfff
4710 827df9f3 balrog
     * GPIO4 Mod        4801e000 - 4801efff
4711 827df9f3 balrog
     * WDTIMER1 Mod        48020000 - 48010fff
4712 827df9f3 balrog
     * WDTIMER Top        48021000 - 48011fff
4713 827df9f3 balrog
     * WDTIMER2 Mod        48022000 - 48012fff
4714 827df9f3 balrog
     * WDTIMER L4        48023000 - 48013fff
4715 827df9f3 balrog
     * WDTIMER3 Mod        48024000 - 48014fff
4716 827df9f3 balrog
     * WDTIMER3 L4        48025000 - 48015fff
4717 827df9f3 balrog
     * WDTIMER4 Mod        48026000 - 48016fff
4718 827df9f3 balrog
     * WDTIMER4 L4        48027000 - 48017fff
4719 827df9f3 balrog
     * GPTIMER1 Mod        48028000 - 48018fff
4720 827df9f3 balrog
     * GPTIMER1 L4        48029000 - 48019fff
4721 827df9f3 balrog
     * GPTIMER2 Mod        4802a000 - 4801afff
4722 827df9f3 balrog
     * GPTIMER2 L4        4802b000 - 4801bfff
4723 827df9f3 balrog
     * L4-Config AP        48040000 - 480407ff
4724 827df9f3 balrog
     * L4-Config IP        48040800 - 48040fff
4725 827df9f3 balrog
     * L4-Config LA        48041000 - 48041fff
4726 827df9f3 balrog
     * ARM11ETB Mod        48048000 - 48049fff
4727 827df9f3 balrog
     * ARM11ETB L4        4804a000 - 4804afff
4728 827df9f3 balrog
     * DISPLAY Top        48050000 - 480503ff
4729 827df9f3 balrog
     * DISPLAY DISPC        48050400 - 480507ff
4730 827df9f3 balrog
     * DISPLAY RFBI        48050800 - 48050bff
4731 827df9f3 balrog
     * DISPLAY VENC        48050c00 - 48050fff
4732 827df9f3 balrog
     * DISPLAY L4        48051000 - 48051fff
4733 827df9f3 balrog
     * CAMERA Top        48052000 - 480523ff
4734 827df9f3 balrog
     * CAMERA core        48052400 - 480527ff
4735 827df9f3 balrog
     * CAMERA DMA        48052800 - 48052bff
4736 827df9f3 balrog
     * CAMERA MMU        48052c00 - 48052fff
4737 827df9f3 balrog
     * CAMERA L4        48053000 - 48053fff
4738 827df9f3 balrog
     * SDMA Mod                48056000 - 48056fff
4739 827df9f3 balrog
     * SDMA L4                48057000 - 48057fff
4740 827df9f3 balrog
     * SSI Top                48058000 - 48058fff
4741 827df9f3 balrog
     * SSI GDD                48059000 - 48059fff
4742 827df9f3 balrog
     * SSI Port1        4805a000 - 4805afff
4743 827df9f3 balrog
     * SSI Port2        4805b000 - 4805bfff
4744 827df9f3 balrog
     * SSI L4                4805c000 - 4805cfff
4745 827df9f3 balrog
     * USB Mod                4805e000 - 480fefff
4746 827df9f3 balrog
     * USB L4                4805f000 - 480fffff
4747 827df9f3 balrog
     * WIN_TRACER1 Mod        48060000 - 48060fff
4748 827df9f3 balrog
     * WIN_TRACER1 L4        48061000 - 48061fff
4749 827df9f3 balrog
     * WIN_TRACER2 Mod        48062000 - 48062fff
4750 827df9f3 balrog
     * WIN_TRACER2 L4        48063000 - 48063fff
4751 827df9f3 balrog
     * WIN_TRACER3 Mod        48064000 - 48064fff
4752 827df9f3 balrog
     * WIN_TRACER3 L4        48065000 - 48065fff
4753 827df9f3 balrog
     * WIN_TRACER4 Top        48066000 - 480660ff
4754 827df9f3 balrog
     * WIN_TRACER4 ETT        48066100 - 480661ff
4755 827df9f3 balrog
     * WIN_TRACER4 WT        48066200 - 480662ff
4756 827df9f3 balrog
     * WIN_TRACER4 L4        48067000 - 48067fff
4757 827df9f3 balrog
     * XTI Mod                48068000 - 48068fff
4758 827df9f3 balrog
     * XTI L4                48069000 - 48069fff
4759 827df9f3 balrog
     * UART1 Mod        4806a000 - 4806afff
4760 827df9f3 balrog
     * UART1 L4                4806b000 - 4806bfff
4761 827df9f3 balrog
     * UART2 Mod        4806c000 - 4806cfff
4762 827df9f3 balrog
     * UART2 L4                4806d000 - 4806dfff
4763 827df9f3 balrog
     * UART3 Mod        4806e000 - 4806efff
4764 827df9f3 balrog
     * UART3 L4                4806f000 - 4806ffff
4765 827df9f3 balrog
     * I2C1 Mod                48070000 - 48070fff
4766 827df9f3 balrog
     * I2C1 L4                48071000 - 48071fff
4767 827df9f3 balrog
     * I2C2 Mod                48072000 - 48072fff
4768 827df9f3 balrog
     * I2C2 L4                48073000 - 48073fff
4769 827df9f3 balrog
     * McBSP1 Mod        48074000 - 48074fff
4770 827df9f3 balrog
     * McBSP1 L4        48075000 - 48075fff
4771 827df9f3 balrog
     * McBSP2 Mod        48076000 - 48076fff
4772 827df9f3 balrog
     * McBSP2 L4        48077000 - 48077fff
4773 827df9f3 balrog
     * GPTIMER3 Mod        48078000 - 48078fff
4774 827df9f3 balrog
     * GPTIMER3 L4        48079000 - 48079fff
4775 827df9f3 balrog
     * GPTIMER4 Mod        4807a000 - 4807afff
4776 827df9f3 balrog
     * GPTIMER4 L4        4807b000 - 4807bfff
4777 827df9f3 balrog
     * GPTIMER5 Mod        4807c000 - 4807cfff
4778 827df9f3 balrog
     * GPTIMER5 L4        4807d000 - 4807dfff
4779 827df9f3 balrog
     * GPTIMER6 Mod        4807e000 - 4807efff
4780 827df9f3 balrog
     * GPTIMER6 L4        4807f000 - 4807ffff
4781 827df9f3 balrog
     * GPTIMER7 Mod        48080000 - 48080fff
4782 827df9f3 balrog
     * GPTIMER7 L4        48081000 - 48081fff
4783 827df9f3 balrog
     * GPTIMER8 Mod        48082000 - 48082fff
4784 827df9f3 balrog
     * GPTIMER8 L4        48083000 - 48083fff
4785 827df9f3 balrog
     * GPTIMER9 Mod        48084000 - 48084fff
4786 827df9f3 balrog
     * GPTIMER9 L4        48085000 - 48085fff
4787 827df9f3 balrog
     * GPTIMER10 Mod        48086000 - 48086fff
4788 827df9f3 balrog
     * GPTIMER10 L4        48087000 - 48087fff
4789 827df9f3 balrog
     * GPTIMER11 Mod        48088000 - 48088fff
4790 827df9f3 balrog
     * GPTIMER11 L4        48089000 - 48089fff
4791 827df9f3 balrog
     * GPTIMER12 Mod        4808a000 - 4808afff
4792 827df9f3 balrog
     * GPTIMER12 L4        4808b000 - 4808bfff
4793 827df9f3 balrog
     * EAC Mod                48090000 - 48090fff
4794 827df9f3 balrog
     * EAC L4                48091000 - 48091fff
4795 827df9f3 balrog
     * FAC Mod                48092000 - 48092fff
4796 827df9f3 balrog
     * FAC L4                48093000 - 48093fff
4797 827df9f3 balrog
     * MAILBOX Mod        48094000 - 48094fff
4798 827df9f3 balrog
     * MAILBOX L4        48095000 - 48095fff
4799 827df9f3 balrog
     * SPI1 Mod                48098000 - 48098fff
4800 827df9f3 balrog
     * SPI1 L4                48099000 - 48099fff
4801 827df9f3 balrog
     * SPI2 Mod                4809a000 - 4809afff
4802 827df9f3 balrog
     * SPI2 L4                4809b000 - 4809bfff
4803 827df9f3 balrog
     * MMC/SDIO Mod        4809c000 - 4809cfff
4804 827df9f3 balrog
     * MMC/SDIO L4        4809d000 - 4809dfff
4805 827df9f3 balrog
     * MS_PRO Mod        4809e000 - 4809efff
4806 827df9f3 balrog
     * MS_PRO L4        4809f000 - 4809ffff
4807 827df9f3 balrog
     * RNG Mod                480a0000 - 480a0fff
4808 827df9f3 balrog
     * RNG L4                480a1000 - 480a1fff
4809 827df9f3 balrog
     * DES3DES Mod        480a2000 - 480a2fff
4810 827df9f3 balrog
     * DES3DES L4        480a3000 - 480a3fff
4811 827df9f3 balrog
     * SHA1MD5 Mod        480a4000 - 480a4fff
4812 827df9f3 balrog
     * SHA1MD5 L4        480a5000 - 480a5fff
4813 827df9f3 balrog
     * AES Mod                480a6000 - 480a6fff
4814 827df9f3 balrog
     * AES L4                480a7000 - 480a7fff
4815 827df9f3 balrog
     * PKA Mod                480a8000 - 480a9fff
4816 827df9f3 balrog
     * PKA L4                480aa000 - 480aafff
4817 827df9f3 balrog
     * MG Mod                480b0000 - 480b0fff
4818 827df9f3 balrog
     * MG L4                480b1000 - 480b1fff
4819 827df9f3 balrog
     * HDQ/1-wire Mod        480b2000 - 480b2fff
4820 827df9f3 balrog
     * HDQ/1-wire L4        480b3000 - 480b3fff
4821 827df9f3 balrog
     * MPU interrupt        480fe000 - 480fefff
4822 54585ffe balrog
     * STI channel base        54000000 - 5400ffff
4823 827df9f3 balrog
     * IVA RAM                5c000000 - 5c01ffff
4824 827df9f3 balrog
     * IVA ROM                5c020000 - 5c027fff
4825 827df9f3 balrog
     * IMG_BUF_A        5c040000 - 5c040fff
4826 827df9f3 balrog
     * IMG_BUF_B        5c042000 - 5c042fff
4827 827df9f3 balrog
     * VLCDS                5c048000 - 5c0487ff
4828 827df9f3 balrog
     * IMX_COEF                5c049000 - 5c04afff
4829 827df9f3 balrog
     * IMX_CMD                5c051000 - 5c051fff
4830 827df9f3 balrog
     * VLCDQ                5c053000 - 5c0533ff
4831 827df9f3 balrog
     * VLCDH                5c054000 - 5c054fff
4832 827df9f3 balrog
     * SEQ_CMD                5c055000 - 5c055fff
4833 827df9f3 balrog
     * IMX_REG                5c056000 - 5c0560ff
4834 827df9f3 balrog
     * VLCD_REG                5c056100 - 5c0561ff
4835 827df9f3 balrog
     * SEQ_REG                5c056200 - 5c0562ff
4836 827df9f3 balrog
     * IMG_BUF_REG        5c056300 - 5c0563ff
4837 827df9f3 balrog
     * SEQIRQ_REG        5c056400 - 5c0564ff
4838 827df9f3 balrog
     * OCP_REG                5c060000 - 5c060fff
4839 827df9f3 balrog
     * SYSC_REG                5c070000 - 5c070fff
4840 827df9f3 balrog
     * MMU_REG                5d000000 - 5d000fff
4841 827df9f3 balrog
     * sDMA R                68000400 - 680005ff
4842 827df9f3 balrog
     * sDMA W                68000600 - 680007ff
4843 827df9f3 balrog
     * Display Control        68000800 - 680009ff
4844 827df9f3 balrog
     * DSP subsystem        68000a00 - 68000bff
4845 827df9f3 balrog
     * MPU subsystem        68000c00 - 68000dff
4846 827df9f3 balrog
     * IVA subsystem        68001000 - 680011ff
4847 827df9f3 balrog
     * USB                68001200 - 680013ff
4848 827df9f3 balrog
     * Camera                68001400 - 680015ff
4849 827df9f3 balrog
     * VLYNQ (firewall)        68001800 - 68001bff
4850 827df9f3 balrog
     * VLYNQ                68001e00 - 68001fff
4851 827df9f3 balrog
     * SSI                68002000 - 680021ff
4852 827df9f3 balrog
     * L4                68002400 - 680025ff
4853 827df9f3 balrog
     * DSP (firewall)        68002800 - 68002bff
4854 827df9f3 balrog
     * DSP subsystem        68002e00 - 68002fff
4855 827df9f3 balrog
     * IVA (firewall)        68003000 - 680033ff
4856 827df9f3 balrog
     * IVA                68003600 - 680037ff
4857 827df9f3 balrog
     * GFX                68003a00 - 68003bff
4858 827df9f3 balrog
     * CMDWR emulation        68003c00 - 68003dff
4859 827df9f3 balrog
     * SMS                68004000 - 680041ff
4860 827df9f3 balrog
     * OCM                68004200 - 680043ff
4861 827df9f3 balrog
     * GPMC                68004400 - 680045ff
4862 827df9f3 balrog
     * RAM (firewall)        68005000 - 680053ff
4863 827df9f3 balrog
     * RAM (err login)        68005400 - 680057ff
4864 827df9f3 balrog
     * ROM (firewall)        68005800 - 68005bff
4865 827df9f3 balrog
     * ROM (err login)        68005c00 - 68005fff
4866 827df9f3 balrog
     * GPMC (firewall)        68006000 - 680063ff
4867 827df9f3 balrog
     * GPMC (err login)        68006400 - 680067ff
4868 827df9f3 balrog
     * SMS (err login)        68006c00 - 68006fff
4869 827df9f3 balrog
     * SMS registers        68008000 - 68008fff
4870 827df9f3 balrog
     * SDRC registers        68009000 - 68009fff
4871 827df9f3 balrog
     * GPMC registers        6800a000   6800afff
4872 827df9f3 balrog
     */
4873 827df9f3 balrog
4874 827df9f3 balrog
    qemu_register_reset(omap2_mpu_reset, s);
4875 827df9f3 balrog
4876 827df9f3 balrog
    return s;
4877 827df9f3 balrog
}