Statistics
| Branch: | Revision:

root / hw / omap1.c @ bc20ba98

History | View | Annotate | Download (108.5 kB)

1
/*
2
 * TI OMAP processors emulation.
3
 *
4
 * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as
8
 * published by the Free Software Foundation; either version 2 or
9
 * (at your option) version 3 of the License.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along
17
 * with this program; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include "hw.h"
20
#include "arm-misc.h"
21
#include "omap.h"
22
#include "sysemu.h"
23
#include "qemu-timer.h"
24
#include "qemu-char.h"
25
#include "soc_dma.h"
26
/* We use pc-style serial ports.  */
27
#include "pc.h"
28

    
29
/* Should signal the TCMI/GPMC */
30
uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
31
{
32
    uint8_t ret;
33

    
34
    OMAP_8B_REG(addr);
35
    cpu_physical_memory_read(addr, (void *) &ret, 1);
36
    return ret;
37
}
38

    
39
void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
40
                uint32_t value)
41
{
42
    uint8_t val8 = value;
43

    
44
    OMAP_8B_REG(addr);
45
    cpu_physical_memory_write(addr, (void *) &val8, 1);
46
}
47

    
48
uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
49
{
50
    uint16_t ret;
51

    
52
    OMAP_16B_REG(addr);
53
    cpu_physical_memory_read(addr, (void *) &ret, 2);
54
    return ret;
55
}
56

    
57
void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
58
                uint32_t value)
59
{
60
    uint16_t val16 = value;
61

    
62
    OMAP_16B_REG(addr);
63
    cpu_physical_memory_write(addr, (void *) &val16, 2);
64
}
65

    
66
uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
67
{
68
    uint32_t ret;
69

    
70
    OMAP_32B_REG(addr);
71
    cpu_physical_memory_read(addr, (void *) &ret, 4);
72
    return ret;
73
}
74

    
75
void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
76
                uint32_t value)
77
{
78
    OMAP_32B_REG(addr);
79
    cpu_physical_memory_write(addr, (void *) &value, 4);
80
}
81

    
82
/* MPU OS timers */
83
struct omap_mpu_timer_s {
84
    qemu_irq irq;
85
    omap_clk clk;
86
    uint32_t val;
87
    int64_t time;
88
    QEMUTimer *timer;
89
    QEMUBH *tick;
90
    int64_t rate;
91
    int it_ena;
92

    
93
    int enable;
94
    int ptv;
95
    int ar;
96
    int st;
97
    uint32_t reset_val;
98
};
99

    
100
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
101
{
102
    uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
103

    
104
    if (timer->st && timer->enable && timer->rate)
105
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
106
                                     timer->rate, get_ticks_per_sec());
107
    else
108
        return timer->val;
109
}
110

    
111
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
112
{
113
    timer->val = omap_timer_read(timer);
114
    timer->time = qemu_get_clock(vm_clock);
115
}
116

    
117
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
118
{
119
    int64_t expires;
120

    
121
    if (timer->enable && timer->st && timer->rate) {
122
        timer->val = timer->reset_val;        /* Should skip this on clk enable */
123
        expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
124
                           get_ticks_per_sec(), timer->rate);
125

    
126
        /* If timer expiry would be sooner than in about 1 ms and
127
         * auto-reload isn't set, then fire immediately.  This is a hack
128
         * to make systems like PalmOS run in acceptable time.  PalmOS
129
         * sets the interval to a very low value and polls the status bit
130
         * in a busy loop when it wants to sleep just a couple of CPU
131
         * ticks.  */
132
        if (expires > (get_ticks_per_sec() >> 10) || timer->ar)
133
            qemu_mod_timer(timer->timer, timer->time + expires);
134
        else
135
            qemu_bh_schedule(timer->tick);
136
    } else
137
        qemu_del_timer(timer->timer);
138
}
139

    
140
static void omap_timer_fire(void *opaque)
141
{
142
    struct omap_mpu_timer_s *timer = opaque;
143

    
144
    if (!timer->ar) {
145
        timer->val = 0;
146
        timer->st = 0;
147
    }
148

    
149
    if (timer->it_ena)
150
        /* Edge-triggered irq */
151
        qemu_irq_pulse(timer->irq);
152
}
153

    
154
static void omap_timer_tick(void *opaque)
155
{
156
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
157

    
158
    omap_timer_sync(timer);
159
    omap_timer_fire(timer);
160
    omap_timer_update(timer);
161
}
162

    
163
static void omap_timer_clk_update(void *opaque, int line, int on)
164
{
165
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
166

    
167
    omap_timer_sync(timer);
168
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
169
    omap_timer_update(timer);
170
}
171

    
172
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
173
{
174
    omap_clk_adduser(timer->clk,
175
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
176
    timer->rate = omap_clk_getrate(timer->clk);
177
}
178

    
179
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
180
{
181
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
182

    
183
    switch (addr) {
184
    case 0x00:        /* CNTL_TIMER */
185
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
186

    
187
    case 0x04:        /* LOAD_TIM */
188
        break;
189

    
190
    case 0x08:        /* READ_TIM */
191
        return omap_timer_read(s);
192
    }
193

    
194
    OMAP_BAD_REG(addr);
195
    return 0;
196
}
197

    
198
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
199
                uint32_t value)
200
{
201
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
202

    
203
    switch (addr) {
204
    case 0x00:        /* CNTL_TIMER */
205
        omap_timer_sync(s);
206
        s->enable = (value >> 5) & 1;
207
        s->ptv = (value >> 2) & 7;
208
        s->ar = (value >> 1) & 1;
209
        s->st = value & 1;
210
        omap_timer_update(s);
211
        return;
212

    
213
    case 0x04:        /* LOAD_TIM */
214
        s->reset_val = value;
215
        return;
216

    
217
    case 0x08:        /* READ_TIM */
218
        OMAP_RO_REG(addr);
219
        break;
220

    
221
    default:
222
        OMAP_BAD_REG(addr);
223
    }
224
}
225

    
226
static CPUReadMemoryFunc * const omap_mpu_timer_readfn[] = {
227
    omap_badwidth_read32,
228
    omap_badwidth_read32,
229
    omap_mpu_timer_read,
230
};
231

    
232
static CPUWriteMemoryFunc * const omap_mpu_timer_writefn[] = {
233
    omap_badwidth_write32,
234
    omap_badwidth_write32,
235
    omap_mpu_timer_write,
236
};
237

    
238
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
239
{
240
    qemu_del_timer(s->timer);
241
    s->enable = 0;
242
    s->reset_val = 31337;
243
    s->val = 0;
244
    s->ptv = 0;
245
    s->ar = 0;
246
    s->st = 0;
247
    s->it_ena = 1;
248
}
249

    
250
static struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
251
                qemu_irq irq, omap_clk clk)
252
{
253
    int iomemtype;
254
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
255
            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
256

    
257
    s->irq = irq;
258
    s->clk = clk;
259
    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
260
    s->tick = qemu_bh_new(omap_timer_fire, s);
261
    omap_mpu_timer_reset(s);
262
    omap_timer_clk_setup(s);
263

    
264
    iomemtype = cpu_register_io_memory(omap_mpu_timer_readfn,
265
                    omap_mpu_timer_writefn, s);
266
    cpu_register_physical_memory(base, 0x100, iomemtype);
267

    
268
    return s;
269
}
270

    
271
/* Watchdog timer */
272
struct omap_watchdog_timer_s {
273
    struct omap_mpu_timer_s timer;
274
    uint8_t last_wr;
275
    int mode;
276
    int free;
277
    int reset;
278
};
279

    
280
static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
281
{
282
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
283

    
284
    switch (addr) {
285
    case 0x00:        /* CNTL_TIMER */
286
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
287
                (s->timer.st << 7) | (s->free << 1);
288

    
289
    case 0x04:        /* READ_TIMER */
290
        return omap_timer_read(&s->timer);
291

    
292
    case 0x08:        /* TIMER_MODE */
293
        return s->mode << 15;
294
    }
295

    
296
    OMAP_BAD_REG(addr);
297
    return 0;
298
}
299

    
300
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
301
                uint32_t value)
302
{
303
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
304

    
305
    switch (addr) {
306
    case 0x00:        /* CNTL_TIMER */
307
        omap_timer_sync(&s->timer);
308
        s->timer.ptv = (value >> 9) & 7;
309
        s->timer.ar = (value >> 8) & 1;
310
        s->timer.st = (value >> 7) & 1;
311
        s->free = (value >> 1) & 1;
312
        omap_timer_update(&s->timer);
313
        break;
314

    
315
    case 0x04:        /* LOAD_TIMER */
316
        s->timer.reset_val = value & 0xffff;
317
        break;
318

    
319
    case 0x08:        /* TIMER_MODE */
320
        if (!s->mode && ((value >> 15) & 1))
321
            omap_clk_get(s->timer.clk);
322
        s->mode |= (value >> 15) & 1;
323
        if (s->last_wr == 0xf5) {
324
            if ((value & 0xff) == 0xa0) {
325
                if (s->mode) {
326
                    s->mode = 0;
327
                    omap_clk_put(s->timer.clk);
328
                }
329
            } else {
330
                /* XXX: on T|E hardware somehow this has no effect,
331
                 * on Zire 71 it works as specified.  */
332
                s->reset = 1;
333
                qemu_system_reset_request();
334
            }
335
        }
336
        s->last_wr = value & 0xff;
337
        break;
338

    
339
    default:
340
        OMAP_BAD_REG(addr);
341
    }
342
}
343

    
344
static CPUReadMemoryFunc * const omap_wd_timer_readfn[] = {
345
    omap_badwidth_read16,
346
    omap_wd_timer_read,
347
    omap_badwidth_read16,
348
};
349

    
350
static CPUWriteMemoryFunc * const omap_wd_timer_writefn[] = {
351
    omap_badwidth_write16,
352
    omap_wd_timer_write,
353
    omap_badwidth_write16,
354
};
355

    
356
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
357
{
358
    qemu_del_timer(s->timer.timer);
359
    if (!s->mode)
360
        omap_clk_get(s->timer.clk);
361
    s->mode = 1;
362
    s->free = 1;
363
    s->reset = 0;
364
    s->timer.enable = 1;
365
    s->timer.it_ena = 1;
366
    s->timer.reset_val = 0xffff;
367
    s->timer.val = 0;
368
    s->timer.st = 0;
369
    s->timer.ptv = 0;
370
    s->timer.ar = 0;
371
    omap_timer_update(&s->timer);
372
}
373

    
374
static struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
375
                qemu_irq irq, omap_clk clk)
376
{
377
    int iomemtype;
378
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
379
            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
380

    
381
    s->timer.irq = irq;
382
    s->timer.clk = clk;
383
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
384
    omap_wd_timer_reset(s);
385
    omap_timer_clk_setup(&s->timer);
386

    
387
    iomemtype = cpu_register_io_memory(omap_wd_timer_readfn,
388
                    omap_wd_timer_writefn, s);
389
    cpu_register_physical_memory(base, 0x100, iomemtype);
390

    
391
    return s;
392
}
393

    
394
/* 32-kHz timer */
395
struct omap_32khz_timer_s {
396
    struct omap_mpu_timer_s timer;
397
};
398

    
399
static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
400
{
401
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
402
    int offset = addr & OMAP_MPUI_REG_MASK;
403

    
404
    switch (offset) {
405
    case 0x00:        /* TVR */
406
        return s->timer.reset_val;
407

    
408
    case 0x04:        /* TCR */
409
        return omap_timer_read(&s->timer);
410

    
411
    case 0x08:        /* CR */
412
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
413

    
414
    default:
415
        break;
416
    }
417
    OMAP_BAD_REG(addr);
418
    return 0;
419
}
420

    
421
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
422
                uint32_t value)
423
{
424
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
425
    int offset = addr & OMAP_MPUI_REG_MASK;
426

    
427
    switch (offset) {
428
    case 0x00:        /* TVR */
429
        s->timer.reset_val = value & 0x00ffffff;
430
        break;
431

    
432
    case 0x04:        /* TCR */
433
        OMAP_RO_REG(addr);
434
        break;
435

    
436
    case 0x08:        /* CR */
437
        s->timer.ar = (value >> 3) & 1;
438
        s->timer.it_ena = (value >> 2) & 1;
439
        if (s->timer.st != (value & 1) || (value & 2)) {
440
            omap_timer_sync(&s->timer);
441
            s->timer.enable = value & 1;
442
            s->timer.st = value & 1;
443
            omap_timer_update(&s->timer);
444
        }
445
        break;
446

    
447
    default:
448
        OMAP_BAD_REG(addr);
449
    }
450
}
451

    
452
static CPUReadMemoryFunc * const omap_os_timer_readfn[] = {
453
    omap_badwidth_read32,
454
    omap_badwidth_read32,
455
    omap_os_timer_read,
456
};
457

    
458
static CPUWriteMemoryFunc * const omap_os_timer_writefn[] = {
459
    omap_badwidth_write32,
460
    omap_badwidth_write32,
461
    omap_os_timer_write,
462
};
463

    
464
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
465
{
466
    qemu_del_timer(s->timer.timer);
467
    s->timer.enable = 0;
468
    s->timer.it_ena = 0;
469
    s->timer.reset_val = 0x00ffffff;
470
    s->timer.val = 0;
471
    s->timer.st = 0;
472
    s->timer.ptv = 0;
473
    s->timer.ar = 1;
474
}
475

    
476
static struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
477
                qemu_irq irq, omap_clk clk)
478
{
479
    int iomemtype;
480
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
481
            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
482

    
483
    s->timer.irq = irq;
484
    s->timer.clk = clk;
485
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
486
    omap_os_timer_reset(s);
487
    omap_timer_clk_setup(&s->timer);
488

    
489
    iomemtype = cpu_register_io_memory(omap_os_timer_readfn,
490
                    omap_os_timer_writefn, s);
491
    cpu_register_physical_memory(base, 0x800, iomemtype);
492

    
493
    return s;
494
}
495

    
496
/* Ultra Low-Power Device Module */
497
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
498
{
499
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
500
    uint16_t ret;
501

    
502
    switch (addr) {
503
    case 0x14:        /* IT_STATUS */
504
        ret = s->ulpd_pm_regs[addr >> 2];
505
        s->ulpd_pm_regs[addr >> 2] = 0;
506
        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
507
        return ret;
508

    
509
    case 0x18:        /* Reserved */
510
    case 0x1c:        /* Reserved */
511
    case 0x20:        /* Reserved */
512
    case 0x28:        /* Reserved */
513
    case 0x2c:        /* Reserved */
514
        OMAP_BAD_REG(addr);
515
    case 0x00:        /* COUNTER_32_LSB */
516
    case 0x04:        /* COUNTER_32_MSB */
517
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
518
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
519
    case 0x10:        /* GAUGING_CTRL */
520
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
521
    case 0x30:        /* CLOCK_CTRL */
522
    case 0x34:        /* SOFT_REQ */
523
    case 0x38:        /* COUNTER_32_FIQ */
524
    case 0x3c:        /* DPLL_CTRL */
525
    case 0x40:        /* STATUS_REQ */
526
        /* XXX: check clk::usecount state for every clock */
527
    case 0x48:        /* LOCL_TIME */
528
    case 0x4c:        /* APLL_CTRL */
529
    case 0x50:        /* POWER_CTRL */
530
        return s->ulpd_pm_regs[addr >> 2];
531
    }
532

    
533
    OMAP_BAD_REG(addr);
534
    return 0;
535
}
536

    
537
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
538
                uint16_t diff, uint16_t value)
539
{
540
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
541
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
542
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
543
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
544
}
545

    
546
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
547
                uint16_t diff, uint16_t value)
548
{
549
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
550
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
551
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
552
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
553
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
554
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
555
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
556
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
557
}
558

    
559
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
560
                uint32_t value)
