Statistics
| Branch: | Revision:

root / hw / omap1.c @ 2507c12a

History | View | Annotate | Download (109.2 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
#include "blockdev.h"
29
#include "range.h"
30

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

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

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

    
46
    OMAP_8B_REG(addr);
47
    cpu_physical_memory_write(addr, (void *) &val8, 1);
48
}
49

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

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

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

    
64
    OMAP_16B_REG(addr);
65
    cpu_physical_memory_write(addr, (void *) &val16, 2);
66
}
67

    
68
uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
69
{
70
    uint32_t ret;
71

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

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

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

    
95
    int enable;
96
    int ptv;
97
    int ar;
98
    int st;
99
    uint32_t reset_val;
100
};
101

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

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

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

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

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

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

    
142
static void omap_timer_fire(void *opaque)
143
{
144
    struct omap_mpu_timer_s *timer = opaque;
145

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

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

    
156
static void omap_timer_tick(void *opaque)
157
{
158
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
159

    
160
    omap_timer_sync(timer);
161
    omap_timer_fire(timer);
162
    omap_timer_update(timer);
163
}
164

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

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

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

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

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

    
189
    case 0x04:        /* LOAD_TIM */
190
        break;
191

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

    
196
    OMAP_BAD_REG(addr);
197
    return 0;
198
}
199

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

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

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

    
219
    case 0x08:        /* READ_TIM */
220
        OMAP_RO_REG(addr);
221
        break;
222

    
223
    default:
224
        OMAP_BAD_REG(addr);
225
    }
226
}
227

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

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

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

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

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

    
266
    iomemtype = cpu_register_io_memory(omap_mpu_timer_readfn,
267
                    omap_mpu_timer_writefn, s, DEVICE_NATIVE_ENDIAN);
268
    cpu_register_physical_memory(base, 0x100, iomemtype);
269

    
270
    return s;
271
}
272

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

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

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

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

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

    
298
    OMAP_BAD_REG(addr);
299
    return 0;
300
}
301

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

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

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

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

    
341
    default:
342
        OMAP_BAD_REG(addr);
343
    }
344
}
345

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

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

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

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

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

    
389
    iomemtype = cpu_register_io_memory(omap_wd_timer_readfn,
390
                    omap_wd_timer_writefn, s, DEVICE_NATIVE_ENDIAN);
391
    cpu_register_physical_memory(base, 0x100, iomemtype);
392

    
393
    return s;
394
}
395

    
396
/* 32-kHz timer */
397
struct omap_32khz_timer_s {
398
    struct omap_mpu_timer_s timer;
399
};
400

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

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

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

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

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

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

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

    
434
    case 0x04:        /* TCR */
435
        OMAP_RO_REG(addr);
436
        break;
437

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

    
449
    default:
450
        OMAP_BAD_REG(addr);
451
    }
452
}
453

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

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

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

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

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

    
491
    iomemtype = cpu_register_io_memory(omap_os_timer_readfn,
492
                    omap_os_timer_writefn, s, DEVICE_NATIVE_ENDIAN);
493
    cpu_register_physical_memory(base, 0x800, iomemtype);
494

    
495
    return s;
496
}
497

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

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

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

    
535
    OMAP_BAD_REG(addr);
536
    return 0;
537
}
538

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
671
    default:
672
        OMAP_BAD_REG(addr);
673
    }
674
}
675

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

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

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

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

    
721
    cpu_register_physical_memory(base, 0x800, iomemtype);
722
    omap_ulpd_pm_reset(mpu);
723
}
724

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

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

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

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

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

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

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

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

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

    
771
    OMAP_BAD_REG(addr);
772
    return 0;
773
}
774

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
897
    default:
898
        OMAP_BAD_REG(addr);
899
    }
900
}
901

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

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

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

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

    
936
    cpu_register_physical_memory(base, 0x800, iomemtype);
937
    omap_pin_cfg_reset(mpu);
938
}
939

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

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

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

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

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

    
979
    OMAP_BAD_REG(addr);
980
    return 0;
981
}
982

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

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

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

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

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

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

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

    
1036
    OMAP_BAD_REG(addr);
1037
    return 0;
1038
}
1039

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

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

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

    
1061
    default:
1062
        OMAP_BAD_REG(addr);
1063
    }
1064
}
1065

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

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

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

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

    
1089
    cpu_register_physical_memory(base, 0x100, iomemtype);
1090

    
1091
    omap_mpui_reset(mpu);
1092
}
1093

    
1094
/* TIPB Bridges */
1095
struct omap_tipb_bridge_s {
1096
    qemu_irq abort;
1097

    
1098
    int width_intr;
1099
    uint16_t control;
1100
    uint16_t alloc;
1101
    uint16_t buffer;
1102
    uint16_t enh_control;
1103
};
1104

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

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

    
1126
    OMAP_BAD_REG(addr);
1127
    return 0;
1128
}
1129

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

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

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

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

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

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

    
1160
    default:
1161
        OMAP_BAD_REG(addr);
1162
    }
1163
}
1164

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

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

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

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

    
1192
    s->abort = abort_irq;
1193
    omap_tipb_bridge_reset(s);
1194

    
1195
    iomemtype = cpu_register_io_memory(omap_tipb_bridge_readfn,
1196
                    omap_tipb_bridge_writefn, s, DEVICE_NATIVE_ENDIAN);
1197
    cpu_register_physical_memory(base, 0x100, iomemtype);
1198

    
1199
    return s;
1200
}
1201

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

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

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

    
1232
    OMAP_BAD_REG(addr);
1233
    return 0;
1234
}
1235

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

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

    
1262
    default:
1263
        OMAP_BAD_REG(addr);
1264
    }
1265
}
1266

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

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

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

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

    
1304
    cpu_register_physical_memory(base, 0x100, iomemtype);
1305
    omap_tcmi_reset(mpu);
1306
}
1307

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

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

    
1316
    OMAP_BAD_REG(addr);
1317
    return 0;
1318
}
1319

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

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

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

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

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

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

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

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

    
1377
    s->dpll = clk;
1378
    omap_dpll_reset(s);
1379

    
1380
    cpu_register_physical_memory(base, 0x100, iomemtype);
1381
}
1382

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

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

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

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

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

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

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

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

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

    
1413
    case 0x20:        /* ARM_CKOUT2 */
1414
        break;
1415
    }
1416

    
1417
    OMAP_BAD_REG(addr);
1418
    return 0;
1419
}
1420

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1688
    OMAP_BAD_REG(addr);
1689
    return 0;
1690
}
1691

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

    
1697
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
1698
}
1699

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

    
1705
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
1706
}
1707

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

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

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

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

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

    
1735
    default:
1736
        OMAP_BAD_REG(addr);
1737
    }
1738
}
1739

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

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

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

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

    
1785
    s->clkm.arm_idlect1 = 0x03ff;
1786
    s->clkm.arm_idlect2 = 0x0100;
1787
    s->clkm.dsp_idlect1 = 0x0002;
1788
    omap_clkm_reset(s);
1789
    s->clkm.cold_start = 0x3a;
1790

    
1791
    cpu_register_physical_memory(mpu_base, 0x100, iomemtype[0]);
1792
    cpu_register_physical_memory(dsp_base, 0x1000, iomemtype[1]);
1793
}
1794

    
1795
/* MPU I/O */
1796
struct omap_mpuio_s {
1797
    qemu_irq irq;
1798
    qemu_irq kbd_irq;
1799
    qemu_irq *in;
1800
    qemu_irq handler[16];
1801
    qemu_irq wakeup;
1802

    
1803
    uint16_t inputs;
1804
    uint16_t outputs;
1805
    uint16_t dir;
1806
    uint16_t edge;
1807
    uint16_t mask;
1808
    uint16_t ints;
1809

    
1810
    uint16_t debounce;
1811
    uint16_t latch;
1812
    uint8_t event;
1813

    
1814
    uint8_t buttons[5];
1815
    uint8_t row_latch;
1816
    uint8_t cols;
1817
    int kbd_mask;
1818
    int clk;
1819
};
1820

    
1821
static void omap_mpuio_set(void *opaque, int line, int level)
1822
{
1823
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1824
    uint16_t prev = s->inputs;
1825

    
1826
    if (level)
1827
        s->inputs |= 1 << line;
1828
    else
1829
        s->inputs &= ~(1 << line);
1830

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

    
1843
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
1844
{
1845
    int i;
1846
    uint8_t *row, rows = 0, cols = ~s->cols;
1847

    
1848
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
1849
        if (*row & cols)
1850
            rows |= i;
1851

    
1852
    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
1853
    s->row_latch = ~rows;
1854
}
1855

    
1856
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
1857
{
1858
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1859
    int offset = addr & OMAP_MPUI_REG_MASK;
1860
    uint16_t ret;
1861

    
1862
    switch (offset) {
1863
    case 0x00:        /* INPUT_LATCH */
1864
        return s->inputs;
1865

    
1866
    case 0x04:        /* OUTPUT_REG */
1867
        return s->outputs;
1868

    
1869
    case 0x08:        /* IO_CNTL */
1870
        return s->dir;
1871

    
1872
    case 0x10:        /* KBR_LATCH */
1873
        return s->row_latch;
1874

    
1875
    case 0x14:        /* KBC_REG */
1876
        return s->cols;
1877

    
1878
    case 0x18:        /* GPIO_EVENT_MODE_REG */
1879
        return s->event;
1880

    
1881
    case 0x1c:        /* GPIO_INT_EDGE_REG */
1882
        return s->edge;
1883

    
1884
    case 0x20:        /* KBD_INT */
1885
        return (~s->row_latch & 0x1f) && !s->kbd_mask;
1886

    
1887
    case 0x24:        /* GPIO_INT */
1888
        ret = s->ints;
1889
        s->ints &= s->mask;
1890
        if (ret)
1891
            qemu_irq_lower(s->irq);
1892
        return ret;
1893

    
1894
    case 0x28:        /* KBD_MASKIT */
1895
        return s->kbd_mask;
1896

    
1897
    case 0x2c:        /* GPIO_MASKIT */
1898
        return s->mask;
1899

    
1900
    case 0x30:        /* GPIO_DEBOUNCING_REG */
1901
        return s->debounce;
1902

    
1903
    case 0x34:        /* GPIO_LATCH_REG */
1904
        return s->latch;
1905
    }
1906

    
1907
    OMAP_BAD_REG(addr);
1908
    return 0;
1909
}
1910

    
1911
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
1912
                uint32_t value)
