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