561
{
562
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
563
    int64_t now, ticks;
564
    int div, mult;
565
    static const int bypass_div[4] = { 1, 2, 4, 4 };
566
    uint16_t diff;
567

    
568
    switch (addr) {
569
    case 0x00:        /* COUNTER_32_LSB */
570
    case 0x04:        /* COUNTER_32_MSB */
571
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
572
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
573
    case 0x14:        /* IT_STATUS */
574
    case 0x40:        /* STATUS_REQ */
575
        OMAP_RO_REG(addr);
576
        break;
577

    
578
    case 0x10:        /* GAUGING_CTRL */
579
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
580
        if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
581
            now = qemu_get_clock(vm_clock);
582

    
583
            if (value & 1)
584
                s->ulpd_gauge_start = now;
585
            else {
586
                now -= s->ulpd_gauge_start;
587

    
588
                /* 32-kHz ticks */
589
                ticks = muldiv64(now, 32768, get_ticks_per_sec());
590
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
591
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
592
                if (ticks >> 32)        /* OVERFLOW_32K */
593
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
594

    
595
                /* High frequency ticks */
596
                ticks = muldiv64(now, 12000000, get_ticks_per_sec());
597
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
598
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
599
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
600
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
601

    
602
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
603
                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
604
            }
605
        }
606
        s->ulpd_pm_regs[addr >> 2] = value;
607
        break;
608

    
609
    case 0x18:        /* Reserved */
610
    case 0x1c:        /* Reserved */
611
    case 0x20:        /* Reserved */
612
    case 0x28:        /* Reserved */
613
    case 0x2c:        /* Reserved */
614
        OMAP_BAD_REG(addr);
615
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
616
    case 0x38:        /* COUNTER_32_FIQ */
617
    case 0x48:        /* LOCL_TIME */
618
    case 0x50:        /* POWER_CTRL */
619
        s->ulpd_pm_regs[addr >> 2] = value;
620
        break;
621

    
622
    case 0x30:        /* CLOCK_CTRL */
623
        diff = s->ulpd_pm_regs[addr >> 2] ^ value;
624
        s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
625
        omap_ulpd_clk_update(s, diff, value);
626
        break;
627

    
628
    case 0x34:        /* SOFT_REQ */
629
        diff = s->ulpd_pm_regs[addr >> 2] ^ value;
630
        s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
631
        omap_ulpd_req_update(s, diff, value);
632
        break;
633

    
634
    case 0x3c:        /* DPLL_CTRL */
635
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
636
         * omitted altogether, probably a typo.  */
637
        /* This register has identical semantics with DPLL(1:3) control
638
         * registers, see omap_dpll_write() */
639
        diff = s->ulpd_pm_regs[addr >> 2] & value;
640
        s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
641
        if (diff & (0x3ff << 2)) {
642
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
643
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
644
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
645
            } else {
646
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
647
                mult = 1;
648
            }
649
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
650
        }
651

    
652
        /* Enter the desired mode.  */
653
        s->ulpd_pm_regs[addr >> 2] =
654
                (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
655
                ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
656

    
657
        /* Act as if the lock is restored.  */
658
        s->ulpd_pm_regs[addr >> 2] |= 2;
659
        break;
660

    
661
    case 0x4c:        /* APLL_CTRL */
662
        diff = s->ulpd_pm_regs[addr >> 2] & value;
663
        s->ulpd_pm_regs[addr >> 2] = value & 0xf;
664
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
665
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
666
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
667
        break;
668

    
669
    default:
670
        OMAP_BAD_REG(addr);
671
    }
672
}
673

    
674
static CPUReadMemoryFunc * const omap_ulpd_pm_readfn[] = {
675
    omap_badwidth_read16,
676
    omap_ulpd_pm_read,
677
    omap_badwidth_read16,
678
};
679

    
680
static CPUWriteMemoryFunc * const omap_ulpd_pm_writefn[] = {
681
    omap_badwidth_write16,
682
    omap_ulpd_pm_write,
683
    omap_badwidth_write16,
684
};
685

    
686
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
687
{
688
    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
689
    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
690
    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
691
    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
692
    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
693
    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
694
    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
695
    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
696
    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
697
    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
698
    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
699
    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
700
    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
701
    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
702
    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
703
    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
704
    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
705
    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
706
    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
707
    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
708
    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
709
    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
710
    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
711
}
712

    
713
static void omap_ulpd_pm_init(target_phys_addr_t base,
714
                struct omap_mpu_state_s *mpu)
715
{
716
    int iomemtype = cpu_register_io_memory(omap_ulpd_pm_readfn,
717
                    omap_ulpd_pm_writefn, mpu);
718

    
719
    cpu_register_physical_memory(base, 0x800, iomemtype);
720
    omap_ulpd_pm_reset(mpu);
721
}
722

    
723
/* OMAP Pin Configuration */
724
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
725
{
726
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
727

    
728
    switch (addr) {
729
    case 0x00:        /* FUNC_MUX_CTRL_0 */
730
    case 0x04:        /* FUNC_MUX_CTRL_1 */
731
    case 0x08:        /* FUNC_MUX_CTRL_2 */
732
        return s->func_mux_ctrl[addr >> 2];
733

    
734
    case 0x0c:        /* COMP_MODE_CTRL_0 */
735
        return s->comp_mode_ctrl[0];
736

    
737
    case 0x10:        /* FUNC_MUX_CTRL_3 */
738
    case 0x14:        /* FUNC_MUX_CTRL_4 */
739
    case 0x18:        /* FUNC_MUX_CTRL_5 */
740
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
741
    case 0x20:        /* FUNC_MUX_CTRL_7 */
742
    case 0x24:        /* FUNC_MUX_CTRL_8 */
743
    case 0x28:        /* FUNC_MUX_CTRL_9 */
744
    case 0x2c:        /* FUNC_MUX_CTRL_A */
745
    case 0x30:        /* FUNC_MUX_CTRL_B */
746
    case 0x34:        /* FUNC_MUX_CTRL_C */
747
    case 0x38:        /* FUNC_MUX_CTRL_D */
748
        return s->func_mux_ctrl[(addr >> 2) - 1];
749

    
750
    case 0x40:        /* PULL_DWN_CTRL_0 */
751
    case 0x44:        /* PULL_DWN_CTRL_1 */
752
    case 0x48:        /* PULL_DWN_CTRL_2 */
753
    case 0x4c:        /* PULL_DWN_CTRL_3 */
754
        return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
755

    
756
    case 0x50:        /* GATE_INH_CTRL_0 */
757
        return s->gate_inh_ctrl[0];
758

    
759
    case 0x60:        /* VOLTAGE_CTRL_0 */
760
        return s->voltage_ctrl[0];
761

    
762
    case 0x70:        /* TEST_DBG_CTRL_0 */
763
        return s->test_dbg_ctrl[0];
764

    
765
    case 0x80:        /* MOD_CONF_CTRL_0 */
766
        return s->mod_conf_ctrl[0];
767
    }
768

    
769
    OMAP_BAD_REG(addr);
770
    return 0;
771
}
772

    
773
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
774
                uint32_t diff, uint32_t value)
775
{
776
    if (s->compat1509) {
777
        if (diff & (1 << 9))                        /* BLUETOOTH */
778
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
779
                            (~value >> 9) & 1);
780
        if (diff & (1 << 7))                        /* USB.CLKO */
781
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
782
                            (value >> 7) & 1);
783
    }
784
}
785

    
786
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
787
                uint32_t diff, uint32_t value)
788
{
789
    if (s->compat1509) {
790
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
791
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
792
                            (value >> 31) & 1);
793
        if (diff & (1 << 1))                        /* CLK32K */
794
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
795
                            (~value >> 1) & 1);
796
    }
797
}
798

    
799
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
800
                uint32_t diff, uint32_t value)
801
{
802
    if (diff & (1 << 31))                        /* CONF_MOD_UART3_CLK_MODE_R */
803
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
804
                         omap_findclk(s, ((value >> 31) & 1) ?
805
                                 "ck_48m" : "armper_ck"));
806
    if (diff & (1 << 30))                        /* CONF_MOD_UART2_CLK_MODE_R */
807
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
808
                         omap_findclk(s, ((value >> 30) & 1) ?
809
                                 "ck_48m" : "armper_ck"));
810
    if (diff & (1 << 29))                        /* CONF_MOD_UART1_CLK_MODE_R */
811
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
812
                         omap_findclk(s, ((value >> 29) & 1) ?
813
                                 "ck_48m" : "armper_ck"));
814
    if (diff & (1 << 23))                        /* CONF_MOD_MMC_SD_CLK_REQ_R */
815
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
816
                         omap_findclk(s, ((value >> 23) & 1) ?
817
                                 "ck_48m" : "armper_ck"));
818
    if (diff & (1 << 12))                        /* CONF_MOD_COM_MCLK_12_48_S */
819
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
820
                         omap_findclk(s, ((value >> 12) & 1) ?
821
                                 "ck_48m" : "armper_ck"));
822
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
823
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
824
}
825

    
826
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
827
                uint32_t value)
828
{
829
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
830
    uint32_t diff;
831

    
832
    switch (addr) {
833
    case 0x00:        /* FUNC_MUX_CTRL_0 */
834
        diff = s->func_mux_ctrl[addr >> 2] ^ value;
835
        s->func_mux_ctrl[addr >> 2] = value;
836
        omap_pin_funcmux0_update(s, diff, value);
837
        return;
838

    
839
    case 0x04:        /* FUNC_MUX_CTRL_1 */
840
        diff = s->func_mux_ctrl[addr >> 2] ^ value;
841
        s->func_mux_ctrl[addr >> 2] = value;
842
        omap_pin_funcmux1_update(s, diff, value);
843
        return;
844

    
845
    case 0x08:        /* FUNC_MUX_CTRL_2 */
846
        s->func_mux_ctrl[addr >> 2] = value;
847
        return;
848

    
849
    case 0x0c:        /* COMP_MODE_CTRL_0 */
850
        s->comp_mode_ctrl[0] = value;
851
        s->compat1509 = (value != 0x0000eaef);
852
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
853
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
854
        return;
855

    
856
    case 0x10:        /* FUNC_MUX_CTRL_3 */
857
    case 0x14:        /* FUNC_MUX_CTRL_4 */
858
    case 0x18:        /* FUNC_MUX_CTRL_5 */
859
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
860
    case 0x20:        /* FUNC_MUX_CTRL_7 */
861
    case 0x24:        /* FUNC_MUX_CTRL_8 */
862
    case 0x28:        /* FUNC_MUX_CTRL_9 */
863
    case 0x2c:        /* FUNC_MUX_CTRL_A */
864
    case 0x30:        /* FUNC_MUX_CTRL_B */
865
    case 0x34:        /* FUNC_MUX_CTRL_C */
866
    case 0x38:        /* FUNC_MUX_CTRL_D */
867
        s->func_mux_ctrl[(addr >> 2) - 1] = value;
868
        return;
869

    
870
    case 0x40:        /* PULL_DWN_CTRL_0 */
871
    case 0x44:        /* PULL_DWN_CTRL_1 */
872
    case 0x48:        /* PULL_DWN_CTRL_2 */
873
    case 0x4c:        /* PULL_DWN_CTRL_3 */
874
        s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
875
        return;
876

    
877
    case 0x50:        /* GATE_INH_CTRL_0 */
878
        s->gate_inh_ctrl[0] = value;
879
        return;
880

    
881
    case 0x60:        /* VOLTAGE_CTRL_0 */
882
        s->voltage_ctrl[0] = value;
883
        return;
884

    
885
    case 0x70:        /* TEST_DBG_CTRL_0 */
886
        s->test_dbg_ctrl[0] = value;
887
        return;
888

    
889
    case 0x80:        /* MOD_CONF_CTRL_0 */
890
        diff = s->mod_conf_ctrl[0] ^ value;
891
        s->mod_conf_ctrl[0] = value;
892
        omap_pin_modconf1_update(s, diff, value);
893
        return;
894

    
895
    default:
896
        OMAP_BAD_REG(addr);
897
    }
898
}
899

    
900
static CPUReadMemoryFunc * const omap_pin_cfg_readfn[] = {
901
    omap_badwidth_read32,
902
    omap_badwidth_read32,
903
    omap_pin_cfg_read,
904
};
905

    
906
static CPUWriteMemoryFunc * const omap_pin_cfg_writefn[] = {
907
    omap_badwidth_write32,
908
    omap_badwidth_write32,
909
    omap_pin_cfg_write,
910
};
911

    
912
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
913
{
914
    /* Start in Compatibility Mode.  */
915
    mpu->compat1509 = 1;
916
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
917
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
918
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
919
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
920
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
921
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
922
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
923
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
924
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
925
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
926
}
927

    
928
static void omap_pin_cfg_init(target_phys_addr_t base,
929
                struct omap_mpu_state_s *mpu)
930
{
931
    int iomemtype = cpu_register_io_memory(omap_pin_cfg_readfn,
932
                    omap_pin_cfg_writefn, mpu);
933

    
934
    cpu_register_physical_memory(base, 0x800, iomemtype);
935
    omap_pin_cfg_reset(mpu);
936
}
937

    
938
/* Device Identification, Die Identification */
939
static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
940
{
941
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
942

    
943
    switch (addr) {
944
    case 0xfffe1800:        /* DIE_ID_LSB */
945
        return 0xc9581f0e;
946
    case 0xfffe1804:        /* DIE_ID_MSB */
947
        return 0xa8858bfa;
948

    
949
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
950
        return 0x00aaaafc;
951
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
952
        return 0xcafeb574;
953

    
954
    case 0xfffed400:        /* JTAG_ID_LSB */
955
        switch (s->mpu_model) {
956
        case omap310:
957
            return 0x03310315;
958
        case omap1510:
959
            return 0x03310115;
960
        default:
961
            hw_error("%s: bad mpu model\n", __FUNCTION__);
962
        }
963
        break;
964

    
965
    case 0xfffed404:        /* JTAG_ID_MSB */
966
        switch (s->mpu_model) {
967
        case omap310:
968
            return 0xfb57402f;
969
        case omap1510:
970
            return 0xfb47002f;
971
        default:
972
            hw_error("%s: bad mpu model\n", __FUNCTION__);
973
        }
974
        break;
975
    }
976

    
977
    OMAP_BAD_REG(addr);
978
    return 0;
979
}
980

    
981
static void omap_id_write(void *opaque, target_phys_addr_t addr,
982
                uint32_t value)
983
{
984
    OMAP_BAD_REG(addr);
985
}
986

    
987
static CPUReadMemoryFunc * const omap_id_readfn[] = {
988
    omap_badwidth_read32,
989
    omap_badwidth_read32,
990
    omap_id_read,
991
};
992

    
993
static CPUWriteMemoryFunc * const omap_id_writefn[] = {
994
    omap_badwidth_write32,
995
    omap_badwidth_write32,
996
    omap_id_write,
997
};
998

    
999
static void omap_id_init(struct omap_mpu_state_s *mpu)
1000
{
1001
    int iomemtype = cpu_register_io_memory(omap_id_readfn,
1002
                    omap_id_writefn, mpu);
1003
    cpu_register_physical_memory_offset(0xfffe1800, 0x800, iomemtype, 0xfffe1800);
1004
    cpu_register_physical_memory_offset(0xfffed400, 0x100, iomemtype, 0xfffed400);
1005
    if (!cpu_is_omap15xx(mpu))
1006
        cpu_register_physical_memory_offset(0xfffe2000, 0x800, iomemtype, 0xfffe2000);
1007
}
1008

    
1009
/* MPUI Control (Dummy) */
1010
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
1011
{
1012
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1013

    
1014
    switch (addr) {
1015
    case 0x00:        /* CTRL */
1016
        return s->mpui_ctrl;
1017
    case 0x04:        /* DEBUG_ADDR */
1018
        return 0x01ffffff;
1019
    case 0x08:        /* DEBUG_DATA */
1020
        return 0xffffffff;
1021
    case 0x0c:        /* DEBUG_FLAG */
1022
        return 0x00000800;
1023
    case 0x10:        /* STATUS */
1024
        return 0x00000000;
1025

    
1026
    /* Not in OMAP310 */
1027
    case 0x14:        /* DSP_STATUS */
1028
    case 0x18:        /* DSP_BOOT_CONFIG */
1029
        return 0x00000000;
1030
    case 0x1c:        /* DSP_MPUI_CONFIG */
1031
        return 0x0000ffff;
1032
    }
1033

    
1034
    OMAP_BAD_REG(addr);
1035
    return 0;
1036
}
1037

    
1038
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
1039
                uint32_t value)