1913
{
1914
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1915
    int offset = addr & OMAP_MPUI_REG_MASK;
1916
    uint16_t diff;
1917
    int ln;
1918

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

    
1931
    case 0x08:        /* IO_CNTL */
1932
        diff = s->outputs & (s->dir ^ value);
1933
        s->dir = value;
1934

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

    
1944
    case 0x14:        /* KBC_REG */
1945
        s->cols = value;
1946
        omap_mpuio_kbd_update(s);
1947
        break;
1948

    
1949
    case 0x18:        /* GPIO_EVENT_MODE_REG */
1950
        s->event = value & 0x1f;
1951
        break;
1952

    
1953
    case 0x1c:        /* GPIO_INT_EDGE_REG */
1954
        s->edge = value;
1955
        break;
1956

    
1957
    case 0x28:        /* KBD_MASKIT */
1958
        s->kbd_mask = value & 1;
1959
        omap_mpuio_kbd_update(s);
1960
        break;
1961

    
1962
    case 0x2c:        /* GPIO_MASKIT */
1963
        s->mask = value;
1964
        break;
1965

    
1966
    case 0x30:        /* GPIO_DEBOUNCING_REG */
1967
        s->debounce = value & 0x1ff;
1968
        break;
1969

    
1970
    case 0x00:        /* INPUT_LATCH */
1971
    case 0x10:        /* KBR_LATCH */
1972
    case 0x20:        /* KBD_INT */
1973
    case 0x24:        /* GPIO_INT */
1974
    case 0x34:        /* GPIO_LATCH_REG */
1975
        OMAP_RO_REG(addr);
1976
        return;
1977

    
1978
    default:
1979
        OMAP_BAD_REG(addr);
1980
        return;
1981
    }
1982
}
1983

    
1984
static CPUReadMemoryFunc * const omap_mpuio_readfn[] = {
1985
    omap_badwidth_read16,
1986
    omap_mpuio_read,
1987
    omap_badwidth_read16,
1988
};
1989

    
1990
static CPUWriteMemoryFunc * const omap_mpuio_writefn[] = {
1991
    omap_badwidth_write16,
1992
    omap_mpuio_write,
1993
    omap_badwidth_write16,
1994
};
1995

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

    
2012
static void omap_mpuio_onoff(void *opaque, int line, int on)
2013
{
2014
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2015

    
2016
    s->clk = on;
2017
    if (on)
2018
        omap_mpuio_kbd_update(s);
2019
}
2020

    
2021
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
2022
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2023
                omap_clk clk)
2024
{
2025
    int iomemtype;
2026
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
2027
            qemu_mallocz(sizeof(struct omap_mpuio_s));
2028

    
2029
    s->irq = gpio_int;
2030
    s->kbd_irq = kbd_int;
2031
    s->wakeup = wakeup;
2032
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2033
    omap_mpuio_reset(s);
2034

    
2035
    iomemtype = cpu_register_io_memory(omap_mpuio_readfn,
2036
                    omap_mpuio_writefn, s, DEVICE_NATIVE_ENDIAN);
2037
    cpu_register_physical_memory(base, 0x800, iomemtype);
2038

    
2039
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2040

    
2041
    return s;
2042
}
2043

    
2044
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2045
{
2046
    return s->in;
2047
}
2048

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

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

    
2061
    if (down)
2062
        s->buttons[row] |= 1 << col;
2063
    else
2064
        s->buttons[row] &= ~(1 << col);
2065

    
2066
    omap_mpuio_kbd_update(s);
2067
}
2068

    
2069
/* MicroWire Interface */
2070
struct omap_uwire_s {
2071
    qemu_irq txirq;
2072
    qemu_irq rxirq;
2073
    qemu_irq txdrq;
2074

    
2075
    uint16_t txbuf;
2076
    uint16_t rxbuf;
2077
    uint16_t control;
2078
    uint16_t setup[5];
2079

    
2080
    uWireSlave *chip[4];
2081
};
2082

    
2083
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
2084
{
2085
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
2086
    uWireSlave *slave = s->chip[chipselect];
2087

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

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

    
2108
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
2109
{
2110
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2111
    int offset = addr & OMAP_MPUI_REG_MASK;
2112

    
2113
    switch (offset) {
2114
    case 0x00:        /* RDR */
2115
        s->control &= ~(1 << 15);                        /* RDRB */
2116
        return s->rxbuf;
2117

    
2118
    case 0x04:        /* CSR */
2119
        return s->control;
2120

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

    
2133
    OMAP_BAD_REG(addr);
2134
    return 0;
2135
}
2136

    
2137
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
2138
                uint32_t value)
2139
{
2140
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2141
    int offset = addr & OMAP_MPUI_REG_MASK;
2142

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

    
2154
    case 0x04:        /* CSR */
2155
        s->control = value & 0x1fff;
2156
        if (value & (1 << 13))                                /* START */
2157
            omap_uwire_transfer_start(s);
2158
        break;
2159

    
2160
    case 0x08:        /* SR1 */
2161
        s->setup[0] = value & 0x003f;
2162
        break;
2163

    
2164
    case 0x0c:        /* SR2 */
2165
        s->setup[1] = value & 0x0fc0;
2166
        break;
2167

    
2168
    case 0x10:        /* SR3 */
2169
        s->setup[2] = value & 0x0003;
2170
        break;
2171

    
2172
    case 0x14:        /* SR4 */
2173
        s->setup[3] = value & 0x0001;
2174
        break;
2175

    
2176
    case 0x18:        /* SR5 */
2177
        s->setup[4] = value & 0x000f;
2178
        break;
2179

    
2180
    default:
2181
        OMAP_BAD_REG(addr);
2182
        return;
2183
    }
2184
}
2185

    
2186
static CPUReadMemoryFunc * const omap_uwire_readfn[] = {
2187
    omap_badwidth_read16,
2188
    omap_uwire_read,
2189
    omap_badwidth_read16,
2190
};
2191

    
2192
static CPUWriteMemoryFunc * const omap_uwire_writefn[] = {
2193
    omap_badwidth_write16,
2194
    omap_uwire_write,
2195
    omap_badwidth_write16,
2196
};
2197

    
2198
static void omap_uwire_reset(struct omap_uwire_s *s)
2199
{
2200
    s->control = 0;
2201
    s->setup[0] = 0;
2202
    s->setup[1] = 0;
2203
    s->setup[2] = 0;
2204
    s->setup[3] = 0;
2205
    s->setup[4] = 0;
2206
}
2207

    
2208
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
2209
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
2210
{
2211
    int iomemtype;
2212
    struct omap_uwire_s *s = (struct omap_uwire_s *)
2213
            qemu_mallocz(sizeof(struct omap_uwire_s));
2214

    
2215
    s->txirq = irq[0];
2216
    s->rxirq = irq[1];
2217
    s->txdrq = dma;
2218
    omap_uwire_reset(s);
2219

    
2220
    iomemtype = cpu_register_io_memory(omap_uwire_readfn,
2221
                    omap_uwire_writefn, s, DEVICE_NATIVE_ENDIAN);
2222
    cpu_register_physical_memory(base, 0x800, iomemtype);
2223

    
2224
    return s;
2225
}
2226

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

    
2235
    s->chip[chipselect] = slave;
