|
|
1.1 ! root 1: /* ! 2: * TI OMAP2 32kHz sync timer emulation. ! 3: * ! 4: * Copyright (C) 2007-2008 Nokia Corporation ! 5: * Written by Andrzej Zaborowski <[email protected]> ! 6: * ! 7: * This program is free software; you can redistribute it and/or ! 8: * modify it under the terms of the GNU General Public License as ! 9: * published by the Free Software Foundation; either version 2 or ! 10: * (at your option) any later version of the License. ! 11: * ! 12: * This program is distributed in the hope that it will be useful, ! 13: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: * GNU General Public License for more details. ! 16: * ! 17: * You should have received a copy of the GNU General Public License along ! 18: * with this program; if not, see <http://www.gnu.org/licenses/>. ! 19: */ ! 20: #include "hw.h" ! 21: #include "qemu-timer.h" ! 22: #include "omap.h" ! 23: struct omap_synctimer_s { ! 24: uint32_t val; ! 25: uint16_t readh; ! 26: }; ! 27: ! 28: /* 32-kHz Sync Timer of the OMAP2 */ ! 29: static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) { ! 30: return muldiv64(qemu_get_clock(vm_clock), 0x8000, get_ticks_per_sec()); ! 31: } ! 32: ! 33: void omap_synctimer_reset(struct omap_synctimer_s *s) ! 34: { ! 35: s->val = omap_synctimer_read(s); ! 36: } ! 37: ! 38: static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr) ! 39: { ! 40: struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque; ! 41: ! 42: switch (addr) { ! 43: case 0x00: /* 32KSYNCNT_REV */ ! 44: return 0x21; ! 45: ! 46: case 0x10: /* CR */ ! 47: return omap_synctimer_read(s) - s->val; ! 48: } ! 49: ! 50: OMAP_BAD_REG(addr); ! 51: return 0; ! 52: } ! 53: ! 54: static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr) ! 55: { ! 56: struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque; ! 57: uint32_t ret; ! 58: ! 59: if (addr & 2) ! 60: return s->readh; ! 61: else { ! 62: ret = omap_synctimer_readw(opaque, addr); ! 63: s->readh = ret >> 16; ! 64: return ret & 0xffff; ! 65: } ! 66: } ! 67: ! 68: static CPUReadMemoryFunc * const omap_synctimer_readfn[] = { ! 69: omap_badwidth_read32, ! 70: omap_synctimer_readh, ! 71: omap_synctimer_readw, ! 72: }; ! 73: ! 74: static void omap_synctimer_write(void *opaque, target_phys_addr_t addr, ! 75: uint32_t value) ! 76: { ! 77: OMAP_BAD_REG(addr); ! 78: } ! 79: ! 80: static CPUWriteMemoryFunc * const omap_synctimer_writefn[] = { ! 81: omap_badwidth_write32, ! 82: omap_synctimer_write, ! 83: omap_synctimer_write, ! 84: }; ! 85: ! 86: struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta, ! 87: struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk) ! 88: { ! 89: struct omap_synctimer_s *s = qemu_mallocz(sizeof(*s)); ! 90: ! 91: omap_synctimer_reset(s); ! 92: omap_l4_attach(ta, 0, l4_register_io_memory( ! 93: omap_synctimer_readfn, omap_synctimer_writefn, s)); ! 94: ! 95: return s; ! 96: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.