1040
{
1041
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1042

    
1043
    switch (addr) {
1044
    case 0x00:        /* CTRL */
1045
        s->mpui_ctrl = value & 0x007fffff;
1046
        break;
1047

    
1048
    case 0x04:        /* DEBUG_ADDR */
1049
    case 0x08:        /* DEBUG_DATA */
1050
    case 0x0c:        /* DEBUG_FLAG */
1051
    case 0x10:        /* STATUS */
1052
    /* Not in OMAP310 */
1053
    case 0x14:        /* DSP_STATUS */
1054
        OMAP_RO_REG(addr);
1055
    case 0x18:        /* DSP_BOOT_CONFIG */
1056
    case 0x1c:        /* DSP_MPUI_CONFIG */
1057
        break;
1058

    
1059
    default:
1060
        OMAP_BAD_REG(addr);
1061
    }
1062
}
1063

    
1064
static CPUReadMemoryFunc * const omap_mpui_readfn[] = {
1065
    omap_badwidth_read32,
1066
    omap_badwidth_read32,
1067
    omap_mpui_read,
1068
};
1069

    
1070
static CPUWriteMemoryFunc * const omap_mpui_writefn[] = {
1071
    omap_badwidth_write32,
1072
    omap_badwidth_write32,
1073
    omap_mpui_write,
1074
};
1075

    
1076
static void omap_mpui_reset(struct omap_mpu_state_s *s)
1077
{
1078
    s->mpui_ctrl = 0x0003ff1b;
1079
}
1080

    
1081
static void omap_mpui_init(target_phys_addr_t base,
1082
                struct omap_mpu_state_s *mpu)
1083
{
1084
    int iomemtype = cpu_register_io_memory(omap_mpui_readfn,
1085
                    omap_mpui_writefn, mpu);
1086

    
1087
    cpu_register_physical_memory(base, 0x100, iomemtype);
1088

    
1089
    omap_mpui_reset(mpu);
1090
}
1091

    
1092
/* TIPB Bridges */
1093
struct omap_tipb_bridge_s {
1094
    qemu_irq abort;
1095

    
1096
    int width_intr;
1097
    uint16_t control;
1098
    uint16_t alloc;
1099
    uint16_t buffer;
1100
    uint16_t enh_control;
1101
};
1102

    
1103
static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
1104
{
1105
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1106

    
1107
    switch (addr) {
1108
    case 0x00:        /* TIPB_CNTL */
1109
        return s->control;
1110
    case 0x04:        /* TIPB_BUS_ALLOC */
1111
        return s->alloc;
1112
    case 0x08:        /* MPU_TIPB_CNTL */
1113
        return s->buffer;
1114
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
1115
        return s->enh_control;
1116
    case 0x10:        /* ADDRESS_DBG */
1117
    case 0x14:        /* DATA_DEBUG_LOW */
1118
    case 0x18:        /* DATA_DEBUG_HIGH */
1119
        return 0xffff;
1120
    case 0x1c:        /* DEBUG_CNTR_SIG */
1121
        return 0x00f8;
1122
    }
1123

    
1124
    OMAP_BAD_REG(addr);
1125
    return 0;
1126
}
1127

    
1128
static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
1129
                uint32_t value)
1130
{
1131
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1132

    
1133
    switch (addr) {
1134
    case 0x00:        /* TIPB_CNTL */
1135
        s->control = value & 0xffff;
1136
        break;
1137

    
1138
    case 0x04:        /* TIPB_BUS_ALLOC */
1139
        s->alloc = value & 0x003f;
1140
        break;
1141

    
1142
    case 0x08:        /* MPU_TIPB_CNTL */
1143
        s->buffer = value & 0x0003;
1144
        break;
1145

    
1146
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
1147
        s->width_intr = !(value & 2);
1148
        s->enh_control = value & 0x000f;
1149
        break;
1150

    
1151
    case 0x10:        /* ADDRESS_DBG */
1152
    case 0x14:        /* DATA_DEBUG_LOW */
1153
    case 0x18:        /* DATA_DEBUG_HIGH */
1154
    case 0x1c:        /* DEBUG_CNTR_SIG */
1155
        OMAP_RO_REG(addr);
1156
        break;
1157

    
1158
    default:
1159
        OMAP_BAD_REG(addr);
1160
    }
1161
}
1162

    
1163
static CPUReadMemoryFunc * const omap_tipb_bridge_readfn[] = {
1164
    omap_badwidth_read16,
1165
    omap_tipb_bridge_read,
1166
    omap_tipb_bridge_read,
1167
};
1168

    
1169
static CPUWriteMemoryFunc * const omap_tipb_bridge_writefn[] = {
1170
    omap_badwidth_write16,
1171
    omap_tipb_bridge_write,
1172
    omap_tipb_bridge_write,
1173
};
1174

    
1175
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
1176
{
1177
    s->control = 0xffff;
1178
    s->alloc = 0x0009;
1179
    s->buffer = 0x0000;
1180
    s->enh_control = 0x000f;
1181
}
1182

    
1183
static struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
1184
                qemu_irq abort_irq, omap_clk clk)
1185
{
1186
    int iomemtype;
1187
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
1188
            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
1189

    
1190
    s->abort = abort_irq;
1191
    omap_tipb_bridge_reset(s);
1192

    
1193
    iomemtype = cpu_register_io_memory(omap_tipb_bridge_readfn,
1194
                    omap_tipb_bridge_writefn, s);
1195
    cpu_register_physical_memory(base, 0x100, iomemtype);
1196

    
1197
    return s;
1198
}
1199

    
1200
/* Dummy Traffic Controller's Memory Interface */
1201
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
1202
{
1203
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1204
    uint32_t ret;
1205

    
1206
    switch (addr) {
1207
    case 0x00:        /* IMIF_PRIO */
1208
    case 0x04:        /* EMIFS_PRIO */
1209
    case 0x08:        /* EMIFF_PRIO */
1210
    case 0x0c:        /* EMIFS_CONFIG */
1211
    case 0x10:        /* EMIFS_CS0_CONFIG */
1212
    case 0x14:        /* EMIFS_CS1_CONFIG */
1213
    case 0x18:        /* EMIFS_CS2_CONFIG */
1214
    case 0x1c:        /* EMIFS_CS3_CONFIG */
1215
    case 0x24:        /* EMIFF_MRS */
1216
    case 0x28:        /* TIMEOUT1 */
1217
    case 0x2c:        /* TIMEOUT2 */
1218
    case 0x30:        /* TIMEOUT3 */
1219
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
1220
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
1221
        return s->tcmi_regs[addr >> 2];
1222

    
1223
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
1224
        ret = s->tcmi_regs[addr >> 2];
1225
        s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
1226
        /* XXX: We can try using the VGA_DIRTY flag for this */
1227
        return ret;
1228
    }
1229

    
1230
    OMAP_BAD_REG(addr);
1231
    return 0;
1232
}
1233

    
1234
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
1235
                uint32_t value)
1236
{
1237
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1238

    
1239
    switch (addr) {
1240
    case 0x00:        /* IMIF_PRIO */
1241
    case 0x04:        /* EMIFS_PRIO */
1242
    case 0x08:        /* EMIFF_PRIO */
1243
    case 0x10:        /* EMIFS_CS0_CONFIG */
1244
    case 0x14:        /* EMIFS_CS1_CONFIG */
1245
    case 0x18:        /* EMIFS_CS2_CONFIG */
1246
    case 0x1c:        /* EMIFS_CS3_CONFIG */
1247
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
1248
    case 0x24:        /* EMIFF_MRS */
1249
    case 0x28:        /* TIMEOUT1 */
1250
    case 0x2c:        /* TIMEOUT2 */
1251
    case 0x30:        /* TIMEOUT3 */
1252
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
1253
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
1254
        s->tcmi_regs[addr >> 2] = value;
1255
        break;
1256
    case 0x0c:        /* EMIFS_CONFIG */
1257
        s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
1258
        break;
1259

    
1260
    default:
1261
        OMAP_BAD_REG(addr);
1262
    }
1263
}
1264

    
1265
static CPUReadMemoryFunc * const omap_tcmi_readfn[] = {
1266
    omap_badwidth_read32,
1267
    omap_badwidth_read32,
1268
    omap_tcmi_read,
1269
};
1270

    
1271
static CPUWriteMemoryFunc * const omap_tcmi_writefn[] = {
1272
    omap_badwidth_write32,
1273
    omap_badwidth_write32,
1274
    omap_tcmi_write,
1275
};
1276

    
1277
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
1278
{
1279
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
1280
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
1281
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
1282
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
1283
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
1284
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
1285
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
1286
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
1287
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
1288
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
1289
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
1290
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
1291
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
1292
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
1293
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
1294
}
1295

    
1296
static void omap_tcmi_init(target_phys_addr_t base,
1297
                struct omap_mpu_state_s *mpu)
1298
{
1299
    int iomemtype = cpu_register_io_memory(omap_tcmi_readfn,
1300
                    omap_tcmi_writefn, mpu);
1301

    
1302
    cpu_register_physical_memory(base, 0x100, iomemtype);
1303
    omap_tcmi_reset(mpu);
1304
}
1305

    
1306
/* Digital phase-locked loops control */
1307
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
1308
{
1309
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1310

    
1311
    if (addr == 0x00)        /* CTL_REG */
1312
        return s->mode;
1313

    
1314
    OMAP_BAD_REG(addr);
1315
    return 0;
1316
}
1317

    
1318
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
1319
                uint32_t value)
1320
{
1321
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1322
    uint16_t diff;
1323
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1324
    int div, mult;
1325

    
1326
    if (addr == 0x00) {        /* CTL_REG */
1327
        /* See omap_ulpd_pm_write() too */
1328
        diff = s->mode & value;
1329
        s->mode = value & 0x2fff;
1330
        if (diff & (0x3ff << 2)) {
1331
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1332
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1333
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1334
            } else {
1335
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1336
                mult = 1;
1337
            }
1338
            omap_clk_setrate(s->dpll, div, mult);
1339
        }
1340

    
1341
        /* Enter the desired mode.  */
1342
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
1343

    
1344
        /* Act as if the lock is restored.  */
1345
        s->mode |= 2;
1346
    } else {
1347
        OMAP_BAD_REG(addr);
1348
    }
1349
}
1350

    
1351
static CPUReadMemoryFunc * const omap_dpll_readfn[] = {
1352
    omap_badwidth_read16,
1353
    omap_dpll_read,
1354
    omap_badwidth_read16,
1355
};
1356

    
1357
static CPUWriteMemoryFunc * const omap_dpll_writefn[] = {
1358
    omap_badwidth_write16,
1359
    omap_dpll_write,
1360
    omap_badwidth_write16,
1361
};
1362

    
1363
static void omap_dpll_reset(struct dpll_ctl_s *s)
1364
{
1365
    s->mode = 0x2002;
1366
    omap_clk_setrate(s->dpll, 1, 1);
1367
}
1368

    
1369
static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
1370
                omap_clk clk)
1371
{
1372
    int iomemtype = cpu_register_io_memory(omap_dpll_readfn,
1373
                    omap_dpll_writefn, s);
1374

    
1375
    s->dpll = clk;
1376
    omap_dpll_reset(s);
1377

    
1378
    cpu_register_physical_memory(base, 0x100, iomemtype);
1379
}
1380

    
1381
/* MPU Clock/Reset/Power Mode Control */
1382
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
1383
{
1384
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1385

    
1386
    switch (addr) {
1387
    case 0x00:        /* ARM_CKCTL */
1388
        return s->clkm.arm_ckctl;
1389

    
1390
    case 0x04:        /* ARM_IDLECT1 */
1391
        return s->clkm.arm_idlect1;
1392

    
1393
    case 0x08:        /* ARM_IDLECT2 */
1394
        return s->clkm.arm_idlect2;
1395

    
1396
    case 0x0c:        /* ARM_EWUPCT */
1397
        return s->clkm.arm_ewupct;
1398

    
1399
    case 0x10:        /* ARM_RSTCT1 */
1400
        return s->clkm.arm_rstct1;
1401

    
1402
    case 0x14:        /* ARM_RSTCT2 */
1403
        return s->clkm.arm_rstct2;
1404

    
1405
    case 0x18:        /* ARM_SYSST */
1406
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
1407

    
1408
    case 0x1c:        /* ARM_CKOUT1 */
1409
        return s->clkm.arm_ckout1;
1410

    
1411
    case 0x20:        /* ARM_CKOUT2 */
1412
        break;
1413
    }
1414

    
1415
    OMAP_BAD_REG(addr);
1416
    return 0;
1417
}
1418

    
1419
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
1420
                uint16_t diff, uint16_t value)
1421
{
1422
    omap_clk clk;
1423

    
1424
    if (diff & (1 << 14)) {                                /* ARM_INTHCK_SEL */
1425
        if (value & (1 << 14))
1426
            /* Reserved */;
1427
        else {
1428
            clk = omap_findclk(s, "arminth_ck");
1429
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1430
        }
1431
    }
1432
    if (diff & (1 << 12)) {                                /* ARM_TIMXO */
1433
        clk = omap_findclk(s, "armtim_ck");
1434
        if (value & (1 << 12))
1435
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
1436
        else
1437
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1438
    }
1439
    /* XXX: en_dspck */
1440
    if (diff & (3 << 10)) {                                /* DSPMMUDIV */
1441
        clk = omap_findclk(s, "dspmmu_ck");
1442
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
1443
    }
1444
    if (diff & (3 << 8)) {                                /* TCDIV */
1445
        clk = omap_findclk(s, "tc_ck");
1446
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
1447
    }
1448
    if (diff & (3 << 6)) {                                /* DSPDIV */
1449
        clk = omap_findclk(s, "dsp_ck");
1450
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
1451
    }
1452
    if (diff & (3 << 4)) {                                /* ARMDIV */
1453
        clk = omap_findclk(s, "arm_ck");
1454
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
1455
    }
1456
    if (diff & (3 << 2)) {                                /* LCDDIV */
1457
        clk = omap_findclk(s, "lcd_ck");
1458
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
1459
    }
1460
    if (diff & (3 << 0)) {                                /* PERDIV */
1461
        clk = omap_findclk(s, "armper_ck");
1462
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
1463
    }
1464
}
1465

    
1466
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
1467
                uint16_t diff, uint16_t value)
1468
{
1469
    omap_clk clk;
1470

    
1471
    if (value & (1 << 11))                                /* SETARM_IDLE */
1472
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
1473
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
1474
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
1475

    
1476
#define SET_CANIDLE(clock, bit)                                \
1477
    if (diff & (1 << bit)) {                                \
1478
        clk = omap_findclk(s, clock);                        \
1479
        omap_clk_canidle(clk, (value >> bit) & 1);        \
1480
    }
1481
    SET_CANIDLE("mpuwd_ck", 0)                                /* IDLWDT_ARM */
1482
    SET_CANIDLE("armxor_ck", 1)                                /* IDLXORP_ARM */
1483
    SET_CANIDLE("mpuper_ck", 2)                                /* IDLPER_ARM */
1484
    SET_CANIDLE("lcd_ck", 3)                                /* IDLLCD_ARM */
1485
    SET_CANIDLE("lb_ck", 4)                                /* IDLLB_ARM */
1486
    SET_CANIDLE("hsab_ck", 5)                                /* IDLHSAB_ARM */
1487
    SET_CANIDLE("tipb_ck", 6)                                /* IDLIF_ARM */
1488
    SET_CANIDLE("dma_ck", 6)                                /* IDLIF_ARM */
1489
    SET_CANIDLE("tc_ck", 6)                                /* IDLIF_ARM */
1490
    SET_CANIDLE("dpll1", 7)                                /* IDLDPLL_ARM */
1491
    SET_CANIDLE("dpll2", 7)                                /* IDLDPLL_ARM */
1492
    SET_CANIDLE("dpll3", 7)                                /* IDLDPLL_ARM */
1493
    SET_CANIDLE("mpui_ck", 8)                                /* IDLAPI_ARM */
1494
    SET_CANIDLE("armtim_ck", 9)                                /* IDLTIM_ARM */
1495
}
1496

    
1497
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
1498
                uint16_t diff, uint16_t value)