2236
}
2237

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

    
2243
    if (output != s->pwl.output) {
2244
        s->pwl.output = output;
2245
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
2246
    }
2247
}
2248

    
2249
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
2250
{
2251
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2252
    int offset = addr & OMAP_MPUI_REG_MASK;
2253

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

    
2264
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
2265
                uint32_t value)
2266
{
2267
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2268
    int offset = addr & OMAP_MPUI_REG_MASK;
2269

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

    
2285
static CPUReadMemoryFunc * const omap_pwl_readfn[] = {
2286
    omap_pwl_read,
2287
    omap_badwidth_read8,
2288
    omap_badwidth_read8,
2289
};
2290

    
2291
static CPUWriteMemoryFunc * const omap_pwl_writefn[] = {
2292
    omap_pwl_write,
2293
    omap_badwidth_write8,
2294
    omap_badwidth_write8,
2295
};
2296

    
2297
static void omap_pwl_reset(struct omap_mpu_state_s *s)
2298
{
2299
    s->pwl.output = 0;
2300
    s->pwl.level = 0;
2301
    s->pwl.enable = 0;
2302
    s->pwl.clk = 1;
2303
    omap_pwl_update(s);
2304
}
2305

    
2306
static void omap_pwl_clk_update(void *opaque, int line, int on)
2307
{
2308
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2309

    
2310
    s->pwl.clk = on;
2311
    omap_pwl_update(s);
2312
}
2313

    
2314
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
2315
                omap_clk clk)
2316
{
2317
    int iomemtype;
2318

    
2319
    omap_pwl_reset(s);
2320

    
2321
    iomemtype = cpu_register_io_memory(omap_pwl_readfn,
2322
                    omap_pwl_writefn, s, DEVICE_NATIVE_ENDIAN);
2323
    cpu_register_physical_memory(base, 0x800, iomemtype);
2324

    
2325
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
2326
}
2327

    
2328
/* Pulse-Width Tone module */
2329
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
2330
{
2331
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2332
    int offset = addr & OMAP_MPUI_REG_MASK;
2333

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

    
2346
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
2347
                uint32_t value)
2348
{
2349
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2350
    int offset = addr & OMAP_MPUI_REG_MASK;
2351

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

    
2389
static CPUReadMemoryFunc * const omap_pwt_readfn[] = {
2390
    omap_pwt_read,
2391
    omap_badwidth_read8,
2392
    omap_badwidth_read8,
2393
};
2394

    
2395
static CPUWriteMemoryFunc * const omap_pwt_writefn[] = {
2396
    omap_pwt_write,
2397
    omap_badwidth_write8,
2398
    omap_badwidth_write8,
2399
};
2400

    
2401
static void omap_pwt_reset(struct omap_mpu_state_s *s)
2402
{
2403
    s->pwt.frc = 0;
2404
    s->pwt.vrc = 0;
2405
    s->pwt.gcr = 0;
2406
}
2407

    
2408
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
2409
                omap_clk clk)
