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