1499
{
1500
    omap_clk clk;
1501

    
1502
#define SET_ONOFF(clock, bit)                                \
1503
    if (diff & (1 << bit)) {                                \
1504
        clk = omap_findclk(s, clock);                        \
1505
        omap_clk_onoff(clk, (value >> bit) & 1);        \
1506
    }
1507
    SET_ONOFF("mpuwd_ck", 0)                                /* EN_WDTCK */
1508
    SET_ONOFF("armxor_ck", 1)                                /* EN_XORPCK */
1509
    SET_ONOFF("mpuper_ck", 2)                                /* EN_PERCK */
1510
    SET_ONOFF("lcd_ck", 3)                                /* EN_LCDCK */
1511
    SET_ONOFF("lb_ck", 4)                                /* EN_LBCK */
1512
    SET_ONOFF("hsab_ck", 5)                                /* EN_HSABCK */
1513
    SET_ONOFF("mpui_ck", 6)                                /* EN_APICK */
1514
    SET_ONOFF("armtim_ck", 7)                                /* EN_TIMCK */
1515
    SET_CANIDLE("dma_ck", 8)                                /* DMACK_REQ */
1516
    SET_ONOFF("arm_gpio_ck", 9)                                /* EN_GPIOCK */
1517
    SET_ONOFF("lbfree_ck", 10)                                /* EN_LBFREECK */
1518
}
1519

    
1520
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
1521
                uint16_t diff, uint16_t value)
1522
{
1523
    omap_clk clk;
1524

    
1525
    if (diff & (3 << 4)) {                                /* TCLKOUT */
1526
        clk = omap_findclk(s, "tclk_out");
1527
        switch ((value >> 4) & 3) {
1528
        case 1:
1529
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
1530
            omap_clk_onoff(clk, 1);
1531
            break;
1532
        case 2:
1533
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1534
            omap_clk_onoff(clk, 1);
1535
            break;
1536
        default:
1537
            omap_clk_onoff(clk, 0);
1538
        }
1539
    }
1540
    if (diff & (3 << 2)) {                                /* DCLKOUT */
1541
        clk = omap_findclk(s, "dclk_out");
1542
        switch ((value >> 2) & 3) {
1543
        case 0:
1544
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
1545
            break;
1546
        case 1:
1547
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
1548
            break;
1549
        case 2:
1550
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
1551
            break;
1552
        case 3:
1553
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1554
            break;
1555
        }
1556
    }
1557
    if (diff & (3 << 0)) {                                /* ACLKOUT */
1558
        clk = omap_findclk(s, "aclk_out");
1559
        switch ((value >> 0) & 3) {
1560
        case 1:
1561
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1562
            omap_clk_onoff(clk, 1);
1563
            break;
1564
        case 2:
1565
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
1566
            omap_clk_onoff(clk, 1);
1567
            break;
1568
        case 3:
1569
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1570
            omap_clk_onoff(clk, 1);
1571
            break;
1572
        default:
1573
            omap_clk_onoff(clk, 0);
1574
        }
1575
    }
1576
}
1577

    
1578
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
1579
                uint32_t value)
1580
{
1581
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1582
    uint16_t diff;
1583
    omap_clk clk;
1584
    static const char *clkschemename[8] = {
1585
        "fully synchronous", "fully asynchronous", "synchronous scalable",
1586
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
1587
    };
1588

    
1589
    switch (addr) {
1590
    case 0x00:        /* ARM_CKCTL */
1591
        diff = s->clkm.arm_ckctl ^ value;
1592
        s->clkm.arm_ckctl = value & 0x7fff;
1593
        omap_clkm_ckctl_update(s, diff, value);
1594
        return;
1595

    
1596
    case 0x04:        /* ARM_IDLECT1 */
1597
        diff = s->clkm.arm_idlect1 ^ value;
1598
        s->clkm.arm_idlect1 = value & 0x0fff;
1599
        omap_clkm_idlect1_update(s, diff, value);
1600
        return;
1601

    
1602
    case 0x08:        /* ARM_IDLECT2 */
1603
        diff = s->clkm.arm_idlect2 ^ value;
1604
        s->clkm.arm_idlect2 = value & 0x07ff;
1605
        omap_clkm_idlect2_update(s, diff, value);
1606
        return;
1607

    
1608
    case 0x0c:        /* ARM_EWUPCT */
1609
        s->clkm.arm_ewupct = value & 0x003f;
1610
        return;
1611

    
1612
    case 0x10:        /* ARM_RSTCT1 */
1613
        diff = s->clkm.arm_rstct1 ^ value;
1614
        s->clkm.arm_rstct1 = value & 0x0007;
1615
        if (value & 9) {
1616
            qemu_system_reset_request();
1617
            s->clkm.cold_start = 0xa;
1618
        }
1619
        if (diff & ~value & 4) {                                /* DSP_RST */
1620
            omap_mpui_reset(s);
1621
            omap_tipb_bridge_reset(s->private_tipb);
1622
            omap_tipb_bridge_reset(s->public_tipb);
1623
        }
1624
        if (diff & 2) {                                                /* DSP_EN */
1625
            clk = omap_findclk(s, "dsp_ck");
1626
            omap_clk_canidle(clk, (~value >> 1) & 1);
1627
        }
1628
        return;
1629

    
1630
    case 0x14:        /* ARM_RSTCT2 */
1631
        s->clkm.arm_rstct2 = value & 0x0001;
1632
        return;
1633

    
1634
    case 0x18:        /* ARM_SYSST */
1635
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
1636
            s->clkm.clocking_scheme = (value >> 11) & 7;
1637
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
1638
                            clkschemename[s->clkm.clocking_scheme]);
1639
        }
1640
        s->clkm.cold_start &= value & 0x3f;
1641
        return;
1642

    
1643
    case 0x1c:        /* ARM_CKOUT1 */
1644
        diff = s->clkm.arm_ckout1 ^ value;
1645
        s->clkm.arm_ckout1 = value & 0x003f;
1646
        omap_clkm_ckout1_update(s, diff, value);
1647
        return;
1648

    
1649
    case 0x20:        /* ARM_CKOUT2 */
1650
    default:
1651
        OMAP_BAD_REG(addr);
1652
    }
1653
}
1654

    
1655
static CPUReadMemoryFunc * const omap_clkm_readfn[] = {
1656
    omap_badwidth_read16,
1657
    omap_clkm_read,
1658
    omap_badwidth_read16,
1659
};
1660

    
1661
static CPUWriteMemoryFunc * const omap_clkm_writefn[] = {
1662
    omap_badwidth_write16,
1663
    omap_clkm_write,
1664
    omap_badwidth_write16,
1665
};
1666

    
1667
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
1668
{
1669
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1670

    
1671
    switch (addr) {
1672
    case 0x04:        /* DSP_IDLECT1 */
1673
        return s->clkm.dsp_idlect1;
1674

    
1675
    case 0x08:        /* DSP_IDLECT2 */
1676
        return s->clkm.dsp_idlect2;
1677

    
1678
    case 0x14:        /* DSP_RSTCT2 */
1679
        return s->clkm.dsp_rstct2;
1680

    
1681
    case 0x18:        /* DSP_SYSST */
1682
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
1683
                (s->env->halted << 6);        /* Quite useless... */
1684
    }
1685

    
1686
    OMAP_BAD_REG(addr);
1687
    return 0;
1688
}
1689

    
1690
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
1691
                uint16_t diff, uint16_t value)
1692
{
1693
    omap_clk clk;
1694

    
1695
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
1696
}
1697

    
1698
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
1699
                uint16_t diff, uint16_t value)
1700
{
1701
    omap_clk clk;
1702

    
1703
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
1704
}
1705

    
1706
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
1707
                uint32_t value)
1708
{
1709
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1710
    uint16_t diff;
1711

    
1712
    switch (addr) {
1713
    case 0x04:        /* DSP_IDLECT1 */
1714
        diff = s->clkm.dsp_idlect1 ^ value;
1715
        s->clkm.dsp_idlect1 = value & 0x01f7;
1716
        omap_clkdsp_idlect1_update(s, diff, value);
1717
        break;
1718

    
1719
    case 0x08:        /* DSP_IDLECT2 */
1720
        s->clkm.dsp_idlect2 = value & 0x0037;
1721
        diff = s->clkm.dsp_idlect1 ^ value;
1722
        omap_clkdsp_idlect2_update(s, diff, value);
1723
        break;
1724

    
1725
    case 0x14:        /* DSP_RSTCT2 */
1726
        s->clkm.dsp_rstct2 = value & 0x0001;
1727
        break;
1728

    
1729
    case 0x18:        /* DSP_SYSST */
1730
        s->clkm.cold_start &= value & 0x3f;
1731
        break;
1732

    
1733
    default:
1734
        OMAP_BAD_REG(addr);
1735
    }
1736
}
1737

    
1738
static CPUReadMemoryFunc * const omap_clkdsp_readfn[] = {
1739
    omap_badwidth_read16,
1740
    omap_clkdsp_read,
1741
    omap_badwidth_read16,
1742
};
1743

    
1744
static CPUWriteMemoryFunc * const omap_clkdsp_writefn[] = {
1745
    omap_badwidth_write16,
1746
    omap_clkdsp_write,
1747
    omap_badwidth_write16,
1748
};
1749

    
1750
static void omap_clkm_reset(struct omap_mpu_state_s *s)
1751
{
1752
    if (s->wdt && s->wdt->reset)
1753
        s->clkm.cold_start = 0x6;
1754
    s->clkm.clocking_scheme = 0;
1755
    omap_clkm_ckctl_update(s, ~0, 0x3000);
1756
    s->clkm.arm_ckctl = 0x3000;
1757
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
1758
    s->clkm.arm_idlect1 = 0x0400;
1759
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
1760
    s->clkm.arm_idlect2 = 0x0100;
1761
    s->clkm.arm_ewupct = 0x003f;
1762
    s->clkm.arm_rstct1 = 0x0000;
1763
    s->clkm.arm_rstct2 = 0x0000;
1764
    s->clkm.arm_ckout1 = 0x0015;
1765
    s->clkm.dpll1_mode = 0x2002;
1766
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
1767
    s->clkm.dsp_idlect1 = 0x0040;
1768
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
1769
    s->clkm.dsp_idlect2 = 0x0000;
1770
    s->clkm.dsp_rstct2 = 0x0000;
1771
}
1772

    
1773
static void omap_clkm_init(target_phys_addr_t mpu_base,
1774
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
1775
{
1776
    int iomemtype[2] = {
1777
        cpu_register_io_memory(omap_clkm_readfn, omap_clkm_writefn, s),
1778
        cpu_register_io_memory(omap_clkdsp_readfn, omap_clkdsp_writefn, s),
1779
    };
1780

    
1781
    s->clkm.arm_idlect1 = 0x03ff;
1782
    s->clkm.arm_idlect2 = 0x0100;
1783
    s->clkm.dsp_idlect1 = 0x0002;
1784
    omap_clkm_reset(s);
1785
    s->clkm.cold_start = 0x3a;
1786

    
1787
    cpu_register_physical_memory(mpu_base, 0x100, iomemtype[0]);
1788
    cpu_register_physical_memory(dsp_base, 0x1000, iomemtype[1]);
1789
}
1790

    
1791
/* MPU I/O */
1792
struct omap_mpuio_s {
1793
    qemu_irq irq;
1794
    qemu_irq kbd_irq;
1795
    qemu_irq *in;
1796
    qemu_irq handler[16];
1797
    qemu_irq wakeup;
1798

    
1799
    uint16_t inputs;
1800
    uint16_t outputs;
1801
    uint16_t dir;
1802
    uint16_t edge;
1803
    uint16_t mask;
1804
    uint16_t ints;
1805

    
1806
    uint16_t debounce;
1807
    uint16_t latch;
1808
    uint8_t event;
1809

    
1810
    uint8_t buttons[5];
1811
    uint8_t row_latch;
1812
    uint8_t cols;
1813
    int kbd_mask;
1814
    int clk;
1815
};
1816

    
1817
static void omap_mpuio_set(void *opaque, int line, int level)
1818
{
1819
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1820
    uint16_t prev = s->inputs;
1821

    
1822
    if (level)
1823
        s->inputs |= 1 << line;
1824
    else
1825
        s->inputs &= ~(1 << line);
1826

    
1827
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
1828
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
1829
            s->ints |= 1 << line;
1830
            qemu_irq_raise(s->irq);
1831
            /* TODO: wakeup */
1832
        }
1833
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
1834
                (s->event >> 1) == line)        /* PIN_SELECT */
1835
            s->latch = s->inputs;
1836
    }
1837
}
1838

    
1839
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
1840
{
1841
    int i;
1842
    uint8_t *row, rows = 0, cols = ~s->cols;
1843

    
1844
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
1845
        if (*row & cols)
1846
            rows |= i;
1847

    
1848
    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
1849
    s->row_latch = ~rows;
1850
}
1851

    
1852
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
1853
{
1854
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1855
    int offset = addr & OMAP_MPUI_REG_MASK;
1856
    uint16_t ret;
1857

    
1858
    switch (offset) {
1859
    case 0x00:        /* INPUT_LATCH */
1860
        return s->inputs;
1861

    
1862
    case 0x04:        /* OUTPUT_REG */
1863
        return s->outputs;
1864

    
1865
    case 0x08:        /* IO_CNTL */
1866
        return s->dir;
1867

    
1868
    case 0x10:        /* KBR_LATCH */
1869
        return s->row_latch;
1870

    
1871
    case 0x14:        /* KBC_REG */
1872
        return s->cols;
1873

    
1874
    case 0x18:        /* GPIO_EVENT_MODE_REG */
1875
        return s->event;
1876

    
1877
    case 0x1c:        /* GPIO_INT_EDGE_REG */
1878
        return s->edge;
1879

    
1880
    case 0x20:        /* KBD_INT */
1881
        return (~s->row_latch & 0x1f) && !s->kbd_mask;
1882

    
1883
    case 0x24:        /* GPIO_INT */
1884
        ret = s->ints;
1885
        s->ints &= s->mask;
1886
        if (ret)
1887
            qemu_irq_lower(s->irq);
1888
        return ret;
1889

    
1890
    case 0x28:        /* KBD_MASKIT */
1891
        return s->kbd_mask;
1892

    
1893
    case 0x2c:        /* GPIO_MASKIT */
1894
        return s->mask;
1895

    
1896
    case 0x30:        /* GPIO_DEBOUNCING_REG */
1897
        return s->debounce;
1898

    
1899
    case 0x34:        /* GPIO_LATCH_REG */
1900
        return s->latch;
1901
    }
1902

    
1903
    OMAP_BAD_REG(addr);
1904
    return 0;
1905
}
1906

    
1907
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
1908
                uint32_t value)