2410
{
2411
    int iomemtype;
2412

    
2413
    s->pwt.clk = clk;
2414
    omap_pwt_reset(s);
2415

    
2416
    iomemtype = cpu_register_io_memory(omap_pwt_readfn,
2417
                    omap_pwt_writefn, s, DEVICE_NATIVE_ENDIAN);
2418
    cpu_register_physical_memory(base, 0x800, iomemtype);
2419
}
2420

    
2421
/* Real-time Clock module */
2422
struct omap_rtc_s {
2423
    qemu_irq irq;
2424
    qemu_irq alarm;
2425
    QEMUTimer *clk;
2426

    
2427
    uint8_t interrupts;
2428
    uint8_t status;
2429
    int16_t comp_reg;
2430
    int running;
2431
    int pm_am;
2432
    int auto_comp;
2433
    int round;
2434
    struct tm alarm_tm;
2435
    time_t alarm_ti;
2436

    
2437
    struct tm current_tm;
2438
    time_t ti;
2439
    uint64_t tick;
2440
};
2441

    
2442
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
2443
{
2444
    /* s->alarm is level-triggered */
2445
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
2446
}
2447

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

    
2455
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
2456
{
2457
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2458
    int offset = addr & OMAP_MPUI_REG_MASK;
2459
    uint8_t i;
2460

    
2461
    switch (offset) {
2462
    case 0x00:        /* SECONDS_REG */
2463
        return to_bcd(s->current_tm.tm_sec);
2464

    
2465
    case 0x04:        /* MINUTES_REG */
2466
        return to_bcd(s->current_tm.tm_min);
2467

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

    
2475
    case 0x0c:        /* DAYS_REG */
2476
        return to_bcd(s->current_tm.tm_mday);
2477

    
2478
    case 0x10:        /* MONTHS_REG */
2479
        return to_bcd(s->current_tm.tm_mon + 1);
2480

    
2481
    case 0x14:        /* YEARS_REG */
2482
        return to_bcd(s->current_tm.tm_year % 100);
2483

    
2484
    case 0x18:        /* WEEK_REG */
2485
        return s->current_tm.tm_wday;
2486

    
2487
    case 0x20:        /* ALARM_SECONDS_REG */
2488
        return to_bcd(s->alarm_tm.tm_sec);
2489

    
2490
    case 0x24:        /* ALARM_MINUTES_REG */
2491
        return to_bcd(s->alarm_tm.tm_min);
2492

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

    
2500
    case 0x2c:        /* ALARM_DAYS_REG */
2501
        return to_bcd(s->alarm_tm.tm_mday);
2502

    
2503
    case 0x30:        /* ALARM_MONTHS_REG */
2504
        return to_bcd(s->alarm_tm.tm_mon + 1);
2505

    
2506
    case 0x34:        /* ALARM_YEARS_REG */
2507
        return to_bcd(s->alarm_tm.tm_year % 100);
2508

    
2509
    case 0x40:        /* RTC_CTRL_REG */
2510
        return (s->pm_am << 3) | (s->auto_comp << 2) |
2511
                (s->round << 1) | s->running;
2512

    
2513
    case 0x44:        /* RTC_STATUS_REG */
2514
        i = s->status;
2515
        s->status &= ~0x3d;
2516
        return i;
2517

    
2518
    case 0x48:        /* RTC_INTERRUPTS_REG */
2519
        return s->interrupts;
2520

    
2521
    case 0x4c:        /* RTC_COMP_LSB_REG */
2522
        return ((uint16_t) s->comp_reg) & 0xff;
2523

    
2524
    case 0x50:        /* RTC_COMP_MSB_REG */
2525
        return ((uint16_t) s->comp_reg) >> 8;
2526
    }
2527

    
2528
    OMAP_BAD_REG(addr);
2529
    return 0;
2530
}
2531

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

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

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

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

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

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

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

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

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

    
2615
    case 0x18:        /* WEEK_REG */
2616
        return;        /* Ignored */
2617

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

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

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

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

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

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

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

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

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

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

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

    
2714
    default:
2715
        OMAP_BAD_REG(addr);
2716
        return;
2717
    }
2718
}
2719

    
2720
static CPUReadMemoryFunc * const omap_rtc_readfn[] = {
2721
    omap_rtc_read,
2722
    omap_badwidth_read8,
2723
    omap_badwidth_read8,
2724
};
2725

    
2726
static CPUWriteMemoryFunc * const omap_rtc_writefn[] = {
2727
    omap_rtc_write,
2728
    omap_badwidth_write8,
2729
    omap_badwidth_write8,
2730
};
2731

    
2732
static void omap_rtc_tick(void *opaque)
2733
{
2734
    struct omap_rtc_s *s = opaque;
2735

    
2736
    if (s->round) {
2737
        /* Round to nearest full minute.  */
2738
        if (s->current_tm.tm_sec < 30)
2739
            s->ti -= s->current_tm.tm_sec;
2740
        else
2741
            s->ti += 60 - s->current_tm.tm_sec;
2742

    
2743
        s->round = 0;
2744
    }
2745

    
2746
    memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
2747

    
2748
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
2749
        s->status |= 0x40;
2750
        omap_rtc_interrupts_update(s);
2751
    }
2752

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

    
2780
    /* Move on */
2781
    if (s->running)
2782
        s->ti ++;
2783
    s->tick += 1000;
2784

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

    
2792
    qemu_mod_timer(s->clk, s->tick);
2793
}
2794

    
2795
static void omap_rtc_reset(struct omap_rtc_s *s)
2796
{
2797
    struct tm tm;
2798

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

    
2812
    omap_rtc_alarm_update(s);
2813
    omap_rtc_tick(s);
2814
}
2815

    
2816
static struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
2817
                qemu_irq *irq, omap_clk clk)
2818
{
2819
    int iomemtype;
2820
    struct omap_rtc_s *s = (struct omap_rtc_s *)
2821
            qemu_mallocz(sizeof(struct omap_rtc_s));
2822

    
2823
    s->irq = irq[0];
2824
    s->alarm = irq[1];
2825
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
2826

    
2827
    omap_rtc_reset(s);
2828

    
2829
    iomemtype = cpu_register_io_memory(omap_rtc_readfn,
2830
                    omap_rtc_writefn, s, DEVICE_NATIVE_ENDIAN);
2831
    cpu_register_physical_memory(base, 0x800, iomemtype);
2832

    
2833
    return s;
2834
}
2835

    
2836
/* Multi-channel Buffered Serial Port interfaces */
2837
struct omap_mcbsp_s {
2838
    qemu_irq txirq;
2839
    qemu_irq rxirq;
2840
    qemu_irq txdrq;
2841
    qemu_irq rxdrq;
2842

    
2843
    uint16_t spcr[2];
2844
    uint16_t rcr[2];
2845
    uint16_t xcr[2];
2846
    uint16_t srgr[2];
2847
    uint16_t mcr[2];
2848
    uint16_t pcr;
2849
    uint16_t rcer[8];
2850
    uint16_t xcer[8];
2851
    int tx_rate;
2852
    int rx_rate;
2853
    int tx_req;
2854
    int rx_req;
2855

    
2856
    I2SCodec *codec;
2857
    QEMUTimer *source_timer;
2858
    QEMUTimer *sink_timer;
2859
};
2860

    
2861
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2862
{
2863
    int irq;
2864

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

    
2877
    if (irq)
2878
        qemu_irq_pulse(s->rxirq);
2879

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

    
2892
    if (irq)
2893
        qemu_irq_pulse(s->txirq);
2894
}
2895

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

    
2905
static void omap_mcbsp_source_tick(void *opaque)
2906
{
2907
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
2908
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
2909

    
2910
    if (!s->rx_rate)
2911
        return;
2912
    if (s->rx_req)
2913
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
2914

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

    
2917
    omap_mcbsp_rx_newdata(s);
2918
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) +
2919
                   get_ticks_per_sec());
