Statistics
| Branch: | Revision:

root / hw / omap1.c @ 3b2e3dc9

History | View | Annotate | Download (108.7 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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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
        cpu_register_io_memory(omap_clkdsp_readfn, omap_clkdsp_writefn, s),
1781
    };
1782

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

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

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

    
1801
    uint16_t inputs;
1802
    uint16_t outputs;
1803
    uint16_t dir;
1804
    uint16_t edge;
1805
    uint16_t mask;
1806
    uint16_t ints;
1807

    
1808
    uint16_t debounce;
1809
    uint16_t latch;
1810
    uint8_t event;
1811

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

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

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

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

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

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

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

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

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

    
1864
    case 0x04:        /* OUTPUT_REG */
1865
        return s->outputs;
1866

    
1867
    case 0x08:        /* IO_CNTL */
1868
        return s->dir;
1869

    
1870
    case 0x10:        /* KBR_LATCH */
1871
        return s->row_latch;
1872

    
1873
    case 0x14:        /* KBC_REG */
1874
        return s->cols;
1875

    
1876
    case 0x18:        /* GPIO_EVENT_MODE_REG */
1877
        return s->event;
1878

    
1879
    case 0x1c:        /* GPIO_INT_EDGE_REG */
1880
        return s->edge;
1881

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

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

    
1892
    case 0x28:        /* KBD_MASKIT */
1893
        return s->kbd_mask;
1894

    
1895
    case 0x2c:        /* GPIO_MASKIT */
1896
        return s->mask;
1897

    
1898
    case 0x30:        /* GPIO_DEBOUNCING_REG */
1899
        return s->debounce;
1900

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

    
1905
    OMAP_BAD_REG(addr);
1906
    return 0;
1907
}
1908

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

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

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

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

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

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

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

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

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

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

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

    
1976
    default:
1977
        OMAP_BAD_REG(addr);
1978
        return;
1979
    }
1980
}
1981

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

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

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

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

    
2014
    s->clk = on;
2015
    if (on)
2016
        omap_mpuio_kbd_update(s);
2017
}
2018

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

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

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

    
2037
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2038

    
2039
    return s;
2040
}
2041

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

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

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

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

    
2064
    omap_mpuio_kbd_update(s);
2065
}
2066

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

    
2073
    uint16_t txbuf;
2074
    uint16_t rxbuf;
2075
    uint16_t control;
2076
    uint16_t setup[5];
2077

    
2078
    uWireSlave *chip[4];
2079
};
2080

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

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

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

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

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

    
2116
    case 0x04:        /* CSR */
2117
        return s->control;
2118

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

    
2131
    OMAP_BAD_REG(addr);
2132
    return 0;
2133
}
2134

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

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

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

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

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

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

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

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

    
2178
    default:
2179
        OMAP_BAD_REG(addr);
2180
        return;
2181
    }
2182
}
2183

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

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

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

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

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

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

    
2222
    return s;
2223
}
2224

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

    
2233
    s->chip[chipselect] = slave;
2234
}
2235

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

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

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

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

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

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

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

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

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

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

    
2308
    s->pwl.clk = on;
2309
    omap_pwl_update(s);
2310
}
2311

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

    
2317
    omap_pwl_reset(s);
2318

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

    
2323
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
2324
}
2325

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

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

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

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

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

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

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

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

    
2411
    s->pwt.clk = clk;
2412
    omap_pwt_reset(s);
2413

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

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

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

    
2435
    struct tm current_tm;
2436
    time_t ti;
2437
    uint64_t tick;
2438
};
2439

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2516
    case 0x48:        /* RTC_INTERRUPTS_REG */
2517
        return s->interrupts;
2518

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

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

    
2526
    OMAP_BAD_REG(addr);
2527
    return 0;
2528
}
2529

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

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

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

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

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

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

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

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

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

    
2613
    case 0x18:        /* WEEK_REG */
2614
        return;        /* Ignored */
2615

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

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

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

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

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

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

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

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

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

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

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

    
2712
    default:
2713
        OMAP_BAD_REG(addr);
2714
        return;
2715
    }