1909
{
1910
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1911
    int offset = addr & OMAP_MPUI_REG_MASK;
1912
    uint16_t diff;
1913
    int ln;
1914

    
1915
    switch (offset) {
1916
    case 0x04:        /* OUTPUT_REG */
1917
        diff = (s->outputs ^ value) & ~s->dir;
1918
        s->outputs = value;
1919
        while ((ln = ffs(diff))) {
1920
            ln --;
1921
            if (s->handler[ln])
1922
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
1923
            diff &= ~(1 << ln);
1924
        }
1925
        break;
1926

    
1927
    case 0x08:        /* IO_CNTL */
1928
        diff = s->outputs & (s->dir ^ value);
1929
        s->dir = value;
1930

    
1931
        value = s->outputs & ~s->dir;
1932
        while ((ln = ffs(diff))) {
1933
            ln --;
1934
            if (s->handler[ln])
1935
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
1936
            diff &= ~(1 << ln);
1937
        }
1938
        break;
1939

    
1940
    case 0x14:        /* KBC_REG */
1941
        s->cols = value;
1942
        omap_mpuio_kbd_update(s);
1943
        break;
1944

    
1945
    case 0x18:        /* GPIO_EVENT_MODE_REG */
1946
        s->event = value & 0x1f;
1947
        break;
1948

    
1949
    case 0x1c:        /* GPIO_INT_EDGE_REG */
1950
        s->edge = value;
1951
        break;
1952

    
1953
    case 0x28:        /* KBD_MASKIT */
1954
        s->kbd_mask = value & 1;
1955
        omap_mpuio_kbd_update(s);
1956
        break;
1957

    
1958
    case 0x2c:        /* GPIO_MASKIT */
1959
        s->mask = value;
1960
        break;
1961

    
1962
    case 0x30:        /* GPIO_DEBOUNCING_REG */
1963
        s->debounce = value & 0x1ff;
1964
        break;
1965

    
1966
    case 0x00:        /* INPUT_LATCH */
1967
    case 0x10:        /* KBR_LATCH */
1968
    case 0x20:        /* KBD_INT */
1969
    case 0x24:        /* GPIO_INT */
1970
    case 0x34:        /* GPIO_LATCH_REG */
1971
        OMAP_RO_REG(addr);
1972
        return;
1973

    
1974
    default:
1975
        OMAP_BAD_REG(addr);
1976
        return;
1977
    }
1978
}
1979

    
1980
static CPUReadMemoryFunc * const omap_mpuio_readfn[] = {
1981
    omap_badwidth_read16,
1982
    omap_mpuio_read,
1983
    omap_badwidth_read16,
1984
};
1985

    
1986
static CPUWriteMemoryFunc * const omap_mpuio_writefn[] = {
1987
    omap_badwidth_write16,
1988
    omap_mpuio_write,
1989
    omap_badwidth_write16,
1990
};
1991

    
1992
static void omap_mpuio_reset(struct omap_mpuio_s *s)
1993
{
1994
    s->inputs = 0;
1995
    s->outputs = 0;
1996
    s->dir = ~0;
1997
    s->event = 0;
1998
    s->edge = 0;
1999
    s->kbd_mask = 0;
2000
    s->mask = 0;
2001
    s->debounce = 0;
2002
    s->latch = 0;
2003
    s->ints = 0;
2004
    s->row_latch = 0x1f;
2005
    s->clk = 1;
2006
}
2007

    
2008
static void omap_mpuio_onoff(void *opaque, int line, int on)
2009
{
2010
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2011

    
2012
    s->clk = on;
2013
    if (on)
2014
        omap_mpuio_kbd_update(s);
2015
}
2016

    
2017
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
2018
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2019
                omap_clk clk)
2020
{
2021
    int iomemtype;
2022
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
2023
            qemu_mallocz(sizeof(struct omap_mpuio_s));
2024

    
2025
    s->irq = gpio_int;
2026
    s->kbd_irq = kbd_int;
2027
    s->wakeup = wakeup;
2028
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2029
    omap_mpuio_reset(s);
2030

    
2031
    iomemtype = cpu_register_io_memory(omap_mpuio_readfn,
2032
                    omap_mpuio_writefn, s);
2033
    cpu_register_physical_memory(base, 0x800, iomemtype);
2034

    
2035
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2036

    
2037
    return s;
2038
}
2039

    
2040
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2041
{
2042
    return s->in;
2043
}
2044

    
2045
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
2046
{
2047
    if (line >= 16 || line < 0)
2048
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
2049
    s->handler[line] = handler;
2050
}
2051

    
2052
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2053
{
2054
    if (row >= 5 || row < 0)
2055
        hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
2056

    
2057
    if (down)
2058
        s->buttons[row] |= 1 << col;
2059
    else
2060
        s->buttons[row] &= ~(1 << col);
2061

    
2062
    omap_mpuio_kbd_update(s);
2063
}
2064

    
2065
/* MicroWire Interface */
2066
struct omap_uwire_s {
2067
    qemu_irq txirq;
2068
    qemu_irq rxirq;
2069
    qemu_irq txdrq;
2070

    
2071
    uint16_t txbuf;
2072
    uint16_t rxbuf;
2073
    uint16_t control;
2074
    uint16_t setup[5];
2075

    
2076
    uWireSlave *chip[4];
2077
};
2078

    
2079
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
2080
{
2081
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
2082
    uWireSlave *slave = s->chip[chipselect];
2083

    
2084
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
2085
        if (s->control & (1 << 12))                        /* CS_CMD */
2086
            if (slave && slave->send)
2087
                slave->send(slave->opaque,
2088
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
2089
        s->control &= ~(1 << 14);                        /* CSRB */
2090
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2091
         * a DRQ.  When is the level IRQ supposed to be reset?  */
2092
    }
2093

    
2094
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
2095
        if (s->control & (1 << 12))                        /* CS_CMD */
2096
            if (slave && slave->receive)
2097
                s->rxbuf = slave->receive(slave->opaque);
2098
        s->control |= 1 << 15;                                /* RDRB */
2099
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2100
         * a DRQ.  When is the level IRQ supposed to be reset?  */
2101
    }
2102
}
2103

    
2104
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
2105
{
2106
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2107
    int offset = addr & OMAP_MPUI_REG_MASK;
2108

    
2109
    switch (offset) {
2110
    case 0x00:        /* RDR */
2111
        s->control &= ~(1 << 15);                        /* RDRB */
2112
        return s->rxbuf;
2113

    
2114
    case 0x04:        /* CSR */
2115
        return s->control;
2116

    
2117
    case 0x08:        /* SR1 */
2118
        return s->setup[0];
2119
    case 0x0c:        /* SR2 */
2120
        return s->setup[1];
2121
    case 0x10:        /* SR3 */
2122
        return s->setup[2];
2123
    case 0x14:        /* SR4 */
2124
        return s->setup[3];
2125
    case 0x18:        /* SR5 */
2126
        return s->setup[4];
2127
    }
2128

    
2129
    OMAP_BAD_REG(addr);
2130
    return 0;
2131
}
2132

    
2133
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
2134
                uint32_t value)
2135
{
2136
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2137
    int offset = addr & OMAP_MPUI_REG_MASK;
2138

    
2139
    switch (offset) {
2140
    case 0x00:        /* TDR */
2141
        s->txbuf = value;                                /* TD */
2142
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
2143
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
2144
                         (s->control & (1 << 12)))) {        /* CS_CMD */
2145
            s->control |= 1 << 14;                        /* CSRB */
2146
            omap_uwire_transfer_start(s);
2147
        }
2148
        break;
2149

    
2150
    case 0x04:        /* CSR */
2151
        s->control = value & 0x1fff;
2152
        if (value & (1 << 13))                                /* START */
2153
            omap_uwire_transfer_start(s);
2154
        break;
2155

    
2156
    case 0x08:        /* SR1 */
2157
        s->setup[0] = value & 0x003f;
2158
        break;
2159

    
2160
    case 0x0c:        /* SR2 */
2161
        s->setup[1] = value & 0x0fc0;
2162
        break;
2163

    
2164
    case 0x10:        /* SR3 */
2165
        s->setup[2] = value & 0x0003;
2166
        break;
2167

    
2168
    case 0x14:        /* SR4 */
2169
        s->setup[3] = value & 0x0001;
2170
        break;
2171

    
2172
    case 0x18:        /* SR5 */
2173
        s->setup[4] = value & 0x000f;
2174
        break;
2175

    
2176
    default:
2177
        OMAP_BAD_REG(addr);
2178
        return;
2179
    }
2180
}
2181

    
2182
static CPUReadMemoryFunc * const omap_uwire_readfn[] = {
2183
    omap_badwidth_read16,
2184
    omap_uwire_read,
2185
    omap_badwidth_read16,
2186
};
2187

    
2188
static CPUWriteMemoryFunc * const omap_uwire_writefn[] = {
2189
    omap_badwidth_write16,
2190
    omap_uwire_write,
2191
    omap_badwidth_write16,
2192
};
2193

    
2194
static void omap_uwire_reset(struct omap_uwire_s *s)
2195
{
2196
    s->control = 0;
2197
    s->setup[0] = 0;
2198
    s->setup[1] = 0;
2199
    s->setup[2] = 0;
2200
    s->setup[3] = 0;
2201
    s->setup[4] = 0;
2202
}
2203

    
2204
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
2205
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
2206
{
2207
    int iomemtype;
2208
    struct omap_uwire_s *s = (struct omap_uwire_s *)
2209
            qemu_mallocz(sizeof(struct omap_uwire_s));
2210

    
2211
    s->txirq = irq[0];
2212
    s->rxirq = irq[1];
2213
    s->txdrq = dma;
2214
    omap_uwire_reset(s);
2215

    
2216
    iomemtype = cpu_register_io_memory(omap_uwire_readfn,
2217
                    omap_uwire_writefn, s);
2218
    cpu_register_physical_memory(base, 0x800, iomemtype);
2219

    
2220
    return s;
2221
}
2222

    
2223
void omap_uwire_attach(struct omap_uwire_s *s,
2224
                uWireSlave *slave, int chipselect)
2225
{
2226
    if (chipselect < 0 || chipselect > 3) {
2227
        fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
2228
        exit(-1);
2229
    }
2230

    
2231
    s->chip[chipselect] = slave;
2232
}
2233

    
2234
/* Pseudonoise Pulse-Width Light Modulator */
2235
static void omap_pwl_update(struct omap_mpu_state_s *s)
2236
{
2237
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
2238

    
2239
    if (output != s->pwl.output) {
2240
        s->pwl.output = output;
2241
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
2242
    }
2243
}
2244

    
2245
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
2246
{
2247
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2248
    int offset = addr & OMAP_MPUI_REG_MASK;
2249

    
2250
    switch (offset) {
2251
    case 0x00:        /* PWL_LEVEL */
2252
        return s->pwl.level;
2253
    case 0x04:        /* PWL_CTRL */
2254
        return s->pwl.enable;
2255
    }
2256
    OMAP_BAD_REG(addr);
2257
    return 0;
2258
}
2259

    
2260
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
2261
                uint32_t value)
2262
{
2263
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2264
    int offset = addr & OMAP_MPUI_REG_MASK;
2265

    
2266
    switch (offset) {
2267
    case 0x00:        /* PWL_LEVEL */
2268
        s->pwl.level = value;
2269
        omap_pwl_update(s);
2270
        break;
2271
    case 0x04:        /* PWL_CTRL */
2272
        s->pwl.enable = value & 1;
2273
        omap_pwl_update(s);
2274
        break;
2275
    default:
2276
        OMAP_BAD_REG(addr);
2277
        return;
2278
    }
2279
}
2280

    
2281
static CPUReadMemoryFunc * const omap_pwl_readfn[] = {
2282
    omap_pwl_read,
2283
    omap_badwidth_read8,
2284
    omap_badwidth_read8,
2285
};
2286

    
2287
static CPUWriteMemoryFunc * const omap_pwl_writefn[] = {
2288
    omap_pwl_write,
2289
    omap_badwidth_write8,
2290
    omap_badwidth_write8,
2291
};
2292

    
2293
static void omap_pwl_reset(struct omap_mpu_state_s *s)
2294
{
2295
    s->pwl.output = 0;
2296
    s->pwl.level = 0;
2297
    s->pwl.enable = 0;
2298
    s->pwl.clk = 1;
2299
    omap_pwl_update(s);
2300
}
2301

    
2302
static void omap_pwl_clk_update(void *opaque, int line, int on)
2303
{
2304
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2305

    
2306
    s->pwl.clk = on;
2307
    omap_pwl_update(s);
2308
}
2309

    
2310
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
2311
                omap_clk clk)
2312
{
2313
    int iomemtype;
2314

    
2315
    omap_pwl_reset(s);
2316

    
2317
    iomemtype = cpu_register_io_memory(omap_pwl_readfn,
2318
                    omap_pwl_writefn, s);
2319
    cpu_register_physical_memory(base, 0x800, iomemtype);
2320

    
2321
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
2322
}
2323

    
2324
/* Pulse-Width Tone module */
2325
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
2326
{
2327
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2328
    int offset = addr & OMAP_MPUI_REG_MASK;
2329

    
2330
    switch (offset) {
2331
    case 0x00:        /* FRC */
2332
        return s->pwt.frc;
2333
    case 0x04:        /* VCR */
2334
        return s->pwt.vrc;
2335
    case 0x08:        /* GCR */
2336
        return s->pwt.gcr;
2337
    }
2338
    OMAP_BAD_REG(addr);
2339
    return 0;
2340
}
2341

    
2342
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
2343
                uint32_t value)
2344
{
2345
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2346
    int offset = addr & OMAP_MPUI_REG_MASK;
2347

    
2348
    switch (offset) {
2349
    case 0x00:        /* FRC */
2350
        s->pwt.frc = value & 0x3f;
2351
        break;
2352
    case 0x04:        /* VRC */
2353
        if ((value ^ s->pwt.vrc) & 1) {
2354
            if (value & 1)
2355
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
2356
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
2357
                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
2358
                                 /* Pre-multiplexer divider */
2359
                                 ((s->pwt.gcr & 2) ? 1 : 154) /
2360
                                 /* Octave multiplexer */
2361
                                 (2 << (value & 3)) *
2362
                                 /* 101/107 divider */
2363
                                 ((value & (1 << 2)) ? 101 : 107) *
2364
                                 /*  49/55 divider */
2365
                                 ((value & (1 << 3)) ?  49 : 55) *
2366
                                 /*  50/63 divider */
2367
                                 ((value & (1 << 4)) ?  50 : 63) *
2368
                                 /*  80/127 divider */
2369
                                 ((value & (1 << 5)) ?  80 : 127) /
2370
                                 (107 * 55 * 63 * 127)));
2371
            else
2372
                printf("%s: silence!\n", __FUNCTION__);
2373
        }
2374
        s->pwt.vrc = value & 0x7f;
2375
        break;
2376
    case 0x08:        /* GCR */
2377
        s->pwt.gcr = value & 3;
2378
        break;
2379
    default:
2380
        OMAP_BAD_REG(addr);
2381
        return;
2382
    }
2383
}
2384

    
2385
static CPUReadMemoryFunc * const omap_pwt_readfn[] = {
2386
    omap_pwt_read,
2387
    omap_badwidth_read8,
2388
    omap_badwidth_read8,
2389
};
2390

    
2391
static CPUWriteMemoryFunc * const omap_pwt_writefn[] = {
2392
    omap_pwt_write,
2393
    omap_badwidth_write8,
2394
    omap_badwidth_write8,
2395
};
2396

    
2397
static void omap_pwt_reset(struct omap_mpu_state_s *s)
2398
{
2399
    s->pwt.frc = 0;
2400
    s->pwt.vrc = 0;
2401
    s->pwt.gcr = 0;
2402
}
2403

    
2404
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
2405
                omap_clk clk)
