Statistics
| Branch: | Revision:

root / hw / omap2.c @ 9f6f0423

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