/*
 * TI OMAP2 32kHz sync timer emulation.
 *
 * Copyright (C) 2007-2008 Nokia Corporation
 * Written by Andrzej Zaborowski <andrew@openedhand.com>
 *
 * 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 <http://www.gnu.org/licenses/>.
 */
#include "hw.h"
#include "qemu-timer.h"
#include "omap.h"
struct omap_synctimer_s {
    MemoryRegion iomem;
    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_ns(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, hwaddr 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, hwaddr 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 void omap_synctimer_write(void *opaque, hwaddr addr,
                uint32_t value)
{
    OMAP_BAD_REG(addr);
}

static const MemoryRegionOps omap_synctimer_ops = {
    .old_mmio = {
        .read = {
            omap_badwidth_read32,
            omap_synctimer_readh,
            omap_synctimer_readw,
        },
        .write = {
            omap_badwidth_write32,
            omap_synctimer_write,
            omap_synctimer_write,
        },
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

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 = g_malloc0(sizeof(*s));

    omap_synctimer_reset(s);
    memory_region_init_io(&s->iomem, &omap_synctimer_ops, s, "omap.synctimer",
                          omap_l4_region_size(ta, 0));
    omap_l4_attach(ta, 0, &s->iomem);

    return s;
}