2406
{
2407
    int iomemtype;
2408

    
2409
    s->pwt.clk = clk;
2410
    omap_pwt_reset(s);
2411

    
2412
    iomemtype = cpu_register_io_memory(omap_pwt_readfn,
2413
                    omap_pwt_writefn, s);
2414
    cpu_register_physical_memory(base, 0x800, iomemtype);
2415
}
2416

    
2417
/* Real-time Clock module */
2418
struct omap_rtc_s {
2419
    qemu_irq irq;
2420
    qemu_irq alarm;
2421
    QEMUTimer *clk;
2422

    
2423
    uint8_t interrupts;
2424
    uint8_t status;
2425
    int16_t comp_reg;
2426
    int running;
2427
    int pm_am;
2428
    int auto_comp;
2429
    int round;
2430
    struct tm alarm_tm;
2431
    time_t alarm_ti;
2432

    
2433
    struct tm current_tm;
2434
    time_t ti;
2435
    uint64_t tick;
2436
};
2437

    
2438
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
2439
{
2440
    /* s->alarm is level-triggered */
2441
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
2442
}
2443

    
2444
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
2445
{
2446
    s->alarm_ti = mktimegm(&s->alarm_tm);
2447
    if (s->alarm_ti == -1)
2448
        printf("%s: conversion failed\n", __FUNCTION__);
2449
}
2450

    
2451
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
2452
{
2453
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2454
    int offset = addr & OMAP_MPUI_REG_MASK;
2455
    uint8_t i;
2456

    
2457
    switch (offset) {
2458
    case 0x00:        /* SECONDS_REG */
2459
        return to_bcd(s->current_tm.tm_sec);
2460

    
2461
    case 0x04:        /* MINUTES_REG */
2462
        return to_bcd(s->current_tm.tm_min);
2463

    
2464
    case 0x08:        /* HOURS_REG */
2465
        if (s->pm_am)
2466
            return ((s->current_tm.tm_hour > 11) << 7) |
2467
                    to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
2468
        else
2469
            return to_bcd(s->current_tm.tm_hour);
2470

    
2471
    case 0x0c:        /* DAYS_REG */
2472
        return to_bcd(s->current_tm.tm_mday);
2473

    
2474
    case 0x10:        /* MONTHS_REG */
2475
        return to_bcd(s->current_tm.tm_mon + 1);
2476

    
2477
    case 0x14:        /* YEARS_REG */
2478
        return to_bcd(s->current_tm.tm_year % 100);
2479

    
2480
    case 0x18:        /* WEEK_REG */
2481
        return s->current_tm.tm_wday;
2482

    
2483
    case 0x20:        /* ALARM_SECONDS_REG */
2484
        return to_bcd(s->alarm_tm.tm_sec);
2485

    
2486
    case 0x24:        /* ALARM_MINUTES_REG */
2487
        return to_bcd(s->alarm_tm.tm_min);
2488

    
2489
    case 0x28:        /* ALARM_HOURS_REG */
2490
        if (s->pm_am)
2491
            return ((s->alarm_tm.tm_hour > 11) << 7) |
2492
                    to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
2493
        else
2494
            return to_bcd(s->alarm_tm.tm_hour);
2495

    
2496
    case 0x2c:        /* ALARM_DAYS_REG */
2497
        return to_bcd(s->alarm_tm.tm_mday);
2498

    
2499
    case 0x30:        /* ALARM_MONTHS_REG */
2500
        return to_bcd(s->alarm_tm.tm_mon + 1);
2501

    
2502
    case 0x34:        /* ALARM_YEARS_REG */
2503
        return to_bcd(s->alarm_tm.tm_year % 100);
2504

    
2505
    case 0x40:        /* RTC_CTRL_REG */
2506
        return (s->pm_am << 3) | (s->auto_comp << 2) |
2507
                (s->round << 1) | s->running;
2508

    
2509
    case 0x44:        /* RTC_STATUS_REG */
2510
        i = s->status;
2511
        s->status &= ~0x3d;
2512
        return i;
2513

    
2514
    case 0x48:        /* RTC_INTERRUPTS_REG */
2515
        return s->interrupts;
2516

    
2517
    case 0x4c:        /* RTC_COMP_LSB_REG */
2518
        return ((uint16_t) s->comp_reg) & 0xff;
2519

    
2520
    case 0x50:        /* RTC_COMP_MSB_REG */
2521
        return ((uint16_t) s->comp_reg) >> 8;
2522
    }
2523

    
2524
    OMAP_BAD_REG(addr);
2525
    return 0;
2526
}
2527

    
2528
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
2529
                uint32_t value)
2530
{
2531
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2532
    int offset = addr & OMAP_MPUI_REG_MASK;
2533
    struct tm new_tm;
2534
    time_t ti[2];
2535

    
2536
    switch (offset) {
2537
    case 0x00:        /* SECONDS_REG */
2538
#ifdef ALMDEBUG
2539
        printf("RTC SEC_REG <-- %02x\n", value);
2540
#endif
2541
        s->ti -= s->current_tm.tm_sec;
2542
        s->ti += from_bcd(value);
2543
        return;
2544

    
2545
    case 0x04:        /* MINUTES_REG */
2546
#ifdef ALMDEBUG
2547
        printf("RTC MIN_REG <-- %02x\n", value);
2548
#endif
2549
        s->ti -= s->current_tm.tm_min * 60;
2550
        s->ti += from_bcd(value) * 60;
2551
        return;
2552

    
2553
    case 0x08:        /* HOURS_REG */
2554
#ifdef ALMDEBUG
2555
        printf("RTC HRS_REG <-- %02x\n", value);
2556
#endif
2557
        s->ti -= s->current_tm.tm_hour * 3600;
2558
        if (s->pm_am) {
2559
            s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
2560
            s->ti += ((value >> 7) & 1) * 43200;
2561
        } else
2562
            s->ti += from_bcd(value & 0x3f) * 3600;
2563
        return;
2564

    
2565
    case 0x0c:        /* DAYS_REG */
2566
#ifdef ALMDEBUG
2567
        printf("RTC DAY_REG <-- %02x\n", value);
2568
#endif
2569
        s->ti -= s->current_tm.tm_mday * 86400;
2570
        s->ti += from_bcd(value) * 86400;
2571
        return;
2572

    
2573
    case 0x10:        /* MONTHS_REG */
2574
#ifdef ALMDEBUG
2575
        printf("RTC MTH_REG <-- %02x\n", value);
2576
#endif
2577
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2578
        new_tm.tm_mon = from_bcd(value);
2579
        ti[0] = mktimegm(&s->current_tm);
2580
        ti[1] = mktimegm(&new_tm);
2581

    
2582
        if (ti[0] != -1 && ti[1] != -1) {
2583
            s->ti -= ti[0];
2584
            s->ti += ti[1];
2585
        } else {
2586
            /* A less accurate version */
2587
            s->ti -= s->current_tm.tm_mon * 2592000;
2588
            s->ti += from_bcd(value) * 2592000;
2589
        }
2590
        return;
2591

    
2592
    case 0x14:        /* YEARS_REG */
2593
#ifdef ALMDEBUG
2594
        printf("RTC YRS_REG <-- %02x\n", value);
2595
#endif
2596
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2597
        new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
2598
        ti[0] = mktimegm(&s->current_tm);
2599
        ti[1] = mktimegm(&new_tm);
2600

    
2601
        if (ti[0] != -1 && ti[1] != -1) {
2602
            s->ti -= ti[0];
2603
            s->ti += ti[1];
2604
        } else {
2605
            /* A less accurate version */
2606
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
2607
            s->ti += from_bcd(value) * 31536000;
2608
        }
2609
        return;
2610

    
2611
    case 0x18:        /* WEEK_REG */
2612
        return;        /* Ignored */
2613

    
2614
    case 0x20:        /* ALARM_SECONDS_REG */
2615
#ifdef ALMDEBUG
2616
        printf("ALM SEC_REG <-- %02x\n", value);
2617
#endif
2618
        s->alarm_tm.tm_sec = from_bcd(value);
2619
        omap_rtc_alarm_update(s);
2620
        return;
2621

    
2622
    case 0x24:        /* ALARM_MINUTES_REG */
2623
#ifdef ALMDEBUG
2624
        printf("ALM MIN_REG <-- %02x\n", value);
2625
#endif
2626
        s->alarm_tm.tm_min = from_bcd(value);
2627
        omap_rtc_alarm_update(s);
2628
        return;
2629

    
2630
    case 0x28:        /* ALARM_HOURS_REG */
2631
#ifdef ALMDEBUG
2632
        printf("ALM HRS_REG <-- %02x\n", value);
2633
#endif
2634
        if (s->pm_am)
2635
            s->alarm_tm.tm_hour =
2636
                    ((from_bcd(value & 0x3f)) % 12) +
2637
                    ((value >> 7) & 1) * 12;
2638
        else
2639
            s->alarm_tm.tm_hour = from_bcd(value);
2640
        omap_rtc_alarm_update(s);
2641
        return;
2642

    
2643
    case 0x2c:        /* ALARM_DAYS_REG */
2644
#ifdef ALMDEBUG
2645
        printf("ALM DAY_REG <-- %02x\n", value);
2646
#endif
2647
        s->alarm_tm.tm_mday = from_bcd(value);
2648
        omap_rtc_alarm_update(s);
2649
        return;
2650

    
2651
    case 0x30:        /* ALARM_MONTHS_REG */
2652
#ifdef ALMDEBUG
2653
        printf("ALM MON_REG <-- %02x\n", value);
2654
#endif
2655
        s->alarm_tm.tm_mon = from_bcd(value);
2656
        omap_rtc_alarm_update(s);
2657
        return;
2658

    
2659
    case 0x34:        /* ALARM_YEARS_REG */
2660
#ifdef ALMDEBUG
2661
        printf("ALM YRS_REG <-- %02x\n", value);
2662
#endif
2663
        s->alarm_tm.tm_year = from_bcd(value);
2664
        omap_rtc_alarm_update(s);
2665
        return;
2666

    
2667
    case 0x40:        /* RTC_CTRL_REG */
2668
#ifdef ALMDEBUG
2669
        printf("RTC CONTROL <-- %02x\n", value);
2670
#endif
2671
        s->pm_am = (value >> 3) & 1;
2672
        s->auto_comp = (value >> 2) & 1;
2673
        s->round = (value >> 1) & 1;
2674
        s->running = value & 1;
2675
        s->status &= 0xfd;
2676
        s->status |= s->running << 1;
2677
        return;
2678

    
2679
    case 0x44:        /* RTC_STATUS_REG */
2680
#ifdef ALMDEBUG
2681
        printf("RTC STATUSL <-- %02x\n", value);
2682
#endif
2683
        s->status &= ~((value & 0xc0) ^ 0x80);
2684
        omap_rtc_interrupts_update(s);
2685
        return;
2686

    
2687
    case 0x48:        /* RTC_INTERRUPTS_REG */
2688
#ifdef ALMDEBUG
2689
        printf("RTC INTRS <-- %02x\n", value);
2690
#endif
2691
        s->interrupts = value;
2692
        return;
2693

    
2694
    case 0x4c:        /* RTC_COMP_LSB_REG */
2695
#ifdef ALMDEBUG
2696
        printf("RTC COMPLSB <-- %02x\n", value);
2697
#endif
2698
        s->comp_reg &= 0xff00;
2699
        s->comp_reg |= 0x00ff & value;
2700
        return;
2701

    
2702
    case 0x50:        /* RTC_COMP_MSB_REG */
2703
#ifdef ALMDEBUG
2704
        printf("RTC COMPMSB <-- %02x\n", value);
2705
#endif
2706
        s->comp_reg &= 0x00ff;
2707
        s->comp_reg |= 0xff00 & (value << 8);
2708
        return;
2709

    
2710
    default:
2711
        OMAP_BAD_REG(addr);
2712
        return;
2713
    }
2714
}
2715

    
2716
static CPUReadMemoryFunc * const omap_rtc_readfn[] = {
2717
    omap_rtc_read,
2718
    omap_badwidth_read8,
2719
    omap_badwidth_read8,
2720
};
2721

    
2722
static CPUWriteMemoryFunc * const omap_rtc_writefn[] = {
2723
    omap_rtc_write,
2724
    omap_badwidth_write8,
2725
    omap_badwidth_write8,
2726
};
2727

    
2728
static void omap_rtc_tick(void *opaque)
2729
{
2730
    struct omap_rtc_s *s = opaque;
2731

    
2732
    if (s->round) {
2733
        /* Round to nearest full minute.  */
2734
        if (s->current_tm.tm_sec < 30)
2735
            s->ti -= s->current_tm.tm_sec;
2736
        else
2737
            s->ti += 60 - s->current_tm.tm_sec;
2738

    
2739
        s->round = 0;
2740
    }
2741

    
2742
    memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
2743

    
2744
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
2745
        s->status |= 0x40;
2746
        omap_rtc_interrupts_update(s);
2747
    }
2748

    
2749
    if (s->interrupts & 0x04)
2750
        switch (s->interrupts & 3) {
2751
        case 0:
2752
            s->status |= 0x04;
2753
            qemu_irq_pulse(s->irq);
2754
            break;
2755
        case 1:
2756
            if (s->current_tm.tm_sec)
2757
                break;
2758
            s->status |= 0x08;
2759
            qemu_irq_pulse(s->irq);
2760
            break;
2761
        case 2:
2762
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
2763
                break;
2764
            s->status |= 0x10;
2765
            qemu_irq_pulse(s->irq);
2766
            break;
2767
        case 3:
2768
            if (s->current_tm.tm_sec ||
2769
                            s->current_tm.tm_min || s->current_tm.tm_hour)
2770
                break;
2771
            s->status |= 0x20;
2772
            qemu_irq_pulse(s->irq);
2773
            break;
2774
        }
2775

    
2776
    /* Move on */
2777
    if (s->running)
2778
        s->ti ++;
2779
    s->tick += 1000;
2780

    
2781
    /*
2782
     * Every full hour add a rough approximation of the compensation
2783
     * register to the 32kHz Timer (which drives the RTC) value. 
2784
     */
2785
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
2786
        s->tick += s->comp_reg * 1000 / 32768;
2787

    
2788
    qemu_mod_timer(s->clk, s->tick);
2789
}
2790

    
2791
static void omap_rtc_reset(struct omap_rtc_s *s)
2792
{
2793
    struct tm tm;
2794

    
2795
    s->interrupts = 0;
2796
    s->comp_reg = 0;
2797
    s->running = 0;
2798
    s->pm_am = 0;
2799
    s->auto_comp = 0;
2800
    s->round = 0;
2801
    s->tick = qemu_get_clock(rt_clock);
2802
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
2803
    s->alarm_tm.tm_mday = 0x01;
2804
    s->status = 1 << 7;
2805
    qemu_get_timedate(&tm, 0);
2806
    s->ti = mktimegm(&tm);
2807

    
2808
    omap_rtc_alarm_update(s);
2809
    omap_rtc_tick(s);
2810
}
2811

    
2812
static struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
2813
                qemu_irq *irq, omap_clk clk)
2814
{
2815
    int iomemtype;
2816
    struct omap_rtc_s *s = (struct omap_rtc_s *)
2817
            qemu_mallocz(sizeof(struct omap_rtc_s));
2818

    
2819
    s->irq = irq[0];
2820
    s->alarm = irq[1];
2821
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
2822

    
2823
    omap_rtc_reset(s);
2824

    
2825
    iomemtype = cpu_register_io_memory(omap_rtc_readfn,
2826
                    omap_rtc_writefn, s);
2827
    cpu_register_physical_memory(base, 0x800, iomemtype);
2828

    
2829
    return s;
2830
}
2831

    
2832
/* Multi-channel Buffered Serial Port interfaces */
2833
struct omap_mcbsp_s {
2834
    qemu_irq txirq;
2835
    qemu_irq rxirq;
2836
    qemu_irq txdrq;
2837
    qemu_irq rxdrq;
2838

    
2839
    uint16_t spcr[2];
2840
    uint16_t rcr[2];
2841
    uint16_t xcr[2];
2842
    uint16_t srgr[2];
2843
    uint16_t mcr[2];
2844
    uint16_t pcr;
2845
    uint16_t rcer[8];
2846
    uint16_t xcer[8];
2847
    int tx_rate;
2848
    int rx_rate;
2849
    int tx_req;
2850
    int rx_req;
2851

    
2852
    I2SCodec *codec;
2853
    QEMUTimer *source_timer;
2854
    QEMUTimer *sink_timer;
2855
};
2856

    
2857
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2858
{
2859
    int irq;
2860

    
2861
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
2862
    case 0:
2863
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
2864
        break;
2865
    case 3:
2866
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
2867
        break;
2868
    default:
2869
        irq = 0;
2870
        break;
2871
    }
2872

    
2873
    if (irq)
2874
        qemu_irq_pulse(s->rxirq);
2875

    
2876
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
2877
    case 0:
2878
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
2879
        break;
2880
    case 3:
2881
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
2882
        break;
2883
    default:
2884
        irq = 0;
2885
        break;
2886
    }
2887

    
2888
    if (irq)
2889
        qemu_irq_pulse(s->txirq);
2890
}
2891

    
2892
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
2893
{
2894
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
2895
        s->spcr[0] |= 1 << 2;                                /* RFULL */
2896
    s->spcr[0] |= 1 << 1;                                /* RRDY */
2897
    qemu_irq_raise(s->rxdrq);
2898
    omap_mcbsp_intr_update(s);
2899
}
2900

    
2901
static void omap_mcbsp_source_tick(void *opaque)
2902
{
2903
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
2904
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
2905

    
2906
    if (!s->rx_rate)
2907
        return;
2908
    if (s->rx_req)
2909
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
2910

    
2911
    s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
2912

    
2913
    omap_mcbsp_rx_newdata(s);
2914
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) +
2915
                   get_ticks_per_sec());
