]> git.proxmox.com Git - qemu.git/blob - hw/omap1.c
hw/omap: Fix default setup for OMAP UART devices
[qemu.git] / hw / omap1.c
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
30 /* Should signal the TCMI/GPMC */
31 uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
32 {
33 uint8_t ret;
34
35 OMAP_8B_REG(addr);
36 cpu_physical_memory_read(addr, (void *) &ret, 1);
37 return ret;
38 }
39
40 void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
41 uint32_t value)
42 {
43 uint8_t val8 = value;
44
45 OMAP_8B_REG(addr);
46 cpu_physical_memory_write(addr, (void *) &val8, 1);
47 }
48
49 uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
50 {
51 uint16_t ret;
52
53 OMAP_16B_REG(addr);
54 cpu_physical_memory_read(addr, (void *) &ret, 2);
55 return ret;
56 }
57
58 void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
59 uint32_t value)
60 {
61 uint16_t val16 = value;
62
63 OMAP_16B_REG(addr);
64 cpu_physical_memory_write(addr, (void *) &val16, 2);
65 }
66
67 uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
68 {
69 uint32_t ret;
70
71 OMAP_32B_REG(addr);
72 cpu_physical_memory_read(addr, (void *) &ret, 4);
73 return ret;
74 }
75
76 void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
77 uint32_t value)
78 {
79 OMAP_32B_REG(addr);
80 cpu_physical_memory_write(addr, (void *) &value, 4);
81 }
82
83 /* MPU OS timers */
84 struct omap_mpu_timer_s {
85 qemu_irq irq;
86 omap_clk clk;
87 uint32_t val;
88 int64_t time;
89 QEMUTimer *timer;
90 QEMUBH *tick;
91 int64_t rate;
92 int it_ena;
93
94 int enable;
95 int ptv;
96 int ar;
97 int st;
98 uint32_t reset_val;
99 };
100
101 static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
102 {
103 uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
104
105 if (timer->st && timer->enable && timer->rate)
106 return timer->val - muldiv64(distance >> (timer->ptv + 1),
107 timer->rate, get_ticks_per_sec());
108 else
109 return timer->val;
110 }
111
112 static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
113 {
114 timer->val = omap_timer_read(timer);
115 timer->time = qemu_get_clock(vm_clock);
116 }
117
118 static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
119 {
120 int64_t expires;
121
122 if (timer->enable && timer->st && timer->rate) {
123 timer->val = timer->reset_val; /* Should skip this on clk enable */
124 expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
125 get_ticks_per_sec(), timer->rate);
126
127 /* If timer expiry would be sooner than in about 1 ms and
128 * auto-reload isn't set, then fire immediately. This is a hack
129 * to make systems like PalmOS run in acceptable time. PalmOS
130 * sets the interval to a very low value and polls the status bit
131 * in a busy loop when it wants to sleep just a couple of CPU
132 * ticks. */
133 if (expires > (get_ticks_per_sec() >> 10) || timer->ar)
134 qemu_mod_timer(timer->timer, timer->time + expires);
135 else
136 qemu_bh_schedule(timer->tick);
137 } else
138 qemu_del_timer(timer->timer);
139 }
140
141 static void omap_timer_fire(void *opaque)
142 {
143 struct omap_mpu_timer_s *timer = opaque;
144
145 if (!timer->ar) {
146 timer->val = 0;
147 timer->st = 0;
148 }
149
150 if (timer->it_ena)
151 /* Edge-triggered irq */
152 qemu_irq_pulse(timer->irq);
153 }
154
155 static void omap_timer_tick(void *opaque)
156 {
157 struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
158
159 omap_timer_sync(timer);
160 omap_timer_fire(timer);
161 omap_timer_update(timer);
162 }
163
164 static void omap_timer_clk_update(void *opaque, int line, int on)
165 {
166 struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
167
168 omap_timer_sync(timer);
169 timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
170 omap_timer_update(timer);
171 }
172
173 static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
174 {
175 omap_clk_adduser(timer->clk,
176 qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
177 timer->rate = omap_clk_getrate(timer->clk);
178 }
179
180 static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
181 {
182 struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
183
184 switch (addr) {
185 case 0x00: /* CNTL_TIMER */
186 return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
187
188 case 0x04: /* LOAD_TIM */
189 break;
190
191 case 0x08: /* READ_TIM */
192 return omap_timer_read(s);
193 }
194
195 OMAP_BAD_REG(addr);
196 return 0;
197 }
198
199 static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
200 uint32_t value)
201 {
202 struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
203
204 switch (addr) {
205 case 0x00: /* CNTL_TIMER */
206 omap_timer_sync(s);
207 s->enable = (value >> 5) & 1;
208 s->ptv = (value >> 2) & 7;
209 s->ar = (value >> 1) & 1;
210 s->st = value & 1;
211 omap_timer_update(s);
212 return;
213
214 case 0x04: /* LOAD_TIM */
215 s->reset_val = value;
216 return;
217
218 case 0x08: /* READ_TIM */
219 OMAP_RO_REG(addr);
220 break;
221
222 default:
223 OMAP_BAD_REG(addr);
224 }
225 }
226
227 static CPUReadMemoryFunc * const omap_mpu_timer_readfn[] = {
228 omap_badwidth_read32,
229 omap_badwidth_read32,
230 omap_mpu_timer_read,
231 };
232
233 static CPUWriteMemoryFunc * const omap_mpu_timer_writefn[] = {
234 omap_badwidth_write32,
235 omap_badwidth_write32,
236 omap_mpu_timer_write,
237 };
238
239 static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
240 {
241 qemu_del_timer(s->timer);
242 s->enable = 0;
243 s->reset_val = 31337;
244 s->val = 0;
245 s->ptv = 0;
246 s->ar = 0;
247 s->st = 0;
248 s->it_ena = 1;
249 }
250
251 static struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
252 qemu_irq irq, omap_clk clk)
253 {
254 int iomemtype;
255 struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
256 qemu_mallocz(sizeof(struct omap_mpu_timer_s));
257
258 s->irq = irq;
259 s->clk = clk;
260 s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
261 s->tick = qemu_bh_new(omap_timer_fire, s);
262 omap_mpu_timer_reset(s);
263 omap_timer_clk_setup(s);
264
265 iomemtype = cpu_register_io_memory(omap_mpu_timer_readfn,
266 omap_mpu_timer_writefn, s);
267 cpu_register_physical_memory(base, 0x100, iomemtype);
268
269 return s;
270 }
271
272 /* Watchdog timer */
273 struct omap_watchdog_timer_s {
274 struct omap_mpu_timer_s timer;
275 uint8_t last_wr;
276 int mode;
277 int free;
278 int reset;
279 };
280
281 static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
282 {
283 struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
284
285 switch (addr) {
286 case 0x00: /* CNTL_TIMER */
287 return (s->timer.ptv << 9) | (s->timer.ar << 8) |
288 (s->timer.st << 7) | (s->free << 1);
289
290 case 0x04: /* READ_TIMER */
291 return omap_timer_read(&s->timer);
292
293 case 0x08: /* TIMER_MODE */
294 return s->mode << 15;
295 }
296
297 OMAP_BAD_REG(addr);
298 return 0;
299 }
300
301 static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
302 uint32_t value)
303 {
304 struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
305
306 switch (addr) {
307 case 0x00: /* CNTL_TIMER */
308 omap_timer_sync(&s->timer);
309 s->timer.ptv = (value >> 9) & 7;
310 s->timer.ar = (value >> 8) & 1;
311 s->timer.st = (value >> 7) & 1;
312 s->free = (value >> 1) & 1;
313 omap_timer_update(&s->timer);
314 break;
315
316 case 0x04: /* LOAD_TIMER */
317 s->timer.reset_val = value & 0xffff;
318 break;
319
320 case 0x08: /* TIMER_MODE */
321 if (!s->mode && ((value >> 15) & 1))
322 omap_clk_get(s->timer.clk);
323 s->mode |= (value >> 15) & 1;
324 if (s->last_wr == 0xf5) {
325 if ((value & 0xff) == 0xa0) {
326 if (s->mode) {
327 s->mode = 0;
328 omap_clk_put(s->timer.clk);
329 }
330 } else {
331 /* XXX: on T|E hardware somehow this has no effect,
332 * on Zire 71 it works as specified. */
333 s->reset = 1;
334 qemu_system_reset_request();
335 }
336 }
337 s->last_wr = value & 0xff;
338 break;
339
340 default:
341 OMAP_BAD_REG(addr);
342 }
343 }
344
345 static CPUReadMemoryFunc * const omap_wd_timer_readfn[] = {
346 omap_badwidth_read16,
347 omap_wd_timer_read,
348 omap_badwidth_read16,
349 };
350
351 static CPUWriteMemoryFunc * const omap_wd_timer_writefn[] = {
352 omap_badwidth_write16,
353 omap_wd_timer_write,
354 omap_badwidth_write16,
355 };
356
357 static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
358 {
359 qemu_del_timer(s->timer.timer);
360 if (!s->mode)
361 omap_clk_get(s->timer.clk);
362 s->mode = 1;
363 s->free = 1;
364 s->reset = 0;
365 s->timer.enable = 1;
366 s->timer.it_ena = 1;
367 s->timer.reset_val = 0xffff;
368 s->timer.val = 0;
369 s->timer.st = 0;
370 s->timer.ptv = 0;
371 s->timer.ar = 0;
372 omap_timer_update(&s->timer);
373 }
374
375 static struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
376 qemu_irq irq, omap_clk clk)
377 {
378 int iomemtype;
379 struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
380 qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
381
382 s->timer.irq = irq;
383 s->timer.clk = clk;
384 s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
385 omap_wd_timer_reset(s);
386 omap_timer_clk_setup(&s->timer);
387
388 iomemtype = cpu_register_io_memory(omap_wd_timer_readfn,
389 omap_wd_timer_writefn, s);
390 cpu_register_physical_memory(base, 0x100, iomemtype);
391
392 return s;
393 }
394
395 /* 32-kHz timer */
396 struct omap_32khz_timer_s {
397 struct omap_mpu_timer_s timer;
398 };
399
400 static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
401 {
402 struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
403 int offset = addr & OMAP_MPUI_REG_MASK;
404
405 switch (offset) {
406 case 0x00: /* TVR */
407 return s->timer.reset_val;
408
409 case 0x04: /* TCR */
410 return omap_timer_read(&s->timer);
411
412 case 0x08: /* CR */
413 return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
414
415 default:
416 break;
417 }
418 OMAP_BAD_REG(addr);
419 return 0;
420 }
421
422 static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
423 uint32_t value)
424 {
425 struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
426 int offset = addr & OMAP_MPUI_REG_MASK;
427
428 switch (offset) {
429 case 0x00: /* TVR */
430 s->timer.reset_val = value & 0x00ffffff;
431 break;
432
433 case 0x04: /* TCR */
434 OMAP_RO_REG(addr);
435 break;
436
437 case 0x08: /* CR */
438 s->timer.ar = (value >> 3) & 1;
439 s->timer.it_ena = (value >> 2) & 1;
440 if (s->timer.st != (value & 1) || (value & 2)) {
441 omap_timer_sync(&s->timer);
442 s->timer.enable = value & 1;
443 s->timer.st = value & 1;
444 omap_timer_update(&s->timer);
445 }
446 break;
447
448 default:
449 OMAP_BAD_REG(addr);
450 }
451 }
452
453 static CPUReadMemoryFunc * const omap_os_timer_readfn[] = {
454 omap_badwidth_read32,
455 omap_badwidth_read32,
456 omap_os_timer_read,
457 };
458
459 static CPUWriteMemoryFunc * const omap_os_timer_writefn[] = {
460 omap_badwidth_write32,
461 omap_badwidth_write32,
462 omap_os_timer_write,
463 };
464
465 static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
466 {
467 qemu_del_timer(s->timer.timer);
468 s->timer.enable = 0;
469 s->timer.it_ena = 0;
470 s->timer.reset_val = 0x00ffffff;
471 s->timer.val = 0;
472 s->timer.st = 0;
473 s->timer.ptv = 0;
474 s->timer.ar = 1;
475 }
476
477 static struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
478 qemu_irq irq, omap_clk clk)
479 {
480 int iomemtype;
481 struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
482 qemu_mallocz(sizeof(struct omap_32khz_timer_s));
483
484 s->timer.irq = irq;
485 s->timer.clk = clk;
486 s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
487 omap_os_timer_reset(s);
488 omap_timer_clk_setup(&s->timer);
489
490 iomemtype = cpu_register_io_memory(omap_os_timer_readfn,
491 omap_os_timer_writefn, s);
492 cpu_register_physical_memory(base, 0x800, iomemtype);
493
494 return s;
495 }
496
497 /* Ultra Low-Power Device Module */
498 static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
499 {
500 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
501 uint16_t ret;
502
503 switch (addr) {
504 case 0x14: /* IT_STATUS */
505 ret = s->ulpd_pm_regs[addr >> 2];
506 s->ulpd_pm_regs[addr >> 2] = 0;
507 qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
508 return ret;
509
510 case 0x18: /* Reserved */
511 case 0x1c: /* Reserved */
512 case 0x20: /* Reserved */
513 case 0x28: /* Reserved */
514 case 0x2c: /* Reserved */
515 OMAP_BAD_REG(addr);
516 case 0x00: /* COUNTER_32_LSB */
517 case 0x04: /* COUNTER_32_MSB */
518 case 0x08: /* COUNTER_HIGH_FREQ_LSB */
519 case 0x0c: /* COUNTER_HIGH_FREQ_MSB */
520 case 0x10: /* GAUGING_CTRL */
521 case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */
522 case 0x30: /* CLOCK_CTRL */
523 case 0x34: /* SOFT_REQ */
524 case 0x38: /* COUNTER_32_FIQ */
525 case 0x3c: /* DPLL_CTRL */
526 case 0x40: /* STATUS_REQ */
527 /* XXX: check clk::usecount state for every clock */
528 case 0x48: /* LOCL_TIME */
529 case 0x4c: /* APLL_CTRL */
530 case 0x50: /* POWER_CTRL */
531 return s->ulpd_pm_regs[addr >> 2];
532 }
533
534 OMAP_BAD_REG(addr);
535 return 0;
536 }
537
538 static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
539 uint16_t diff, uint16_t value)
540 {
541 if (diff & (1 << 4)) /* USB_MCLK_EN */
542 omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
543 if (diff & (1 << 5)) /* DIS_USB_PVCI_CLK */
544 omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
545 }
546
547 static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
548 uint16_t diff, uint16_t value)
549 {
550 if (diff & (1 << 0)) /* SOFT_DPLL_REQ */
551 omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
552 if (diff & (1 << 1)) /* SOFT_COM_REQ */
553 omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
554 if (diff & (1 << 2)) /* SOFT_SDW_REQ */
555 omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
556 if (diff & (1 << 3)) /* SOFT_USB_REQ */
557 omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
558 }
559
560 static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
561 uint32_t value)
562 {
563 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
564 int64_t now, ticks;
565 int div, mult;
566 static const int bypass_div[4] = { 1, 2, 4, 4 };
567 uint16_t diff;
568
569 switch (addr) {
570 case 0x00: /* COUNTER_32_LSB */
571 case 0x04: /* COUNTER_32_MSB */
572 case 0x08: /* COUNTER_HIGH_FREQ_LSB */
573 case 0x0c: /* COUNTER_HIGH_FREQ_MSB */
574 case 0x14: /* IT_STATUS */
575 case 0x40: /* STATUS_REQ */
576 OMAP_RO_REG(addr);
577 break;
578
579 case 0x10: /* GAUGING_CTRL */
580 /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
581 if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
582 now = qemu_get_clock(vm_clock);
583
584 if (value & 1)
585 s->ulpd_gauge_start = now;
586 else {
587 now -= s->ulpd_gauge_start;
588
589 /* 32-kHz ticks */
590 ticks = muldiv64(now, 32768, get_ticks_per_sec());
591 s->ulpd_pm_regs[0x00 >> 2] = (ticks >> 0) & 0xffff;
592 s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
593 if (ticks >> 32) /* OVERFLOW_32K */
594 s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
595
596 /* High frequency ticks */
597 ticks = muldiv64(now, 12000000, get_ticks_per_sec());
598 s->ulpd_pm_regs[0x08 >> 2] = (ticks >> 0) & 0xffff;
599 s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
600 if (ticks >> 32) /* OVERFLOW_HI_FREQ */
601 s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
602
603 s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0; /* IT_GAUGING */
604 qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
605 }
606 }
607 s->ulpd_pm_regs[addr >> 2] = value;
608 break;
609
610 case 0x18: /* Reserved */
611 case 0x1c: /* Reserved */
612 case 0x20: /* Reserved */
613 case 0x28: /* Reserved */
614 case 0x2c: /* Reserved */
615 OMAP_BAD_REG(addr);
616 case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */
617 case 0x38: /* COUNTER_32_FIQ */
618 case 0x48: /* LOCL_TIME */
619 case 0x50: /* POWER_CTRL */
620 s->ulpd_pm_regs[addr >> 2] = value;
621 break;
622
623 case 0x30: /* CLOCK_CTRL */
624 diff = s->ulpd_pm_regs[addr >> 2] ^ value;
625 s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
626 omap_ulpd_clk_update(s, diff, value);
627 break;
628
629 case 0x34: /* SOFT_REQ */
630 diff = s->ulpd_pm_regs[addr >> 2] ^ value;
631 s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
632 omap_ulpd_req_update(s, diff, value);
633 break;
634
635 case 0x3c: /* DPLL_CTRL */
636 /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
637 * omitted altogether, probably a typo. */
638 /* This register has identical semantics with DPLL(1:3) control
639 * registers, see omap_dpll_write() */
640 diff = s->ulpd_pm_regs[addr >> 2] & value;
641 s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
642 if (diff & (0x3ff << 2)) {
643 if (value & (1 << 4)) { /* PLL_ENABLE */
644 div = ((value >> 5) & 3) + 1; /* PLL_DIV */
645 mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */
646 } else {
647 div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */
648 mult = 1;
649 }
650 omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
651 }
652
653 /* Enter the desired mode. */
654 s->ulpd_pm_regs[addr >> 2] =
655 (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
656 ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
657
658 /* Act as if the lock is restored. */
659 s->ulpd_pm_regs[addr >> 2] |= 2;
660 break;
661
662 case 0x4c: /* APLL_CTRL */
663 diff = s->ulpd_pm_regs[addr >> 2] & value;
664 s->ulpd_pm_regs[addr >> 2] = value & 0xf;
665 if (diff & (1 << 0)) /* APLL_NDPLL_SWITCH */
666 omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
667 (value & (1 << 0)) ? "apll" : "dpll4"));
668 break;
669
670 default:
671 OMAP_BAD_REG(addr);
672 }
673 }
674
675 static CPUReadMemoryFunc * const omap_ulpd_pm_readfn[] = {
676 omap_badwidth_read16,
677 omap_ulpd_pm_read,
678 omap_badwidth_read16,
679 };
680
681 static CPUWriteMemoryFunc * const omap_ulpd_pm_writefn[] = {
682 omap_badwidth_write16,
683 omap_ulpd_pm_write,
684 omap_badwidth_write16,
685 };
686
687 static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
688 {
689 mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
690 mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
691 mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
692 mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
693 mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
694 mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
695 mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
696 mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
697 mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
698 mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
699 mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
700 omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
701 mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
702 omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
703 mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
704 mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
705 mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
706 mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
707 mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
708 mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
709 mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
710 omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
711 omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
712 }
713
714 static void omap_ulpd_pm_init(target_phys_addr_t base,
715 struct omap_mpu_state_s *mpu)
716 {
717 int iomemtype = cpu_register_io_memory(omap_ulpd_pm_readfn,
718 omap_ulpd_pm_writefn, mpu);
719
720 cpu_register_physical_memory(base, 0x800, iomemtype);
721 omap_ulpd_pm_reset(mpu);
722 }
723
724 /* OMAP Pin Configuration */
725 static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
726 {
727 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
728
729 switch (addr) {
730 case 0x00: /* FUNC_MUX_CTRL_0 */
731 case 0x04: /* FUNC_MUX_CTRL_1 */
732 case 0x08: /* FUNC_MUX_CTRL_2 */
733 return s->func_mux_ctrl[addr >> 2];
734
735 case 0x0c: /* COMP_MODE_CTRL_0 */
736 return s->comp_mode_ctrl[0];
737
738 case 0x10: /* FUNC_MUX_CTRL_3 */
739 case 0x14: /* FUNC_MUX_CTRL_4 */
740 case 0x18: /* FUNC_MUX_CTRL_5 */
741 case 0x1c: /* FUNC_MUX_CTRL_6 */
742 case 0x20: /* FUNC_MUX_CTRL_7 */
743 case 0x24: /* FUNC_MUX_CTRL_8 */
744 case 0x28: /* FUNC_MUX_CTRL_9 */
745 case 0x2c: /* FUNC_MUX_CTRL_A */
746 case 0x30: /* FUNC_MUX_CTRL_B */
747 case 0x34: /* FUNC_MUX_CTRL_C */
748 case 0x38: /* FUNC_MUX_CTRL_D */
749 return s->func_mux_ctrl[(addr >> 2) - 1];
750
751 case 0x40: /* PULL_DWN_CTRL_0 */
752 case 0x44: /* PULL_DWN_CTRL_1 */
753 case 0x48: /* PULL_DWN_CTRL_2 */
754 case 0x4c: /* PULL_DWN_CTRL_3 */
755 return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
756
757 case 0x50: /* GATE_INH_CTRL_0 */
758 return s->gate_inh_ctrl[0];
759
760 case 0x60: /* VOLTAGE_CTRL_0 */
761 return s->voltage_ctrl[0];
762
763 case 0x70: /* TEST_DBG_CTRL_0 */
764 return s->test_dbg_ctrl[0];
765
766 case 0x80: /* MOD_CONF_CTRL_0 */
767 return s->mod_conf_ctrl[0];
768 }
769
770 OMAP_BAD_REG(addr);
771 return 0;
772 }
773
774 static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
775 uint32_t diff, uint32_t value)
776 {
777 if (s->compat1509) {
778 if (diff & (1 << 9)) /* BLUETOOTH */
779 omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
780 (~value >> 9) & 1);
781 if (diff & (1 << 7)) /* USB.CLKO */
782 omap_clk_onoff(omap_findclk(s, "usb.clko"),
783 (value >> 7) & 1);
784 }
785 }
786
787 static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
788 uint32_t diff, uint32_t value)
789 {
790 if (s->compat1509) {
791 if (diff & (1 << 31)) /* MCBSP3_CLK_HIZ_DI */
792 omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
793 (value >> 31) & 1);
794 if (diff & (1 << 1)) /* CLK32K */
795 omap_clk_onoff(omap_findclk(s, "clk32k_out"),
796 (~value >> 1) & 1);
797 }
798 }
799
800 static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
801 uint32_t diff, uint32_t value)
802 {
803 if (diff & (1 << 31)) /* CONF_MOD_UART3_CLK_MODE_R */
804 omap_clk_reparent(omap_findclk(s, "uart3_ck"),
805 omap_findclk(s, ((value >> 31) & 1) ?
806 "ck_48m" : "armper_ck"));
807 if (diff & (1 << 30)) /* CONF_MOD_UART2_CLK_MODE_R */
808 omap_clk_reparent(omap_findclk(s, "uart2_ck"),
809 omap_findclk(s, ((value >> 30) & 1) ?
810 "ck_48m" : "armper_ck"));
811 if (diff & (1 << 29)) /* CONF_MOD_UART1_CLK_MODE_R */
812 omap_clk_reparent(omap_findclk(s, "uart1_ck"),
813 omap_findclk(s, ((value >> 29) & 1) ?
814 "ck_48m" : "armper_ck"));
815 if (diff & (1 << 23)) /* CONF_MOD_MMC_SD_CLK_REQ_R */
816 omap_clk_reparent(omap_findclk(s, "mmc_ck"),
817 omap_findclk(s, ((value >> 23) & 1) ?
818 "ck_48m" : "armper_ck"));
819 if (diff & (1 << 12)) /* CONF_MOD_COM_MCLK_12_48_S */
820 omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
821 omap_findclk(s, ((value >> 12) & 1) ?
822 "ck_48m" : "armper_ck"));
823 if (diff & (1 << 9)) /* CONF_MOD_USB_HOST_HHC_UHO */
824 omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
825 }
826
827 static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
828 uint32_t value)
829 {
830 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
831 uint32_t diff;
832
833 switch (addr) {
834 case 0x00: /* FUNC_MUX_CTRL_0 */
835 diff = s->func_mux_ctrl[addr >> 2] ^ value;
836 s->func_mux_ctrl[addr >> 2] = value;
837 omap_pin_funcmux0_update(s, diff, value);
838 return;
839
840 case 0x04: /* FUNC_MUX_CTRL_1 */
841 diff = s->func_mux_ctrl[addr >> 2] ^ value;
842 s->func_mux_ctrl[addr >> 2] = value;
843 omap_pin_funcmux1_update(s, diff, value);
844 return;
845
846 case 0x08: /* FUNC_MUX_CTRL_2 */
847 s->func_mux_ctrl[addr >> 2] = value;
848 return;
849
850 case 0x0c: /* COMP_MODE_CTRL_0 */
851 s->comp_mode_ctrl[0] = value;
852 s->compat1509 = (value != 0x0000eaef);
853 omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
854 omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
855 return;
856
857 case 0x10: /* FUNC_MUX_CTRL_3 */
858 case 0x14: /* FUNC_MUX_CTRL_4 */
859 case 0x18: /* FUNC_MUX_CTRL_5 */
860 case 0x1c: /* FUNC_MUX_CTRL_6 */
861 case 0x20: /* FUNC_MUX_CTRL_7 */
862 case 0x24: /* FUNC_MUX_CTRL_8 */
863 case 0x28: /* FUNC_MUX_CTRL_9 */
864 case 0x2c: /* FUNC_MUX_CTRL_A */
865 case 0x30: /* FUNC_MUX_CTRL_B */
866 case 0x34: /* FUNC_MUX_CTRL_C */
867 case 0x38: /* FUNC_MUX_CTRL_D */
868 s->func_mux_ctrl[(addr >> 2) - 1] = value;
869 return;
870
871 case 0x40: /* PULL_DWN_CTRL_0 */
872 case 0x44: /* PULL_DWN_CTRL_1 */
873 case 0x48: /* PULL_DWN_CTRL_2 */
874 case 0x4c: /* PULL_DWN_CTRL_3 */
875 s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
876 return;
877
878 case 0x50: /* GATE_INH_CTRL_0 */
879 s->gate_inh_ctrl[0] = value;
880 return;
881
882 case 0x60: /* VOLTAGE_CTRL_0 */
883 s->voltage_ctrl[0] = value;
884 return;
885
886 case 0x70: /* TEST_DBG_CTRL_0 */
887 s->test_dbg_ctrl[0] = value;
888 return;
889
890 case 0x80: /* MOD_CONF_CTRL_0 */
891 diff = s->mod_conf_ctrl[0] ^ value;
892 s->mod_conf_ctrl[0] = value;
893 omap_pin_modconf1_update(s, diff, value);
894 return;
895
896 default:
897 OMAP_BAD_REG(addr);
898 }
899 }
900
901 static CPUReadMemoryFunc * const omap_pin_cfg_readfn[] = {
902 omap_badwidth_read32,
903 omap_badwidth_read32,
904 omap_pin_cfg_read,
905 };
906
907 static CPUWriteMemoryFunc * const omap_pin_cfg_writefn[] = {
908 omap_badwidth_write32,
909 omap_badwidth_write32,
910 omap_pin_cfg_write,
911 };
912
913 static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
914 {
915 /* Start in Compatibility Mode. */
916 mpu->compat1509 = 1;
917 omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
918 omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
919 omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
920 memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
921 memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
922 memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
923 memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
924 memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
925 memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
926 memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
927 }
928
929 static void omap_pin_cfg_init(target_phys_addr_t base,
930 struct omap_mpu_state_s *mpu)
931 {
932 int iomemtype = cpu_register_io_memory(omap_pin_cfg_readfn,
933 omap_pin_cfg_writefn, mpu);
934
935 cpu_register_physical_memory(base, 0x800, iomemtype);
936 omap_pin_cfg_reset(mpu);
937 }
938
939 /* Device Identification, Die Identification */
940 static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
941 {
942 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
943
944 switch (addr) {
945 case 0xfffe1800: /* DIE_ID_LSB */
946 return 0xc9581f0e;
947 case 0xfffe1804: /* DIE_ID_MSB */
948 return 0xa8858bfa;
949
950 case 0xfffe2000: /* PRODUCT_ID_LSB */
951 return 0x00aaaafc;
952 case 0xfffe2004: /* PRODUCT_ID_MSB */
953 return 0xcafeb574;
954
955 case 0xfffed400: /* JTAG_ID_LSB */
956 switch (s->mpu_model) {
957 case omap310:
958 return 0x03310315;
959 case omap1510:
960 return 0x03310115;
961 default:
962 hw_error("%s: bad mpu model\n", __FUNCTION__);
963 }
964 break;
965
966 case 0xfffed404: /* JTAG_ID_MSB */
967 switch (s->mpu_model) {
968 case omap310:
969 return 0xfb57402f;
970 case omap1510:
971 return 0xfb47002f;
972 default:
973 hw_error("%s: bad mpu model\n", __FUNCTION__);
974 }
975 break;
976 }
977
978 OMAP_BAD_REG(addr);
979 return 0;
980 }
981
982 static void omap_id_write(void *opaque, target_phys_addr_t addr,
983 uint32_t value)
984 {
985 OMAP_BAD_REG(addr);
986 }
987
988 static CPUReadMemoryFunc * const omap_id_readfn[] = {
989 omap_badwidth_read32,
990 omap_badwidth_read32,
991 omap_id_read,
992 };
993
994 static CPUWriteMemoryFunc * const omap_id_writefn[] = {
995 omap_badwidth_write32,
996 omap_badwidth_write32,
997 omap_id_write,
998 };
999
1000 static void omap_id_init(struct omap_mpu_state_s *mpu)
1001 {
1002 int iomemtype = cpu_register_io_memory(omap_id_readfn,
1003 omap_id_writefn, mpu);
1004 cpu_register_physical_memory_offset(0xfffe1800, 0x800, iomemtype, 0xfffe1800);
1005 cpu_register_physical_memory_offset(0xfffed400, 0x100, iomemtype, 0xfffed400);
1006 if (!cpu_is_omap15xx(mpu))
1007 cpu_register_physical_memory_offset(0xfffe2000, 0x800, iomemtype, 0xfffe2000);
1008 }
1009
1010 /* MPUI Control (Dummy) */
1011 static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
1012 {
1013 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1014
1015 switch (addr) {
1016 case 0x00: /* CTRL */
1017 return s->mpui_ctrl;
1018 case 0x04: /* DEBUG_ADDR */
1019 return 0x01ffffff;
1020 case 0x08: /* DEBUG_DATA */
1021 return 0xffffffff;
1022 case 0x0c: /* DEBUG_FLAG */
1023 return 0x00000800;
1024 case 0x10: /* STATUS */
1025 return 0x00000000;
1026
1027 /* Not in OMAP310 */
1028 case 0x14: /* DSP_STATUS */
1029 case 0x18: /* DSP_BOOT_CONFIG */
1030 return 0x00000000;
1031 case 0x1c: /* DSP_MPUI_CONFIG */
1032 return 0x0000ffff;
1033 }
1034
1035 OMAP_BAD_REG(addr);
1036 return 0;
1037 }
1038
1039 static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
1040 uint32_t value)
1041 {
1042 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1043
1044 switch (addr) {
1045 case 0x00: /* CTRL */
1046 s->mpui_ctrl = value & 0x007fffff;
1047 break;
1048
1049 case 0x04: /* DEBUG_ADDR */
1050 case 0x08: /* DEBUG_DATA */
1051 case 0x0c: /* DEBUG_FLAG */
1052 case 0x10: /* STATUS */
1053 /* Not in OMAP310 */
1054 case 0x14: /* DSP_STATUS */
1055 OMAP_RO_REG(addr);
1056 case 0x18: /* DSP_BOOT_CONFIG */
1057 case 0x1c: /* DSP_MPUI_CONFIG */
1058 break;
1059
1060 default:
1061 OMAP_BAD_REG(addr);
1062 }
1063 }
1064
1065 static CPUReadMemoryFunc * const omap_mpui_readfn[] = {
1066 omap_badwidth_read32,
1067 omap_badwidth_read32,
1068 omap_mpui_read,
1069 };
1070
1071 static CPUWriteMemoryFunc * const omap_mpui_writefn[] = {
1072 omap_badwidth_write32,
1073 omap_badwidth_write32,
1074 omap_mpui_write,
1075 };
1076
1077 static void omap_mpui_reset(struct omap_mpu_state_s *s)
1078 {
1079 s->mpui_ctrl = 0x0003ff1b;
1080 }
1081
1082 static void omap_mpui_init(target_phys_addr_t base,
1083 struct omap_mpu_state_s *mpu)
1084 {
1085 int iomemtype = cpu_register_io_memory(omap_mpui_readfn,
1086 omap_mpui_writefn, mpu);
1087
1088 cpu_register_physical_memory(base, 0x100, iomemtype);
1089
1090 omap_mpui_reset(mpu);
1091 }
1092
1093 /* TIPB Bridges */
1094 struct omap_tipb_bridge_s {
1095 qemu_irq abort;
1096
1097 int width_intr;
1098 uint16_t control;
1099 uint16_t alloc;
1100 uint16_t buffer;
1101 uint16_t enh_control;
1102 };
1103
1104 static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
1105 {
1106 struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1107
1108 switch (addr) {
1109 case 0x00: /* TIPB_CNTL */
1110 return s->control;
1111 case 0x04: /* TIPB_BUS_ALLOC */
1112 return s->alloc;
1113 case 0x08: /* MPU_TIPB_CNTL */
1114 return s->buffer;
1115 case 0x0c: /* ENHANCED_TIPB_CNTL */
1116 return s->enh_control;
1117 case 0x10: /* ADDRESS_DBG */
1118 case 0x14: /* DATA_DEBUG_LOW */
1119 case 0x18: /* DATA_DEBUG_HIGH */
1120 return 0xffff;
1121 case 0x1c: /* DEBUG_CNTR_SIG */
1122 return 0x00f8;
1123 }
1124
1125 OMAP_BAD_REG(addr);
1126 return 0;
1127 }
1128
1129 static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
1130 uint32_t value)
1131 {
1132 struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1133
1134 switch (addr) {
1135 case 0x00: /* TIPB_CNTL */
1136 s->control = value & 0xffff;
1137 break;
1138
1139 case 0x04: /* TIPB_BUS_ALLOC */
1140 s->alloc = value & 0x003f;
1141 break;
1142
1143 case 0x08: /* MPU_TIPB_CNTL */
1144 s->buffer = value & 0x0003;
1145 break;
1146
1147 case 0x0c: /* ENHANCED_TIPB_CNTL */
1148 s->width_intr = !(value & 2);
1149 s->enh_control = value & 0x000f;
1150 break;
1151
1152 case 0x10: /* ADDRESS_DBG */
1153 case 0x14: /* DATA_DEBUG_LOW */
1154 case 0x18: /* DATA_DEBUG_HIGH */
1155 case 0x1c: /* DEBUG_CNTR_SIG */
1156 OMAP_RO_REG(addr);
1157 break;
1158
1159 default:
1160 OMAP_BAD_REG(addr);
1161 }
1162 }
1163
1164 static CPUReadMemoryFunc * const omap_tipb_bridge_readfn[] = {
1165 omap_badwidth_read16,
1166 omap_tipb_bridge_read,
1167 omap_tipb_bridge_read,
1168 };
1169
1170 static CPUWriteMemoryFunc * const omap_tipb_bridge_writefn[] = {
1171 omap_badwidth_write16,
1172 omap_tipb_bridge_write,
1173 omap_tipb_bridge_write,
1174 };
1175
1176 static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
1177 {
1178 s->control = 0xffff;
1179 s->alloc = 0x0009;
1180 s->buffer = 0x0000;
1181 s->enh_control = 0x000f;
1182 }
1183
1184 static struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
1185 qemu_irq abort_irq, omap_clk clk)
1186 {
1187 int iomemtype;
1188 struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
1189 qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
1190
1191 s->abort = abort_irq;
1192 omap_tipb_bridge_reset(s);
1193
1194 iomemtype = cpu_register_io_memory(omap_tipb_bridge_readfn,
1195 omap_tipb_bridge_writefn, s);
1196 cpu_register_physical_memory(base, 0x100, iomemtype);
1197
1198 return s;
1199 }
1200
1201 /* Dummy Traffic Controller's Memory Interface */
1202 static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
1203 {
1204 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1205 uint32_t ret;
1206
1207 switch (addr) {
1208 case 0x00: /* IMIF_PRIO */
1209 case 0x04: /* EMIFS_PRIO */
1210 case 0x08: /* EMIFF_PRIO */
1211 case 0x0c: /* EMIFS_CONFIG */
1212 case 0x10: /* EMIFS_CS0_CONFIG */
1213 case 0x14: /* EMIFS_CS1_CONFIG */
1214 case 0x18: /* EMIFS_CS2_CONFIG */
1215 case 0x1c: /* EMIFS_CS3_CONFIG */
1216 case 0x24: /* EMIFF_MRS */
1217 case 0x28: /* TIMEOUT1 */
1218 case 0x2c: /* TIMEOUT2 */
1219 case 0x30: /* TIMEOUT3 */
1220 case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
1221 case 0x40: /* EMIFS_CFG_DYN_WAIT */
1222 return s->tcmi_regs[addr >> 2];
1223
1224 case 0x20: /* EMIFF_SDRAM_CONFIG */
1225 ret = s->tcmi_regs[addr >> 2];
1226 s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
1227 /* XXX: We can try using the VGA_DIRTY flag for this */
1228 return ret;
1229 }
1230
1231 OMAP_BAD_REG(addr);
1232 return 0;
1233 }
1234
1235 static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
1236 uint32_t value)
1237 {
1238 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1239
1240 switch (addr) {
1241 case 0x00: /* IMIF_PRIO */
1242 case 0x04: /* EMIFS_PRIO */
1243 case 0x08: /* EMIFF_PRIO */
1244 case 0x10: /* EMIFS_CS0_CONFIG */
1245 case 0x14: /* EMIFS_CS1_CONFIG */
1246 case 0x18: /* EMIFS_CS2_CONFIG */
1247 case 0x1c: /* EMIFS_CS3_CONFIG */
1248 case 0x20: /* EMIFF_SDRAM_CONFIG */
1249 case 0x24: /* EMIFF_MRS */
1250 case 0x28: /* TIMEOUT1 */
1251 case 0x2c: /* TIMEOUT2 */
1252 case 0x30: /* TIMEOUT3 */
1253 case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
1254 case 0x40: /* EMIFS_CFG_DYN_WAIT */
1255 s->tcmi_regs[addr >> 2] = value;
1256 break;
1257 case 0x0c: /* EMIFS_CONFIG */
1258 s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
1259 break;
1260
1261 default:
1262 OMAP_BAD_REG(addr);
1263 }
1264 }
1265
1266 static CPUReadMemoryFunc * const omap_tcmi_readfn[] = {
1267 omap_badwidth_read32,
1268 omap_badwidth_read32,
1269 omap_tcmi_read,
1270 };
1271
1272 static CPUWriteMemoryFunc * const omap_tcmi_writefn[] = {
1273 omap_badwidth_write32,
1274 omap_badwidth_write32,
1275 omap_tcmi_write,
1276 };
1277
1278 static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
1279 {
1280 mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
1281 mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
1282 mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
1283 mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
1284 mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
1285 mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
1286 mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
1287 mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
1288 mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
1289 mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
1290 mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
1291 mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
1292 mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
1293 mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
1294 mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
1295 }
1296
1297 static void omap_tcmi_init(target_phys_addr_t base,
1298 struct omap_mpu_state_s *mpu)
1299 {
1300 int iomemtype = cpu_register_io_memory(omap_tcmi_readfn,
1301 omap_tcmi_writefn, mpu);
1302
1303 cpu_register_physical_memory(base, 0x100, iomemtype);
1304 omap_tcmi_reset(mpu);
1305 }
1306
1307 /* Digital phase-locked loops control */
1308 static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
1309 {
1310 struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1311
1312 if (addr == 0x00) /* CTL_REG */
1313 return s->mode;
1314
1315 OMAP_BAD_REG(addr);
1316 return 0;
1317 }
1318
1319 static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
1320 uint32_t value)
1321 {
1322 struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1323 uint16_t diff;
1324 static const int bypass_div[4] = { 1, 2, 4, 4 };
1325 int div, mult;
1326
1327 if (addr == 0x00) { /* CTL_REG */
1328 /* See omap_ulpd_pm_write() too */
1329 diff = s->mode & value;
1330 s->mode = value & 0x2fff;
1331 if (diff & (0x3ff << 2)) {
1332 if (value & (1 << 4)) { /* PLL_ENABLE */
1333 div = ((value >> 5) & 3) + 1; /* PLL_DIV */
1334 mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */
1335 } else {
1336 div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */
1337 mult = 1;
1338 }
1339 omap_clk_setrate(s->dpll, div, mult);
1340 }
1341
1342 /* Enter the desired mode. */
1343 s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
1344
1345 /* Act as if the lock is restored. */
1346 s->mode |= 2;
1347 } else {
1348 OMAP_BAD_REG(addr);
1349 }
1350 }
1351
1352 static CPUReadMemoryFunc * const omap_dpll_readfn[] = {
1353 omap_badwidth_read16,
1354 omap_dpll_read,
1355 omap_badwidth_read16,
1356 };
1357
1358 static CPUWriteMemoryFunc * const omap_dpll_writefn[] = {
1359 omap_badwidth_write16,
1360 omap_dpll_write,
1361 omap_badwidth_write16,
1362 };
1363
1364 static void omap_dpll_reset(struct dpll_ctl_s *s)
1365 {
1366 s->mode = 0x2002;
1367 omap_clk_setrate(s->dpll, 1, 1);
1368 }
1369
1370 static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
1371 omap_clk clk)
1372 {
1373 int iomemtype = cpu_register_io_memory(omap_dpll_readfn,
1374 omap_dpll_writefn, s);
1375
1376 s->dpll = clk;
1377 omap_dpll_reset(s);
1378
1379 cpu_register_physical_memory(base, 0x100, iomemtype);
1380 }
1381
1382 /* MPU Clock/Reset/Power Mode Control */
1383 static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
1384 {
1385 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1386
1387 switch (addr) {
1388 case 0x00: /* ARM_CKCTL */
1389 return s->clkm.arm_ckctl;
1390
1391 case 0x04: /* ARM_IDLECT1 */
1392 return s->clkm.arm_idlect1;
1393
1394 case 0x08: /* ARM_IDLECT2 */
1395 return s->clkm.arm_idlect2;
1396
1397 case 0x0c: /* ARM_EWUPCT */
1398 return s->clkm.arm_ewupct;
1399
1400 case 0x10: /* ARM_RSTCT1 */
1401 return s->clkm.arm_rstct1;
1402
1403 case 0x14: /* ARM_RSTCT2 */
1404 return s->clkm.arm_rstct2;
1405
1406 case 0x18: /* ARM_SYSST */
1407 return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
1408
1409 case 0x1c: /* ARM_CKOUT1 */
1410 return s->clkm.arm_ckout1;
1411
1412 case 0x20: /* ARM_CKOUT2 */
1413 break;
1414 }
1415
1416 OMAP_BAD_REG(addr);
1417 return 0;
1418 }
1419
1420 static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
1421 uint16_t diff, uint16_t value)
1422 {
1423 omap_clk clk;
1424
1425 if (diff & (1 << 14)) { /* ARM_INTHCK_SEL */
1426 if (value & (1 << 14))
1427 /* Reserved */;
1428 else {
1429 clk = omap_findclk(s, "arminth_ck");
1430 omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1431 }
1432 }
1433 if (diff & (1 << 12)) { /* ARM_TIMXO */
1434 clk = omap_findclk(s, "armtim_ck");
1435 if (value & (1 << 12))
1436 omap_clk_reparent(clk, omap_findclk(s, "clkin"));
1437 else
1438 omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1439 }
1440 /* XXX: en_dspck */
1441 if (diff & (3 << 10)) { /* DSPMMUDIV */
1442 clk = omap_findclk(s, "dspmmu_ck");
1443 omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
1444 }
1445 if (diff & (3 << 8)) { /* TCDIV */
1446 clk = omap_findclk(s, "tc_ck");
1447 omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
1448 }
1449 if (diff & (3 << 6)) { /* DSPDIV */
1450 clk = omap_findclk(s, "dsp_ck");
1451 omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
1452 }
1453 if (diff & (3 << 4)) { /* ARMDIV */
1454 clk = omap_findclk(s, "arm_ck");
1455 omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
1456 }
1457 if (diff & (3 << 2)) { /* LCDDIV */
1458 clk = omap_findclk(s, "lcd_ck");
1459 omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
1460 }
1461 if (diff & (3 << 0)) { /* PERDIV */
1462 clk = omap_findclk(s, "armper_ck");
1463 omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
1464 }
1465 }
1466
1467 static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
1468 uint16_t diff, uint16_t value)
1469 {
1470 omap_clk clk;
1471
1472 if (value & (1 << 11)) /* SETARM_IDLE */
1473 cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
1474 if (!(value & (1 << 10))) /* WKUP_MODE */
1475 qemu_system_shutdown_request(); /* XXX: disable wakeup from IRQ */
1476
1477 #define SET_CANIDLE(clock, bit) \
1478 if (diff & (1 << bit)) { \
1479 clk = omap_findclk(s, clock); \
1480 omap_clk_canidle(clk, (value >> bit) & 1); \
1481 }
1482 SET_CANIDLE("mpuwd_ck", 0) /* IDLWDT_ARM */
1483 SET_CANIDLE("armxor_ck", 1) /* IDLXORP_ARM */
1484 SET_CANIDLE("mpuper_ck", 2) /* IDLPER_ARM */
1485 SET_CANIDLE("lcd_ck", 3) /* IDLLCD_ARM */
1486 SET_CANIDLE("lb_ck", 4) /* IDLLB_ARM */
1487 SET_CANIDLE("hsab_ck", 5) /* IDLHSAB_ARM */
1488 SET_CANIDLE("tipb_ck", 6) /* IDLIF_ARM */
1489 SET_CANIDLE("dma_ck", 6) /* IDLIF_ARM */
1490 SET_CANIDLE("tc_ck", 6) /* IDLIF_ARM */
1491 SET_CANIDLE("dpll1", 7) /* IDLDPLL_ARM */
1492 SET_CANIDLE("dpll2", 7) /* IDLDPLL_ARM */
1493 SET_CANIDLE("dpll3", 7) /* IDLDPLL_ARM */
1494 SET_CANIDLE("mpui_ck", 8) /* IDLAPI_ARM */
1495 SET_CANIDLE("armtim_ck", 9) /* IDLTIM_ARM */
1496 }
1497
1498 static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
1499 uint16_t diff, uint16_t value)
1500 {
1501 omap_clk clk;
1502
1503 #define SET_ONOFF(clock, bit) \
1504 if (diff & (1 << bit)) { \
1505 clk = omap_findclk(s, clock); \
1506 omap_clk_onoff(clk, (value >> bit) & 1); \
1507 }
1508 SET_ONOFF("mpuwd_ck", 0) /* EN_WDTCK */
1509 SET_ONOFF("armxor_ck", 1) /* EN_XORPCK */
1510 SET_ONOFF("mpuper_ck", 2) /* EN_PERCK */
1511 SET_ONOFF("lcd_ck", 3) /* EN_LCDCK */
1512 SET_ONOFF("lb_ck", 4) /* EN_LBCK */
1513 SET_ONOFF("hsab_ck", 5) /* EN_HSABCK */
1514 SET_ONOFF("mpui_ck", 6) /* EN_APICK */
1515 SET_ONOFF("armtim_ck", 7) /* EN_TIMCK */
1516 SET_CANIDLE("dma_ck", 8) /* DMACK_REQ */
1517 SET_ONOFF("arm_gpio_ck", 9) /* EN_GPIOCK */
1518 SET_ONOFF("lbfree_ck", 10) /* EN_LBFREECK */
1519 }
1520
1521 static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
1522 uint16_t diff, uint16_t value)
1523 {
1524 omap_clk clk;
1525
1526 if (diff & (3 << 4)) { /* TCLKOUT */
1527 clk = omap_findclk(s, "tclk_out");
1528 switch ((value >> 4) & 3) {
1529 case 1:
1530 omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
1531 omap_clk_onoff(clk, 1);
1532 break;
1533 case 2:
1534 omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1535 omap_clk_onoff(clk, 1);
1536 break;
1537 default:
1538 omap_clk_onoff(clk, 0);
1539 }
1540 }
1541 if (diff & (3 << 2)) { /* DCLKOUT */
1542 clk = omap_findclk(s, "dclk_out");
1543 switch ((value >> 2) & 3) {
1544 case 0:
1545 omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
1546 break;
1547 case 1:
1548 omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
1549 break;
1550 case 2:
1551 omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
1552 break;
1553 case 3:
1554 omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1555 break;
1556 }
1557 }
1558 if (diff & (3 << 0)) { /* ACLKOUT */
1559 clk = omap_findclk(s, "aclk_out");
1560 switch ((value >> 0) & 3) {
1561 case 1:
1562 omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1563 omap_clk_onoff(clk, 1);
1564 break;
1565 case 2:
1566 omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
1567 omap_clk_onoff(clk, 1);
1568 break;
1569 case 3:
1570 omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1571 omap_clk_onoff(clk, 1);
1572 break;
1573 default:
1574 omap_clk_onoff(clk, 0);
1575 }
1576 }
1577 }
1578
1579 static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
1580 uint32_t value)
1581 {
1582 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1583 uint16_t diff;
1584 omap_clk clk;
1585 static const char *clkschemename[8] = {
1586 "fully synchronous", "fully asynchronous", "synchronous scalable",
1587 "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
1588 };
1589
1590 switch (addr) {
1591 case 0x00: /* ARM_CKCTL */
1592 diff = s->clkm.arm_ckctl ^ value;
1593 s->clkm.arm_ckctl = value & 0x7fff;
1594 omap_clkm_ckctl_update(s, diff, value);
1595 return;
1596
1597 case 0x04: /* ARM_IDLECT1 */
1598 diff = s->clkm.arm_idlect1 ^ value;
1599 s->clkm.arm_idlect1 = value & 0x0fff;
1600 omap_clkm_idlect1_update(s, diff, value);
1601 return;
1602
1603 case 0x08: /* ARM_IDLECT2 */
1604 diff = s->clkm.arm_idlect2 ^ value;
1605 s->clkm.arm_idlect2 = value & 0x07ff;
1606 omap_clkm_idlect2_update(s, diff, value);
1607 return;
1608
1609 case 0x0c: /* ARM_EWUPCT */
1610 s->clkm.arm_ewupct = value & 0x003f;
1611 return;
1612
1613 case 0x10: /* ARM_RSTCT1 */
1614 diff = s->clkm.arm_rstct1 ^ value;
1615 s->clkm.arm_rstct1 = value & 0x0007;
1616 if (value & 9) {
1617 qemu_system_reset_request();
1618 s->clkm.cold_start = 0xa;
1619 }
1620 if (diff & ~value & 4) { /* DSP_RST */
1621 omap_mpui_reset(s);
1622 omap_tipb_bridge_reset(s->private_tipb);
1623 omap_tipb_bridge_reset(s->public_tipb);
1624 }
1625 if (diff & 2) { /* DSP_EN */
1626 clk = omap_findclk(s, "dsp_ck");
1627 omap_clk_canidle(clk, (~value >> 1) & 1);
1628 }
1629 return;
1630
1631 case 0x14: /* ARM_RSTCT2 */
1632 s->clkm.arm_rstct2 = value & 0x0001;
1633 return;
1634
1635 case 0x18: /* ARM_SYSST */
1636 if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
1637 s->clkm.clocking_scheme = (value >> 11) & 7;
1638 printf("%s: clocking scheme set to %s\n", __FUNCTION__,
1639 clkschemename[s->clkm.clocking_scheme]);
1640 }
1641 s->clkm.cold_start &= value & 0x3f;
1642 return;
1643
1644 case 0x1c: /* ARM_CKOUT1 */
1645 diff = s->clkm.arm_ckout1 ^ value;
1646 s->clkm.arm_ckout1 = value & 0x003f;
1647 omap_clkm_ckout1_update(s, diff, value);
1648 return;
1649
1650 case 0x20: /* ARM_CKOUT2 */
1651 default:
1652 OMAP_BAD_REG(addr);
1653 }
1654 }
1655
1656 static CPUReadMemoryFunc * const omap_clkm_readfn[] = {
1657 omap_badwidth_read16,
1658 omap_clkm_read,
1659 omap_badwidth_read16,
1660 };
1661
1662 static CPUWriteMemoryFunc * const omap_clkm_writefn[] = {
1663 omap_badwidth_write16,
1664 omap_clkm_write,
1665 omap_badwidth_write16,
1666 };
1667
1668 static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
1669 {
1670 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1671
1672 switch (addr) {
1673 case 0x04: /* DSP_IDLECT1 */
1674 return s->clkm.dsp_idlect1;
1675
1676 case 0x08: /* DSP_IDLECT2 */
1677 return s->clkm.dsp_idlect2;
1678
1679 case 0x14: /* DSP_RSTCT2 */
1680 return s->clkm.dsp_rstct2;
1681
1682 case 0x18: /* DSP_SYSST */
1683 return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
1684 (s->env->halted << 6); /* Quite useless... */
1685 }
1686
1687 OMAP_BAD_REG(addr);
1688 return 0;
1689 }
1690
1691 static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
1692 uint16_t diff, uint16_t value)
1693 {
1694 omap_clk clk;
1695
1696 SET_CANIDLE("dspxor_ck", 1); /* IDLXORP_DSP */
1697 }
1698
1699 static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
1700 uint16_t diff, uint16_t value)
1701 {
1702 omap_clk clk;
1703
1704 SET_ONOFF("dspxor_ck", 1); /* EN_XORPCK */
1705 }
1706
1707 static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
1708 uint32_t value)
1709 {
1710 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1711 uint16_t diff;
1712
1713 switch (addr) {
1714 case 0x04: /* DSP_IDLECT1 */
1715 diff = s->clkm.dsp_idlect1 ^ value;
1716 s->clkm.dsp_idlect1 = value & 0x01f7;
1717 omap_clkdsp_idlect1_update(s, diff, value);
1718 break;
1719
1720 case 0x08: /* DSP_IDLECT2 */
1721 s->clkm.dsp_idlect2 = value & 0x0037;
1722 diff = s->clkm.dsp_idlect1 ^ value;
1723 omap_clkdsp_idlect2_update(s, diff, value);
1724 break;
1725
1726 case 0x14: /* DSP_RSTCT2 */
1727 s->clkm.dsp_rstct2 = value & 0x0001;
1728 break;
1729
1730 case 0x18: /* DSP_SYSST */
1731 s->clkm.cold_start &= value & 0x3f;
1732 break;
1733
1734 default:
1735 OMAP_BAD_REG(addr);
1736 }
1737 }
1738
1739 static CPUReadMemoryFunc * const omap_clkdsp_readfn[] = {
1740 omap_badwidth_read16,
1741 omap_clkdsp_read,
1742 omap_badwidth_read16,
1743 };
1744
1745 static CPUWriteMemoryFunc * const omap_clkdsp_writefn[] = {
1746 omap_badwidth_write16,
1747 omap_clkdsp_write,
1748 omap_badwidth_write16,
1749 };
1750
1751 static void omap_clkm_reset(struct omap_mpu_state_s *s)
1752 {
1753 if (s->wdt && s->wdt->reset)
1754 s->clkm.cold_start = 0x6;
1755 s->clkm.clocking_scheme = 0;
1756 omap_clkm_ckctl_update(s, ~0, 0x3000);
1757 s->clkm.arm_ckctl = 0x3000;
1758 omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
1759 s->clkm.arm_idlect1 = 0x0400;
1760 omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
1761 s->clkm.arm_idlect2 = 0x0100;
1762 s->clkm.arm_ewupct = 0x003f;
1763 s->clkm.arm_rstct1 = 0x0000;
1764 s->clkm.arm_rstct2 = 0x0000;
1765 s->clkm.arm_ckout1 = 0x0015;
1766 s->clkm.dpll1_mode = 0x2002;
1767 omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
1768 s->clkm.dsp_idlect1 = 0x0040;
1769 omap_clkdsp_idlect2_update(s, ~0, 0x0000);
1770 s->clkm.dsp_idlect2 = 0x0000;
1771 s->clkm.dsp_rstct2 = 0x0000;
1772 }
1773
1774 static void omap_clkm_init(target_phys_addr_t mpu_base,
1775 target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
1776 {
1777 int iomemtype[2] = {
1778 cpu_register_io_memory(omap_clkm_readfn, omap_clkm_writefn, s),
1779 cpu_register_io_memory(omap_clkdsp_readfn, omap_clkdsp_writefn, s),
1780 };
1781
1782 s->clkm.arm_idlect1 = 0x03ff;
1783 s->clkm.arm_idlect2 = 0x0100;
1784 s->clkm.dsp_idlect1 = 0x0002;
1785 omap_clkm_reset(s);
1786 s->clkm.cold_start = 0x3a;
1787
1788 cpu_register_physical_memory(mpu_base, 0x100, iomemtype[0]);
1789 cpu_register_physical_memory(dsp_base, 0x1000, iomemtype[1]);
1790 }
1791
1792 /* MPU I/O */
1793 struct omap_mpuio_s {
1794 qemu_irq irq;
1795 qemu_irq kbd_irq;
1796 qemu_irq *in;
1797 qemu_irq handler[16];
1798 qemu_irq wakeup;
1799
1800 uint16_t inputs;
1801 uint16_t outputs;
1802 uint16_t dir;
1803 uint16_t edge;
1804 uint16_t mask;
1805 uint16_t ints;
1806
1807 uint16_t debounce;
1808 uint16_t latch;
1809 uint8_t event;
1810
1811 uint8_t buttons[5];
1812 uint8_t row_latch;
1813 uint8_t cols;
1814 int kbd_mask;
1815 int clk;
1816 };
1817
1818 static void omap_mpuio_set(void *opaque, int line, int level)
1819 {
1820 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1821 uint16_t prev = s->inputs;
1822
1823 if (level)
1824 s->inputs |= 1 << line;
1825 else
1826 s->inputs &= ~(1 << line);
1827
1828 if (((1 << line) & s->dir & ~s->mask) && s->clk) {
1829 if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
1830 s->ints |= 1 << line;
1831 qemu_irq_raise(s->irq);
1832 /* TODO: wakeup */
1833 }
1834 if ((s->event & (1 << 0)) && /* SET_GPIO_EVENT_MODE */
1835 (s->event >> 1) == line) /* PIN_SELECT */
1836 s->latch = s->inputs;
1837 }
1838 }
1839
1840 static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
1841 {
1842 int i;
1843 uint8_t *row, rows = 0, cols = ~s->cols;
1844
1845 for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
1846 if (*row & cols)
1847 rows |= i;
1848
1849 qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
1850 s->row_latch = ~rows;
1851 }
1852
1853 static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
1854 {
1855 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1856 int offset = addr & OMAP_MPUI_REG_MASK;
1857 uint16_t ret;
1858
1859 switch (offset) {
1860 case 0x00: /* INPUT_LATCH */
1861 return s->inputs;
1862
1863 case 0x04: /* OUTPUT_REG */
1864 return s->outputs;
1865
1866 case 0x08: /* IO_CNTL */
1867 return s->dir;
1868
1869 case 0x10: /* KBR_LATCH */
1870 return s->row_latch;
1871
1872 case 0x14: /* KBC_REG */
1873 return s->cols;
1874
1875 case 0x18: /* GPIO_EVENT_MODE_REG */
1876 return s->event;
1877
1878 case 0x1c: /* GPIO_INT_EDGE_REG */
1879 return s->edge;
1880
1881 case 0x20: /* KBD_INT */
1882 return (~s->row_latch & 0x1f) && !s->kbd_mask;
1883
1884 case 0x24: /* GPIO_INT */
1885 ret = s->ints;
1886 s->ints &= s->mask;
1887 if (ret)
1888 qemu_irq_lower(s->irq);
1889 return ret;
1890
1891 case 0x28: /* KBD_MASKIT */
1892 return s->kbd_mask;
1893
1894 case 0x2c: /* GPIO_MASKIT */
1895 return s->mask;
1896
1897 case 0x30: /* GPIO_DEBOUNCING_REG */
1898 return s->debounce;
1899
1900 case 0x34: /* GPIO_LATCH_REG */
1901 return s->latch;
1902 }
1903
1904 OMAP_BAD_REG(addr);
1905 return 0;
1906 }
1907
1908 static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
1909 uint32_t value)
1910 {
1911 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1912 int offset = addr & OMAP_MPUI_REG_MASK;
1913 uint16_t diff;
1914 int ln;
1915
1916 switch (offset) {
1917 case 0x04: /* OUTPUT_REG */
1918 diff = (s->outputs ^ value) & ~s->dir;
1919 s->outputs = value;
1920 while ((ln = ffs(diff))) {
1921 ln --;
1922 if (s->handler[ln])
1923 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
1924 diff &= ~(1 << ln);
1925 }
1926 break;
1927
1928 case 0x08: /* IO_CNTL */
1929 diff = s->outputs & (s->dir ^ value);
1930 s->dir = value;
1931
1932 value = s->outputs & ~s->dir;
1933 while ((ln = ffs(diff))) {
1934 ln --;
1935 if (s->handler[ln])
1936 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
1937 diff &= ~(1 << ln);
1938 }
1939 break;
1940
1941 case 0x14: /* KBC_REG */
1942 s->cols = value;
1943 omap_mpuio_kbd_update(s);
1944 break;
1945
1946 case 0x18: /* GPIO_EVENT_MODE_REG */
1947 s->event = value & 0x1f;
1948 break;
1949
1950 case 0x1c: /* GPIO_INT_EDGE_REG */
1951 s->edge = value;
1952 break;
1953
1954 case 0x28: /* KBD_MASKIT */
1955 s->kbd_mask = value & 1;
1956 omap_mpuio_kbd_update(s);
1957 break;
1958
1959 case 0x2c: /* GPIO_MASKIT */
1960 s->mask = value;
1961 break;
1962
1963 case 0x30: /* GPIO_DEBOUNCING_REG */
1964 s->debounce = value & 0x1ff;
1965 break;
1966
1967 case 0x00: /* INPUT_LATCH */
1968 case 0x10: /* KBR_LATCH */
1969 case 0x20: /* KBD_INT */
1970 case 0x24: /* GPIO_INT */
1971 case 0x34: /* GPIO_LATCH_REG */
1972 OMAP_RO_REG(addr);
1973 return;
1974
1975 default:
1976 OMAP_BAD_REG(addr);
1977 return;
1978 }
1979 }
1980
1981 static CPUReadMemoryFunc * const omap_mpuio_readfn[] = {
1982 omap_badwidth_read16,
1983 omap_mpuio_read,
1984 omap_badwidth_read16,
1985 };
1986
1987 static CPUWriteMemoryFunc * const omap_mpuio_writefn[] = {
1988 omap_badwidth_write16,
1989 omap_mpuio_write,
1990 omap_badwidth_write16,
1991 };
1992
1993 static void omap_mpuio_reset(struct omap_mpuio_s *s)
1994 {
1995 s->inputs = 0;
1996 s->outputs = 0;
1997 s->dir = ~0;
1998 s->event = 0;
1999 s->edge = 0;
2000 s->kbd_mask = 0;
2001 s->mask = 0;
2002 s->debounce = 0;
2003 s->latch = 0;
2004 s->ints = 0;
2005 s->row_latch = 0x1f;
2006 s->clk = 1;
2007 }
2008
2009 static void omap_mpuio_onoff(void *opaque, int line, int on)
2010 {
2011 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2012
2013 s->clk = on;
2014 if (on)
2015 omap_mpuio_kbd_update(s);
2016 }
2017
2018 struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
2019 qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2020 omap_clk clk)
2021 {
2022 int iomemtype;
2023 struct omap_mpuio_s *s = (struct omap_mpuio_s *)
2024 qemu_mallocz(sizeof(struct omap_mpuio_s));
2025
2026 s->irq = gpio_int;
2027 s->kbd_irq = kbd_int;
2028 s->wakeup = wakeup;
2029 s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2030 omap_mpuio_reset(s);
2031
2032 iomemtype = cpu_register_io_memory(omap_mpuio_readfn,
2033 omap_mpuio_writefn, s);
2034 cpu_register_physical_memory(base, 0x800, iomemtype);
2035
2036 omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2037
2038 return s;
2039 }
2040
2041 qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2042 {
2043 return s->in;
2044 }
2045
2046 void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
2047 {
2048 if (line >= 16 || line < 0)
2049 hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
2050 s->handler[line] = handler;
2051 }
2052
2053 void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2054 {
2055 if (row >= 5 || row < 0)
2056 hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
2057
2058 if (down)
2059 s->buttons[row] |= 1 << col;
2060 else
2061 s->buttons[row] &= ~(1 << col);
2062
2063 omap_mpuio_kbd_update(s);
2064 }
2065
2066 /* MicroWire Interface */
2067 struct omap_uwire_s {
2068 qemu_irq txirq;
2069 qemu_irq rxirq;
2070 qemu_irq txdrq;
2071
2072 uint16_t txbuf;
2073 uint16_t rxbuf;
2074 uint16_t control;
2075 uint16_t setup[5];
2076
2077 uWireSlave *chip[4];
2078 };
2079
2080 static void omap_uwire_transfer_start(struct omap_uwire_s *s)
2081 {
2082 int chipselect = (s->control >> 10) & 3; /* INDEX */
2083 uWireSlave *slave = s->chip[chipselect];
2084
2085 if ((s->control >> 5) & 0x1f) { /* NB_BITS_WR */
2086 if (s->control & (1 << 12)) /* CS_CMD */
2087 if (slave && slave->send)
2088 slave->send(slave->opaque,
2089 s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
2090 s->control &= ~(1 << 14); /* CSRB */
2091 /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2092 * a DRQ. When is the level IRQ supposed to be reset? */
2093 }
2094
2095 if ((s->control >> 0) & 0x1f) { /* NB_BITS_RD */
2096 if (s->control & (1 << 12)) /* CS_CMD */
2097 if (slave && slave->receive)
2098 s->rxbuf = slave->receive(slave->opaque);
2099 s->control |= 1 << 15; /* RDRB */
2100 /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2101 * a DRQ. When is the level IRQ supposed to be reset? */
2102 }
2103 }
2104
2105 static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
2106 {
2107 struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2108 int offset = addr & OMAP_MPUI_REG_MASK;
2109
2110 switch (offset) {
2111 case 0x00: /* RDR */
2112 s->control &= ~(1 << 15); /* RDRB */
2113 return s->rxbuf;
2114
2115 case 0x04: /* CSR */
2116 return s->control;
2117
2118 case 0x08: /* SR1 */
2119 return s->setup[0];
2120 case 0x0c: /* SR2 */
2121 return s->setup[1];
2122 case 0x10: /* SR3 */
2123 return s->setup[2];
2124 case 0x14: /* SR4 */
2125 return s->setup[3];
2126 case 0x18: /* SR5 */
2127 return s->setup[4];
2128 }
2129
2130 OMAP_BAD_REG(addr);
2131 return 0;
2132 }
2133
2134 static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
2135 uint32_t value)
2136 {
2137 struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2138 int offset = addr & OMAP_MPUI_REG_MASK;
2139
2140 switch (offset) {
2141 case 0x00: /* TDR */
2142 s->txbuf = value; /* TD */
2143 if ((s->setup[4] & (1 << 2)) && /* AUTO_TX_EN */
2144 ((s->setup[4] & (1 << 3)) || /* CS_TOGGLE_TX_EN */
2145 (s->control & (1 << 12)))) { /* CS_CMD */
2146 s->control |= 1 << 14; /* CSRB */
2147 omap_uwire_transfer_start(s);
2148 }
2149 break;
2150
2151 case 0x04: /* CSR */
2152 s->control = value & 0x1fff;
2153 if (value & (1 << 13)) /* START */
2154 omap_uwire_transfer_start(s);
2155 break;
2156
2157 case 0x08: /* SR1 */
2158 s->setup[0] = value & 0x003f;
2159 break;
2160
2161 case 0x0c: /* SR2 */
2162 s->setup[1] = value & 0x0fc0;
2163 break;
2164
2165 case 0x10: /* SR3 */
2166 s->setup[2] = value & 0x0003;
2167 break;
2168
2169 case 0x14: /* SR4 */
2170 s->setup[3] = value & 0x0001;
2171 break;
2172
2173 case 0x18: /* SR5 */
2174 s->setup[4] = value & 0x000f;
2175 break;
2176
2177 default:
2178 OMAP_BAD_REG(addr);
2179 return;
2180 }
2181 }
2182
2183 static CPUReadMemoryFunc * const omap_uwire_readfn[] = {
2184 omap_badwidth_read16,
2185 omap_uwire_read,
2186 omap_badwidth_read16,
2187 };
2188
2189 static CPUWriteMemoryFunc * const omap_uwire_writefn[] = {
2190 omap_badwidth_write16,
2191 omap_uwire_write,
2192 omap_badwidth_write16,
2193 };
2194
2195 static void omap_uwire_reset(struct omap_uwire_s *s)
2196 {
2197 s->control = 0;
2198 s->setup[0] = 0;
2199 s->setup[1] = 0;
2200 s->setup[2] = 0;
2201 s->setup[3] = 0;
2202 s->setup[4] = 0;
2203 }
2204
2205 struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
2206 qemu_irq *irq, qemu_irq dma, omap_clk clk)
2207 {
2208 int iomemtype;
2209 struct omap_uwire_s *s = (struct omap_uwire_s *)
2210 qemu_mallocz(sizeof(struct omap_uwire_s));
2211
2212 s->txirq = irq[0];
2213 s->rxirq = irq[1];
2214 s->txdrq = dma;
2215 omap_uwire_reset(s);
2216
2217 iomemtype = cpu_register_io_memory(omap_uwire_readfn,
2218 omap_uwire_writefn, s);
2219 cpu_register_physical_memory(base, 0x800, iomemtype);
2220
2221 return s;
2222 }
2223
2224 void omap_uwire_attach(struct omap_uwire_s *s,
2225 uWireSlave *slave, int chipselect)
2226 {
2227 if (chipselect < 0 || chipselect > 3) {
2228 fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
2229 exit(-1);
2230 }
2231
2232 s->chip[chipselect] = slave;
2233 }
2234
2235 /* Pseudonoise Pulse-Width Light Modulator */
2236 static void omap_pwl_update(struct omap_mpu_state_s *s)
2237 {
2238 int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
2239
2240 if (output != s->pwl.output) {
2241 s->pwl.output = output;
2242 printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
2243 }
2244 }
2245
2246 static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
2247 {
2248 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2249 int offset = addr & OMAP_MPUI_REG_MASK;
2250
2251 switch (offset) {
2252 case 0x00: /* PWL_LEVEL */
2253 return s->pwl.level;
2254 case 0x04: /* PWL_CTRL */
2255 return s->pwl.enable;
2256 }
2257 OMAP_BAD_REG(addr);
2258 return 0;
2259 }
2260
2261 static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
2262 uint32_t value)
2263 {
2264 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2265 int offset = addr & OMAP_MPUI_REG_MASK;
2266
2267 switch (offset) {
2268 case 0x00: /* PWL_LEVEL */
2269 s->pwl.level = value;
2270 omap_pwl_update(s);
2271 break;
2272 case 0x04: /* PWL_CTRL */
2273 s->pwl.enable = value & 1;
2274 omap_pwl_update(s);
2275 break;
2276 default:
2277 OMAP_BAD_REG(addr);
2278 return;
2279 }
2280 }
2281
2282 static CPUReadMemoryFunc * const omap_pwl_readfn[] = {
2283 omap_pwl_read,
2284 omap_badwidth_read8,
2285 omap_badwidth_read8,
2286 };
2287
2288 static CPUWriteMemoryFunc * const omap_pwl_writefn[] = {
2289 omap_pwl_write,
2290 omap_badwidth_write8,
2291 omap_badwidth_write8,
2292 };
2293
2294 static void omap_pwl_reset(struct omap_mpu_state_s *s)
2295 {
2296 s->pwl.output = 0;
2297 s->pwl.level = 0;
2298 s->pwl.enable = 0;
2299 s->pwl.clk = 1;
2300 omap_pwl_update(s);
2301 }
2302
2303 static void omap_pwl_clk_update(void *opaque, int line, int on)
2304 {
2305 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2306
2307 s->pwl.clk = on;
2308 omap_pwl_update(s);
2309 }
2310
2311 static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
2312 omap_clk clk)
2313 {
2314 int iomemtype;
2315
2316 omap_pwl_reset(s);
2317
2318 iomemtype = cpu_register_io_memory(omap_pwl_readfn,
2319 omap_pwl_writefn, s);
2320 cpu_register_physical_memory(base, 0x800, iomemtype);
2321
2322 omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
2323 }
2324
2325 /* Pulse-Width Tone module */
2326 static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
2327 {
2328 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2329 int offset = addr & OMAP_MPUI_REG_MASK;
2330
2331 switch (offset) {
2332 case 0x00: /* FRC */
2333 return s->pwt.frc;
2334 case 0x04: /* VCR */
2335 return s->pwt.vrc;
2336 case 0x08: /* GCR */
2337 return s->pwt.gcr;
2338 }
2339 OMAP_BAD_REG(addr);
2340 return 0;
2341 }
2342
2343 static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
2344 uint32_t value)
2345 {
2346 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2347 int offset = addr & OMAP_MPUI_REG_MASK;
2348
2349 switch (offset) {
2350 case 0x00: /* FRC */
2351 s->pwt.frc = value & 0x3f;
2352 break;
2353 case 0x04: /* VRC */
2354 if ((value ^ s->pwt.vrc) & 1) {
2355 if (value & 1)
2356 printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
2357 /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
2358 ((omap_clk_getrate(s->pwt.clk) >> 3) /
2359 /* Pre-multiplexer divider */
2360 ((s->pwt.gcr & 2) ? 1 : 154) /
2361 /* Octave multiplexer */
2362 (2 << (value & 3)) *
2363 /* 101/107 divider */
2364 ((value & (1 << 2)) ? 101 : 107) *
2365 /* 49/55 divider */
2366 ((value & (1 << 3)) ? 49 : 55) *
2367 /* 50/63 divider */
2368 ((value & (1 << 4)) ? 50 : 63) *
2369 /* 80/127 divider */
2370 ((value & (1 << 5)) ? 80 : 127) /
2371 (107 * 55 * 63 * 127)));
2372 else
2373 printf("%s: silence!\n", __FUNCTION__);
2374 }
2375 s->pwt.vrc = value & 0x7f;
2376 break;
2377 case 0x08: /* GCR */
2378 s->pwt.gcr = value & 3;
2379 break;
2380 default:
2381 OMAP_BAD_REG(addr);
2382 return;
2383 }
2384 }
2385
2386 static CPUReadMemoryFunc * const omap_pwt_readfn[] = {
2387 omap_pwt_read,
2388 omap_badwidth_read8,
2389 omap_badwidth_read8,
2390 };
2391
2392 static CPUWriteMemoryFunc * const omap_pwt_writefn[] = {
2393 omap_pwt_write,
2394 omap_badwidth_write8,
2395 omap_badwidth_write8,
2396 };
2397
2398 static void omap_pwt_reset(struct omap_mpu_state_s *s)
2399 {
2400 s->pwt.frc = 0;
2401 s->pwt.vrc = 0;
2402 s->pwt.gcr = 0;
2403 }
2404
2405 static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
2406 omap_clk clk)
2407 {
2408 int iomemtype;
2409
2410 s->pwt.clk = clk;
2411 omap_pwt_reset(s);
2412
2413 iomemtype = cpu_register_io_memory(omap_pwt_readfn,
2414 omap_pwt_writefn, s);
2415 cpu_register_physical_memory(base, 0x800, iomemtype);
2416 }
2417
2418 /* Real-time Clock module */
2419 struct omap_rtc_s {
2420 qemu_irq irq;
2421 qemu_irq alarm;
2422 QEMUTimer *clk;
2423
2424 uint8_t interrupts;
2425 uint8_t status;
2426 int16_t comp_reg;
2427 int running;
2428 int pm_am;
2429 int auto_comp;
2430 int round;
2431 struct tm alarm_tm;
2432 time_t alarm_ti;
2433
2434 struct tm current_tm;
2435 time_t ti;
2436 uint64_t tick;
2437 };
2438
2439 static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
2440 {
2441 /* s->alarm is level-triggered */
2442 qemu_set_irq(s->alarm, (s->status >> 6) & 1);
2443 }
2444
2445 static void omap_rtc_alarm_update(struct omap_rtc_s *s)
2446 {
2447 s->alarm_ti = mktimegm(&s->alarm_tm);
2448 if (s->alarm_ti == -1)
2449 printf("%s: conversion failed\n", __FUNCTION__);
2450 }
2451
2452 static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
2453 {
2454 struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2455 int offset = addr & OMAP_MPUI_REG_MASK;
2456 uint8_t i;
2457
2458 switch (offset) {
2459 case 0x00: /* SECONDS_REG */
2460 return to_bcd(s->current_tm.tm_sec);
2461
2462 case 0x04: /* MINUTES_REG */
2463 return to_bcd(s->current_tm.tm_min);
2464
2465 case 0x08: /* HOURS_REG */
2466 if (s->pm_am)
2467 return ((s->current_tm.tm_hour > 11) << 7) |
2468 to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
2469 else
2470 return to_bcd(s->current_tm.tm_hour);
2471
2472 case 0x0c: /* DAYS_REG */
2473 return to_bcd(s->current_tm.tm_mday);
2474
2475 case 0x10: /* MONTHS_REG */
2476 return to_bcd(s->current_tm.tm_mon + 1);
2477
2478 case 0x14: /* YEARS_REG */
2479 return to_bcd(s->current_tm.tm_year % 100);
2480
2481 case 0x18: /* WEEK_REG */
2482 return s->current_tm.tm_wday;
2483
2484 case 0x20: /* ALARM_SECONDS_REG */
2485 return to_bcd(s->alarm_tm.tm_sec);
2486
2487 case 0x24: /* ALARM_MINUTES_REG */
2488 return to_bcd(s->alarm_tm.tm_min);
2489
2490 case 0x28: /* ALARM_HOURS_REG */
2491 if (s->pm_am)
2492 return ((s->alarm_tm.tm_hour > 11) << 7) |
2493 to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
2494 else
2495 return to_bcd(s->alarm_tm.tm_hour);
2496
2497 case 0x2c: /* ALARM_DAYS_REG */
2498 return to_bcd(s->alarm_tm.tm_mday);
2499
2500 case 0x30: /* ALARM_MONTHS_REG */
2501 return to_bcd(s->alarm_tm.tm_mon + 1);
2502
2503 case 0x34: /* ALARM_YEARS_REG */
2504 return to_bcd(s->alarm_tm.tm_year % 100);
2505
2506 case 0x40: /* RTC_CTRL_REG */
2507 return (s->pm_am << 3) | (s->auto_comp << 2) |
2508 (s->round << 1) | s->running;
2509
2510 case 0x44: /* RTC_STATUS_REG */
2511 i = s->status;
2512 s->status &= ~0x3d;
2513 return i;
2514
2515 case 0x48: /* RTC_INTERRUPTS_REG */
2516 return s->interrupts;
2517
2518 case 0x4c: /* RTC_COMP_LSB_REG */
2519 return ((uint16_t) s->comp_reg) & 0xff;
2520
2521 case 0x50: /* RTC_COMP_MSB_REG */
2522 return ((uint16_t) s->comp_reg) >> 8;
2523 }
2524
2525 OMAP_BAD_REG(addr);
2526 return 0;
2527 }
2528
2529 static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
2530 uint32_t value)
2531 {
2532 struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2533 int offset = addr & OMAP_MPUI_REG_MASK;
2534 struct tm new_tm;
2535 time_t ti[2];
2536
2537 switch (offset) {
2538 case 0x00: /* SECONDS_REG */
2539 #ifdef ALMDEBUG
2540 printf("RTC SEC_REG <-- %02x\n", value);
2541 #endif
2542 s->ti -= s->current_tm.tm_sec;
2543 s->ti += from_bcd(value);
2544 return;
2545
2546 case 0x04: /* MINUTES_REG */
2547 #ifdef ALMDEBUG
2548 printf("RTC MIN_REG <-- %02x\n", value);
2549 #endif
2550 s->ti -= s->current_tm.tm_min * 60;
2551 s->ti += from_bcd(value) * 60;
2552 return;
2553
2554 case 0x08: /* HOURS_REG */
2555 #ifdef ALMDEBUG
2556 printf("RTC HRS_REG <-- %02x\n", value);
2557 #endif
2558 s->ti -= s->current_tm.tm_hour * 3600;
2559 if (s->pm_am) {
2560 s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
2561 s->ti += ((value >> 7) & 1) * 43200;
2562 } else
2563 s->ti += from_bcd(value & 0x3f) * 3600;
2564 return;
2565
2566 case 0x0c: /* DAYS_REG */
2567 #ifdef ALMDEBUG
2568 printf("RTC DAY_REG <-- %02x\n", value);
2569 #endif
2570 s->ti -= s->current_tm.tm_mday * 86400;
2571 s->ti += from_bcd(value) * 86400;
2572 return;
2573
2574 case 0x10: /* MONTHS_REG */
2575 #ifdef ALMDEBUG
2576 printf("RTC MTH_REG <-- %02x\n", value);
2577 #endif
2578 memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2579 new_tm.tm_mon = from_bcd(value);
2580 ti[0] = mktimegm(&s->current_tm);
2581 ti[1] = mktimegm(&new_tm);
2582
2583 if (ti[0] != -1 && ti[1] != -1) {
2584 s->ti -= ti[0];
2585 s->ti += ti[1];
2586 } else {
2587 /* A less accurate version */
2588 s->ti -= s->current_tm.tm_mon * 2592000;
2589 s->ti += from_bcd(value) * 2592000;
2590 }
2591 return;
2592
2593 case 0x14: /* YEARS_REG */
2594 #ifdef ALMDEBUG
2595 printf("RTC YRS_REG <-- %02x\n", value);
2596 #endif
2597 memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2598 new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
2599 ti[0] = mktimegm(&s->current_tm);
2600 ti[1] = mktimegm(&new_tm);
2601
2602 if (ti[0] != -1 && ti[1] != -1) {
2603 s->ti -= ti[0];
2604 s->ti += ti[1];
2605 } else {
2606 /* A less accurate version */
2607 s->ti -= (s->current_tm.tm_year % 100) * 31536000;
2608 s->ti += from_bcd(value) * 31536000;
2609 }
2610 return;
2611
2612 case 0x18: /* WEEK_REG */
2613 return; /* Ignored */
2614
2615 case 0x20: /* ALARM_SECONDS_REG */
2616 #ifdef ALMDEBUG
2617 printf("ALM SEC_REG <-- %02x\n", value);
2618 #endif
2619 s->alarm_tm.tm_sec = from_bcd(value);
2620 omap_rtc_alarm_update(s);
2621 return;
2622
2623 case 0x24: /* ALARM_MINUTES_REG */
2624 #ifdef ALMDEBUG
2625 printf("ALM MIN_REG <-- %02x\n", value);
2626 #endif
2627 s->alarm_tm.tm_min = from_bcd(value);
2628 omap_rtc_alarm_update(s);
2629 return;
2630
2631 case 0x28: /* ALARM_HOURS_REG */
2632 #ifdef ALMDEBUG
2633 printf("ALM HRS_REG <-- %02x\n", value);
2634 #endif
2635 if (s->pm_am)
2636 s->alarm_tm.tm_hour =
2637 ((from_bcd(value & 0x3f)) % 12) +
2638 ((value >> 7) & 1) * 12;
2639 else
2640 s->alarm_tm.tm_hour = from_bcd(value);
2641 omap_rtc_alarm_update(s);
2642 return;
2643
2644 case 0x2c: /* ALARM_DAYS_REG */
2645 #ifdef ALMDEBUG
2646 printf("ALM DAY_REG <-- %02x\n", value);
2647 #endif
2648 s->alarm_tm.tm_mday = from_bcd(value);
2649 omap_rtc_alarm_update(s);
2650 return;
2651
2652 case 0x30: /* ALARM_MONTHS_REG */
2653 #ifdef ALMDEBUG
2654 printf("ALM MON_REG <-- %02x\n", value);
2655 #endif
2656 s->alarm_tm.tm_mon = from_bcd(value);
2657 omap_rtc_alarm_update(s);
2658 return;
2659
2660 case 0x34: /* ALARM_YEARS_REG */
2661 #ifdef ALMDEBUG
2662 printf("ALM YRS_REG <-- %02x\n", value);
2663 #endif
2664 s->alarm_tm.tm_year = from_bcd(value);
2665 omap_rtc_alarm_update(s);
2666 return;
2667
2668 case 0x40: /* RTC_CTRL_REG */
2669 #ifdef ALMDEBUG
2670 printf("RTC CONTROL <-- %02x\n", value);
2671 #endif
2672 s->pm_am = (value >> 3) & 1;
2673 s->auto_comp = (value >> 2) & 1;
2674 s->round = (value >> 1) & 1;
2675 s->running = value & 1;
2676 s->status &= 0xfd;
2677 s->status |= s->running << 1;
2678 return;
2679
2680 case 0x44: /* RTC_STATUS_REG */
2681 #ifdef ALMDEBUG
2682 printf("RTC STATUSL <-- %02x\n", value);
2683 #endif
2684 s->status &= ~((value & 0xc0) ^ 0x80);
2685 omap_rtc_interrupts_update(s);
2686 return;
2687
2688 case 0x48: /* RTC_INTERRUPTS_REG */
2689 #ifdef ALMDEBUG
2690 printf("RTC INTRS <-- %02x\n", value);
2691 #endif
2692 s->interrupts = value;
2693 return;
2694
2695 case 0x4c: /* RTC_COMP_LSB_REG */
2696 #ifdef ALMDEBUG
2697 printf("RTC COMPLSB <-- %02x\n", value);
2698 #endif
2699 s->comp_reg &= 0xff00;
2700 s->comp_reg |= 0x00ff & value;
2701 return;
2702
2703 case 0x50: /* RTC_COMP_MSB_REG */
2704 #ifdef ALMDEBUG
2705 printf("RTC COMPMSB <-- %02x\n", value);
2706 #endif
2707 s->comp_reg &= 0x00ff;
2708 s->comp_reg |= 0xff00 & (value << 8);
2709 return;
2710
2711 default:
2712 OMAP_BAD_REG(addr);
2713 return;
2714 }
2715 }
2716
2717 static CPUReadMemoryFunc * const omap_rtc_readfn[] = {
2718 omap_rtc_read,
2719 omap_badwidth_read8,
2720 omap_badwidth_read8,
2721 };
2722
2723 static CPUWriteMemoryFunc * const omap_rtc_writefn[] = {
2724 omap_rtc_write,
2725 omap_badwidth_write8,
2726 omap_badwidth_write8,
2727 };
2728
2729 static void omap_rtc_tick(void *opaque)
2730 {
2731 struct omap_rtc_s *s = opaque;
2732
2733 if (s->round) {
2734 /* Round to nearest full minute. */
2735 if (s->current_tm.tm_sec < 30)
2736 s->ti -= s->current_tm.tm_sec;
2737 else
2738 s->ti += 60 - s->current_tm.tm_sec;
2739
2740 s->round = 0;
2741 }
2742
2743 memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
2744
2745 if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
2746 s->status |= 0x40;
2747 omap_rtc_interrupts_update(s);
2748 }
2749
2750 if (s->interrupts & 0x04)
2751 switch (s->interrupts & 3) {
2752 case 0:
2753 s->status |= 0x04;
2754 qemu_irq_pulse(s->irq);
2755 break;
2756 case 1:
2757 if (s->current_tm.tm_sec)
2758 break;
2759 s->status |= 0x08;
2760 qemu_irq_pulse(s->irq);
2761 break;
2762 case 2:
2763 if (s->current_tm.tm_sec || s->current_tm.tm_min)
2764 break;
2765 s->status |= 0x10;
2766 qemu_irq_pulse(s->irq);
2767 break;
2768 case 3:
2769 if (s->current_tm.tm_sec ||
2770 s->current_tm.tm_min || s->current_tm.tm_hour)
2771 break;
2772 s->status |= 0x20;
2773 qemu_irq_pulse(s->irq);
2774 break;
2775 }
2776
2777 /* Move on */
2778 if (s->running)
2779 s->ti ++;
2780 s->tick += 1000;
2781
2782 /*
2783 * Every full hour add a rough approximation of the compensation
2784 * register to the 32kHz Timer (which drives the RTC) value.
2785 */
2786 if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
2787 s->tick += s->comp_reg * 1000 / 32768;
2788
2789 qemu_mod_timer(s->clk, s->tick);
2790 }
2791
2792 static void omap_rtc_reset(struct omap_rtc_s *s)
2793 {
2794 struct tm tm;
2795
2796 s->interrupts = 0;
2797 s->comp_reg = 0;
2798 s->running = 0;
2799 s->pm_am = 0;
2800 s->auto_comp = 0;
2801 s->round = 0;
2802 s->tick = qemu_get_clock(rt_clock);
2803 memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
2804 s->alarm_tm.tm_mday = 0x01;
2805 s->status = 1 << 7;
2806 qemu_get_timedate(&tm, 0);
2807 s->ti = mktimegm(&tm);
2808
2809 omap_rtc_alarm_update(s);
2810 omap_rtc_tick(s);
2811 }
2812
2813 static struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
2814 qemu_irq *irq, omap_clk clk)
2815 {
2816 int iomemtype;
2817 struct omap_rtc_s *s = (struct omap_rtc_s *)
2818 qemu_mallocz(sizeof(struct omap_rtc_s));
2819
2820 s->irq = irq[0];
2821 s->alarm = irq[1];
2822 s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
2823
2824 omap_rtc_reset(s);
2825
2826 iomemtype = cpu_register_io_memory(omap_rtc_readfn,
2827 omap_rtc_writefn, s);
2828 cpu_register_physical_memory(base, 0x800, iomemtype);
2829
2830 return s;
2831 }
2832
2833 /* Multi-channel Buffered Serial Port interfaces */
2834 struct omap_mcbsp_s {
2835 qemu_irq txirq;
2836 qemu_irq rxirq;
2837 qemu_irq txdrq;
2838 qemu_irq rxdrq;
2839
2840 uint16_t spcr[2];
2841 uint16_t rcr[2];
2842 uint16_t xcr[2];
2843 uint16_t srgr[2];
2844 uint16_t mcr[2];
2845 uint16_t pcr;
2846 uint16_t rcer[8];
2847 uint16_t xcer[8];
2848 int tx_rate;
2849 int rx_rate;
2850 int tx_req;
2851 int rx_req;
2852
2853 I2SCodec *codec;
2854 QEMUTimer *source_timer;
2855 QEMUTimer *sink_timer;
2856 };
2857
2858 static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2859 {
2860 int irq;
2861
2862 switch ((s->spcr[0] >> 4) & 3) { /* RINTM */
2863 case 0:
2864 irq = (s->spcr[0] >> 1) & 1; /* RRDY */
2865 break;
2866 case 3:
2867 irq = (s->spcr[0] >> 3) & 1; /* RSYNCERR */
2868 break;
2869 default:
2870 irq = 0;
2871 break;
2872 }
2873
2874 if (irq)
2875 qemu_irq_pulse(s->rxirq);
2876
2877 switch ((s->spcr[1] >> 4) & 3) { /* XINTM */
2878 case 0:
2879 irq = (s->spcr[1] >> 1) & 1; /* XRDY */
2880 break;
2881 case 3:
2882 irq = (s->spcr[1] >> 3) & 1; /* XSYNCERR */
2883 break;
2884 default:
2885 irq = 0;
2886 break;
2887 }
2888
2889 if (irq)
2890 qemu_irq_pulse(s->txirq);
2891 }
2892
2893 static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
2894 {
2895 if ((s->spcr[0] >> 1) & 1) /* RRDY */
2896 s->spcr[0] |= 1 << 2; /* RFULL */
2897 s->spcr[0] |= 1 << 1; /* RRDY */
2898 qemu_irq_raise(s->rxdrq);
2899 omap_mcbsp_intr_update(s);
2900 }
2901
2902 static void omap_mcbsp_source_tick(void *opaque)
2903 {
2904 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
2905 static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
2906
2907 if (!s->rx_rate)
2908 return;
2909 if (s->rx_req)
2910 printf("%s: Rx FIFO overrun\n", __FUNCTION__);
2911
2912 s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
2913
2914 omap_mcbsp_rx_newdata(s);
2915 qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) +
2916 get_ticks_per_sec());
2917 }
2918
2919 static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
2920 {
2921 if (!s->codec || !s->codec->rts)
2922 omap_mcbsp_source_tick(s);
2923 else if (s->codec->in.len) {
2924 s->rx_req = s->codec->in.len;
2925 omap_mcbsp_rx_newdata(s);
2926 }
2927 }
2928
2929 static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
2930 {
2931 qemu_del_timer(s->source_timer);
2932 }
2933
2934 static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
2935 {
2936 s->spcr[0] &= ~(1 << 1); /* RRDY */
2937 qemu_irq_lower(s->rxdrq);
2938 omap_mcbsp_intr_update(s);
2939 }
2940
2941 static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
2942 {
2943 s->spcr[1] |= 1 << 1; /* XRDY */
2944 qemu_irq_raise(s->txdrq);
2945 omap_mcbsp_intr_update(s);
2946 }
2947
2948 static void omap_mcbsp_sink_tick(void *opaque)
2949 {
2950 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
2951 static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
2952
2953 if (!s->tx_rate)
2954 return;
2955 if (s->tx_req)
2956 printf("%s: Tx FIFO underrun\n", __FUNCTION__);
2957
2958 s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
2959
2960 omap_mcbsp_tx_newdata(s);
2961 qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) +
2962 get_ticks_per_sec());
2963 }
2964
2965 static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
2966 {
2967 if (!s->codec || !s->codec->cts)
2968 omap_mcbsp_sink_tick(s);
2969 else if (s->codec->out.size) {
2970 s->tx_req = s->codec->out.size;
2971 omap_mcbsp_tx_newdata(s);
2972 }
2973 }
2974
2975 static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
2976 {
2977 s->spcr[1] &= ~(1 << 1); /* XRDY */
2978 qemu_irq_lower(s->txdrq);
2979 omap_mcbsp_intr_update(s);
2980 if (s->codec && s->codec->cts)
2981 s->codec->tx_swallow(s->codec->opaque);
2982 }
2983
2984 static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
2985 {
2986 s->tx_req = 0;
2987 omap_mcbsp_tx_done(s);
2988 qemu_del_timer(s->sink_timer);
2989 }
2990
2991 static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
2992 {
2993 int prev_rx_rate, prev_tx_rate;
2994 int rx_rate = 0, tx_rate = 0;
2995 int cpu_rate = 1500000; /* XXX */
2996
2997 /* TODO: check CLKSTP bit */
2998 if (s->spcr[1] & (1 << 6)) { /* GRST */
2999 if (s->spcr[0] & (1 << 0)) { /* RRST */
3000 if ((s->srgr[1] & (1 << 13)) && /* CLKSM */
3001 (s->pcr & (1 << 8))) { /* CLKRM */
3002 if (~s->pcr & (1 << 7)) /* SCLKME */
3003 rx_rate = cpu_rate /
3004 ((s->srgr[0] & 0xff) + 1); /* CLKGDV */
3005 } else
3006 if (s->codec)
3007 rx_rate = s->codec->rx_rate;
3008 }
3009
3010 if (s->spcr[1] & (1 << 0)) { /* XRST */
3011 if ((s->srgr[1] & (1 << 13)) && /* CLKSM */
3012 (s->pcr & (1 << 9))) { /* CLKXM */
3013 if (~s->pcr & (1 << 7)) /* SCLKME */
3014 tx_rate = cpu_rate /
3015 ((s->srgr[0] & 0xff) + 1); /* CLKGDV */
3016 } else
3017 if (s->codec)
3018 tx_rate = s->codec->tx_rate;
3019 }
3020 }
3021 prev_tx_rate = s->tx_rate;
3022 prev_rx_rate = s->rx_rate;
3023 s->tx_rate = tx_rate;
3024 s->rx_rate = rx_rate;
3025
3026 if (s->codec)
3027 s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3028
3029 if (!prev_tx_rate && tx_rate)
3030 omap_mcbsp_tx_start(s);
3031 else if (s->tx_rate && !tx_rate)
3032 omap_mcbsp_tx_stop(s);
3033
3034 if (!prev_rx_rate && rx_rate)
3035 omap_mcbsp_rx_start(s);
3036 else if (prev_tx_rate && !tx_rate)
3037 omap_mcbsp_rx_stop(s);
3038 }
3039
3040 static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
3041 {
3042 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3043 int offset = addr & OMAP_MPUI_REG_MASK;
3044 uint16_t ret;
3045
3046 switch (offset) {
3047 case 0x00: /* DRR2 */
3048 if (((s->rcr[0] >> 5) & 7) < 3) /* RWDLEN1 */
3049 return 0x0000;
3050 /* Fall through. */
3051 case 0x02: /* DRR1 */
3052 if (s->rx_req < 2) {
3053 printf("%s: Rx FIFO underrun\n", __FUNCTION__);
3054 omap_mcbsp_rx_done(s);
3055 } else {
3056 s->tx_req -= 2;
3057 if (s->codec && s->codec->in.len >= 2) {
3058 ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
3059 ret |= s->codec->in.fifo[s->codec->in.start ++];
3060 s->codec->in.len -= 2;
3061 } else
3062 ret = 0x0000;
3063 if (!s->tx_req)
3064 omap_mcbsp_rx_done(s);
3065 return ret;
3066 }
3067 return 0x0000;
3068
3069 case 0x04: /* DXR2 */
3070 case 0x06: /* DXR1 */
3071 return 0x0000;
3072
3073 case 0x08: /* SPCR2 */
3074 return s->spcr[1];
3075 case 0x0a: /* SPCR1 */
3076 return s->spcr[0];
3077 case 0x0c: /* RCR2 */
3078 return s->rcr[1];
3079 case 0x0e: /* RCR1 */
3080 return s->rcr[0];
3081 case 0x10: /* XCR2 */
3082 return s->xcr[1];
3083 case 0x12: /* XCR1 */
3084 return s->xcr[0];
3085 case 0x14: /* SRGR2 */
3086 return s->srgr[1];
3087 case 0x16: /* SRGR1 */
3088 return s->srgr[0];
3089 case 0x18: /* MCR2 */
3090 return s->mcr[1];
3091 case 0x1a: /* MCR1 */
3092 return s->mcr[0];
3093 case 0x1c: /* RCERA */
3094 return s->rcer[0];
3095 case 0x1e: /* RCERB */
3096 return s->rcer[1];
3097 case 0x20: /* XCERA */
3098 return s->xcer[0];
3099 case 0x22: /* XCERB */
3100 return s->xcer[1];
3101 case 0x24: /* PCR0 */
3102 return s->pcr;
3103 case 0x26: /* RCERC */
3104 return s->rcer[2];
3105 case 0x28: /* RCERD */
3106 return s->rcer[3];
3107 case 0x2a: /* XCERC */
3108 return s->xcer[2];
3109 case 0x2c: /* XCERD */
3110 return s->xcer[3];
3111 case 0x2e: /* RCERE */
3112 return s->rcer[4];
3113 case 0x30: /* RCERF */
3114 return s->rcer[5];
3115 case 0x32: /* XCERE */
3116 return s->xcer[4];
3117 case 0x34: /* XCERF */
3118 return s->xcer[5];
3119 case 0x36: /* RCERG */
3120 return s->rcer[6];
3121 case 0x38: /* RCERH */
3122 return s->rcer[7];
3123 case 0x3a: /* XCERG */
3124 return s->xcer[6];
3125 case 0x3c: /* XCERH */
3126 return s->xcer[7];
3127 }
3128
3129 OMAP_BAD_REG(addr);
3130 return 0;
3131 }
3132
3133 static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
3134 uint32_t value)
3135 {
3136 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3137 int offset = addr & OMAP_MPUI_REG_MASK;
3138
3139 switch (offset) {
3140 case 0x00: /* DRR2 */
3141 case 0x02: /* DRR1 */
3142 OMAP_RO_REG(addr);
3143 return;
3144
3145 case 0x04: /* DXR2 */
3146 if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */
3147 return;
3148 /* Fall through. */
3149 case 0x06: /* DXR1 */
3150 if (s->tx_req > 1) {
3151 s->tx_req -= 2;
3152 if (s->codec && s->codec->cts) {
3153 s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
3154 s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
3155 }
3156 if (s->tx_req < 2)
3157 omap_mcbsp_tx_done(s);
3158 } else
3159 printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3160 return;
3161
3162 case 0x08: /* SPCR2 */
3163 s->spcr[1] &= 0x0002;
3164 s->spcr[1] |= 0x03f9 & value;
3165 s->spcr[1] |= 0x0004 & (value << 2); /* XEMPTY := XRST */
3166 if (~value & 1) /* XRST */
3167 s->spcr[1] &= ~6;
3168 omap_mcbsp_req_update(s);
3169 return;
3170 case 0x0a: /* SPCR1 */
3171 s->spcr[0] &= 0x0006;
3172 s->spcr[0] |= 0xf8f9 & value;
3173 if (value & (1 << 15)) /* DLB */
3174 printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
3175 if (~value & 1) { /* RRST */
3176 s->spcr[0] &= ~6;
3177 s->rx_req = 0;
3178 omap_mcbsp_rx_done(s);
3179 }
3180 omap_mcbsp_req_update(s);
3181 return;
3182
3183 case 0x0c: /* RCR2 */
3184 s->rcr[1] = value & 0xffff;
3185 return;
3186 case 0x0e: /* RCR1 */
3187 s->rcr[0] = value & 0x7fe0;
3188 return;
3189 case 0x10: /* XCR2 */
3190 s->xcr[1] = value & 0xffff;
3191 return;
3192 case 0x12: /* XCR1 */
3193 s->xcr[0] = value & 0x7fe0;
3194 return;
3195 case 0x14: /* SRGR2 */
3196 s->srgr[1] = value & 0xffff;
3197 omap_mcbsp_req_update(s);
3198 return;
3199 case 0x16: /* SRGR1 */
3200 s->srgr[0] = value & 0xffff;
3201 omap_mcbsp_req_update(s);
3202 return;
3203 case 0x18: /* MCR2 */
3204 s->mcr[1] = value & 0x03e3;
3205 if (value & 3) /* XMCM */
3206 printf("%s: Tx channel selection mode enable attempt\n",
3207 __FUNCTION__);
3208 return;
3209 case 0x1a: /* MCR1 */
3210 s->mcr[0] = value & 0x03e1;
3211 if (value & 1) /* RMCM */
3212 printf("%s: Rx channel selection mode enable attempt\n",
3213 __FUNCTION__);
3214 return;
3215 case 0x1c: /* RCERA */
3216 s->rcer[0] = value & 0xffff;
3217 return;
3218 case 0x1e: /* RCERB */
3219 s->rcer[1] = value & 0xffff;
3220 return;
3221 case 0x20: /* XCERA */
3222 s->xcer[0] = value & 0xffff;
3223 return;
3224 case 0x22: /* XCERB */
3225 s->xcer[1] = value & 0xffff;
3226 return;
3227 case 0x24: /* PCR0 */
3228 s->pcr = value & 0x7faf;
3229 return;
3230 case 0x26: /* RCERC */
3231 s->rcer[2] = value & 0xffff;
3232 return;
3233 case 0x28: /* RCERD */
3234 s->rcer[3] = value & 0xffff;
3235 return;
3236 case 0x2a: /* XCERC */
3237 s->xcer[2] = value & 0xffff;
3238 return;
3239 case 0x2c: /* XCERD */
3240 s->xcer[3] = value & 0xffff;
3241 return;
3242 case 0x2e: /* RCERE */
3243 s->rcer[4] = value & 0xffff;
3244 return;
3245 case 0x30: /* RCERF */
3246 s->rcer[5] = value & 0xffff;
3247 return;
3248 case 0x32: /* XCERE */
3249 s->xcer[4] = value & 0xffff;
3250 return;
3251 case 0x34: /* XCERF */
3252 s->xcer[5] = value & 0xffff;
3253 return;
3254 case 0x36: /* RCERG */
3255 s->rcer[6] = value & 0xffff;
3256 return;
3257 case 0x38: /* RCERH */
3258 s->rcer[7] = value & 0xffff;
3259 return;
3260 case 0x3a: /* XCERG */
3261 s->xcer[6] = value & 0xffff;
3262 return;
3263 case 0x3c: /* XCERH */
3264 s->xcer[7] = value & 0xffff;
3265 return;
3266 }
3267
3268 OMAP_BAD_REG(addr);
3269 }
3270
3271 static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
3272 uint32_t value)
3273 {
3274 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3275 int offset = addr & OMAP_MPUI_REG_MASK;
3276
3277 if (offset == 0x04) { /* DXR */
3278 if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */
3279 return;
3280 if (s->tx_req > 3) {
3281 s->tx_req -= 4;
3282 if (s->codec && s->codec->cts) {
3283 s->codec->out.fifo[s->codec->out.len ++] =
3284 (value >> 24) & 0xff;
3285 s->codec->out.fifo[s->codec->out.len ++] =
3286 (value >> 16) & 0xff;
3287 s->codec->out.fifo[s->codec->out.len ++] =
3288 (value >> 8) & 0xff;
3289 s->codec->out.fifo[s->codec->out.len ++] =
3290 (value >> 0) & 0xff;
3291 }
3292 if (s->tx_req < 4)
3293 omap_mcbsp_tx_done(s);
3294 } else
3295 printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3296 return;
3297 }
3298
3299 omap_badwidth_write16(opaque, addr, value);
3300 }
3301
3302 static CPUReadMemoryFunc * const omap_mcbsp_readfn[] = {
3303 omap_badwidth_read16,
3304 omap_mcbsp_read,
3305 omap_badwidth_read16,
3306 };
3307
3308 static CPUWriteMemoryFunc * const omap_mcbsp_writefn[] = {
3309 omap_badwidth_write16,
3310 omap_mcbsp_writeh,
3311 omap_mcbsp_writew,
3312 };
3313
3314 static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
3315 {
3316 memset(&s->spcr, 0, sizeof(s->spcr));
3317 memset(&s->rcr, 0, sizeof(s->rcr));
3318 memset(&s->xcr, 0, sizeof(s->xcr));
3319 s->srgr[0] = 0x0001;
3320 s->srgr[1] = 0x2000;
3321 memset(&s->mcr, 0, sizeof(s->mcr));
3322 memset(&s->pcr, 0, sizeof(s->pcr));
3323 memset(&s->rcer, 0, sizeof(s->rcer));
3324 memset(&s->xcer, 0, sizeof(s->xcer));
3325 s->tx_req = 0;
3326 s->rx_req = 0;
3327 s->tx_rate = 0;
3328 s->rx_rate = 0;
3329 qemu_del_timer(s->source_timer);
3330 qemu_del_timer(s->sink_timer);
3331 }
3332
3333 struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
3334 qemu_irq *irq, qemu_irq *dma, omap_clk clk)
3335 {
3336 int iomemtype;
3337 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
3338 qemu_mallocz(sizeof(struct omap_mcbsp_s));
3339
3340 s->txirq = irq[0];
3341 s->rxirq = irq[1];
3342 s->txdrq = dma[0];
3343 s->rxdrq = dma[1];
3344 s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
3345 s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
3346 omap_mcbsp_reset(s);
3347
3348 iomemtype = cpu_register_io_memory(omap_mcbsp_readfn,
3349 omap_mcbsp_writefn, s);
3350 cpu_register_physical_memory(base, 0x800, iomemtype);
3351
3352 return s;
3353 }
3354
3355 static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
3356 {
3357 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3358
3359 if (s->rx_rate) {
3360 s->rx_req = s->codec->in.len;
3361 omap_mcbsp_rx_newdata(s);
3362 }
3363 }
3364
3365 static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
3366 {
3367 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3368
3369 if (s->tx_rate) {
3370 s->tx_req = s->codec->out.size;
3371 omap_mcbsp_tx_newdata(s);
3372 }
3373 }
3374
3375 void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
3376 {
3377 s->codec = slave;
3378 slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
3379 slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
3380 }
3381
3382 /* LED Pulse Generators */
3383 struct omap_lpg_s {
3384 QEMUTimer *tm;
3385
3386 uint8_t control;
3387 uint8_t power;
3388 int64_t on;
3389 int64_t period;
3390 int clk;
3391 int cycle;
3392 };
3393
3394 static void omap_lpg_tick(void *opaque)
3395 {
3396 struct omap_lpg_s *s = opaque;
3397
3398 if (s->cycle)
3399 qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
3400 else
3401 qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
3402
3403 s->cycle = !s->cycle;
3404 printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
3405 }
3406
3407 static void omap_lpg_update(struct omap_lpg_s *s)
3408 {
3409 int64_t on, period = 1, ticks = 1000;
3410 static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
3411
3412 if (~s->control & (1 << 6)) /* LPGRES */
3413 on = 0;
3414 else if (s->control & (1 << 7)) /* PERM_ON */
3415 on = period;
3416 else {
3417 period = muldiv64(ticks, per[s->control & 7], /* PERCTRL */
3418 256 / 32);
3419 on = (s->clk && s->power) ? muldiv64(ticks,
3420 per[(s->control >> 3) & 7], 256) : 0; /* ONCTRL */
3421 }
3422
3423 qemu_del_timer(s->tm);
3424 if (on == period && s->on < s->period)
3425 printf("%s: LED is on\n", __FUNCTION__);
3426 else if (on == 0 && s->on)
3427 printf("%s: LED is off\n", __FUNCTION__);
3428 else if (on && (on != s->on || period != s->period)) {
3429 s->cycle = 0;
3430 s->on = on;
3431 s->period = period;
3432 omap_lpg_tick(s);
3433 return;
3434 }
3435
3436 s->on = on;
3437 s->period = period;
3438 }
3439
3440 static void omap_lpg_reset(struct omap_lpg_s *s)
3441 {
3442 s->control = 0x00;
3443 s->power = 0x00;
3444 s->clk = 1;
3445 omap_lpg_update(s);
3446 }
3447
3448 static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
3449 {
3450 struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3451 int offset = addr & OMAP_MPUI_REG_MASK;
3452
3453 switch (offset) {
3454 case 0x00: /* LCR */
3455 return s->control;
3456
3457 case 0x04: /* PMR */
3458 return s->power;
3459 }
3460
3461 OMAP_BAD_REG(addr);
3462 return 0;
3463 }
3464
3465 static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
3466 uint32_t value)
3467 {
3468 struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3469 int offset = addr & OMAP_MPUI_REG_MASK;
3470
3471 switch (offset) {
3472 case 0x00: /* LCR */
3473 if (~value & (1 << 6)) /* LPGRES */
3474 omap_lpg_reset(s);
3475 s->control = value & 0xff;
3476 omap_lpg_update(s);
3477 return;
3478
3479 case 0x04: /* PMR */
3480 s->power = value & 0x01;
3481 omap_lpg_update(s);
3482 return;
3483
3484 default:
3485 OMAP_BAD_REG(addr);
3486 return;
3487 }
3488 }
3489
3490 static CPUReadMemoryFunc * const omap_lpg_readfn[] = {
3491 omap_lpg_read,
3492 omap_badwidth_read8,
3493 omap_badwidth_read8,
3494 };
3495
3496 static CPUWriteMemoryFunc * const omap_lpg_writefn[] = {
3497 omap_lpg_write,
3498 omap_badwidth_write8,
3499 omap_badwidth_write8,
3500 };
3501
3502 static void omap_lpg_clk_update(void *opaque, int line, int on)
3503 {
3504 struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3505
3506 s->clk = on;
3507 omap_lpg_update(s);
3508 }
3509
3510 static struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
3511 {
3512 int iomemtype;
3513 struct omap_lpg_s *s = (struct omap_lpg_s *)
3514 qemu_mallocz(sizeof(struct omap_lpg_s));
3515
3516 s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
3517
3518 omap_lpg_reset(s);
3519
3520 iomemtype = cpu_register_io_memory(omap_lpg_readfn,
3521 omap_lpg_writefn, s);
3522 cpu_register_physical_memory(base, 0x800, iomemtype);
3523
3524 omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
3525
3526 return s;
3527 }
3528
3529 /* MPUI Peripheral Bridge configuration */
3530 static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
3531 {
3532 if (addr == OMAP_MPUI_BASE) /* CMR */
3533 return 0xfe4d;
3534
3535 OMAP_BAD_REG(addr);
3536 return 0;
3537 }
3538
3539 static CPUReadMemoryFunc * const omap_mpui_io_readfn[] = {
3540 omap_badwidth_read16,
3541 omap_mpui_io_read,
3542 omap_badwidth_read16,
3543 };
3544
3545 static CPUWriteMemoryFunc * const omap_mpui_io_writefn[] = {
3546 omap_badwidth_write16,
3547 omap_badwidth_write16,
3548 omap_badwidth_write16,
3549 };
3550
3551 static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
3552 {
3553 int iomemtype = cpu_register_io_memory(omap_mpui_io_readfn,
3554 omap_mpui_io_writefn, mpu);
3555 cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
3556 }
3557
3558 /* General chip reset */
3559 static void omap1_mpu_reset(void *opaque)
3560 {
3561 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3562
3563 omap_inth_reset(mpu->ih[0]);
3564 omap_inth_reset(mpu->ih[1]);
3565 omap_dma_reset(mpu->dma);
3566 omap_mpu_timer_reset(mpu->timer[0]);
3567 omap_mpu_timer_reset(mpu->timer[1]);
3568 omap_mpu_timer_reset(mpu->timer[2]);
3569 omap_wd_timer_reset(mpu->wdt);
3570 omap_os_timer_reset(mpu->os_timer);
3571 omap_lcdc_reset(mpu->lcd);
3572 omap_ulpd_pm_reset(mpu);
3573 omap_pin_cfg_reset(mpu);
3574 omap_mpui_reset(mpu);
3575 omap_tipb_bridge_reset(mpu->private_tipb);
3576 omap_tipb_bridge_reset(mpu->public_tipb);
3577 omap_dpll_reset(&mpu->dpll[0]);
3578 omap_dpll_reset(&mpu->dpll[1]);
3579 omap_dpll_reset(&mpu->dpll[2]);
3580 omap_uart_reset(mpu->uart[0]);
3581 omap_uart_reset(mpu->uart[1]);
3582 omap_uart_reset(mpu->uart[2]);
3583 omap_mmc_reset(mpu->mmc);
3584 omap_mpuio_reset(mpu->mpuio);
3585 omap_gpio_reset(mpu->gpio);
3586 omap_uwire_reset(mpu->microwire);
3587 omap_pwl_reset(mpu);
3588 omap_pwt_reset(mpu);
3589 omap_i2c_reset(mpu->i2c[0]);
3590 omap_rtc_reset(mpu->rtc);
3591 omap_mcbsp_reset(mpu->mcbsp1);
3592 omap_mcbsp_reset(mpu->mcbsp2);
3593 omap_mcbsp_reset(mpu->mcbsp3);
3594 omap_lpg_reset(mpu->led[0]);
3595 omap_lpg_reset(mpu->led[1]);
3596 omap_clkm_reset(mpu);
3597 cpu_reset(mpu->env);
3598 }
3599
3600 static const struct omap_map_s {
3601 target_phys_addr_t phys_dsp;
3602 target_phys_addr_t phys_mpu;
3603 uint32_t size;
3604 const char *name;
3605 } omap15xx_dsp_mm[] = {
3606 /* Strobe 0 */
3607 { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" }, /* CS0 */
3608 { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" }, /* CS1 */
3609 { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" }, /* CS3 */
3610 { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" }, /* CS4 */
3611 { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" }, /* CS5 */
3612 { 0xe1013000, 0xfffb3000, 0x800, "uWire" }, /* CS6 */
3613 { 0xe1013800, 0xfffb3800, 0x800, "I^2C" }, /* CS7 */
3614 { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" }, /* CS8 */
3615 { 0xe1014800, 0xfffb4800, 0x800, "RTC" }, /* CS9 */
3616 { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" }, /* CS10 */
3617 { 0xe1015800, 0xfffb5800, 0x800, "PWL" }, /* CS11 */
3618 { 0xe1016000, 0xfffb6000, 0x800, "PWT" }, /* CS12 */
3619 { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" }, /* CS14 */
3620 { 0xe1017800, 0xfffb7800, 0x800, "MMC" }, /* CS15 */
3621 { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" }, /* CS18 */
3622 { 0xe1019800, 0xfffb9800, 0x800, "UART3" }, /* CS19 */
3623 { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" }, /* CS25 */
3624 /* Strobe 1 */
3625 { 0xe101e000, 0xfffce000, 0x800, "GPIOs" }, /* CS28 */
3626
3627 { 0 }
3628 };
3629
3630 static void omap_setup_dsp_mapping(const struct omap_map_s *map)
3631 {
3632 int io;
3633
3634 for (; map->phys_dsp; map ++) {
3635 io = cpu_get_physical_page_desc(map->phys_mpu);
3636
3637 cpu_register_physical_memory(map->phys_dsp, map->size, io);
3638 }
3639 }
3640
3641 void omap_mpu_wakeup(void *opaque, int irq, int req)
3642 {
3643 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3644
3645 if (mpu->env->halted)
3646 cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
3647 }
3648
3649 static const struct dma_irq_map omap1_dma_irq_map[] = {
3650 { 0, OMAP_INT_DMA_CH0_6 },
3651 { 0, OMAP_INT_DMA_CH1_7 },
3652 { 0, OMAP_INT_DMA_CH2_8 },
3653 { 0, OMAP_INT_DMA_CH3 },
3654 { 0, OMAP_INT_DMA_CH4 },
3655 { 0, OMAP_INT_DMA_CH5 },
3656 { 1, OMAP_INT_1610_DMA_CH6 },
3657 { 1, OMAP_INT_1610_DMA_CH7 },
3658 { 1, OMAP_INT_1610_DMA_CH8 },
3659 { 1, OMAP_INT_1610_DMA_CH9 },
3660 { 1, OMAP_INT_1610_DMA_CH10 },
3661 { 1, OMAP_INT_1610_DMA_CH11 },
3662 { 1, OMAP_INT_1610_DMA_CH12 },
3663 { 1, OMAP_INT_1610_DMA_CH13 },
3664 { 1, OMAP_INT_1610_DMA_CH14 },
3665 { 1, OMAP_INT_1610_DMA_CH15 }
3666 };
3667
3668 /* DMA ports for OMAP1 */
3669 static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
3670 target_phys_addr_t addr)
3671 {
3672 return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
3673 }
3674
3675 static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
3676 target_phys_addr_t addr)
3677 {
3678 return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
3679 }
3680
3681 static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
3682 target_phys_addr_t addr)
3683 {
3684 return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
3685 }
3686
3687 static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
3688 target_phys_addr_t addr)
3689 {
3690 return addr >= 0xfffb0000 && addr < 0xffff0000;
3691 }
3692
3693 static int omap_validate_local_addr(struct omap_mpu_state_s *s,
3694 target_phys_addr_t addr)
3695 {
3696 return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
3697 }
3698
3699 static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
3700 target_phys_addr_t addr)
3701 {
3702 return addr >= 0xe1010000 && addr < 0xe1020004;
3703 }
3704
3705 struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
3706 const char *core)
3707 {
3708 int i;
3709 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
3710 qemu_mallocz(sizeof(struct omap_mpu_state_s));
3711 ram_addr_t imif_base, emiff_base;
3712 qemu_irq *cpu_irq;
3713 qemu_irq dma_irqs[6];
3714 DriveInfo *dinfo;
3715
3716 if (!core)
3717 core = "ti925t";
3718
3719 /* Core */
3720 s->mpu_model = omap310;
3721 s->env = cpu_init(core);
3722 if (!s->env) {
3723 fprintf(stderr, "Unable to find CPU definition\n");
3724 exit(1);
3725 }
3726 s->sdram_size = sdram_size;
3727 s->sram_size = OMAP15XX_SRAM_SIZE;
3728
3729 s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
3730
3731 /* Clocks */
3732 omap_clk_init(s);
3733
3734 /* Memory-mapped stuff */
3735 cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
3736 (emiff_base = qemu_ram_alloc(NULL, "omap1.dram",
3737 s->sdram_size)) | IO_MEM_RAM);
3738 cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
3739 (imif_base = qemu_ram_alloc(NULL, "omap1.sram",
3740 s->sram_size)) | IO_MEM_RAM);
3741
3742 omap_clkm_init(0xfffece00, 0xe1008000, s);
3743
3744 cpu_irq = arm_pic_init_cpu(s->env);
3745 s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0],
3746 cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
3747 omap_findclk(s, "arminth_ck"));
3748 s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, &s->irq[1],
3749 omap_inth_get_pin(s->ih[0], OMAP_INT_15XX_IH2_IRQ),
3750 NULL, omap_findclk(s, "arminth_ck"));
3751
3752 for (i = 0; i < 6; i ++)
3753 dma_irqs[i] =
3754 s->irq[omap1_dma_irq_map[i].ih][omap1_dma_irq_map[i].intr];
3755 s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
3756 s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
3757
3758 s->port[emiff ].addr_valid = omap_validate_emiff_addr;
3759 s->port[emifs ].addr_valid = omap_validate_emifs_addr;
3760 s->port[imif ].addr_valid = omap_validate_imif_addr;
3761 s->port[tipb ].addr_valid = omap_validate_tipb_addr;
3762 s->port[local ].addr_valid = omap_validate_local_addr;
3763 s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
3764
3765 /* Register SDRAM and SRAM DMA ports for fast transfers. */
3766 soc_dma_port_add_mem_ram(s->dma,
3767 emiff_base, OMAP_EMIFF_BASE, s->sdram_size);
3768 soc_dma_port_add_mem_ram(s->dma,
3769 imif_base, OMAP_IMIF_BASE, s->sram_size);
3770
3771 s->timer[0] = omap_mpu_timer_init(0xfffec500,
3772 s->irq[0][OMAP_INT_TIMER1],
3773 omap_findclk(s, "mputim_ck"));
3774 s->timer[1] = omap_mpu_timer_init(0xfffec600,
3775 s->irq[0][OMAP_INT_TIMER2],
3776 omap_findclk(s, "mputim_ck"));
3777 s->timer[2] = omap_mpu_timer_init(0xfffec700,
3778 s->irq[0][OMAP_INT_TIMER3],
3779 omap_findclk(s, "mputim_ck"));
3780
3781 s->wdt = omap_wd_timer_init(0xfffec800,
3782 s->irq[0][OMAP_INT_WD_TIMER],
3783 omap_findclk(s, "armwdt_ck"));
3784
3785 s->os_timer = omap_os_timer_init(0xfffb9000,
3786 s->irq[1][OMAP_INT_OS_TIMER],
3787 omap_findclk(s, "clk32-kHz"));
3788
3789 s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
3790 omap_dma_get_lcdch(s->dma), imif_base, emiff_base,
3791 omap_findclk(s, "lcd_ck"));
3792
3793 omap_ulpd_pm_init(0xfffe0800, s);
3794 omap_pin_cfg_init(0xfffe1000, s);
3795 omap_id_init(s);
3796
3797 omap_mpui_init(0xfffec900, s);
3798
3799 s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
3800 s->irq[0][OMAP_INT_BRIDGE_PRIV],
3801 omap_findclk(s, "tipb_ck"));
3802 s->public_tipb = omap_tipb_bridge_init(0xfffed300,
3803 s->irq[0][OMAP_INT_BRIDGE_PUB],
3804 omap_findclk(s, "tipb_ck"));
3805
3806 omap_tcmi_init(0xfffecc00, s);
3807
3808 s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
3809 omap_findclk(s, "uart1_ck"),
3810 omap_findclk(s, "uart1_ck"),
3811 s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
3812 "uart1",
3813 serial_hds[0]);
3814 s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
3815 omap_findclk(s, "uart2_ck"),
3816 omap_findclk(s, "uart2_ck"),
3817 s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
3818 "uart2",
3819 serial_hds[0] ? serial_hds[1] : NULL);
3820 s->uart[2] = omap_uart_init(0xfffb9800, s->irq[0][OMAP_INT_UART3],
3821 omap_findclk(s, "uart3_ck"),
3822 omap_findclk(s, "uart3_ck"),
3823 s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
3824 "uart3",
3825 serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
3826
3827 omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
3828 omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
3829 omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
3830
3831 dinfo = drive_get(IF_SD, 0, 0);
3832 if (!dinfo) {
3833 fprintf(stderr, "qemu: missing SecureDigital device\n");
3834 exit(1);
3835 }
3836 s->mmc = omap_mmc_init(0xfffb7800, dinfo->bdrv,
3837 s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
3838 omap_findclk(s, "mmc_ck"));
3839
3840 s->mpuio = omap_mpuio_init(0xfffb5000,
3841 s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
3842 s->wakeup, omap_findclk(s, "clk32-kHz"));
3843
3844 s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
3845 omap_findclk(s, "arm_gpio_ck"));
3846
3847 s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
3848 s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
3849
3850 omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
3851 omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
3852
3853 s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
3854 &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
3855
3856 s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
3857 omap_findclk(s, "clk32-kHz"));
3858
3859 s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
3860 &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
3861 s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
3862 &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
3863 s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
3864 &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
3865
3866 s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
3867 s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
3868
3869 /* Register mappings not currenlty implemented:
3870 * MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310)
3871 * MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310)
3872 * USB W2FC fffb4000 - fffb47ff
3873 * Camera Interface fffb6800 - fffb6fff
3874 * USB Host fffba000 - fffba7ff
3875 * FAC fffba800 - fffbafff
3876 * HDQ/1-Wire fffbc000 - fffbc7ff
3877 * TIPB switches fffbc800 - fffbcfff
3878 * Mailbox fffcf000 - fffcf7ff
3879 * Local bus IF fffec100 - fffec1ff
3880 * Local bus MMU fffec200 - fffec2ff
3881 * DSP MMU fffed200 - fffed2ff
3882 */
3883
3884 omap_setup_dsp_mapping(omap15xx_dsp_mm);
3885 omap_setup_mpui_io(s);
3886
3887 qemu_register_reset(omap1_mpu_reset, s);
3888
3889 return s;
3890 }