2920
}
2921

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

    
2932
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
2933
{
2934
    qemu_del_timer(s->source_timer);
2935
}
2936

    
2937
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
2938
{
2939
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
2940
    qemu_irq_lower(s->rxdrq);
2941
    omap_mcbsp_intr_update(s);
2942
}
2943

    
2944
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
2945
{
2946
    s->spcr[1] |= 1 << 1;                                /* XRDY */
2947
    qemu_irq_raise(s->txdrq);
2948
    omap_mcbsp_intr_update(s);
2949
}
2950

    
2951
static void omap_mcbsp_sink_tick(void *opaque)
2952
{
2953
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
2954
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
2955

    
2956
    if (!s->tx_rate)
2957
        return;
2958
    if (s->tx_req)
2959
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
2960

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

    
2963
    omap_mcbsp_tx_newdata(s);
2964
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) +
2965
                   get_ticks_per_sec());
2966
}
2967

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

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

    
2987
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
2988
{
2989
    s->tx_req = 0;
2990
    omap_mcbsp_tx_done(s);
2991
    qemu_del_timer(s->sink_timer);
2992
}
2993

    
2994
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
2995
{
2996
    int prev_rx_rate, prev_tx_rate;
2997
    int rx_rate = 0, tx_rate = 0;
2998
    int cpu_rate = 1500000;        /* XXX */
2999

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

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

    
3029
    if (s->codec)
3030
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3031

    
3032
    if (!prev_tx_rate && tx_rate)
3033
        omap_mcbsp_tx_start(s);
3034
    else if (s->tx_rate && !tx_rate)
3035
        omap_mcbsp_tx_stop(s);
3036

    
3037
    if (!prev_rx_rate && rx_rate)
3038
        omap_mcbsp_rx_start(s);
3039
    else if (prev_tx_rate && !tx_rate)
3040
        omap_mcbsp_rx_stop(s);
3041
}
3042

    
3043
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
3044
{
3045
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3046
    int offset = addr & OMAP_MPUI_REG_MASK;
3047
    uint16_t ret;
3048

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

    
3072
    case 0x04:        /* DXR2 */
3073
    case 0x06:        /* DXR1 */
3074
        return 0x0000;
3075

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

    
3132
    OMAP_BAD_REG(addr);
3133
    return 0;
3134
}
3135

    
3136
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
3137
                uint32_t value)
3138
{
3139
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3140
    int offset = addr & OMAP_MPUI_REG_MASK;
3141

    
3142
    switch (offset) {
3143
    case 0x00:        /* DRR2 */
3144
    case 0x02:        /* DRR1 */
3145
        OMAP_RO_REG(addr);
3146
        return;
3147

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

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

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

    
3271
    OMAP_BAD_REG(addr);
3272
}
3273

    
3274
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
3275
                uint32_t value)
3276
{
3277
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3278
    int offset = addr & OMAP_MPUI_REG_MASK;
3279

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

    
3302
    omap_badwidth_write16(opaque, addr, value);
3303
}
3304

    
3305
static CPUReadMemoryFunc * const omap_mcbsp_readfn[] = {
3306
    omap_badwidth_read16,
3307
    omap_mcbsp_read,
3308
    omap_badwidth_read16,
3309
};
3310

    
3311
static CPUWriteMemoryFunc * const omap_mcbsp_writefn[] = {
3312
    omap_badwidth_write16,
3313
    omap_mcbsp_writeh,
3314
    omap_mcbsp_writew,
3315
};
3316

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

    
3336
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
3337
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
3338
{
3339
    int iomemtype;
3340
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
3341
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
3342

    
3343
    s->txirq = irq[0];
3344
    s->rxirq = irq[1];
3345
    s->txdrq = dma[0];
3346
    s->rxdrq = dma[1];
3347
    s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
3348
    s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
3349
    omap_mcbsp_reset(s);
3350

    
3351
    iomemtype = cpu_register_io_memory(omap_mcbsp_readfn,
3352
                    omap_mcbsp_writefn, s, DEVICE_NATIVE_ENDIAN);
3353
    cpu_register_physical_memory(base, 0x800, iomemtype);
3354

    
3355
    return s;
3356
}
3357

    
3358
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
3359
{
3360
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3361

    
3362
    if (s->rx_rate) {
3363
        s->rx_req = s->codec->in.len;
3364
        omap_mcbsp_rx_newdata(s);
3365
    }
3366
}
3367

    
3368
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
3369
{
3370
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3371

    
3372
    if (s->tx_rate) {
3373
        s->tx_req = s->codec->out.size;
3374
        omap_mcbsp_tx_newdata(s);
3375
    }
3376
}
3377

    
3378
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
3379
{
3380
    s->codec = slave;
3381
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
3382
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
3383
}
3384

    
3385
/* LED Pulse Generators */
3386
struct omap_lpg_s {
3387
    QEMUTimer *tm;
3388

    
3389
    uint8_t control;
3390
    uint8_t power;
3391
    int64_t on;
3392
    int64_t period;
3393
    int clk;
3394
    int cycle;
3395
};
3396

    
3397
static void omap_lpg_tick(void *opaque)
3398
{
3399
    struct omap_lpg_s *s = opaque;
3400

    
3401
    if (s->cycle)
3402
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
3403
    else
3404
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
3405

    
3406
    s->cycle = !s->cycle;
3407
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
3408
}
3409

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

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

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

    
3439
    s->on = on;