2916
}
2917

    
2918
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
2919
{
2920
    if (!s->codec || !s->codec->rts)
2921
        omap_mcbsp_source_tick(s);
2922
    else if (s->codec->in.len) {
2923
        s->rx_req = s->codec->in.len;
2924
        omap_mcbsp_rx_newdata(s);
2925
    }
2926
}
2927

    
2928
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
2929
{
2930
    qemu_del_timer(s->source_timer);
2931
}
2932

    
2933
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
2934
{
2935
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
2936
    qemu_irq_lower(s->rxdrq);
2937
    omap_mcbsp_intr_update(s);
2938
}
2939

    
2940
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
2941
{
2942
    s->spcr[1] |= 1 << 1;                                /* XRDY */
2943
    qemu_irq_raise(s->txdrq);
2944
    omap_mcbsp_intr_update(s);
2945
}
2946

    
2947
static void omap_mcbsp_sink_tick(void *opaque)
2948
{
2949
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
2950
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
2951

    
2952
    if (!s->tx_rate)
2953
        return;
2954
    if (s->tx_req)
2955
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
2956

    
2957
    s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
2958

    
2959
    omap_mcbsp_tx_newdata(s);
2960
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) +
2961
                   get_ticks_per_sec());
2962
}
2963

    
2964
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
2965
{
2966
    if (!s->codec || !s->codec->cts)
2967
        omap_mcbsp_sink_tick(s);
2968
    else if (s->codec->out.size) {
2969
        s->tx_req = s->codec->out.size;
2970
        omap_mcbsp_tx_newdata(s);
2971
    }
2972
}
2973

    
2974
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
2975
{
2976
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
2977
    qemu_irq_lower(s->txdrq);
2978
    omap_mcbsp_intr_update(s);
2979
    if (s->codec && s->codec->cts)
2980
        s->codec->tx_swallow(s->codec->opaque);
2981
}
2982

    
2983
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
2984
{
2985
    s->tx_req = 0;
2986
    omap_mcbsp_tx_done(s);
2987
    qemu_del_timer(s->sink_timer);
2988
}
2989

    
2990
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
2991
{
2992
    int prev_rx_rate, prev_tx_rate;
2993
    int rx_rate = 0, tx_rate = 0;
2994
    int cpu_rate = 1500000;        /* XXX */
2995

    
2996
    /* TODO: check CLKSTP bit */
2997
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
2998
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
2999
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3000
                            (s->pcr & (1 << 8))) {        /* CLKRM */
3001
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3002
                    rx_rate = cpu_rate /
3003
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3004
            } else
3005
                if (s->codec)
3006
                    rx_rate = s->codec->rx_rate;
3007
        }
3008

    
3009
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
3010
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3011
                            (s->pcr & (1 << 9))) {        /* CLKXM */
3012
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3013
                    tx_rate = cpu_rate /
3014
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3015
            } else
3016
                if (s->codec)
3017
                    tx_rate = s->codec->tx_rate;
3018
        }
3019
    }
3020
    prev_tx_rate = s->tx_rate;
3021
    prev_rx_rate = s->rx_rate;
3022
    s->tx_rate = tx_rate;
3023
    s->rx_rate = rx_rate;
3024

    
3025
    if (s->codec)
3026
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3027

    
3028
    if (!prev_tx_rate && tx_rate)
3029
        omap_mcbsp_tx_start(s);
3030
    else if (s->tx_rate && !tx_rate)
3031
        omap_mcbsp_tx_stop(s);
3032

    
3033
    if (!prev_rx_rate && rx_rate)
3034
        omap_mcbsp_rx_start(s);
3035
    else if (prev_tx_rate && !tx_rate)
3036
        omap_mcbsp_rx_stop(s);
3037
}
3038

    
3039
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
3040
{
3041
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3042
    int offset = addr & OMAP_MPUI_REG_MASK;
3043
    uint16_t ret;
3044

    
3045
    switch (offset) {
3046
    case 0x00:        /* DRR2 */
3047
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
3048
            return 0x0000;
3049
        /* Fall through.  */
3050
    case 0x02:        /* DRR1 */
3051
        if (s->rx_req < 2) {
3052
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
3053
            omap_mcbsp_rx_done(s);
3054
        } else {
3055
            s->tx_req -= 2;
3056
            if (s->codec && s->codec->in.len >= 2) {
3057
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
3058
                ret |= s->codec->in.fifo[s->codec->in.start ++];
3059
                s->codec->in.len -= 2;
3060
            } else
3061
                ret = 0x0000;
3062
            if (!s->tx_req)
3063
                omap_mcbsp_rx_done(s);
3064
            return ret;
3065
        }
3066
        return 0x0000;
3067

    
3068
    case 0x04:        /* DXR2 */
3069
    case 0x06:        /* DXR1 */
3070
        return 0x0000;
3071

    
3072
    case 0x08:        /* SPCR2 */
3073
        return s->spcr[1];
3074
    case 0x0a:        /* SPCR1 */
3075
        return s->spcr[0];
3076
    case 0x0c:        /* RCR2 */
3077
        return s->rcr[1];
3078
    case 0x0e:        /* RCR1 */
3079
        return s->rcr[0];
3080
    case 0x10:        /* XCR2 */
3081
        return s->xcr[1];
3082
    case 0x12:        /* XCR1 */
3083
        return s->xcr[0];
3084
    case 0x14:        /* SRGR2 */
3085
        return s->srgr[1];
3086
    case 0x16:        /* SRGR1 */
3087
        return s->srgr[0];
3088
    case 0x18:        /* MCR2 */
3089
        return s->mcr[1];
3090
    case 0x1a:        /* MCR1 */
3091
        return s->mcr[0];
3092
    case 0x1c:        /* RCERA */
3093
        return s->rcer[0];
3094
    case 0x1e:        /* RCERB */
3095
        return s->rcer[1];
3096
    case 0x20:        /* XCERA */
3097
        return s->xcer[0];
3098
    case 0x22:        /* XCERB */
3099
        return s->xcer[1];
3100
    case 0x24:        /* PCR0 */
3101
        return s->pcr;
3102
    case 0x26:        /* RCERC */
3103
        return s->rcer[2];
3104
    case 0x28:        /* RCERD */
3105
        return s->rcer[3];
3106
    case 0x2a:        /* XCERC */
3107
        return s->xcer[2];
3108
    case 0x2c:        /* XCERD */
3109
        return s->xcer[3];
3110
    case 0x2e:        /* RCERE */
3111
        return s->rcer[4];
3112
    case 0x30:        /* RCERF */
3113
        return s->rcer[5];
3114
    case 0x32:        /* XCERE */
3115
        return s->xcer[4];
3116
    case 0x34:        /* XCERF */
3117
        return s->xcer[5];
3118
    case 0x36:        /* RCERG */
3119
        return s->rcer[6];
3120
    case 0x38:        /* RCERH */
3121
        return s->rcer[7];
3122
    case 0x3a:        /* XCERG */
3123
        return s->xcer[6];
3124
    case 0x3c:        /* XCERH */
3125
        return s->xcer[7];
3126
    }
3127

    
3128
    OMAP_BAD_REG(addr);
3129
    return 0;
3130
}
3131

    
3132
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
3133
                uint32_t value)
3134
{
3135
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3136
    int offset = addr & OMAP_MPUI_REG_MASK;
3137

    
3138
    switch (offset) {
3139
    case 0x00:        /* DRR2 */
3140
    case 0x02:        /* DRR1 */
3141
        OMAP_RO_REG(addr);
3142
        return;
3143

    
3144
    case 0x04:        /* DXR2 */
3145
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
3146
            return;
3147
        /* Fall through.  */
3148
    case 0x06:        /* DXR1 */
3149
        if (s->tx_req > 1) {
3150
            s->tx_req -= 2;
3151
            if (s->codec && s->codec->cts) {
3152
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
3153
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
3154
            }
3155
            if (s->tx_req < 2)
3156
                omap_mcbsp_tx_done(s);
3157
        } else
3158
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3159
        return;
3160

    
3161
    case 0x08:        /* SPCR2 */
3162
        s->spcr[1] &= 0x0002;
3163
        s->spcr[1] |= 0x03f9 & value;
3164
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
3165
        if (~value & 1)                                        /* XRST */
3166
            s->spcr[1] &= ~6;
3167
        omap_mcbsp_req_update(s);
3168
        return;
3169
    case 0x0a:        /* SPCR1 */
3170
        s->spcr[0] &= 0x0006;
3171
        s->spcr[0] |= 0xf8f9 & value;
3172
        if (value & (1 << 15))                                /* DLB */
3173
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
3174
        if (~value & 1) {                                /* RRST */
3175
            s->spcr[0] &= ~6;
3176
            s->rx_req = 0;
3177
            omap_mcbsp_rx_done(s);
3178
        }
3179
        omap_mcbsp_req_update(s);
3180
        return;
3181

    
3182
    case 0x0c:        /* RCR2 */
3183
        s->rcr[1] = value & 0xffff;
3184
        return;
3185
    case 0x0e:        /* RCR1 */
3186
        s->rcr[0] = value & 0x7fe0;
3187
        return;
3188
    case 0x10:        /* XCR2 */
3189
        s->xcr[1] = value & 0xffff;
3190
        return;
3191
    case 0x12:        /* XCR1 */
3192
        s->xcr[0] = value & 0x7fe0;
3193
        return;
3194
    case 0x14:        /* SRGR2 */
3195
        s->srgr[1] = value & 0xffff;
3196
        omap_mcbsp_req_update(s);
3197
        return;
3198
    case 0x16:        /* SRGR1 */
3199
        s->srgr[0] = value & 0xffff;
3200
        omap_mcbsp_req_update(s);
3201
        return;
3202
    case 0x18:        /* MCR2 */
3203
        s->mcr[1] = value & 0x03e3;
3204
        if (value & 3)                                        /* XMCM */
3205
            printf("%s: Tx channel selection mode enable attempt\n",
3206
                            __FUNCTION__);
3207
        return;
3208
    case 0x1a:        /* MCR1 */
3209
        s->mcr[0] = value & 0x03e1;
3210
        if (value & 1)                                        /* RMCM */
3211
            printf("%s: Rx channel selection mode enable attempt\n",
3212
                            __FUNCTION__);
3213
        return;
3214
    case 0x1c:        /* RCERA */
3215
        s->rcer[0] = value & 0xffff;
3216
        return;
3217
    case 0x1e:        /* RCERB */
3218
        s->rcer[1] = value & 0xffff;
3219
        return;
3220
    case 0x20:        /* XCERA */
3221
        s->xcer[0] = value & 0xffff;
3222
        return;
3223
    case 0x22:        /* XCERB */
3224
        s->xcer[1] = value & 0xffff;
3225
        return;
3226
    case 0x24:        /* PCR0 */
3227
        s->pcr = value & 0x7faf;
3228
        return;
3229
    case 0x26:        /* RCERC */
3230
        s->rcer[2] = value & 0xffff;
3231
        return;
3232
    case 0x28:        /* RCERD */
3233
        s->rcer[3] = value & 0xffff;
3234
        return;
3235
    case 0x2a:        /* XCERC */
3236
        s->xcer[2] = value & 0xffff;
3237
        return;
3238
    case 0x2c:        /* XCERD */
3239
        s->xcer[3] = value & 0xffff;
3240
        return;
3241
    case 0x2e:        /* RCERE */
3242
        s->rcer[4] = value & 0xffff;
3243
        return;
3244
    case 0x30:        /* RCERF */
3245
        s->rcer[5] = value & 0xffff;
3246
        return;
3247
    case 0x32:        /* XCERE */
3248
        s->xcer[4] = value & 0xffff;
3249
        return;
3250
    case 0x34:        /* XCERF */
3251
        s->xcer[5] = value & 0xffff;
3252
        return;
3253
    case 0x36:        /* RCERG */
3254
        s->rcer[6] = value & 0xffff;
3255
        return;
3256
    case 0x38:        /* RCERH */
3257
        s->rcer[7] = value & 0xffff;
3258
        return;
3259
    case 0x3a:        /* XCERG */
3260
        s->xcer[6] = value & 0xffff;
3261
        return;
3262
    case 0x3c:        /* XCERH */
3263
        s->xcer[7] = value & 0xffff;
3264
        return;
3265
    }
3266

    
3267
    OMAP_BAD_REG(addr);
3268
}
3269

    
3270
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
3271
                uint32_t value)
3272
{
3273
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3274
    int offset = addr & OMAP_MPUI_REG_MASK;
3275

    
3276
    if (offset == 0x04) {                                /* DXR */
3277
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
3278
            return;
3279
        if (s->tx_req > 3) {
3280
            s->tx_req -= 4;
3281
            if (s->codec && s->codec->cts) {
3282
                s->codec->out.fifo[s->codec->out.len ++] =
3283
                        (value >> 24) & 0xff;
3284
                s->codec->out.fifo[s->codec->out.len ++] =
3285
                        (value >> 16) & 0xff;
3286
                s->codec->out.fifo[s->codec->out.len ++] =
3287
                        (value >> 8) & 0xff;
3288
                s->codec->out.fifo[s->codec->out.len ++] =
3289
                        (value >> 0) & 0xff;
3290
            }
3291
            if (s->tx_req < 4)
3292
                omap_mcbsp_tx_done(s);
3293
        } else
3294
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3295
        return;
3296
    }
3297

    
3298
    omap_badwidth_write16(opaque, addr, value);
3299
}
3300

    
3301
static CPUReadMemoryFunc * const omap_mcbsp_readfn[] = {
3302
    omap_badwidth_read16,
3303
    omap_mcbsp_read,
3304
    omap_badwidth_read16,
3305
};
3306

    
3307
static CPUWriteMemoryFunc * const omap_mcbsp_writefn[] = {
3308
    omap_badwidth_write16,
3309
    omap_mcbsp_writeh,
3310
    omap_mcbsp_writew,
3311
};
3312

    
3313
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
3314
{
3315
    memset(&s->spcr, 0, sizeof(s->spcr));
3316
    memset(&s->rcr, 0, sizeof(s->rcr));
3317
    memset(&s->xcr, 0, sizeof(s->xcr));
3318
    s->srgr[0] = 0x0001;
3319
    s->srgr[1] = 0x2000;
3320
    memset(&s->mcr, 0, sizeof(s->mcr));
3321
    memset(&s->pcr, 0, sizeof(s->pcr));
3322
    memset(&s->rcer, 0, sizeof(s->rcer));
3323
    memset(&s->xcer, 0, sizeof(s->xcer));
3324
    s->tx_req = 0;
3325
    s->rx_req = 0;
3326
    s->tx_rate = 0;
3327
    s->rx_rate = 0;
3328
    qemu_del_timer(s->source_timer);
3329
    qemu_del_timer(s->sink_timer);
3330
}
3331

    
3332
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
3333
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
3334
{
3335
    int iomemtype;
3336
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
3337
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
3338

    
3339
    s->txirq = irq[0];
3340
    s->rxirq = irq[1];
3341
    s->txdrq = dma[0];
3342
    s->rxdrq = dma[1];
3343
    s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
3344
    s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
3345
    omap_mcbsp_reset(s);
3346

    
3347
    iomemtype = cpu_register_io_memory(omap_mcbsp_readfn,
3348
                    omap_mcbsp_writefn, s);
3349
    cpu_register_physical_memory(base, 0x800, iomemtype);
3350

    
3351
    return s;
3352
}
3353

    
3354
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
3355
{
3356
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3357

    
3358
    if (s->rx_rate) {
3359
        s->rx_req = s->codec->in.len;
3360
        omap_mcbsp_rx_newdata(s);
3361
    }
3362
}
3363

    
3364
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
3365
{
3366
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3367

    
3368
    if (s->tx_rate) {
3369
        s->tx_req = s->codec->out.size;
3370
        omap_mcbsp_tx_newdata(s);
3371
    }
3372
}
3373

    
3374
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
3375
{
3376
    s->codec = slave;
3377
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
3378
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
3379
}
3380

    
3381
/* LED Pulse Generators */
3382
struct omap_lpg_s {
3383
    QEMUTimer *tm;
3384

    
3385
    uint8_t control;
3386
    uint8_t power;
3387
    int64_t on;
3388
    int64_t period;
3389
    int clk;
3390
    int cycle;
3391
};
3392

    
3393
static void omap_lpg_tick(void *opaque)
3394
{
3395
    struct omap_lpg_s *s = opaque;
3396

    
3397
    if (s->cycle)
3398
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
3399
    else
3400
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
3401

    
3402
    s->cycle = !s->cycle;
3403
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
3404
}
3405

    
3406
static void omap_lpg_update(struct omap_lpg_s *s)
3407
{
3408
    int64_t on, period = 1, ticks = 1000;
3409
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
3410

    
3411
    if (~s->control & (1 << 6))                                        /* LPGRES */
3412
        on = 0;
3413
    else if (s->control & (1 << 7))                                /* PERM_ON */
3414
        on = period;
3415
    else {
3416
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
3417
                        256 / 32);
3418
        on = (s->clk && s->power) ? muldiv64(ticks,
3419
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
3420
    }
3421

    
3422
    qemu_del_timer(s->tm);
3423
    if (on == period && s->on < s->period)
3424
        printf("%s: LED is on\n", __FUNCTION__);
3425
    else if (on == 0 && s->on)
3426
        printf("%s: LED is off\n", __FUNCTION__);
3427
    else if (on && (on != s->on || period != s->period)) {
3428
        s->cycle = 0;
3429
        s->on = on;
3430
        s->period = period;
3431
        omap_lpg_tick(s);
3432
        return;
3433
    }
3434

    
3435
    s->on = on;
3436
    s->period = period;
3437
}
3438

    
3439
static void omap_lpg_reset(struct omap_lpg_s *s)
3440
{
3441
    s->control = 0x00;
3442
    s->power = 0x00;
3443
    s->clk = 1;
3444
    omap_lpg_update(s);
3445
}
3446

    
3447
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
3448
{
3449
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3450
    int offset = addr & OMAP_MPUI_REG_MASK;
3451

    
3452
    switch (offset) {
3453
    case 0x00:        /* LCR */
3454
        return s->control;
3455

    
3456
    case 0x04:        /* PMR */
3457
        return s->power;
3458
    }
3459

    
3460
    OMAP_BAD_REG(addr);
3461
    return 0;
3462
}
3463

    
3464
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
3465
                uint32_t value)
