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/arm.h" 21 #include "hw/arm/omap.h" 22 #include "sysemu/sysemu.h" 23 #include "hw/arm/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, &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, &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, &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, &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, &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, &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_clock_get_ns(QEMU_CLOCK_VIRTUAL) - 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_clock_get_ns(QEMU_CLOCK_VIRTUAL); 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 timer_mod(timer->timer, timer->time + expires); 134 else 135 qemu_bh_schedule(timer->tick); 136 } else 137 timer_del(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 timer_del(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 = timer_new_ns(QEMU_CLOCK_VIRTUAL, 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, NULL, &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 timer_del(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 = timer_new_ns(QEMU_CLOCK_VIRTUAL, 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, NULL, &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 timer_del(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 = timer_new_ns(QEMU_CLOCK_VIRTUAL, 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, NULL, &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_clock_get_ns(QEMU_CLOCK_VIRTUAL); 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, NULL, &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, NULL, &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, NULL, &omap_id_ops, mpu, 1025 "omap-id", 0x100000000ULL); 1026 memory_region_init_alias(&mpu->id_iomem_e18, NULL, "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, NULL, "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, NULL, "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, NULL, &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, NULL, &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, NULL, &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, NULL, &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(CPU(s->cpu), 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 CPUState *cpu = CPU(s->cpu); 1725 1726 if (size != 2) { 1727 return omap_badwidth_read16(opaque, addr); 1728 } 1729 1730 switch (addr) { 1731 case 0x04: /* DSP_IDLECT1 */ 1732 return s->clkm.dsp_idlect1; 1733 1734 case 0x08: /* DSP_IDLECT2 */ 1735 return s->clkm.dsp_idlect2; 1736 1737 case 0x14: /* DSP_RSTCT2 */ 1738 return s->clkm.dsp_rstct2; 1739 1740 case 0x18: /* DSP_SYSST */ 1741 cpu = CPU(s->cpu); 1742 return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start | 1743 (cpu->halted << 6); /* Quite useless... */ 1744 } 1745 1746 OMAP_BAD_REG(addr); 1747 return 0; 1748 } 1749 1750 static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s, 1751 uint16_t diff, uint16_t value) 1752 { 1753 omap_clk clk; 1754 1755 SET_CANIDLE("dspxor_ck", 1); /* IDLXORP_DSP */ 1756 } 1757 1758 static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s, 1759 uint16_t diff, uint16_t value) 1760 { 1761 omap_clk clk; 1762 1763 SET_ONOFF("dspxor_ck", 1); /* EN_XORPCK */ 1764 } 1765 1766 static void omap_clkdsp_write(void *opaque, hwaddr addr, 1767 uint64_t value, unsigned size) 1768 { 1769 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; 1770 uint16_t diff; 1771 1772 if (size != 2) { 1773 return omap_badwidth_write16(opaque, addr, value); 1774 } 1775 1776 switch (addr) { 1777 case 0x04: /* DSP_IDLECT1 */ 1778 diff = s->clkm.dsp_idlect1 ^ value; 1779 s->clkm.dsp_idlect1 = value & 0x01f7; 1780 omap_clkdsp_idlect1_update(s, diff, value); 1781 break; 1782 1783 case 0x08: /* DSP_IDLECT2 */ 1784 s->clkm.dsp_idlect2 = value & 0x0037; 1785 diff = s->clkm.dsp_idlect1 ^ value; 1786 omap_clkdsp_idlect2_update(s, diff, value); 1787 break; 1788 1789 case 0x14: /* DSP_RSTCT2 */ 1790 s->clkm.dsp_rstct2 = value & 0x0001; 1791 break; 1792 1793 case 0x18: /* DSP_SYSST */ 1794 s->clkm.cold_start &= value & 0x3f; 1795 break; 1796 1797 default: 1798 OMAP_BAD_REG(addr); 1799 } 1800 } 1801 1802 static const MemoryRegionOps omap_clkdsp_ops = { 1803 .read = omap_clkdsp_read, 1804 .write = omap_clkdsp_write, 1805 .endianness = DEVICE_NATIVE_ENDIAN, 1806 }; 1807 1808 static void omap_clkm_reset(struct omap_mpu_state_s *s) 1809 { 1810 if (s->wdt && s->wdt->reset) 1811 s->clkm.cold_start = 0x6; 1812 s->clkm.clocking_scheme = 0; 1813 omap_clkm_ckctl_update(s, ~0, 0x3000); 1814 s->clkm.arm_ckctl = 0x3000; 1815 omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400); 1816 s->clkm.arm_idlect1 = 0x0400; 1817 omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100); 1818 s->clkm.arm_idlect2 = 0x0100; 1819 s->clkm.arm_ewupct = 0x003f; 1820 s->clkm.arm_rstct1 = 0x0000; 1821 s->clkm.arm_rstct2 = 0x0000; 1822 s->clkm.arm_ckout1 = 0x0015; 1823 s->clkm.dpll1_mode = 0x2002; 1824 omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040); 1825 s->clkm.dsp_idlect1 = 0x0040; 1826 omap_clkdsp_idlect2_update(s, ~0, 0x0000); 1827 s->clkm.dsp_idlect2 = 0x0000; 1828 s->clkm.dsp_rstct2 = 0x0000; 1829 } 1830 1831 static void omap_clkm_init(MemoryRegion *memory, hwaddr mpu_base, 1832 hwaddr dsp_base, struct omap_mpu_state_s *s) 1833 { 1834 memory_region_init_io(&s->clkm_iomem, NULL, &omap_clkm_ops, s, 1835 "omap-clkm", 0x100); 1836 memory_region_init_io(&s->clkdsp_iomem, NULL, &omap_clkdsp_ops, s, 1837 "omap-clkdsp", 0x1000); 1838 1839 s->clkm.arm_idlect1 = 0x03ff; 1840 s->clkm.arm_idlect2 = 0x0100; 1841 s->clkm.dsp_idlect1 = 0x0002; 1842 omap_clkm_reset(s); 1843 s->clkm.cold_start = 0x3a; 1844 1845 memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem); 1846 memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem); 1847 } 1848 1849 /* MPU I/O */ 1850 struct omap_mpuio_s { 1851 qemu_irq irq; 1852 qemu_irq kbd_irq; 1853 qemu_irq *in; 1854 qemu_irq handler[16]; 1855 qemu_irq wakeup; 1856 MemoryRegion iomem; 1857 1858 uint16_t inputs; 1859 uint16_t outputs; 1860 uint16_t dir; 1861 uint16_t edge; 1862 uint16_t mask; 1863 uint16_t ints; 1864 1865 uint16_t debounce; 1866 uint16_t latch; 1867 uint8_t event; 1868 1869 uint8_t buttons[5]; 1870 uint8_t row_latch; 1871 uint8_t cols; 1872 int kbd_mask; 1873 int clk; 1874 }; 1875 1876 static void omap_mpuio_set(void *opaque, int line, int level) 1877 { 1878 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque; 1879 uint16_t prev = s->inputs; 1880 1881 if (level) 1882 s->inputs |= 1 << line; 1883 else 1884 s->inputs &= ~(1 << line); 1885 1886 if (((1 << line) & s->dir & ~s->mask) && s->clk) { 1887 if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) { 1888 s->ints |= 1 << line; 1889 qemu_irq_raise(s->irq); 1890 /* TODO: wakeup */ 1891 } 1892 if ((s->event & (1 << 0)) && /* SET_GPIO_EVENT_MODE */ 1893 (s->event >> 1) == line) /* PIN_SELECT */ 1894 s->latch = s->inputs; 1895 } 1896 } 1897 1898 static void omap_mpuio_kbd_update(struct omap_mpuio_s *s) 1899 { 1900 int i; 1901 uint8_t *row, rows = 0, cols = ~s->cols; 1902 1903 for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1) 1904 if (*row & cols) 1905 rows |= i; 1906 1907 qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk); 1908 s->row_latch = ~rows; 1909 } 1910 1911 static uint64_t omap_mpuio_read(void *opaque, hwaddr addr, 1912 unsigned size) 1913 { 1914 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque; 1915 int offset = addr & OMAP_MPUI_REG_MASK; 1916 uint16_t ret; 1917 1918 if (size != 2) { 1919 return omap_badwidth_read16(opaque, addr); 1920 } 1921 1922 switch (offset) { 1923 case 0x00: /* INPUT_LATCH */ 1924 return s->inputs; 1925 1926 case 0x04: /* OUTPUT_REG */ 1927 return s->outputs; 1928 1929 case 0x08: /* IO_CNTL */ 1930 return s->dir; 1931 1932 case 0x10: /* KBR_LATCH */ 1933 return s->row_latch; 1934 1935 case 0x14: /* KBC_REG */ 1936 return s->cols; 1937 1938 case 0x18: /* GPIO_EVENT_MODE_REG */ 1939 return s->event; 1940 1941 case 0x1c: /* GPIO_INT_EDGE_REG */ 1942 return s->edge; 1943 1944 case 0x20: /* KBD_INT */ 1945 return (~s->row_latch & 0x1f) && !s->kbd_mask; 1946 1947 case 0x24: /* GPIO_INT */ 1948 ret = s->ints; 1949 s->ints &= s->mask; 1950 if (ret) 1951 qemu_irq_lower(s->irq); 1952 return ret; 1953 1954 case 0x28: /* KBD_MASKIT */ 1955 return s->kbd_mask; 1956 1957 case 0x2c: /* GPIO_MASKIT */ 1958 return s->mask; 1959 1960 case 0x30: /* GPIO_DEBOUNCING_REG */ 1961 return s->debounce; 1962 1963 case 0x34: /* GPIO_LATCH_REG */ 1964 return s->latch; 1965 } 1966 1967 OMAP_BAD_REG(addr); 1968 return 0; 1969 } 1970 1971 static void omap_mpuio_write(void *opaque, hwaddr addr, 1972 uint64_t value, unsigned size) 1973 { 1974 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque; 1975 int offset = addr & OMAP_MPUI_REG_MASK; 1976 uint16_t diff; 1977 int ln; 1978 1979 if (size != 2) { 1980 return omap_badwidth_write16(opaque, addr, value); 1981 } 1982 1983 switch (offset) { 1984 case 0x04: /* OUTPUT_REG */ 1985 diff = (s->outputs ^ value) & ~s->dir; 1986 s->outputs = value; 1987 while ((ln = ffs(diff))) { 1988 ln --; 1989 if (s->handler[ln]) 1990 qemu_set_irq(s->handler[ln], (value >> ln) & 1); 1991 diff &= ~(1 << ln); 1992 } 1993 break; 1994 1995 case 0x08: /* IO_CNTL */ 1996 diff = s->outputs & (s->dir ^ value); 1997 s->dir = value; 1998 1999 value = s->outputs & ~s->dir; 2000 while ((ln = ffs(diff))) { 2001 ln --; 2002 if (s->handler[ln]) 2003 qemu_set_irq(s->handler[ln], (value >> ln) & 1); 2004 diff &= ~(1 << ln); 2005 } 2006 break; 2007 2008 case 0x14: /* KBC_REG */ 2009 s->cols = value; 2010 omap_mpuio_kbd_update(s); 2011 break; 2012 2013 case 0x18: /* GPIO_EVENT_MODE_REG */ 2014 s->event = value & 0x1f; 2015 break; 2016 2017 case 0x1c: /* GPIO_INT_EDGE_REG */ 2018 s->edge = value; 2019 break; 2020 2021 case 0x28: /* KBD_MASKIT */ 2022 s->kbd_mask = value & 1; 2023 omap_mpuio_kbd_update(s); 2024 break; 2025 2026 case 0x2c: /* GPIO_MASKIT */ 2027 s->mask = value; 2028 break; 2029 2030 case 0x30: /* GPIO_DEBOUNCING_REG */ 2031 s->debounce = value & 0x1ff; 2032 break; 2033 2034 case 0x00: /* INPUT_LATCH */ 2035 case 0x10: /* KBR_LATCH */ 2036 case 0x20: /* KBD_INT */ 2037 case 0x24: /* GPIO_INT */ 2038 case 0x34: /* GPIO_LATCH_REG */ 2039 OMAP_RO_REG(addr); 2040 return; 2041 2042 default: 2043 OMAP_BAD_REG(addr); 2044 return; 2045 } 2046 } 2047 2048 static const MemoryRegionOps omap_mpuio_ops = { 2049 .read = omap_mpuio_read, 2050 .write = omap_mpuio_write, 2051 .endianness = DEVICE_NATIVE_ENDIAN, 2052 }; 2053 2054 static void omap_mpuio_reset(struct omap_mpuio_s *s) 2055 { 2056 s->inputs = 0; 2057 s->outputs = 0; 2058 s->dir = ~0; 2059 s->event = 0; 2060 s->edge = 0; 2061 s->kbd_mask = 0; 2062 s->mask = 0; 2063 s->debounce = 0; 2064 s->latch = 0; 2065 s->ints = 0; 2066 s->row_latch = 0x1f; 2067 s->clk = 1; 2068 } 2069 2070 static void omap_mpuio_onoff(void *opaque, int line, int on) 2071 { 2072 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque; 2073 2074 s->clk = on; 2075 if (on) 2076 omap_mpuio_kbd_update(s); 2077 } 2078 2079 static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory, 2080 hwaddr base, 2081 qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup, 2082 omap_clk clk) 2083 { 2084 struct omap_mpuio_s *s = (struct omap_mpuio_s *) 2085 g_malloc0(sizeof(struct omap_mpuio_s)); 2086 2087 s->irq = gpio_int; 2088 s->kbd_irq = kbd_int; 2089 s->wakeup = wakeup; 2090 s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16); 2091 omap_mpuio_reset(s); 2092 2093 memory_region_init_io(&s->iomem, NULL, &omap_mpuio_ops, s, 2094 "omap-mpuio", 0x800); 2095 memory_region_add_subregion(memory, base, &s->iomem); 2096 2097 omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]); 2098 2099 return s; 2100 } 2101 2102 qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s) 2103 { 2104 return s->in; 2105 } 2106 2107 void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler) 2108 { 2109 if (line >= 16 || line < 0) 2110 hw_error("%s: No GPIO line %i\n", __FUNCTION__, line); 2111 s->handler[line] = handler; 2112 } 2113 2114 void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down) 2115 { 2116 if (row >= 5 || row < 0) 2117 hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row); 2118 2119 if (down) 2120 s->buttons[row] |= 1 << col; 2121 else 2122 s->buttons[row] &= ~(1 << col); 2123 2124 omap_mpuio_kbd_update(s); 2125 } 2126 2127 /* MicroWire Interface */ 2128 struct omap_uwire_s { 2129 MemoryRegion iomem; 2130 qemu_irq txirq; 2131 qemu_irq rxirq; 2132 qemu_irq txdrq; 2133 2134 uint16_t txbuf; 2135 uint16_t rxbuf; 2136 uint16_t control; 2137 uint16_t setup[5]; 2138 2139 uWireSlave *chip[4]; 2140 }; 2141 2142 static void omap_uwire_transfer_start(struct omap_uwire_s *s) 2143 { 2144 int chipselect = (s->control >> 10) & 3; /* INDEX */ 2145 uWireSlave *slave = s->chip[chipselect]; 2146 2147 if ((s->control >> 5) & 0x1f) { /* NB_BITS_WR */ 2148 if (s->control & (1 << 12)) /* CS_CMD */ 2149 if (slave && slave->send) 2150 slave->send(slave->opaque, 2151 s->txbuf >> (16 - ((s->control >> 5) & 0x1f))); 2152 s->control &= ~(1 << 14); /* CSRB */ 2153 /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or 2154 * a DRQ. When is the level IRQ supposed to be reset? */ 2155 } 2156 2157 if ((s->control >> 0) & 0x1f) { /* NB_BITS_RD */ 2158 if (s->control & (1 << 12)) /* CS_CMD */ 2159 if (slave && slave->receive) 2160 s->rxbuf = slave->receive(slave->opaque); 2161 s->control |= 1 << 15; /* RDRB */ 2162 /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or 2163 * a DRQ. When is the level IRQ supposed to be reset? */ 2164 } 2165 } 2166 2167 static uint64_t omap_uwire_read(void *opaque, hwaddr addr, 2168 unsigned size) 2169 { 2170 struct omap_uwire_s *s = (struct omap_uwire_s *) opaque; 2171 int offset = addr & OMAP_MPUI_REG_MASK; 2172 2173 if (size != 2) { 2174 return omap_badwidth_read16(opaque, addr); 2175 } 2176 2177 switch (offset) { 2178 case 0x00: /* RDR */ 2179 s->control &= ~(1 << 15); /* RDRB */ 2180 return s->rxbuf; 2181 2182 case 0x04: /* CSR */ 2183 return s->control; 2184 2185 case 0x08: /* SR1 */ 2186 return s->setup[0]; 2187 case 0x0c: /* SR2 */ 2188 return s->setup[1]; 2189 case 0x10: /* SR3 */ 2190 return s->setup[2]; 2191 case 0x14: /* SR4 */ 2192 return s->setup[3]; 2193 case 0x18: /* SR5 */ 2194 return s->setup[4]; 2195 } 2196 2197 OMAP_BAD_REG(addr); 2198 return 0; 2199 } 2200 2201 static void omap_uwire_write(void *opaque, hwaddr addr, 2202 uint64_t value, unsigned size) 2203 { 2204 struct omap_uwire_s *s = (struct omap_uwire_s *) opaque; 2205 int offset = addr & OMAP_MPUI_REG_MASK; 2206 2207 if (size != 2) { 2208 return omap_badwidth_write16(opaque, addr, value); 2209 } 2210 2211 switch (offset) { 2212 case 0x00: /* TDR */ 2213 s->txbuf = value; /* TD */ 2214 if ((s->setup[4] & (1 << 2)) && /* AUTO_TX_EN */ 2215 ((s->setup[4] & (1 << 3)) || /* CS_TOGGLE_TX_EN */ 2216 (s->control & (1 << 12)))) { /* CS_CMD */ 2217 s->control |= 1 << 14; /* CSRB */ 2218 omap_uwire_transfer_start(s); 2219 } 2220 break; 2221 2222 case 0x04: /* CSR */ 2223 s->control = value & 0x1fff; 2224 if (value & (1 << 13)) /* START */ 2225 omap_uwire_transfer_start(s); 2226 break; 2227 2228 case 0x08: /* SR1 */ 2229 s->setup[0] = value & 0x003f; 2230 break; 2231 2232 case 0x0c: /* SR2 */ 2233 s->setup[1] = value & 0x0fc0; 2234 break; 2235 2236 case 0x10: /* SR3 */ 2237 s->setup[2] = value & 0x0003; 2238 break; 2239 2240 case 0x14: /* SR4 */ 2241 s->setup[3] = value & 0x0001; 2242 break; 2243 2244 case 0x18: /* SR5 */ 2245 s->setup[4] = value & 0x000f; 2246 break; 2247 2248 default: 2249 OMAP_BAD_REG(addr); 2250 return; 2251 } 2252 } 2253 2254 static const MemoryRegionOps omap_uwire_ops = { 2255 .read = omap_uwire_read, 2256 .write = omap_uwire_write, 2257 .endianness = DEVICE_NATIVE_ENDIAN, 2258 }; 2259 2260 static void omap_uwire_reset(struct omap_uwire_s *s) 2261 { 2262 s->control = 0; 2263 s->setup[0] = 0; 2264 s->setup[1] = 0; 2265 s->setup[2] = 0; 2266 s->setup[3] = 0; 2267 s->setup[4] = 0; 2268 } 2269 2270 static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory, 2271 hwaddr base, 2272 qemu_irq txirq, qemu_irq rxirq, 2273 qemu_irq dma, 2274 omap_clk clk) 2275 { 2276 struct omap_uwire_s *s = (struct omap_uwire_s *) 2277 g_malloc0(sizeof(struct omap_uwire_s)); 2278 2279 s->txirq = txirq; 2280 s->rxirq = rxirq; 2281 s->txdrq = dma; 2282 omap_uwire_reset(s); 2283 2284 memory_region_init_io(&s->iomem, NULL, &omap_uwire_ops, s, "omap-uwire", 0x800); 2285 memory_region_add_subregion(system_memory, base, &s->iomem); 2286 2287 return s; 2288 } 2289 2290 void omap_uwire_attach(struct omap_uwire_s *s, 2291 uWireSlave *slave, int chipselect) 2292 { 2293 if (chipselect < 0 || chipselect > 3) { 2294 fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect); 2295 exit(-1); 2296 } 2297 2298 s->chip[chipselect] = slave; 2299 } 2300 2301 /* Pseudonoise Pulse-Width Light Modulator */ 2302 struct omap_pwl_s { 2303 MemoryRegion iomem; 2304 uint8_t output; 2305 uint8_t level; 2306 uint8_t enable; 2307 int clk; 2308 }; 2309 2310 static void omap_pwl_update(struct omap_pwl_s *s) 2311 { 2312 int output = (s->clk && s->enable) ? s->level : 0; 2313 2314 if (output != s->output) { 2315 s->output = output; 2316 printf("%s: Backlight now at %i/256\n", __FUNCTION__, output); 2317 } 2318 } 2319 2320 static uint64_t omap_pwl_read(void *opaque, hwaddr addr, 2321 unsigned size) 2322 { 2323 struct omap_pwl_s *s = (struct omap_pwl_s *) opaque; 2324 int offset = addr & OMAP_MPUI_REG_MASK; 2325 2326 if (size != 1) { 2327 return omap_badwidth_read8(opaque, addr); 2328 } 2329 2330 switch (offset) { 2331 case 0x00: /* PWL_LEVEL */ 2332 return s->level; 2333 case 0x04: /* PWL_CTRL */ 2334 return s->enable; 2335 } 2336 OMAP_BAD_REG(addr); 2337 return 0; 2338 } 2339 2340 static void omap_pwl_write(void *opaque, hwaddr addr, 2341 uint64_t value, unsigned size) 2342 { 2343 struct omap_pwl_s *s = (struct omap_pwl_s *) opaque; 2344 int offset = addr & OMAP_MPUI_REG_MASK; 2345 2346 if (size != 1) { 2347 return omap_badwidth_write8(opaque, addr, value); 2348 } 2349 2350 switch (offset) { 2351 case 0x00: /* PWL_LEVEL */ 2352 s->level = value; 2353 omap_pwl_update(s); 2354 break; 2355 case 0x04: /* PWL_CTRL */ 2356 s->enable = value & 1; 2357 omap_pwl_update(s); 2358 break; 2359 default: 2360 OMAP_BAD_REG(addr); 2361 return; 2362 } 2363 } 2364 2365 static const MemoryRegionOps omap_pwl_ops = { 2366 .read = omap_pwl_read, 2367 .write = omap_pwl_write, 2368 .endianness = DEVICE_NATIVE_ENDIAN, 2369 }; 2370 2371 static void omap_pwl_reset(struct omap_pwl_s *s) 2372 { 2373 s->output = 0; 2374 s->level = 0; 2375 s->enable = 0; 2376 s->clk = 1; 2377 omap_pwl_update(s); 2378 } 2379 2380 static void omap_pwl_clk_update(void *opaque, int line, int on) 2381 { 2382 struct omap_pwl_s *s = (struct omap_pwl_s *) opaque; 2383 2384 s->clk = on; 2385 omap_pwl_update(s); 2386 } 2387 2388 static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory, 2389 hwaddr base, 2390 omap_clk clk) 2391 { 2392 struct omap_pwl_s *s = g_malloc0(sizeof(*s)); 2393 2394 omap_pwl_reset(s); 2395 2396 memory_region_init_io(&s->iomem, NULL, &omap_pwl_ops, s, 2397 "omap-pwl", 0x800); 2398 memory_region_add_subregion(system_memory, base, &s->iomem); 2399 2400 omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]); 2401 return s; 2402 } 2403 2404 /* Pulse-Width Tone module */ 2405 struct omap_pwt_s { 2406 MemoryRegion iomem; 2407 uint8_t frc; 2408 uint8_t vrc; 2409 uint8_t gcr; 2410 omap_clk clk; 2411 }; 2412 2413 static uint64_t omap_pwt_read(void *opaque, hwaddr addr, 2414 unsigned size) 2415 { 2416 struct omap_pwt_s *s = (struct omap_pwt_s *) opaque; 2417 int offset = addr & OMAP_MPUI_REG_MASK; 2418 2419 if (size != 1) { 2420 return omap_badwidth_read8(opaque, addr); 2421 } 2422 2423 switch (offset) { 2424 case 0x00: /* FRC */ 2425 return s->frc; 2426 case 0x04: /* VCR */ 2427 return s->vrc; 2428 case 0x08: /* GCR */ 2429 return s->gcr; 2430 } 2431 OMAP_BAD_REG(addr); 2432 return 0; 2433 } 2434 2435 static void omap_pwt_write(void *opaque, hwaddr addr, 2436 uint64_t value, unsigned size) 2437 { 2438 struct omap_pwt_s *s = (struct omap_pwt_s *) opaque; 2439 int offset = addr & OMAP_MPUI_REG_MASK; 2440 2441 if (size != 1) { 2442 return omap_badwidth_write8(opaque, addr, value); 2443 } 2444 2445 switch (offset) { 2446 case 0x00: /* FRC */ 2447 s->frc = value & 0x3f; 2448 break; 2449 case 0x04: /* VRC */ 2450 if ((value ^ s->vrc) & 1) { 2451 if (value & 1) 2452 printf("%s: %iHz buzz on\n", __FUNCTION__, (int) 2453 /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */ 2454 ((omap_clk_getrate(s->clk) >> 3) / 2455 /* Pre-multiplexer divider */ 2456 ((s->gcr & 2) ? 1 : 154) / 2457 /* Octave multiplexer */ 2458 (2 << (value & 3)) * 2459 /* 101/107 divider */ 2460 ((value & (1 << 2)) ? 101 : 107) * 2461 /* 49/55 divider */ 2462 ((value & (1 << 3)) ? 49 : 55) * 2463 /* 50/63 divider */ 2464 ((value & (1 << 4)) ? 50 : 63) * 2465 /* 80/127 divider */ 2466 ((value & (1 << 5)) ? 80 : 127) / 2467 (107 * 55 * 63 * 127))); 2468 else 2469 printf("%s: silence!\n", __FUNCTION__); 2470 } 2471 s->vrc = value & 0x7f; 2472 break; 2473 case 0x08: /* GCR */ 2474 s->gcr = value & 3; 2475 break; 2476 default: 2477 OMAP_BAD_REG(addr); 2478 return; 2479 } 2480 } 2481 2482 static const MemoryRegionOps omap_pwt_ops = { 2483 .read =omap_pwt_read, 2484 .write = omap_pwt_write, 2485 .endianness = DEVICE_NATIVE_ENDIAN, 2486 }; 2487 2488 static void omap_pwt_reset(struct omap_pwt_s *s) 2489 { 2490 s->frc = 0; 2491 s->vrc = 0; 2492 s->gcr = 0; 2493 } 2494 2495 static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory, 2496 hwaddr base, 2497 omap_clk clk) 2498 { 2499 struct omap_pwt_s *s = g_malloc0(sizeof(*s)); 2500 s->clk = clk; 2501 omap_pwt_reset(s); 2502 2503 memory_region_init_io(&s->iomem, NULL, &omap_pwt_ops, s, 2504 "omap-pwt", 0x800); 2505 memory_region_add_subregion(system_memory, base, &s->iomem); 2506 return s; 2507 } 2508 2509 /* Real-time Clock module */ 2510 struct omap_rtc_s { 2511 MemoryRegion iomem; 2512 qemu_irq irq; 2513 qemu_irq alarm; 2514 QEMUTimer *clk; 2515 2516 uint8_t interrupts; 2517 uint8_t status; 2518 int16_t comp_reg; 2519 int running; 2520 int pm_am; 2521 int auto_comp; 2522 int round; 2523 struct tm alarm_tm; 2524 time_t alarm_ti; 2525 2526 struct tm current_tm; 2527 time_t ti; 2528 uint64_t tick; 2529 }; 2530 2531 static void omap_rtc_interrupts_update(struct omap_rtc_s *s) 2532 { 2533 /* s->alarm is level-triggered */ 2534 qemu_set_irq(s->alarm, (s->status >> 6) & 1); 2535 } 2536 2537 static void omap_rtc_alarm_update(struct omap_rtc_s *s) 2538 { 2539 s->alarm_ti = mktimegm(&s->alarm_tm); 2540 if (s->alarm_ti == -1) 2541 printf("%s: conversion failed\n", __FUNCTION__); 2542 } 2543 2544 static uint64_t omap_rtc_read(void *opaque, hwaddr addr, 2545 unsigned size) 2546 { 2547 struct omap_rtc_s *s = (struct omap_rtc_s *) opaque; 2548 int offset = addr & OMAP_MPUI_REG_MASK; 2549 uint8_t i; 2550 2551 if (size != 1) { 2552 return omap_badwidth_read8(opaque, addr); 2553 } 2554 2555 switch (offset) { 2556 case 0x00: /* SECONDS_REG */ 2557 return to_bcd(s->current_tm.tm_sec); 2558 2559 case 0x04: /* MINUTES_REG */ 2560 return to_bcd(s->current_tm.tm_min); 2561 2562 case 0x08: /* HOURS_REG */ 2563 if (s->pm_am) 2564 return ((s->current_tm.tm_hour > 11) << 7) | 2565 to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1); 2566 else 2567 return to_bcd(s->current_tm.tm_hour); 2568 2569 case 0x0c: /* DAYS_REG */ 2570 return to_bcd(s->current_tm.tm_mday); 2571 2572 case 0x10: /* MONTHS_REG */ 2573 return to_bcd(s->current_tm.tm_mon + 1); 2574 2575 case 0x14: /* YEARS_REG */ 2576 return to_bcd(s->current_tm.tm_year % 100); 2577 2578 case 0x18: /* WEEK_REG */ 2579 return s->current_tm.tm_wday; 2580 2581 case 0x20: /* ALARM_SECONDS_REG */ 2582 return to_bcd(s->alarm_tm.tm_sec); 2583 2584 case 0x24: /* ALARM_MINUTES_REG */ 2585 return to_bcd(s->alarm_tm.tm_min); 2586 2587 case 0x28: /* ALARM_HOURS_REG */ 2588 if (s->pm_am) 2589 return ((s->alarm_tm.tm_hour > 11) << 7) | 2590 to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1); 2591 else 2592 return to_bcd(s->alarm_tm.tm_hour); 2593 2594 case 0x2c: /* ALARM_DAYS_REG */ 2595 return to_bcd(s->alarm_tm.tm_mday); 2596 2597 case 0x30: /* ALARM_MONTHS_REG */ 2598 return to_bcd(s->alarm_tm.tm_mon + 1); 2599 2600 case 0x34: /* ALARM_YEARS_REG */ 2601 return to_bcd(s->alarm_tm.tm_year % 100); 2602 2603 case 0x40: /* RTC_CTRL_REG */ 2604 return (s->pm_am << 3) | (s->auto_comp << 2) | 2605 (s->round << 1) | s->running; 2606 2607 case 0x44: /* RTC_STATUS_REG */ 2608 i = s->status; 2609 s->status &= ~0x3d; 2610 return i; 2611 2612 case 0x48: /* RTC_INTERRUPTS_REG */ 2613 return s->interrupts; 2614 2615 case 0x4c: /* RTC_COMP_LSB_REG */ 2616 return ((uint16_t) s->comp_reg) & 0xff; 2617 2618 case 0x50: /* RTC_COMP_MSB_REG */ 2619 return ((uint16_t) s->comp_reg) >> 8; 2620 } 2621 2622 OMAP_BAD_REG(addr); 2623 return 0; 2624 } 2625 2626 static void omap_rtc_write(void *opaque, hwaddr addr, 2627 uint64_t value, unsigned size) 2628 { 2629 struct omap_rtc_s *s = (struct omap_rtc_s *) opaque; 2630 int offset = addr & OMAP_MPUI_REG_MASK; 2631 struct tm new_tm; 2632 time_t ti[2]; 2633 2634 if (size != 1) { 2635 return omap_badwidth_write8(opaque, addr, value); 2636 } 2637 2638 switch (offset) { 2639 case 0x00: /* SECONDS_REG */ 2640 #ifdef ALMDEBUG 2641 printf("RTC SEC_REG <-- %02x\n", value); 2642 #endif 2643 s->ti -= s->current_tm.tm_sec; 2644 s->ti += from_bcd(value); 2645 return; 2646 2647 case 0x04: /* MINUTES_REG */ 2648 #ifdef ALMDEBUG 2649 printf("RTC MIN_REG <-- %02x\n", value); 2650 #endif 2651 s->ti -= s->current_tm.tm_min * 60; 2652 s->ti += from_bcd(value) * 60; 2653 return; 2654 2655 case 0x08: /* HOURS_REG */ 2656 #ifdef ALMDEBUG 2657 printf("RTC HRS_REG <-- %02x\n", value); 2658 #endif 2659 s->ti -= s->current_tm.tm_hour * 3600; 2660 if (s->pm_am) { 2661 s->ti += (from_bcd(value & 0x3f) & 12) * 3600; 2662 s->ti += ((value >> 7) & 1) * 43200; 2663 } else 2664 s->ti += from_bcd(value & 0x3f) * 3600; 2665 return; 2666 2667 case 0x0c: /* DAYS_REG */ 2668 #ifdef ALMDEBUG 2669 printf("RTC DAY_REG <-- %02x\n", value); 2670 #endif 2671 s->ti -= s->current_tm.tm_mday * 86400; 2672 s->ti += from_bcd(value) * 86400; 2673 return; 2674 2675 case 0x10: /* MONTHS_REG */ 2676 #ifdef ALMDEBUG 2677 printf("RTC MTH_REG <-- %02x\n", value); 2678 #endif 2679 memcpy(&new_tm, &s->current_tm, sizeof(new_tm)); 2680 new_tm.tm_mon = from_bcd(value); 2681 ti[0] = mktimegm(&s->current_tm); 2682 ti[1] = mktimegm(&new_tm); 2683 2684 if (ti[0] != -1 && ti[1] != -1) { 2685 s->ti -= ti[0]; 2686 s->ti += ti[1]; 2687 } else { 2688 /* A less accurate version */ 2689 s->ti -= s->current_tm.tm_mon * 2592000; 2690 s->ti += from_bcd(value) * 2592000; 2691 } 2692 return; 2693 2694 case 0x14: /* YEARS_REG */ 2695 #ifdef ALMDEBUG 2696 printf("RTC YRS_REG <-- %02x\n", value); 2697 #endif 2698 memcpy(&new_tm, &s->current_tm, sizeof(new_tm)); 2699 new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100); 2700 ti[0] = mktimegm(&s->current_tm); 2701 ti[1] = mktimegm(&new_tm); 2702 2703 if (ti[0] != -1 && ti[1] != -1) { 2704 s->ti -= ti[0]; 2705 s->ti += ti[1]; 2706 } else { 2707 /* A less accurate version */ 2708 s->ti -= (s->current_tm.tm_year % 100) * 31536000; 2709 s->ti += from_bcd(value) * 31536000; 2710 } 2711 return; 2712 2713 case 0x18: /* WEEK_REG */ 2714 return; /* Ignored */ 2715 2716 case 0x20: /* ALARM_SECONDS_REG */ 2717 #ifdef ALMDEBUG 2718 printf("ALM SEC_REG <-- %02x\n", value); 2719 #endif 2720 s->alarm_tm.tm_sec = from_bcd(value); 2721 omap_rtc_alarm_update(s); 2722 return; 2723 2724 case 0x24: /* ALARM_MINUTES_REG */ 2725 #ifdef ALMDEBUG 2726 printf("ALM MIN_REG <-- %02x\n", value); 2727 #endif 2728 s->alarm_tm.tm_min = from_bcd(value); 2729 omap_rtc_alarm_update(s); 2730 return; 2731 2732 case 0x28: /* ALARM_HOURS_REG */ 2733 #ifdef ALMDEBUG 2734 printf("ALM HRS_REG <-- %02x\n", value); 2735 #endif 2736 if (s->pm_am) 2737 s->alarm_tm.tm_hour = 2738 ((from_bcd(value & 0x3f)) % 12) + 2739 ((value >> 7) & 1) * 12; 2740 else 2741 s->alarm_tm.tm_hour = from_bcd(value); 2742 omap_rtc_alarm_update(s); 2743 return; 2744 2745 case 0x2c: /* ALARM_DAYS_REG */ 2746 #ifdef ALMDEBUG 2747 printf("ALM DAY_REG <-- %02x\n", value); 2748 #endif 2749 s->alarm_tm.tm_mday = from_bcd(value); 2750 omap_rtc_alarm_update(s); 2751 return; 2752 2753 case 0x30: /* ALARM_MONTHS_REG */ 2754 #ifdef ALMDEBUG 2755 printf("ALM MON_REG <-- %02x\n", value); 2756 #endif 2757 s->alarm_tm.tm_mon = from_bcd(value); 2758 omap_rtc_alarm_update(s); 2759 return; 2760 2761 case 0x34: /* ALARM_YEARS_REG */ 2762 #ifdef ALMDEBUG 2763 printf("ALM YRS_REG <-- %02x\n", value); 2764 #endif 2765 s->alarm_tm.tm_year = from_bcd(value); 2766 omap_rtc_alarm_update(s); 2767 return; 2768 2769 case 0x40: /* RTC_CTRL_REG */ 2770 #ifdef ALMDEBUG 2771 printf("RTC CONTROL <-- %02x\n", value); 2772 #endif 2773 s->pm_am = (value >> 3) & 1; 2774 s->auto_comp = (value >> 2) & 1; 2775 s->round = (value >> 1) & 1; 2776 s->running = value & 1; 2777 s->status &= 0xfd; 2778 s->status |= s->running << 1; 2779 return; 2780 2781 case 0x44: /* RTC_STATUS_REG */ 2782 #ifdef ALMDEBUG 2783 printf("RTC STATUSL <-- %02x\n", value); 2784 #endif 2785 s->status &= ~((value & 0xc0) ^ 0x80); 2786 omap_rtc_interrupts_update(s); 2787 return; 2788 2789 case 0x48: /* RTC_INTERRUPTS_REG */ 2790 #ifdef ALMDEBUG 2791 printf("RTC INTRS <-- %02x\n", value); 2792 #endif 2793 s->interrupts = value; 2794 return; 2795 2796 case 0x4c: /* RTC_COMP_LSB_REG */ 2797 #ifdef ALMDEBUG 2798 printf("RTC COMPLSB <-- %02x\n", value); 2799 #endif 2800 s->comp_reg &= 0xff00; 2801 s->comp_reg |= 0x00ff & value; 2802 return; 2803 2804 case 0x50: /* RTC_COMP_MSB_REG */ 2805 #ifdef ALMDEBUG 2806 printf("RTC COMPMSB <-- %02x\n", value); 2807 #endif 2808 s->comp_reg &= 0x00ff; 2809 s->comp_reg |= 0xff00 & (value << 8); 2810 return; 2811 2812 default: 2813 OMAP_BAD_REG(addr); 2814 return; 2815 } 2816 } 2817 2818 static const MemoryRegionOps omap_rtc_ops = { 2819 .read = omap_rtc_read, 2820 .write = omap_rtc_write, 2821 .endianness = DEVICE_NATIVE_ENDIAN, 2822 }; 2823 2824 static void omap_rtc_tick(void *opaque) 2825 { 2826 struct omap_rtc_s *s = opaque; 2827 2828 if (s->round) { 2829 /* Round to nearest full minute. */ 2830 if (s->current_tm.tm_sec < 30) 2831 s->ti -= s->current_tm.tm_sec; 2832 else 2833 s->ti += 60 - s->current_tm.tm_sec; 2834 2835 s->round = 0; 2836 } 2837 2838 localtime_r(&s->ti, &s->current_tm); 2839 2840 if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) { 2841 s->status |= 0x40; 2842 omap_rtc_interrupts_update(s); 2843 } 2844 2845 if (s->interrupts & 0x04) 2846 switch (s->interrupts & 3) { 2847 case 0: 2848 s->status |= 0x04; 2849 qemu_irq_pulse(s->irq); 2850 break; 2851 case 1: 2852 if (s->current_tm.tm_sec) 2853 break; 2854 s->status |= 0x08; 2855 qemu_irq_pulse(s->irq); 2856 break; 2857 case 2: 2858 if (s->current_tm.tm_sec || s->current_tm.tm_min) 2859 break; 2860 s->status |= 0x10; 2861 qemu_irq_pulse(s->irq); 2862 break; 2863 case 3: 2864 if (s->current_tm.tm_sec || 2865 s->current_tm.tm_min || s->current_tm.tm_hour) 2866 break; 2867 s->status |= 0x20; 2868 qemu_irq_pulse(s->irq); 2869 break; 2870 } 2871 2872 /* Move on */ 2873 if (s->running) 2874 s->ti ++; 2875 s->tick += 1000; 2876 2877 /* 2878 * Every full hour add a rough approximation of the compensation 2879 * register to the 32kHz Timer (which drives the RTC) value. 2880 */ 2881 if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min) 2882 s->tick += s->comp_reg * 1000 / 32768; 2883 2884 timer_mod(s->clk, s->tick); 2885 } 2886 2887 static void omap_rtc_reset(struct omap_rtc_s *s) 2888 { 2889 struct tm tm; 2890 2891 s->interrupts = 0; 2892 s->comp_reg = 0; 2893 s->running = 0; 2894 s->pm_am = 0; 2895 s->auto_comp = 0; 2896 s->round = 0; 2897 s->tick = qemu_clock_get_ms(rtc_clock); 2898 memset(&s->alarm_tm, 0, sizeof(s->alarm_tm)); 2899 s->alarm_tm.tm_mday = 0x01; 2900 s->status = 1 << 7; 2901 qemu_get_timedate(&tm, 0); 2902 s->ti = mktimegm(&tm); 2903 2904 omap_rtc_alarm_update(s); 2905 omap_rtc_tick(s); 2906 } 2907 2908 static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory, 2909 hwaddr base, 2910 qemu_irq timerirq, qemu_irq alarmirq, 2911 omap_clk clk) 2912 { 2913 struct omap_rtc_s *s = (struct omap_rtc_s *) 2914 g_malloc0(sizeof(struct omap_rtc_s)); 2915 2916 s->irq = timerirq; 2917 s->alarm = alarmirq; 2918 s->clk = timer_new_ms(rtc_clock, omap_rtc_tick, s); 2919 2920 omap_rtc_reset(s); 2921 2922 memory_region_init_io(&s->iomem, NULL, &omap_rtc_ops, s, 2923 "omap-rtc", 0x800); 2924 memory_region_add_subregion(system_memory, base, &s->iomem); 2925 2926 return s; 2927 } 2928 2929 /* Multi-channel Buffered Serial Port interfaces */ 2930 struct omap_mcbsp_s { 2931 MemoryRegion iomem; 2932 qemu_irq txirq; 2933 qemu_irq rxirq; 2934 qemu_irq txdrq; 2935 qemu_irq rxdrq; 2936 2937 uint16_t spcr[2]; 2938 uint16_t rcr[2]; 2939 uint16_t xcr[2]; 2940 uint16_t srgr[2]; 2941 uint16_t mcr[2]; 2942 uint16_t pcr; 2943 uint16_t rcer[8]; 2944 uint16_t xcer[8]; 2945 int tx_rate; 2946 int rx_rate; 2947 int tx_req; 2948 int rx_req; 2949 2950 I2SCodec *codec; 2951 QEMUTimer *source_timer; 2952 QEMUTimer *sink_timer; 2953 }; 2954 2955 static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s) 2956 { 2957 int irq; 2958 2959 switch ((s->spcr[0] >> 4) & 3) { /* RINTM */ 2960 case 0: 2961 irq = (s->spcr[0] >> 1) & 1; /* RRDY */ 2962 break; 2963 case 3: 2964 irq = (s->spcr[0] >> 3) & 1; /* RSYNCERR */ 2965 break; 2966 default: 2967 irq = 0; 2968 break; 2969 } 2970 2971 if (irq) 2972 qemu_irq_pulse(s->rxirq); 2973 2974 switch ((s->spcr[1] >> 4) & 3) { /* XINTM */ 2975 case 0: 2976 irq = (s->spcr[1] >> 1) & 1; /* XRDY */ 2977 break; 2978 case 3: 2979 irq = (s->spcr[1] >> 3) & 1; /* XSYNCERR */ 2980 break; 2981 default: 2982 irq = 0; 2983 break; 2984 } 2985 2986 if (irq) 2987 qemu_irq_pulse(s->txirq); 2988 } 2989 2990 static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s) 2991 { 2992 if ((s->spcr[0] >> 1) & 1) /* RRDY */ 2993 s->spcr[0] |= 1 << 2; /* RFULL */ 2994 s->spcr[0] |= 1 << 1; /* RRDY */ 2995 qemu_irq_raise(s->rxdrq); 2996 omap_mcbsp_intr_update(s); 2997 } 2998 2999 static void omap_mcbsp_source_tick(void *opaque) 3000 { 3001 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque; 3002 static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 }; 3003 3004 if (!s->rx_rate) 3005 return; 3006 if (s->rx_req) 3007 printf("%s: Rx FIFO overrun\n", __FUNCTION__); 3008 3009 s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7]; 3010 3011 omap_mcbsp_rx_newdata(s); 3012 timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 3013 get_ticks_per_sec()); 3014 } 3015 3016 static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s) 3017 { 3018 if (!s->codec || !s->codec->rts) 3019 omap_mcbsp_source_tick(s); 3020 else if (s->codec->in.len) { 3021 s->rx_req = s->codec->in.len; 3022 omap_mcbsp_rx_newdata(s); 3023 } 3024 } 3025 3026 static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s) 3027 { 3028 timer_del(s->source_timer); 3029 } 3030 3031 static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s) 3032 { 3033 s->spcr[0] &= ~(1 << 1); /* RRDY */ 3034 qemu_irq_lower(s->rxdrq); 3035 omap_mcbsp_intr_update(s); 3036 } 3037 3038 static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s) 3039 { 3040 s->spcr[1] |= 1 << 1; /* XRDY */ 3041 qemu_irq_raise(s->txdrq); 3042 omap_mcbsp_intr_update(s); 3043 } 3044 3045 static void omap_mcbsp_sink_tick(void *opaque) 3046 { 3047 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque; 3048 static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 }; 3049 3050 if (!s->tx_rate) 3051 return; 3052 if (s->tx_req) 3053 printf("%s: Tx FIFO underrun\n", __FUNCTION__); 3054 3055 s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7]; 3056 3057 omap_mcbsp_tx_newdata(s); 3058 timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 3059 get_ticks_per_sec()); 3060 } 3061 3062 static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s) 3063 { 3064 if (!s->codec || !s->codec->cts) 3065 omap_mcbsp_sink_tick(s); 3066 else if (s->codec->out.size) { 3067 s->tx_req = s->codec->out.size; 3068 omap_mcbsp_tx_newdata(s); 3069 } 3070 } 3071 3072 static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s) 3073 { 3074 s->spcr[1] &= ~(1 << 1); /* XRDY */ 3075 qemu_irq_lower(s->txdrq); 3076 omap_mcbsp_intr_update(s); 3077 if (s->codec && s->codec->cts) 3078 s->codec->tx_swallow(s->codec->opaque); 3079 } 3080 3081 static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s) 3082 { 3083 s->tx_req = 0; 3084 omap_mcbsp_tx_done(s); 3085 timer_del(s->sink_timer); 3086 } 3087 3088 static void omap_mcbsp_req_update(struct omap_mcbsp_s *s) 3089 { 3090 int prev_rx_rate, prev_tx_rate; 3091 int rx_rate = 0, tx_rate = 0; 3092 int cpu_rate = 1500000; /* XXX */ 3093 3094 /* TODO: check CLKSTP bit */ 3095 if (s->spcr[1] & (1 << 6)) { /* GRST */ 3096 if (s->spcr[0] & (1 << 0)) { /* RRST */ 3097 if ((s->srgr[1] & (1 << 13)) && /* CLKSM */ 3098 (s->pcr & (1 << 8))) { /* CLKRM */ 3099 if (~s->pcr & (1 << 7)) /* SCLKME */ 3100 rx_rate = cpu_rate / 3101 ((s->srgr[0] & 0xff) + 1); /* CLKGDV */ 3102 } else 3103 if (s->codec) 3104 rx_rate = s->codec->rx_rate; 3105 } 3106 3107 if (s->spcr[1] & (1 << 0)) { /* XRST */ 3108 if ((s->srgr[1] & (1 << 13)) && /* CLKSM */ 3109 (s->pcr & (1 << 9))) { /* CLKXM */ 3110 if (~s->pcr & (1 << 7)) /* SCLKME */ 3111 tx_rate = cpu_rate / 3112 ((s->srgr[0] & 0xff) + 1); /* CLKGDV */ 3113 } else 3114 if (s->codec) 3115 tx_rate = s->codec->tx_rate; 3116 } 3117 } 3118 prev_tx_rate = s->tx_rate; 3119 prev_rx_rate = s->rx_rate; 3120 s->tx_rate = tx_rate; 3121 s->rx_rate = rx_rate; 3122 3123 if (s->codec) 3124 s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate); 3125 3126 if (!prev_tx_rate && tx_rate) 3127 omap_mcbsp_tx_start(s); 3128 else if (s->tx_rate && !tx_rate) 3129 omap_mcbsp_tx_stop(s); 3130 3131 if (!prev_rx_rate && rx_rate) 3132 omap_mcbsp_rx_start(s); 3133 else if (prev_tx_rate && !tx_rate) 3134 omap_mcbsp_rx_stop(s); 3135 } 3136 3137 static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr, 3138 unsigned size) 3139 { 3140 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque; 3141 int offset = addr & OMAP_MPUI_REG_MASK; 3142 uint16_t ret; 3143 3144 if (size != 2) { 3145 return omap_badwidth_read16(opaque, addr); 3146 } 3147 3148 switch (offset) { 3149 case 0x00: /* DRR2 */ 3150 if (((s->rcr[0] >> 5) & 7) < 3) /* RWDLEN1 */ 3151 return 0x0000; 3152 /* Fall through. */ 3153 case 0x02: /* DRR1 */ 3154 if (s->rx_req < 2) { 3155 printf("%s: Rx FIFO underrun\n", __FUNCTION__); 3156 omap_mcbsp_rx_done(s); 3157 } else { 3158 s->tx_req -= 2; 3159 if (s->codec && s->codec->in.len >= 2) { 3160 ret = s->codec->in.fifo[s->codec->in.start ++] << 8; 3161 ret |= s->codec->in.fifo[s->codec->in.start ++]; 3162 s->codec->in.len -= 2; 3163 } else 3164 ret = 0x0000; 3165 if (!s->tx_req) 3166 omap_mcbsp_rx_done(s); 3167 return ret; 3168 } 3169 return 0x0000; 3170 3171 case 0x04: /* DXR2 */ 3172 case 0x06: /* DXR1 */ 3173 return 0x0000; 3174 3175 case 0x08: /* SPCR2 */ 3176 return s->spcr[1]; 3177 case 0x0a: /* SPCR1 */ 3178 return s->spcr[0]; 3179 case 0x0c: /* RCR2 */ 3180 return s->rcr[1]; 3181 case 0x0e: /* RCR1 */ 3182 return s->rcr[0]; 3183 case 0x10: /* XCR2 */ 3184 return s->xcr[1]; 3185 case 0x12: /* XCR1 */ 3186 return s->xcr[0]; 3187 case 0x14: /* SRGR2 */ 3188 return s->srgr[1]; 3189 case 0x16: /* SRGR1 */ 3190 return s->srgr[0]; 3191 case 0x18: /* MCR2 */ 3192 return s->mcr[1]; 3193 case 0x1a: /* MCR1 */ 3194 return s->mcr[0]; 3195 case 0x1c: /* RCERA */ 3196 return s->rcer[0]; 3197 case 0x1e: /* RCERB */ 3198 return s->rcer[1]; 3199 case 0x20: /* XCERA */ 3200 return s->xcer[0]; 3201 case 0x22: /* XCERB */ 3202 return s->xcer[1]; 3203 case 0x24: /* PCR0 */ 3204 return s->pcr; 3205 case 0x26: /* RCERC */ 3206 return s->rcer[2]; 3207 case 0x28: /* RCERD */ 3208 return s->rcer[3]; 3209 case 0x2a: /* XCERC */ 3210 return s->xcer[2]; 3211 case 0x2c: /* XCERD */ 3212 return s->xcer[3]; 3213 case 0x2e: /* RCERE */ 3214 return s->rcer[4]; 3215 case 0x30: /* RCERF */ 3216 return s->rcer[5]; 3217 case 0x32: /* XCERE */ 3218 return s->xcer[4]; 3219 case 0x34: /* XCERF */ 3220 return s->xcer[5]; 3221 case 0x36: /* RCERG */ 3222 return s->rcer[6]; 3223 case 0x38: /* RCERH */ 3224 return s->rcer[7]; 3225 case 0x3a: /* XCERG */ 3226 return s->xcer[6]; 3227 case 0x3c: /* XCERH */ 3228 return s->xcer[7]; 3229 } 3230 3231 OMAP_BAD_REG(addr); 3232 return 0; 3233 } 3234 3235 static void omap_mcbsp_writeh(void *opaque, hwaddr addr, 3236 uint32_t value) 3237 { 3238 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque; 3239 int offset = addr & OMAP_MPUI_REG_MASK; 3240 3241 switch (offset) { 3242 case 0x00: /* DRR2 */ 3243 case 0x02: /* DRR1 */ 3244 OMAP_RO_REG(addr); 3245 return; 3246 3247 case 0x04: /* DXR2 */ 3248 if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */ 3249 return; 3250 /* Fall through. */ 3251 case 0x06: /* DXR1 */ 3252 if (s->tx_req > 1) { 3253 s->tx_req -= 2; 3254 if (s->codec && s->codec->cts) { 3255 s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff; 3256 s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff; 3257 } 3258 if (s->tx_req < 2) 3259 omap_mcbsp_tx_done(s); 3260 } else 3261 printf("%s: Tx FIFO overrun\n", __FUNCTION__); 3262 return; 3263 3264 case 0x08: /* SPCR2 */ 3265 s->spcr[1] &= 0x0002; 3266 s->spcr[1] |= 0x03f9 & value; 3267 s->spcr[1] |= 0x0004 & (value << 2); /* XEMPTY := XRST */ 3268 if (~value & 1) /* XRST */ 3269 s->spcr[1] &= ~6; 3270 omap_mcbsp_req_update(s); 3271 return; 3272 case 0x0a: /* SPCR1 */ 3273 s->spcr[0] &= 0x0006; 3274 s->spcr[0] |= 0xf8f9 & value; 3275 if (value & (1 << 15)) /* DLB */ 3276 printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__); 3277 if (~value & 1) { /* RRST */ 3278 s->spcr[0] &= ~6; 3279 s->rx_req = 0; 3280 omap_mcbsp_rx_done(s); 3281 } 3282 omap_mcbsp_req_update(s); 3283 return; 3284 3285 case 0x0c: /* RCR2 */ 3286 s->rcr[1] = value & 0xffff; 3287 return; 3288 case 0x0e: /* RCR1 */ 3289 s->rcr[0] = value & 0x7fe0; 3290 return; 3291 case 0x10: /* XCR2 */ 3292 s->xcr[1] = value & 0xffff; 3293 return; 3294 case 0x12: /* XCR1 */ 3295 s->xcr[0] = value & 0x7fe0; 3296 return; 3297 case 0x14: /* SRGR2 */ 3298 s->srgr[1] = value & 0xffff; 3299 omap_mcbsp_req_update(s); 3300 return; 3301 case 0x16: /* SRGR1 */ 3302 s->srgr[0] = value & 0xffff; 3303 omap_mcbsp_req_update(s); 3304 return; 3305 case 0x18: /* MCR2 */ 3306 s->mcr[1] = value & 0x03e3; 3307 if (value & 3) /* XMCM */ 3308 printf("%s: Tx channel selection mode enable attempt\n", 3309 __FUNCTION__); 3310 return; 3311 case 0x1a: /* MCR1 */ 3312 s->mcr[0] = value & 0x03e1; 3313 if (value & 1) /* RMCM */ 3314 printf("%s: Rx channel selection mode enable attempt\n", 3315 __FUNCTION__); 3316 return; 3317 case 0x1c: /* RCERA */ 3318 s->rcer[0] = value & 0xffff; 3319 return; 3320 case 0x1e: /* RCERB */ 3321 s->rcer[1] = value & 0xffff; 3322 return; 3323 case 0x20: /* XCERA */ 3324 s->xcer[0] = value & 0xffff; 3325 return; 3326 case 0x22: /* XCERB */ 3327 s->xcer[1] = value & 0xffff; 3328 return; 3329 case 0x24: /* PCR0 */ 3330 s->pcr = value & 0x7faf; 3331 return; 3332 case 0x26: /* RCERC */ 3333 s->rcer[2] = value & 0xffff; 3334 return; 3335 case 0x28: /* RCERD */ 3336 s->rcer[3] = value & 0xffff; 3337 return; 3338 case 0x2a: /* XCERC */ 3339 s->xcer[2] = value & 0xffff; 3340 return; 3341 case 0x2c: /* XCERD */ 3342 s->xcer[3] = value & 0xffff; 3343 return; 3344 case 0x2e: /* RCERE */ 3345 s->rcer[4] = value & 0xffff; 3346 return; 3347 case 0x30: /* RCERF */ 3348 s->rcer[5] = value & 0xffff; 3349 return; 3350 case 0x32: /* XCERE */ 3351 s->xcer[4] = value & 0xffff; 3352 return; 3353 case 0x34: /* XCERF */ 3354 s->xcer[5] = value & 0xffff; 3355 return; 3356 case 0x36: /* RCERG */ 3357 s->rcer[6] = value & 0xffff; 3358 return; 3359 case 0x38: /* RCERH */ 3360 s->rcer[7] = value & 0xffff; 3361 return; 3362 case 0x3a: /* XCERG */ 3363 s->xcer[6] = value & 0xffff; 3364 return; 3365 case 0x3c: /* XCERH */ 3366 s->xcer[7] = value & 0xffff; 3367 return; 3368 } 3369 3370 OMAP_BAD_REG(addr); 3371 } 3372 3373 static void omap_mcbsp_writew(void *opaque, hwaddr addr, 3374 uint32_t value) 3375 { 3376 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque; 3377 int offset = addr & OMAP_MPUI_REG_MASK; 3378 3379 if (offset == 0x04) { /* DXR */ 3380 if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */ 3381 return; 3382 if (s->tx_req > 3) { 3383 s->tx_req -= 4; 3384 if (s->codec && s->codec->cts) { 3385 s->codec->out.fifo[s->codec->out.len ++] = 3386 (value >> 24) & 0xff; 3387 s->codec->out.fifo[s->codec->out.len ++] = 3388 (value >> 16) & 0xff; 3389 s->codec->out.fifo[s->codec->out.len ++] = 3390 (value >> 8) & 0xff; 3391 s->codec->out.fifo[s->codec->out.len ++] = 3392 (value >> 0) & 0xff; 3393 } 3394 if (s->tx_req < 4) 3395 omap_mcbsp_tx_done(s); 3396 } else 3397 printf("%s: Tx FIFO overrun\n", __FUNCTION__); 3398 return; 3399 } 3400 3401 omap_badwidth_write16(opaque, addr, value); 3402 } 3403 3404 static void omap_mcbsp_write(void *opaque, hwaddr addr, 3405 uint64_t value, unsigned size) 3406 { 3407 switch (size) { 3408 case 2: return omap_mcbsp_writeh(opaque, addr, value); 3409 case 4: return omap_mcbsp_writew(opaque, addr, value); 3410 default: return omap_badwidth_write16(opaque, addr, value); 3411 } 3412 } 3413 3414 static const MemoryRegionOps omap_mcbsp_ops = { 3415 .read = omap_mcbsp_read, 3416 .write = omap_mcbsp_write, 3417 .endianness = DEVICE_NATIVE_ENDIAN, 3418 }; 3419 3420 static void omap_mcbsp_reset(struct omap_mcbsp_s *s) 3421 { 3422 memset(&s->spcr, 0, sizeof(s->spcr)); 3423 memset(&s->rcr, 0, sizeof(s->rcr)); 3424 memset(&s->xcr, 0, sizeof(s->xcr)); 3425 s->srgr[0] = 0x0001; 3426 s->srgr[1] = 0x2000; 3427 memset(&s->mcr, 0, sizeof(s->mcr)); 3428 memset(&s->pcr, 0, sizeof(s->pcr)); 3429 memset(&s->rcer, 0, sizeof(s->rcer)); 3430 memset(&s->xcer, 0, sizeof(s->xcer)); 3431 s->tx_req = 0; 3432 s->rx_req = 0; 3433 s->tx_rate = 0; 3434 s->rx_rate = 0; 3435 timer_del(s->source_timer); 3436 timer_del(s->sink_timer); 3437 } 3438 3439 static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory, 3440 hwaddr base, 3441 qemu_irq txirq, qemu_irq rxirq, 3442 qemu_irq *dma, omap_clk clk) 3443 { 3444 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) 3445 g_malloc0(sizeof(struct omap_mcbsp_s)); 3446 3447 s->txirq = txirq; 3448 s->rxirq = rxirq; 3449 s->txdrq = dma[0]; 3450 s->rxdrq = dma[1]; 3451 s->sink_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_sink_tick, s); 3452 s->source_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_source_tick, s); 3453 omap_mcbsp_reset(s); 3454 3455 memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800); 3456 memory_region_add_subregion(system_memory, base, &s->iomem); 3457 3458 return s; 3459 } 3460 3461 static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level) 3462 { 3463 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque; 3464 3465 if (s->rx_rate) { 3466 s->rx_req = s->codec->in.len; 3467 omap_mcbsp_rx_newdata(s); 3468 } 3469 } 3470 3471 static void omap_mcbsp_i2s_start(void *opaque, int line, int level) 3472 { 3473 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque; 3474 3475 if (s->tx_rate) { 3476 s->tx_req = s->codec->out.size; 3477 omap_mcbsp_tx_newdata(s); 3478 } 3479 } 3480 3481 void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave) 3482 { 3483 s->codec = slave; 3484 slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0]; 3485 slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0]; 3486 } 3487 3488 /* LED Pulse Generators */ 3489 struct omap_lpg_s { 3490 MemoryRegion iomem; 3491 QEMUTimer *tm; 3492 3493 uint8_t control; 3494 uint8_t power; 3495 int64_t on; 3496 int64_t period; 3497 int clk; 3498 int cycle; 3499 }; 3500 3501 static void omap_lpg_tick(void *opaque) 3502 { 3503 struct omap_lpg_s *s = opaque; 3504 3505 if (s->cycle) 3506 timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->period - s->on); 3507 else 3508 timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on); 3509 3510 s->cycle = !s->cycle; 3511 printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off"); 3512 } 3513 3514 static void omap_lpg_update(struct omap_lpg_s *s) 3515 { 3516 int64_t on, period = 1, ticks = 1000; 3517 static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 }; 3518 3519 if (~s->control & (1 << 6)) /* LPGRES */ 3520 on = 0; 3521 else if (s->control & (1 << 7)) /* PERM_ON */ 3522 on = period; 3523 else { 3524 period = muldiv64(ticks, per[s->control & 7], /* PERCTRL */ 3525 256 / 32); 3526 on = (s->clk && s->power) ? muldiv64(ticks, 3527 per[(s->control >> 3) & 7], 256) : 0; /* ONCTRL */ 3528 } 3529 3530 timer_del(s->tm); 3531 if (on == period && s->on < s->period) 3532 printf("%s: LED is on\n", __FUNCTION__); 3533 else if (on == 0 && s->on) 3534 printf("%s: LED is off\n", __FUNCTION__); 3535 else if (on && (on != s->on || period != s->period)) { 3536 s->cycle = 0; 3537 s->on = on; 3538 s->period = period; 3539 omap_lpg_tick(s); 3540 return; 3541 } 3542 3543 s->on = on; 3544 s->period = period; 3545 } 3546 3547 static void omap_lpg_reset(struct omap_lpg_s *s) 3548 { 3549 s->control = 0x00; 3550 s->power = 0x00; 3551 s->clk = 1; 3552 omap_lpg_update(s); 3553 } 3554 3555 static uint64_t omap_lpg_read(void *opaque, hwaddr addr, 3556 unsigned size) 3557 { 3558 struct omap_lpg_s *s = (struct omap_lpg_s *) opaque; 3559 int offset = addr & OMAP_MPUI_REG_MASK; 3560 3561 if (size != 1) { 3562 return omap_badwidth_read8(opaque, addr); 3563 } 3564 3565 switch (offset) { 3566 case 0x00: /* LCR */ 3567 return s->control; 3568 3569 case 0x04: /* PMR */ 3570 return s->power; 3571 } 3572 3573 OMAP_BAD_REG(addr); 3574 return 0; 3575 } 3576 3577 static void omap_lpg_write(void *opaque, hwaddr addr, 3578 uint64_t value, unsigned size) 3579 { 3580 struct omap_lpg_s *s = (struct omap_lpg_s *) opaque; 3581 int offset = addr & OMAP_MPUI_REG_MASK; 3582 3583 if (size != 1) { 3584 return omap_badwidth_write8(opaque, addr, value); 3585 } 3586 3587 switch (offset) { 3588 case 0x00: /* LCR */ 3589 if (~value & (1 << 6)) /* LPGRES */ 3590 omap_lpg_reset(s); 3591 s->control = value & 0xff; 3592 omap_lpg_update(s); 3593 return; 3594 3595 case 0x04: /* PMR */ 3596 s->power = value & 0x01; 3597 omap_lpg_update(s); 3598 return; 3599 3600 default: 3601 OMAP_BAD_REG(addr); 3602 return; 3603 } 3604 } 3605 3606 static const MemoryRegionOps omap_lpg_ops = { 3607 .read = omap_lpg_read, 3608 .write = omap_lpg_write, 3609 .endianness = DEVICE_NATIVE_ENDIAN, 3610 }; 3611 3612 static void omap_lpg_clk_update(void *opaque, int line, int on) 3613 { 3614 struct omap_lpg_s *s = (struct omap_lpg_s *) opaque; 3615 3616 s->clk = on; 3617 omap_lpg_update(s); 3618 } 3619 3620 static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory, 3621 hwaddr base, omap_clk clk) 3622 { 3623 struct omap_lpg_s *s = (struct omap_lpg_s *) 3624 g_malloc0(sizeof(struct omap_lpg_s)); 3625 3626 s->tm = timer_new_ms(QEMU_CLOCK_VIRTUAL, omap_lpg_tick, s); 3627 3628 omap_lpg_reset(s); 3629 3630 memory_region_init_io(&s->iomem, NULL, &omap_lpg_ops, s, "omap-lpg", 0x800); 3631 memory_region_add_subregion(system_memory, base, &s->iomem); 3632 3633 omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]); 3634 3635 return s; 3636 } 3637 3638 /* MPUI Peripheral Bridge configuration */ 3639 static uint64_t omap_mpui_io_read(void *opaque, hwaddr addr, 3640 unsigned size) 3641 { 3642 if (size != 2) { 3643 return omap_badwidth_read16(opaque, addr); 3644 } 3645 3646 if (addr == OMAP_MPUI_BASE) /* CMR */ 3647 return 0xfe4d; 3648 3649 OMAP_BAD_REG(addr); 3650 return 0; 3651 } 3652 3653 static void omap_mpui_io_write(void *opaque, hwaddr addr, 3654 uint64_t value, unsigned size) 3655 { 3656 /* FIXME: infinite loop */ 3657 omap_badwidth_write16(opaque, addr, value); 3658 } 3659 3660 static const MemoryRegionOps omap_mpui_io_ops = { 3661 .read = omap_mpui_io_read, 3662 .write = omap_mpui_io_write, 3663 .endianness = DEVICE_NATIVE_ENDIAN, 3664 }; 3665 3666 static void omap_setup_mpui_io(MemoryRegion *system_memory, 3667 struct omap_mpu_state_s *mpu) 3668 { 3669 memory_region_init_io(&mpu->mpui_io_iomem, NULL, &omap_mpui_io_ops, mpu, 3670 "omap-mpui-io", 0x7fff); 3671 memory_region_add_subregion(system_memory, OMAP_MPUI_BASE, 3672 &mpu->mpui_io_iomem); 3673 } 3674 3675 /* General chip reset */ 3676 static void omap1_mpu_reset(void *opaque) 3677 { 3678 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque; 3679 3680 omap_dma_reset(mpu->dma); 3681 omap_mpu_timer_reset(mpu->timer[0]); 3682 omap_mpu_timer_reset(mpu->timer[1]); 3683 omap_mpu_timer_reset(mpu->timer[2]); 3684 omap_wd_timer_reset(mpu->wdt); 3685 omap_os_timer_reset(mpu->os_timer); 3686 omap_lcdc_reset(mpu->lcd); 3687 omap_ulpd_pm_reset(mpu); 3688 omap_pin_cfg_reset(mpu); 3689 omap_mpui_reset(mpu); 3690 omap_tipb_bridge_reset(mpu->private_tipb); 3691 omap_tipb_bridge_reset(mpu->public_tipb); 3692 omap_dpll_reset(mpu->dpll[0]); 3693 omap_dpll_reset(mpu->dpll[1]); 3694 omap_dpll_reset(mpu->dpll[2]); 3695 omap_uart_reset(mpu->uart[0]); 3696 omap_uart_reset(mpu->uart[1]); 3697 omap_uart_reset(mpu->uart[2]); 3698 omap_mmc_reset(mpu->mmc); 3699 omap_mpuio_reset(mpu->mpuio); 3700 omap_uwire_reset(mpu->microwire); 3701 omap_pwl_reset(mpu->pwl); 3702 omap_pwt_reset(mpu->pwt); 3703 omap_rtc_reset(mpu->rtc); 3704 omap_mcbsp_reset(mpu->mcbsp1); 3705 omap_mcbsp_reset(mpu->mcbsp2); 3706 omap_mcbsp_reset(mpu->mcbsp3); 3707 omap_lpg_reset(mpu->led[0]); 3708 omap_lpg_reset(mpu->led[1]); 3709 omap_clkm_reset(mpu); 3710 cpu_reset(CPU(mpu->cpu)); 3711 } 3712 3713 static const struct omap_map_s { 3714 hwaddr phys_dsp; 3715 hwaddr phys_mpu; 3716 uint32_t size; 3717 const char *name; 3718 } omap15xx_dsp_mm[] = { 3719 /* Strobe 0 */ 3720 { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" }, /* CS0 */ 3721 { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" }, /* CS1 */ 3722 { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" }, /* CS3 */ 3723 { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" }, /* CS4 */ 3724 { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" }, /* CS5 */ 3725 { 0xe1013000, 0xfffb3000, 0x800, "uWire" }, /* CS6 */ 3726 { 0xe1013800, 0xfffb3800, 0x800, "I^2C" }, /* CS7 */ 3727 { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" }, /* CS8 */ 3728 { 0xe1014800, 0xfffb4800, 0x800, "RTC" }, /* CS9 */ 3729 { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" }, /* CS10 */ 3730 { 0xe1015800, 0xfffb5800, 0x800, "PWL" }, /* CS11 */ 3731 { 0xe1016000, 0xfffb6000, 0x800, "PWT" }, /* CS12 */ 3732 { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" }, /* CS14 */ 3733 { 0xe1017800, 0xfffb7800, 0x800, "MMC" }, /* CS15 */ 3734 { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" }, /* CS18 */ 3735 { 0xe1019800, 0xfffb9800, 0x800, "UART3" }, /* CS19 */ 3736 { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" }, /* CS25 */ 3737 /* Strobe 1 */ 3738 { 0xe101e000, 0xfffce000, 0x800, "GPIOs" }, /* CS28 */ 3739 3740 { 0 } 3741 }; 3742 3743 static void omap_setup_dsp_mapping(MemoryRegion *system_memory, 3744 const struct omap_map_s *map) 3745 { 3746 MemoryRegion *io; 3747 3748 for (; map->phys_dsp; map ++) { 3749 io = g_new(MemoryRegion, 1); 3750 memory_region_init_alias(io, NULL, map->name, 3751 system_memory, map->phys_mpu, map->size); 3752 memory_region_add_subregion(system_memory, map->phys_dsp, io); 3753 } 3754 } 3755 3756 void omap_mpu_wakeup(void *opaque, int irq, int req) 3757 { 3758 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque; 3759 CPUState *cpu = CPU(mpu->cpu); 3760 3761 if (cpu->halted) { 3762 cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB); 3763 } 3764 } 3765 3766 static const struct dma_irq_map omap1_dma_irq_map[] = { 3767 { 0, OMAP_INT_DMA_CH0_6 }, 3768 { 0, OMAP_INT_DMA_CH1_7 }, 3769 { 0, OMAP_INT_DMA_CH2_8 }, 3770 { 0, OMAP_INT_DMA_CH3 }, 3771 { 0, OMAP_INT_DMA_CH4 }, 3772 { 0, OMAP_INT_DMA_CH5 }, 3773 { 1, OMAP_INT_1610_DMA_CH6 }, 3774 { 1, OMAP_INT_1610_DMA_CH7 }, 3775 { 1, OMAP_INT_1610_DMA_CH8 }, 3776 { 1, OMAP_INT_1610_DMA_CH9 }, 3777 { 1, OMAP_INT_1610_DMA_CH10 }, 3778 { 1, OMAP_INT_1610_DMA_CH11 }, 3779 { 1, OMAP_INT_1610_DMA_CH12 }, 3780 { 1, OMAP_INT_1610_DMA_CH13 }, 3781 { 1, OMAP_INT_1610_DMA_CH14 }, 3782 { 1, OMAP_INT_1610_DMA_CH15 } 3783 }; 3784 3785 /* DMA ports for OMAP1 */ 3786 static int omap_validate_emiff_addr(struct omap_mpu_state_s *s, 3787 hwaddr addr) 3788 { 3789 return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr); 3790 } 3791 3792 static int omap_validate_emifs_addr(struct omap_mpu_state_s *s, 3793 hwaddr addr) 3794 { 3795 return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE, 3796 addr); 3797 } 3798 3799 static int omap_validate_imif_addr(struct omap_mpu_state_s *s, 3800 hwaddr addr) 3801 { 3802 return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr); 3803 } 3804 3805 static int omap_validate_tipb_addr(struct omap_mpu_state_s *s, 3806 hwaddr addr) 3807 { 3808 return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr); 3809 } 3810 3811 static int omap_validate_local_addr(struct omap_mpu_state_s *s, 3812 hwaddr addr) 3813 { 3814 return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr); 3815 } 3816 3817 static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s, 3818 hwaddr addr) 3819 { 3820 return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr); 3821 } 3822 3823 struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory, 3824 unsigned long sdram_size, 3825 const char *core) 3826 { 3827 int i; 3828 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) 3829 g_malloc0(sizeof(struct omap_mpu_state_s)); 3830 qemu_irq dma_irqs[6]; 3831 DriveInfo *dinfo; 3832 SysBusDevice *busdev; 3833 3834 if (!core) 3835 core = "ti925t"; 3836 3837 /* Core */ 3838 s->mpu_model = omap310; 3839 s->cpu = cpu_arm_init(core); 3840 if (s->cpu == NULL) { 3841 fprintf(stderr, "Unable to find CPU definition\n"); 3842 exit(1); 3843 } 3844 s->sdram_size = sdram_size; 3845 s->sram_size = OMAP15XX_SRAM_SIZE; 3846 3847 s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0]; 3848 3849 /* Clocks */ 3850 omap_clk_init(s); 3851 3852 /* Memory-mapped stuff */ 3853 memory_region_init_ram(&s->emiff_ram, NULL, "omap1.dram", s->sdram_size); 3854 vmstate_register_ram_global(&s->emiff_ram); 3855 memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram); 3856 memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size); 3857 vmstate_register_ram_global(&s->imif_ram); 3858 memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram); 3859 3860 omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s); 3861 3862 s->ih[0] = qdev_create(NULL, "omap-intc"); 3863 qdev_prop_set_uint32(s->ih[0], "size", 0x100); 3864 qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck")); 3865 qdev_init_nofail(s->ih[0]); 3866 busdev = SYS_BUS_DEVICE(s->ih[0]); 3867 sysbus_connect_irq(busdev, 0, 3868 qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); 3869 sysbus_connect_irq(busdev, 1, 3870 qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ)); 3871 sysbus_mmio_map(busdev, 0, 0xfffecb00); 3872 s->ih[1] = qdev_create(NULL, "omap-intc"); 3873 qdev_prop_set_uint32(s->ih[1], "size", 0x800); 3874 qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck")); 3875 qdev_init_nofail(s->ih[1]); 3876 busdev = SYS_BUS_DEVICE(s->ih[1]); 3877 sysbus_connect_irq(busdev, 0, 3878 qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ)); 3879 /* The second interrupt controller's FIQ output is not wired up */ 3880 sysbus_mmio_map(busdev, 0, 0xfffe0000); 3881 3882 for (i = 0; i < 6; i++) { 3883 dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih], 3884 omap1_dma_irq_map[i].intr); 3885 } 3886 s->dma = omap_dma_init(0xfffed800, dma_irqs, system_memory, 3887 qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD), 3888 s, omap_findclk(s, "dma_ck"), omap_dma_3_1); 3889 3890 s->port[emiff ].addr_valid = omap_validate_emiff_addr; 3891 s->port[emifs ].addr_valid = omap_validate_emifs_addr; 3892 s->port[imif ].addr_valid = omap_validate_imif_addr; 3893 s->port[tipb ].addr_valid = omap_validate_tipb_addr; 3894 s->port[local ].addr_valid = omap_validate_local_addr; 3895 s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr; 3896 3897 /* Register SDRAM and SRAM DMA ports for fast transfers. */ 3898 soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->emiff_ram), 3899 OMAP_EMIFF_BASE, s->sdram_size); 3900 soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram), 3901 OMAP_IMIF_BASE, s->sram_size); 3902 3903 s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500, 3904 qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1), 3905 omap_findclk(s, "mputim_ck")); 3906 s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600, 3907 qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2), 3908 omap_findclk(s, "mputim_ck")); 3909 s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700, 3910 qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3), 3911 omap_findclk(s, "mputim_ck")); 3912 3913 s->wdt = omap_wd_timer_init(system_memory, 0xfffec800, 3914 qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER), 3915 omap_findclk(s, "armwdt_ck")); 3916 3917 s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000, 3918 qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER), 3919 omap_findclk(s, "clk32-kHz")); 3920 3921 s->lcd = omap_lcdc_init(system_memory, 0xfffec000, 3922 qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL), 3923 omap_dma_get_lcdch(s->dma), 3924 omap_findclk(s, "lcd_ck")); 3925 3926 omap_ulpd_pm_init(system_memory, 0xfffe0800, s); 3927 omap_pin_cfg_init(system_memory, 0xfffe1000, s); 3928 omap_id_init(system_memory, s); 3929 3930 omap_mpui_init(system_memory, 0xfffec900, s); 3931 3932 s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00, 3933 qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV), 3934 omap_findclk(s, "tipb_ck")); 3935 s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300, 3936 qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB), 3937 omap_findclk(s, "tipb_ck")); 3938 3939 omap_tcmi_init(system_memory, 0xfffecc00, s); 3940 3941 s->uart[0] = omap_uart_init(0xfffb0000, 3942 qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1), 3943 omap_findclk(s, "uart1_ck"), 3944 omap_findclk(s, "uart1_ck"), 3945 s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX], 3946 "uart1", 3947 serial_hds[0]); 3948 s->uart[1] = omap_uart_init(0xfffb0800, 3949 qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2), 3950 omap_findclk(s, "uart2_ck"), 3951 omap_findclk(s, "uart2_ck"), 3952 s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX], 3953 "uart2", 3954 serial_hds[0] ? serial_hds[1] : NULL); 3955 s->uart[2] = omap_uart_init(0xfffb9800, 3956 qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3), 3957 omap_findclk(s, "uart3_ck"), 3958 omap_findclk(s, "uart3_ck"), 3959 s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX], 3960 "uart3", 3961 serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL); 3962 3963 s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00, 3964 omap_findclk(s, "dpll1")); 3965 s->dpll[1] = omap_dpll_init(system_memory, 0xfffed000, 3966 omap_findclk(s, "dpll2")); 3967 s->dpll[2] = omap_dpll_init(system_memory, 0xfffed100, 3968 omap_findclk(s, "dpll3")); 3969 3970 dinfo = drive_get(IF_SD, 0, 0); 3971 if (!dinfo) { 3972 fprintf(stderr, "qemu: missing SecureDigital device\n"); 3973 exit(1); 3974 } 3975 s->mmc = omap_mmc_init(0xfffb7800, system_memory, dinfo->bdrv, 3976 qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN), 3977 &s->drq[OMAP_DMA_MMC_TX], 3978 omap_findclk(s, "mmc_ck")); 3979 3980 s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000, 3981 qdev_get_gpio_in(s->ih[1], OMAP_INT_KEYBOARD), 3982 qdev_get_gpio_in(s->ih[1], OMAP_INT_MPUIO), 3983 s->wakeup, omap_findclk(s, "clk32-kHz")); 3984 3985 s->gpio = qdev_create(NULL, "omap-gpio"); 3986 qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model); 3987 qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck")); 3988 qdev_init_nofail(s->gpio); 3989 sysbus_connect_irq(SYS_BUS_DEVICE(s->gpio), 0, 3990 qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1)); 3991 sysbus_mmio_map(SYS_BUS_DEVICE(s->gpio), 0, 0xfffce000); 3992 3993 s->microwire = omap_uwire_init(system_memory, 0xfffb3000, 3994 qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireTX), 3995 qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireRX), 3996 s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck")); 3997 3998 s->pwl = omap_pwl_init(system_memory, 0xfffb5800, 3999 omap_findclk(s, "armxor_ck")); 4000 s->pwt = omap_pwt_init(system_memory, 0xfffb6000, 4001 omap_findclk(s, "armxor_ck")); 4002 4003 s->i2c[0] = qdev_create(NULL, "omap_i2c"); 4004 qdev_prop_set_uint8(s->i2c[0], "revision", 0x11); 4005 qdev_prop_set_ptr(s->i2c[0], "fclk", omap_findclk(s, "mpuper_ck")); 4006 qdev_init_nofail(s->i2c[0]); 4007 busdev = SYS_BUS_DEVICE(s->i2c[0]); 4008 sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C)); 4009 sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_I2C_TX]); 4010 sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_I2C_RX]); 4011 sysbus_mmio_map(busdev, 0, 0xfffb3800); 4012 4013 s->rtc = omap_rtc_init(system_memory, 0xfffb4800, 4014 qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER), 4015 qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM), 4016 omap_findclk(s, "clk32-kHz")); 4017 4018 s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800, 4019 qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX), 4020 qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX), 4021 &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck")); 4022 s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000, 4023 qdev_get_gpio_in(s->ih[0], 4024 OMAP_INT_310_McBSP2_TX), 4025 qdev_get_gpio_in(s->ih[0], 4026 OMAP_INT_310_McBSP2_RX), 4027 &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck")); 4028 s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000, 4029 qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX), 4030 qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX), 4031 &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck")); 4032 4033 s->led[0] = omap_lpg_init(system_memory, 4034 0xfffbd000, omap_findclk(s, "clk32-kHz")); 4035 s->led[1] = omap_lpg_init(system_memory, 4036 0xfffbd800, omap_findclk(s, "clk32-kHz")); 4037 4038 /* Register mappings not currenlty implemented: 4039 * MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310) 4040 * MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310) 4041 * USB W2FC fffb4000 - fffb47ff 4042 * Camera Interface fffb6800 - fffb6fff 4043 * USB Host fffba000 - fffba7ff 4044 * FAC fffba800 - fffbafff 4045 * HDQ/1-Wire fffbc000 - fffbc7ff 4046 * TIPB switches fffbc800 - fffbcfff 4047 * Mailbox fffcf000 - fffcf7ff 4048 * Local bus IF fffec100 - fffec1ff 4049 * Local bus MMU fffec200 - fffec2ff 4050 * DSP MMU fffed200 - fffed2ff 4051 */ 4052 4053 omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm); 4054 omap_setup_mpui_io(system_memory, s); 4055 4056 qemu_register_reset(omap1_mpu_reset, s); 4057 4058 return s; 4059 } 4060