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