3466
{
3467
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3468
    int offset = addr & OMAP_MPUI_REG_MASK;
3469

    
3470
    switch (offset) {
3471
    case 0x00:        /* LCR */
3472
        if (~value & (1 << 6))                                        /* LPGRES */
3473
            omap_lpg_reset(s);
3474
        s->control = value & 0xff;
3475
        omap_lpg_update(s);
3476
        return;
3477

    
3478
    case 0x04:        /* PMR */
3479
        s->power = value & 0x01;
3480
        omap_lpg_update(s);
3481
        return;
3482

    
3483
    default:
3484
        OMAP_BAD_REG(addr);
3485
        return;
3486
    }
3487
}
3488

    
3489
static CPUReadMemoryFunc * const omap_lpg_readfn[] = {
3490
    omap_lpg_read,
3491
    omap_badwidth_read8,
3492
    omap_badwidth_read8,
3493
};
3494

    
3495
static CPUWriteMemoryFunc * const omap_lpg_writefn[] = {
3496
    omap_lpg_write,
3497
    omap_badwidth_write8,
3498
    omap_badwidth_write8,
3499
};
3500

    
3501
static void omap_lpg_clk_update(void *opaque, int line, int on)
3502
{
3503
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3504

    
3505
    s->clk = on;
3506
    omap_lpg_update(s);
3507
}
3508

    
3509
static struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
3510
{
3511
    int iomemtype;
3512
    struct omap_lpg_s *s = (struct omap_lpg_s *)
3513
            qemu_mallocz(sizeof(struct omap_lpg_s));
3514

    
3515
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
3516

    
3517
    omap_lpg_reset(s);
3518

    
3519
    iomemtype = cpu_register_io_memory(omap_lpg_readfn,
3520
                    omap_lpg_writefn, s);
3521
    cpu_register_physical_memory(base, 0x800, iomemtype);
3522

    
3523
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
3524

    
3525
    return s;
3526
}
3527

    
3528
/* MPUI Peripheral Bridge configuration */
3529
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
3530
{
3531
    if (addr == OMAP_MPUI_BASE)        /* CMR */
3532
        return 0xfe4d;
3533

    
3534
    OMAP_BAD_REG(addr);
3535
    return 0;
3536
}
3537

    
3538
static CPUReadMemoryFunc * const omap_mpui_io_readfn[] = {
3539
    omap_badwidth_read16,
3540
    omap_mpui_io_read,
3541
    omap_badwidth_read16,
3542
};
3543

    
3544
static CPUWriteMemoryFunc * const omap_mpui_io_writefn[] = {
3545
    omap_badwidth_write16,
3546
    omap_badwidth_write16,
3547
    omap_badwidth_write16,
3548
};
3549

    
3550
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
3551
{
3552
    int iomemtype = cpu_register_io_memory(omap_mpui_io_readfn,
3553
                    omap_mpui_io_writefn, mpu);
3554
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
3555
}
3556

    
3557
/* General chip reset */
3558
static void omap1_mpu_reset(void *opaque)
3559
{
3560
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3561

    
3562
    omap_inth_reset(mpu->ih[0]);
3563
    omap_inth_reset(mpu->ih[1]);
3564
    omap_dma_reset(mpu->dma);
3565
    omap_mpu_timer_reset(mpu->timer[0]);
3566
    omap_mpu_timer_reset(mpu->timer[1]);
3567
    omap_mpu_timer_reset(mpu->timer[2]);
3568
    omap_wd_timer_reset(mpu->wdt);
3569
    omap_os_timer_reset(mpu->os_timer);
3570
    omap_lcdc_reset(mpu->lcd);
3571
    omap_ulpd_pm_reset(mpu);
3572
    omap_pin_cfg_reset(mpu);
3573
    omap_mpui_reset(mpu);
3574
    omap_tipb_bridge_reset(mpu->private_tipb);
3575
    omap_tipb_bridge_reset(mpu->public_tipb);
3576
    omap_dpll_reset(&mpu->dpll[0]);
3577
    omap_dpll_reset(&mpu->dpll[1]);
3578
    omap_dpll_reset(&mpu->dpll[2]);
3579
    omap_uart_reset(mpu->uart[0]);
3580
    omap_uart_reset(mpu->uart[1]);
3581
    omap_uart_reset(mpu->uart[2]);
3582
    omap_mmc_reset(mpu->mmc);
3583
    omap_mpuio_reset(mpu->mpuio);
3584
    omap_gpio_reset(mpu->gpio);
3585
    omap_uwire_reset(mpu->microwire);
3586
    omap_pwl_reset(mpu);
3587
    omap_pwt_reset(mpu);
3588
    omap_i2c_reset(mpu->i2c[0]);
3589
    omap_rtc_reset(mpu->rtc);
3590
    omap_mcbsp_reset(mpu->mcbsp1);
3591
    omap_mcbsp_reset(mpu->mcbsp2);
3592
    omap_mcbsp_reset(mpu->mcbsp3);
3593
    omap_lpg_reset(mpu->led[0]);
3594
    omap_lpg_reset(mpu->led[1]);
3595
    omap_clkm_reset(mpu);
3596
    cpu_reset(mpu->env);
3597
}
3598

    
3599
static const struct omap_map_s {
3600
    target_phys_addr_t phys_dsp;
3601
    target_phys_addr_t phys_mpu;
3602
    uint32_t size;
3603
    const char *name;
3604
} omap15xx_dsp_mm[] = {
3605
    /* Strobe 0 */
3606
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
3607
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
3608
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
3609
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
3610
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
3611
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
3612
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
3613
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
3614
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
3615
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
3616
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
3617
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
3618
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
3619
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
3620
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
3621
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
3622
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
3623
    /* Strobe 1 */
3624
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
3625

    
3626
    { 0 }
3627
};
3628

    
3629
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
3630
{
3631
    int io;
3632

    
3633
    for (; map->phys_dsp; map ++) {
3634
        io = cpu_get_physical_page_desc(map->phys_mpu);
3635

    
3636
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
3637
    }
3638
}
3639

    
3640
void omap_mpu_wakeup(void *opaque, int irq, int req)
3641
{
3642
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3643

    
3644
    if (mpu->env->halted)
3645
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
3646
}
3647

    
3648
static const struct dma_irq_map omap1_dma_irq_map[] = {
3649
    { 0, OMAP_INT_DMA_CH0_6 },
3650
    { 0, OMAP_INT_DMA_CH1_7 },
3651
    { 0, OMAP_INT_DMA_CH2_8 },
3652
    { 0, OMAP_INT_DMA_CH3 },
3653
    { 0, OMAP_INT_DMA_CH4 },
3654
    { 0, OMAP_INT_DMA_CH5 },
3655
    { 1, OMAP_INT_1610_DMA_CH6 },
3656
    { 1, OMAP_INT_1610_DMA_CH7 },
3657
    { 1, OMAP_INT_1610_DMA_CH8 },
3658
    { 1, OMAP_INT_1610_DMA_CH9 },
3659
    { 1, OMAP_INT_1610_DMA_CH10 },
3660
    { 1, OMAP_INT_1610_DMA_CH11 },
3661
    { 1, OMAP_INT_1610_DMA_CH12 },
3662
    { 1, OMAP_INT_1610_DMA_CH13 },
3663
    { 1, OMAP_INT_1610_DMA_CH14 },
3664
    { 1, OMAP_INT_1610_DMA_CH15 }
3665
};
3666

    
3667
/* DMA ports for OMAP1 */
3668
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
3669
                target_phys_addr_t addr)
3670
{
3671
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
3672
}
3673

    
3674
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
3675
                target_phys_addr_t addr)
3676
{
3677
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
3678
}
3679

    
3680
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
3681
                target_phys_addr_t addr)
3682
{
3683
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
3684
}
3685

    
3686
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
3687
                target_phys_addr_t addr)
3688
{
3689
    return addr >= 0xfffb0000 && addr < 0xffff0000;
3690
}
3691

    
3692
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
3693
                target_phys_addr_t addr)
3694
{
3695
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
3696
}
3697

    
3698
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
3699
                target_phys_addr_t addr)
3700
{
3701
    return addr >= 0xe1010000 && addr < 0xe1020004;
3702
}
3703

    
3704
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
3705
                const char *core)
3706
{
3707
    int i;
3708
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
3709
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
3710
    ram_addr_t imif_base, emiff_base;
3711
    qemu_irq *cpu_irq;
3712
    qemu_irq dma_irqs[6];
3713
    DriveInfo *dinfo;
3714

    
3715
    if (!core)
3716
        core = "ti925t";
3717

    
3718
    /* Core */
3719
    s->mpu_model = omap310;
3720
    s->env = cpu_init(core);
3721
    if (!s->env) {
3722
        fprintf(stderr, "Unable to find CPU definition\n");
3723
        exit(1);
3724
    }
3725
    s->sdram_size = sdram_size;
3726
    s->sram_size = OMAP15XX_SRAM_SIZE;
3727

    
3728
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
3729

    
3730
    /* Clocks */
3731
    omap_clk_init(s);
3732

    
3733
    /* Memory-mapped stuff */
3734
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
3735
                    (emiff_base = qemu_ram_alloc(NULL, "omap1.dram",
3736
                                                 s->sdram_size)) | IO_MEM_RAM);
3737
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
3738
                    (imif_base = qemu_ram_alloc(NULL, "omap1.sram",
3739
                                                s->sram_size)) | IO_MEM_RAM);
3740

    
3741
    omap_clkm_init(0xfffece00, 0xe1008000, s);
3742

    
3743
    cpu_irq = arm_pic_init_cpu(s->env);
3744
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0],
3745
                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
3746
                    omap_findclk(s, "arminth_ck"));
3747
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, &s->irq[1],
3748
                    omap_inth_get_pin(s->ih[0], OMAP_INT_15XX_IH2_IRQ),
3749
                    NULL, omap_findclk(s, "arminth_ck"));
3750

    
3751
    for (i = 0; i < 6; i ++)
3752
        dma_irqs[i] =
3753
                s->irq[omap1_dma_irq_map[i].ih][omap1_dma_irq_map[i].intr];
3754
    s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
3755
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
3756

    
3757
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
3758
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
3759
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
3760
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
3761
    s->port[local    ].addr_valid = omap_validate_local_addr;
3762
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
3763

    
3764
    /* Register SDRAM and SRAM DMA ports for fast transfers.  */
3765
    soc_dma_port_add_mem_ram(s->dma,
3766
                    emiff_base, OMAP_EMIFF_BASE, s->sdram_size);
3767
    soc_dma_port_add_mem_ram(s->dma,
3768
                    imif_base, OMAP_IMIF_BASE, s->sram_size);
3769

    
3770
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
3771
                    s->irq[0][OMAP_INT_TIMER1],
3772
                    omap_findclk(s, "mputim_ck"));
3773
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
3774
                    s->irq[0][OMAP_INT_TIMER2],
3775
                    omap_findclk(s, "mputim_ck"));
3776
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
3777
                    s->irq[0][OMAP_INT_TIMER3],
3778
                    omap_findclk(s, "mputim_ck"));
3779

    
3780
    s->wdt = omap_wd_timer_init(0xfffec800,
3781
                    s->irq[0][OMAP_INT_WD_TIMER],
3782
                    omap_findclk(s, "armwdt_ck"));
3783

    
3784
    s->os_timer = omap_os_timer_init(0xfffb9000,
3785
                    s->irq[1][OMAP_INT_OS_TIMER],
3786
                    omap_findclk(s, "clk32-kHz"));
3787

    
3788
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
3789
                    omap_dma_get_lcdch(s->dma), imif_base, emiff_base,
3790
                    omap_findclk(s, "lcd_ck"));
3791

    
3792
    omap_ulpd_pm_init(0xfffe0800, s);
3793
    omap_pin_cfg_init(0xfffe1000, s);
3794
    omap_id_init(s);
3795

    
3796
    omap_mpui_init(0xfffec900, s);
3797

    
3798
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
3799
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
3800
                    omap_findclk(s, "tipb_ck"));
3801
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
3802
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
3803
                    omap_findclk(s, "tipb_ck"));
3804

    
3805
    omap_tcmi_init(0xfffecc00, s);
3806

    
3807
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
3808
                    omap_findclk(s, "uart1_ck"),
3809
                    omap_findclk(s, "uart1_ck"),
3810
                    s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
3811
                    serial_hds[0]);
3812
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
3813
                    omap_findclk(s, "uart2_ck"),
3814
                    omap_findclk(s, "uart2_ck"),
3815
                    s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
3816
                    serial_hds[0] ? serial_hds[1] : NULL);
3817
    s->uart[2] = omap_uart_init(0xfffb9800, s->irq[0][OMAP_INT_UART3],
3818
                    omap_findclk(s, "uart3_ck"),
3819
                    omap_findclk(s, "uart3_ck"),
3820
                    s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
3821
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
3822

    
3823
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
3824
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
3825
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
3826

    
3827
    dinfo = drive_get(IF_SD, 0, 0);
3828
    if (!dinfo) {
3829
        fprintf(stderr, "qemu: missing SecureDigital device\n");
3830
        exit(1);
3831
    }
3832
    s->mmc = omap_mmc_init(0xfffb7800, dinfo->bdrv,
3833
                    s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
3834
                    omap_findclk(s, "mmc_ck"));
3835

    
3836
    s->mpuio = omap_mpuio_init(0xfffb5000,
3837
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
3838
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
3839

    
3840
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
3841
                    omap_findclk(s, "arm_gpio_ck"));
3842

    
3843
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
3844
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
3845

    
3846
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
3847
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
3848

    
3849
    s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
3850
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
3851

    
3852
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
3853
                    omap_findclk(s, "clk32-kHz"));
3854

    
3855
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
3856
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
3857
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
3858
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
3859
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
3860
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
3861

    
3862
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
3863
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
3864

    
3865
    /* Register mappings not currenlty implemented:
3866
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
3867
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
3868
     * USB W2FC                fffb4000 - fffb47ff
3869
     * Camera Interface        fffb6800 - fffb6fff
3870
     * USB Host                fffba000 - fffba7ff
3871
     * FAC                fffba800 - fffbafff
3872
     * HDQ/1-Wire        fffbc000 - fffbc7ff
3873
     * TIPB switches        fffbc800 - fffbcfff
3874
     * Mailbox                fffcf000 - fffcf7ff
3875
     * Local bus IF        fffec100 - fffec1ff
3876
     * Local bus MMU        fffec200 - fffec2ff
3877
     * DSP MMU                fffed200 - fffed2ff
3878
     */
3879

    
3880
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
3881
    omap_setup_mpui_io(s);
3882

    
3883
    qemu_register_reset(omap1_mpu_reset, s);
3884

    
3885
    return s;
3886
}