diff --git a/Makefile.target b/Makefile.target index 6cd8e1012a9492404493c7b655c7211acd8c9966..85a82938119ecaac8c15add9288873f9b564134d 100644 --- a/Makefile.target +++ b/Makefile.target @@ -269,7 +269,7 @@ obj-arm-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o obj-arm-y += gumstix.o obj-arm-y += zaurus.o ide/microdrive.o spitz.o tosa.o tc6393xb.o obj-arm-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o omap_gpio.o -obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o +obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o obj-arm-y += omap_sx1.o palm.o tsc210x.o obj-arm-y += nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o obj-arm-y += mst_fpga.o mainstone.o diff --git a/hw/omap.h b/hw/omap.h index 14fdb6f2ae86e681598124dd2a914fbc061193eb..b898230595531d8efcd0b9d3f174ea4e10b409c9 100644 --- a/hw/omap.h +++ b/hw/omap.h @@ -645,8 +645,11 @@ struct omap_32khz_timer_s; struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base, qemu_irq irq, omap_clk clk); -void omap_synctimer_init(struct omap_target_agent_s *ta, +/* OMAP2 sysctimer */ +struct omap_synctimer_s; +struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta, struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk); +void omap_synctimer_reset(struct omap_synctimer_s *s); struct omap_tipb_bridge_s; struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base, @@ -939,11 +942,7 @@ struct omap_mpu_state_s { struct omap_l4_s *l4; struct omap_gp_timer_s *gptimer[12]; - - struct omap_synctimer_s { - uint32_t val; - uint16_t readh; - } synctimer; + struct omap_synctimer_s *synctimer; struct omap_prcm_s *prcm; struct omap_sdrc_s *sdrc; diff --git a/hw/omap2.c b/hw/omap2.c index 5ad5a98070def4eb53b2cb421c28d5114b358227..bbf8c12988822edb8845421ab4285c49d8632bdc 100644 --- a/hw/omap2.c +++ b/hw/omap2.c @@ -29,74 +29,6 @@ #include "soc_dma.h" #include "audio/audio.h" -/* 32-kHz Sync Timer of the OMAP2 */ -static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) { - return muldiv64(qemu_get_clock(vm_clock), 0x8000, get_ticks_per_sec()); -} - -static void omap_synctimer_reset(struct omap_synctimer_s *s) -{ - s->val = omap_synctimer_read(s); -} - -static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr) -{ - struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque; - - switch (addr) { - case 0x00: /* 32KSYNCNT_REV */ - return 0x21; - - case 0x10: /* CR */ - return omap_synctimer_read(s) - s->val; - } - - OMAP_BAD_REG(addr); - return 0; -} - -static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr) -{ - struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque; - uint32_t ret; - - if (addr & 2) - return s->readh; - else { - ret = omap_synctimer_readw(opaque, addr); - s->readh = ret >> 16; - return ret & 0xffff; - } -} - -static CPUReadMemoryFunc * const omap_synctimer_readfn[] = { - omap_badwidth_read32, - omap_synctimer_readh, - omap_synctimer_readw, -}; - -static void omap_synctimer_write(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - OMAP_BAD_REG(addr); -} - -static CPUWriteMemoryFunc * const omap_synctimer_writefn[] = { - omap_badwidth_write32, - omap_synctimer_write, - omap_synctimer_write, -}; - -void omap_synctimer_init(struct omap_target_agent_s *ta, - struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk) -{ - struct omap_synctimer_s *s = &mpu->synctimer; - - omap_synctimer_reset(s); - omap_l4_attach(ta, 0, l4_register_io_memory( - omap_synctimer_readfn, omap_synctimer_writefn, s)); -} - /* Multichannel SPI */ struct omap_mcspi_s { qemu_irq irq; @@ -3473,7 +3405,7 @@ static void omap2_mpu_reset(void *opaque) omap_gp_timer_reset(mpu->gptimer[9]); omap_gp_timer_reset(mpu->gptimer[10]); omap_gp_timer_reset(mpu->gptimer[11]); - omap_synctimer_reset(&mpu->synctimer); + omap_synctimer_reset(mpu->synctimer); omap_sdrc_reset(mpu->sdrc); omap_gpmc_reset(mpu->gpmc); omap_dss_reset(mpu->dss); @@ -3634,7 +3566,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, omap_tap_init(omap_l4ta(s->l4, 2), s); - omap_synctimer_init(omap_l4tao(s->l4, 2), s, + s->synctimer = omap_synctimer_init(omap_l4tao(s->l4, 2), s, omap_findclk(s, "clk32-kHz"), omap_findclk(s, "core_l4_iclk")); diff --git a/hw/omap_synctimer.c b/hw/omap_synctimer.c new file mode 100644 index 0000000000000000000000000000000000000000..118668aead0078e11d67158d7539505bf9b17d83 --- /dev/null +++ b/hw/omap_synctimer.c @@ -0,0 +1,96 @@ +/* + * TI OMAP2 32kHz sync timer emulation. + * + * Copyright (C) 2007-2008 Nokia Corporation + * Written by Andrzej Zaborowski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) any later version of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ +#include "hw.h" +#include "qemu-timer.h" +#include "omap.h" +struct omap_synctimer_s { + uint32_t val; + uint16_t readh; +}; + +/* 32-kHz Sync Timer of the OMAP2 */ +static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) { + return muldiv64(qemu_get_clock(vm_clock), 0x8000, get_ticks_per_sec()); +} + +void omap_synctimer_reset(struct omap_synctimer_s *s) +{ + s->val = omap_synctimer_read(s); +} + +static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr) +{ + struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque; + + switch (addr) { + case 0x00: /* 32KSYNCNT_REV */ + return 0x21; + + case 0x10: /* CR */ + return omap_synctimer_read(s) - s->val; + } + + OMAP_BAD_REG(addr); + return 0; +} + +static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr) +{ + struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque; + uint32_t ret; + + if (addr & 2) + return s->readh; + else { + ret = omap_synctimer_readw(opaque, addr); + s->readh = ret >> 16; + return ret & 0xffff; + } +} + +static CPUReadMemoryFunc * const omap_synctimer_readfn[] = { + omap_badwidth_read32, + omap_synctimer_readh, + omap_synctimer_readw, +}; + +static void omap_synctimer_write(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + OMAP_BAD_REG(addr); +} + +static CPUWriteMemoryFunc * const omap_synctimer_writefn[] = { + omap_badwidth_write32, + omap_synctimer_write, + omap_synctimer_write, +}; + +struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta, + struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk) +{ + struct omap_synctimer_s *s = qemu_mallocz(sizeof(*s)); + + omap_synctimer_reset(s); + omap_l4_attach(ta, 0, l4_register_io_memory( + omap_synctimer_readfn, omap_synctimer_writefn, s)); + + return s; +}