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