3440
    s->period = period;
3441
}
3442

    
3443
static void omap_lpg_reset(struct omap_lpg_s *s)
3444
{
3445
    s->control = 0x00;
3446
    s->power = 0x00;
3447
    s->clk = 1;
3448
    omap_lpg_update(s);
3449
}
3450

    
3451
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
3452
{
3453
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3454
    int offset = addr & OMAP_MPUI_REG_MASK;
3455

    
3456
    switch (offset) {
3457
    case 0x00:        /* LCR */
3458
        return s->control;
3459

    
3460
    case 0x04:        /* PMR */
3461
        return s->power;
3462
    }
3463

    
3464
    OMAP_BAD_REG(addr);
3465
    return 0;
3466
}
3467

    
3468
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
3469
                uint32_t value)
3470
{
3471
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3472
    int offset = addr & OMAP_MPUI_REG_MASK;
3473

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

    
3482
    case 0x04:        /* PMR */
3483
        s->power = value & 0x01;
3484
        omap_lpg_update(s);
3485
        return;
3486

    
3487
    default:
3488
        OMAP_BAD_REG(addr);
3489
        return;
3490
    }
3491
}
3492

    
3493
static CPUReadMemoryFunc * const omap_lpg_readfn[] = {
3494
    omap_lpg_read,
3495
    omap_badwidth_read8,
3496
    omap_badwidth_read8,
3497
};
3498

    
3499
static CPUWriteMemoryFunc * const omap_lpg_writefn[] = {
3500
    omap_lpg_write,
3501
    omap_badwidth_write8,
3502
    omap_badwidth_write8,
3503
};
3504

    
3505
static void omap_lpg_clk_update(void *opaque, int line, int on)
3506
{
3507
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3508

    
3509
    s->clk = on;
3510
    omap_lpg_update(s);
3511
}
3512

    
3513
static struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
3514
{
3515
    int iomemtype;
3516
    struct omap_lpg_s *s = (struct omap_lpg_s *)
3517
            qemu_mallocz(sizeof(struct omap_lpg_s));
3518

    
3519
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
3520

    
3521
    omap_lpg_reset(s);
3522

    
3523
    iomemtype = cpu_register_io_memory(omap_lpg_readfn,
3524
                    omap_lpg_writefn, s, DEVICE_NATIVE_ENDIAN);
3525
    cpu_register_physical_memory(base, 0x800, iomemtype);
3526

    
3527
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
3528

    
3529
    return s;
3530
}
3531

    
3532
/* MPUI Peripheral Bridge configuration */
3533
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
3534
{
3535
    if (addr == OMAP_MPUI_BASE)        /* CMR */
3536
        return 0xfe4d;
3537

    
3538
    OMAP_BAD_REG(addr);
3539
    return 0;
3540
}
3541

    
3542
static CPUReadMemoryFunc * const omap_mpui_io_readfn[] = {
3543
    omap_badwidth_read16,
3544
    omap_mpui_io_read,
3545
    omap_badwidth_read16,
3546
};
3547

    
3548
static CPUWriteMemoryFunc * const omap_mpui_io_writefn[] = {
3549
    omap_badwidth_write16,
3550
    omap_badwidth_write16,
3551
    omap_badwidth_write16,
3552
};
3553

    
3554
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
3555
{
3556
    int iomemtype = cpu_register_io_memory(omap_mpui_io_readfn,
3557
                    omap_mpui_io_writefn, mpu, DEVICE_NATIVE_ENDIAN);
3558
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
3559
}
3560

    
3561
/* General chip reset */
3562
static void omap1_mpu_reset(void *opaque)
3563
{
3564
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3565

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

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

    
3630
    { 0 }
3631
};
3632

    
3633
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
3634
{
3635
    int io;
3636

    
3637
    for (; map->phys_dsp; map ++) {
3638
        io = cpu_get_physical_page_desc(map->phys_mpu);
3639

    
3640
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
3641
    }
3642
}
3643

    
3644
void omap_mpu_wakeup(void *opaque, int irq, int req)
3645
{
3646
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3647

    
3648
    if (mpu->env->halted)
3649
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
3650
}
3651

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

    
3671
/* DMA ports for OMAP1 */
3672
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
3673
                target_phys_addr_t addr)
3674
{
3675
    return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr);
3676
}
3677

    
3678
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
3679
                target_phys_addr_t addr)
3680
{
3681
    return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE,
3682
                             addr);
3683
}
3684

    
3685
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
3686
                target_phys_addr_t addr)
3687
{
3688
    return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr);
3689
}
3690

    
3691
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
3692
                target_phys_addr_t addr)
3693
{
3694
    return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);
3695
}
3696

    
3697
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
3698
                target_phys_addr_t addr)
3699
{
3700
    return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
3701
}
3702

    
3703
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
3704
                target_phys_addr_t addr)
3705
{
3706
    return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
3707
}
3708

    
3709
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
3710
                const char *core)
