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