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