Statistics
| Branch: | Revision:

root / hw / timer / omap_synctimer.c @ 3bd88451

History | View | Annotate | Download (2.8 kB)

1 011d87d0 cmchao
/*
2 011d87d0 cmchao
 * TI OMAP2 32kHz sync timer emulation.
3 011d87d0 cmchao
 *
4 011d87d0 cmchao
 * Copyright (C) 2007-2008 Nokia Corporation
5 011d87d0 cmchao
 * Written by Andrzej Zaborowski <andrew@openedhand.com>
6 011d87d0 cmchao
 *
7 011d87d0 cmchao
 * This program is free software; you can redistribute it and/or
8 011d87d0 cmchao
 * modify it under the terms of the GNU General Public License as
9 011d87d0 cmchao
 * published by the Free Software Foundation; either version 2 or
10 011d87d0 cmchao
 * (at your option) any later version of the License.
11 011d87d0 cmchao
 *
12 011d87d0 cmchao
 * This program is distributed in the hope that it will be useful,
13 011d87d0 cmchao
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 011d87d0 cmchao
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 011d87d0 cmchao
 * GNU General Public License for more details.
16 011d87d0 cmchao
 *
17 011d87d0 cmchao
 * You should have received a copy of the GNU General Public License along
18 011d87d0 cmchao
 * with this program; if not, see <http://www.gnu.org/licenses/>.
19 011d87d0 cmchao
 */
20 83c9f4ca Paolo Bonzini
#include "hw/hw.h"
21 1de7afc9 Paolo Bonzini
#include "qemu/timer.h"
22 0d09e41a Paolo Bonzini
#include "hw/arm/omap.h"
23 011d87d0 cmchao
struct omap_synctimer_s {
24 fcb40162 Avi Kivity
    MemoryRegion iomem;
25 011d87d0 cmchao
    uint32_t val;
26 011d87d0 cmchao
    uint16_t readh;
27 011d87d0 cmchao
};
28 011d87d0 cmchao
29 011d87d0 cmchao
/* 32-kHz Sync Timer of the OMAP2 */
30 011d87d0 cmchao
static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
31 74475455 Paolo Bonzini
    return muldiv64(qemu_get_clock_ns(vm_clock), 0x8000, get_ticks_per_sec());
32 011d87d0 cmchao
}
33 011d87d0 cmchao
34 011d87d0 cmchao
void omap_synctimer_reset(struct omap_synctimer_s *s)
35 011d87d0 cmchao
{
36 011d87d0 cmchao
    s->val = omap_synctimer_read(s);
37 011d87d0 cmchao
}
38 011d87d0 cmchao
39 a8170e5e Avi Kivity
static uint32_t omap_synctimer_readw(void *opaque, hwaddr addr)
40 011d87d0 cmchao
{
41 011d87d0 cmchao
    struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
42 011d87d0 cmchao
43 011d87d0 cmchao
    switch (addr) {
44 011d87d0 cmchao
    case 0x00:        /* 32KSYNCNT_REV */
45 011d87d0 cmchao
        return 0x21;
46 011d87d0 cmchao
47 011d87d0 cmchao
    case 0x10:        /* CR */
48 011d87d0 cmchao
        return omap_synctimer_read(s) - s->val;
49 011d87d0 cmchao
    }
50 011d87d0 cmchao
51 011d87d0 cmchao
    OMAP_BAD_REG(addr);
52 011d87d0 cmchao
    return 0;
53 011d87d0 cmchao
}
54 011d87d0 cmchao
55 a8170e5e Avi Kivity
static uint32_t omap_synctimer_readh(void *opaque, hwaddr addr)
56 011d87d0 cmchao
{
57 011d87d0 cmchao
    struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
58 011d87d0 cmchao
    uint32_t ret;
59 011d87d0 cmchao
60 011d87d0 cmchao
    if (addr & 2)
61 011d87d0 cmchao
        return s->readh;
62 011d87d0 cmchao
    else {
63 011d87d0 cmchao
        ret = omap_synctimer_readw(opaque, addr);
64 011d87d0 cmchao
        s->readh = ret >> 16;
65 011d87d0 cmchao
        return ret & 0xffff;
66 011d87d0 cmchao
    }
67 011d87d0 cmchao
}
68 011d87d0 cmchao
69 a8170e5e Avi Kivity
static void omap_synctimer_write(void *opaque, hwaddr addr,
70 011d87d0 cmchao
                uint32_t value)
71 011d87d0 cmchao
{
72 011d87d0 cmchao
    OMAP_BAD_REG(addr);
73 011d87d0 cmchao
}
74 011d87d0 cmchao
75 fcb40162 Avi Kivity
static const MemoryRegionOps omap_synctimer_ops = {
76 fcb40162 Avi Kivity
    .old_mmio = {
77 fcb40162 Avi Kivity
        .read = {
78 fcb40162 Avi Kivity
            omap_badwidth_read32,
79 fcb40162 Avi Kivity
            omap_synctimer_readh,
80 fcb40162 Avi Kivity
            omap_synctimer_readw,
81 fcb40162 Avi Kivity
        },
82 fcb40162 Avi Kivity
        .write = {
83 fcb40162 Avi Kivity
            omap_badwidth_write32,
84 fcb40162 Avi Kivity
            omap_synctimer_write,
85 fcb40162 Avi Kivity
            omap_synctimer_write,
86 fcb40162 Avi Kivity
        },
87 fcb40162 Avi Kivity
    },
88 fcb40162 Avi Kivity
    .endianness = DEVICE_NATIVE_ENDIAN,
89 011d87d0 cmchao
};
90 011d87d0 cmchao
91 011d87d0 cmchao
struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta,
92 011d87d0 cmchao
                struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk)
93 011d87d0 cmchao
{
94 7267c094 Anthony Liguori
    struct omap_synctimer_s *s = g_malloc0(sizeof(*s));
95 011d87d0 cmchao
96 011d87d0 cmchao
    omap_synctimer_reset(s);
97 fcb40162 Avi Kivity
    memory_region_init_io(&s->iomem, &omap_synctimer_ops, s, "omap.synctimer",
98 fcb40162 Avi Kivity
                          omap_l4_region_size(ta, 0));
99 f44336c5 Avi Kivity
    omap_l4_attach(ta, 0, &s->iomem);
100 011d87d0 cmchao
101 011d87d0 cmchao
    return s;
102 011d87d0 cmchao
}