2716
}
2717

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

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

    
2730
static void omap_rtc_tick(void *opaque)
2731
{
2732
    struct omap_rtc_s *s = opaque;
2733

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

    
2741
        s->round = 0;
2742
    }
2743

    
2744
    memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
2745

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

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

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

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

    
2790
    qemu_mod_timer(s->clk, s->tick);
2791
}
2792

    
2793
static void omap_rtc_reset(struct omap_rtc_s *s)
2794
{
2795
    struct tm tm;
2796

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

    
2810
    omap_rtc_alarm_update(s);
2811
    omap_rtc_tick(s);
2812
}
2813

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

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

    
2825
    omap_rtc_reset(s);
2826

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

    
2831
    return s;
2832
}
2833

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

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

    
2854
    I2SCodec *codec;
2855
    QEMUTimer *source_timer;
2856
    QEMUTimer *sink_timer;
2857
};
2858

    
2859
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2860
{
2861
    int irq;
2862

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

    
2875
    if (irq)
2876
        qemu_irq_pulse(s->rxirq);
2877

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

    
2890
    if (irq)
2891
        qemu_irq_pulse(s->txirq);
2892
}
2893

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3027
    if (s->codec)
3028
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3029

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

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

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

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

    
3070
    case 0x04:        /* DXR2 */
3071
    case 0x06:        /* DXR1 */
3072
        return 0x0000;
3073

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

    
3130
    OMAP_BAD_REG(addr);
3131
    return 0;
3132
}
3133

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

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

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

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

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

    
3269
    OMAP_BAD_REG(addr);
3270
}
3271

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

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

    
3300
    omap_badwidth_write16(opaque, addr, value);
3301
}
3302

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

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

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

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

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

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

    
3353
    return s;
3354
}
3355

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

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

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

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

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

    
3383
/* LED Pulse Generators */
3384
struct omap_lpg_s {
3385
    QEMUTimer *tm;
3386

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

    
3395
static void omap_lpg_tick(void *opaque)
3396
{
3397
    struct omap_lpg_s *s = opaque;
3398

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

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

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

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

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

    
3437
    s->on = on;
3438
    s->period = period;
3439
}
3440

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

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

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

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

    
3462
    OMAP_BAD_REG(addr);
3463
    return 0;
3464
}
3465

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

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

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

    
3485
    default:
3486
        OMAP_BAD_REG(addr);
3487
        return;
3488
    }
3489
}
3490

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

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

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

    
3507
    s->clk = on;
3508
    omap_lpg_update(s);
3509
}
3510

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

    
3517
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
3518

    
3519
    omap_lpg_reset(s);
3520

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

    
3525
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
3526

    
3527
    return s;
3528
}
3529

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

    
3536
    OMAP_BAD_REG(addr);
3537
    return 0;
3538
}
3539

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

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

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

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

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

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

    
3628
    { 0 }
3629
};
3630

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

    
3635
    for (; map->phys_dsp; map ++) {
3636
        io = cpu_get_physical_page_desc(map->phys_mpu);
3637

    
3638
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
3639
    }
3640
}
3641

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

    
3646
    if (mpu->env->halted)
3647
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
3648
}
3649

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

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

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

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

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

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

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

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

    
3718
    if (!core)
3719
        core = "ti925t";
3720

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

    
3731
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
3732

    
3733
    /* Clocks */
3734
    omap_clk_init(s);
3735

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

    
3744
    omap_clkm_init(0xfffece00, 0xe1008000, s);
3745

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

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

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

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

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

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

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

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

    
3795
    omap_ulpd_pm_init(0xfffe0800, s);
3796
    omap_pin_cfg_init(0xfffe1000, s);
3797
    omap_id_init(s);
3798

    
3799
    omap_mpui_init(0xfffec900, s);
3800

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

    
3808
    omap_tcmi_init(0xfffecc00, s);
3809

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

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

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

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

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

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

    
3852
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
3853
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
3854

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

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

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

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

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

    
3886
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
3887
    omap_setup_mpui_io(s);
3888

    
3889
    qemu_register_reset(omap1_mpu_reset, s);
3890

    
3891
    return s;
3892
}