3711
{
3712
    int i;
3713
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
3714
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
3715
    ram_addr_t imif_base, emiff_base;
3716
    qemu_irq *cpu_irq;
3717
    qemu_irq dma_irqs[6];
3718
    DriveInfo *dinfo;
3719

    
3720
    if (!core)
3721
        core = "ti925t";
3722

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

    
3733
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
3734

    
3735
    /* Clocks */
3736
    omap_clk_init(s);
3737

    
3738
    /* Memory-mapped stuff */
3739
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
3740
                    (emiff_base = qemu_ram_alloc(NULL, "omap1.dram",
3741
                                                 s->sdram_size)) | IO_MEM_RAM);
3742
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
3743
                    (imif_base = qemu_ram_alloc(NULL, "omap1.sram",
3744
                                                s->sram_size)) | IO_MEM_RAM);
3745

    
3746
    omap_clkm_init(0xfffece00, 0xe1008000, s);
3747

    
3748
    cpu_irq = arm_pic_init_cpu(s->env);
3749
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0],
3750
                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
3751
                    omap_findclk(s, "arminth_ck"));
3752
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, &s->irq[1],
3753
                    omap_inth_get_pin(s->ih[0], OMAP_INT_15XX_IH2_IRQ),
3754
                    NULL, omap_findclk(s, "arminth_ck"));
3755

    
3756
    for (i = 0; i < 6; i ++)
3757
        dma_irqs[i] =
3758
                s->irq[omap1_dma_irq_map[i].ih][omap1_dma_irq_map[i].intr];
3759
    s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
3760
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
3761

    
3762
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
3763
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
3764
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
3765
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
3766
    s->port[local    ].addr_valid = omap_validate_local_addr;
3767
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
3768

    
3769
    /* Register SDRAM and SRAM DMA ports for fast transfers.  */
3770
    soc_dma_port_add_mem_ram(s->dma,
3771
                    emiff_base, OMAP_EMIFF_BASE, s->sdram_size);
3772
    soc_dma_port_add_mem_ram(s->dma,
3773
                    imif_base, OMAP_IMIF_BASE, s->sram_size);
3774

    
3775
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
3776
                    s->irq[0][OMAP_INT_TIMER1],
3777
                    omap_findclk(s, "mputim_ck"));
3778
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
3779
                    s->irq[0][OMAP_INT_TIMER2],
3780
                    omap_findclk(s, "mputim_ck"));
3781
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
3782
                    s->irq[0][OMAP_INT_TIMER3],
3783
                    omap_findclk(s, "mputim_ck"));
3784

    
3785
    s->wdt = omap_wd_timer_init(0xfffec800,
3786
                    s->irq[0][OMAP_INT_WD_TIMER],
3787
                    omap_findclk(s, "armwdt_ck"));
3788

    
3789
    s->os_timer = omap_os_timer_init(0xfffb9000,
3790
                    s->irq[1][OMAP_INT_OS_TIMER],
3791
                    omap_findclk(s, "clk32-kHz"));
3792

    
3793
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
3794
                    omap_dma_get_lcdch(s->dma), imif_base, emiff_base,
3795
                    omap_findclk(s, "lcd_ck"));
3796

    
3797
    omap_ulpd_pm_init(0xfffe0800, s);
3798
    omap_pin_cfg_init(0xfffe1000, s);
3799
    omap_id_init(s);
3800

    
3801
    omap_mpui_init(0xfffec900, s);
3802

    
3803
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
3804
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
3805
                    omap_findclk(s, "tipb_ck"));
3806
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
3807
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
3808
                    omap_findclk(s, "tipb_ck"));
3809

    
3810
    omap_tcmi_init(0xfffecc00, s);
3811

    
3812
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
3813
                    omap_findclk(s, "uart1_ck"),
3814
                    omap_findclk(s, "uart1_ck"),
3815
                    s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
3816
                    "uart1",
3817
                    serial_hds[0]);
3818
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
3819
                    omap_findclk(s, "uart2_ck"),
3820
                    omap_findclk(s, "uart2_ck"),
3821
                    s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
3822
                    "uart2",
3823
                    serial_hds[0] ? serial_hds[1] : NULL);
3824
    s->uart[2] = omap_uart_init(0xfffb9800, s->irq[0][OMAP_INT_UART3],
3825
                    omap_findclk(s, "uart3_ck"),
3826
                    omap_findclk(s, "uart3_ck"),
3827
                    s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
3828
                    "uart3",
3829
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
3830

    
3831
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
3832
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
3833
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
3834

    
3835
    dinfo = drive_get(IF_SD, 0, 0);
3836
    if (!dinfo) {
3837
        fprintf(stderr, "qemu: missing SecureDigital device\n");
3838
        exit(1);
3839
    }
3840
    s->mmc = omap_mmc_init(0xfffb7800, dinfo->bdrv,
3841
                    s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
3842
                    omap_findclk(s, "mmc_ck"));
3843

    
3844
    s->mpuio = omap_mpuio_init(0xfffb5000,
3845
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
3846
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
3847

    
3848
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
3849
                    omap_findclk(s, "arm_gpio_ck"));
3850

    
3851
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
3852
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
3853

    
3854
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
3855
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
3856

    
3857
    s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
3858
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
3859

    
3860
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
3861
                    omap_findclk(s, "clk32-kHz"));
3862

    
3863
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
3864
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
3865
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
3866
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
3867
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
3868
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
3869

    
3870
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
3871
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
3872

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

    
3888
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
3889
    omap_setup_mpui_io(s);
3890

    
3891
    qemu_register_reset(omap1_mpu_reset, s);
3892

    
3893
    return s;
3894
}