[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 5/5] xen/arm: Add OMAP5 architected timer initialization codes.
On Aug 7, 2013, at 6:14 AM, Julien Grall <julien.grall@xxxxxxxxxx> wrote: > On 5 August 2013 12:49, Chen Baozi <baozich@xxxxxxxxx> wrote: >> Signed-off-by: Chen Baozi <baozich@xxxxxxxxx> >> --- >> xen/arch/arm/platforms/omap5.c | 72 >> +++++++++++++++++++++++++++++++++++ >> xen/arch/arm/time.c | 7 +++- >> xen/include/asm-arm/platforms/omap5.h | 15 ++++++++ >> 3 files changed, 93 insertions(+), 1 deletion(-) >> >> diff --git a/xen/arch/arm/platforms/omap5.c b/xen/arch/arm/platforms/omap5.c >> index eecf35b..568b53d 100644 >> --- a/xen/arch/arm/platforms/omap5.c >> +++ b/xen/arch/arm/platforms/omap5.c >> @@ -20,6 +20,77 @@ >> #include <xen/config.h> >> #include <asm/platforms/omap5.h> >> #include <asm/platform.h> >> +#include <xen/mm.h> >> +#include <xen/vmap.h> >> + >> +static uint16_t num_den[8][2] = { >> + { 0, 0 }, /* not used */ >> + { 26 * 64, 26 * 125 }, /* 12.0 Mhz */ >> + { 2 * 768, 2 * 1625 }, /* 13.0 Mhz */ >> + { 0, 0 }, /* not used */ >> + { 130 * 8, 130 * 25 }, /* 19.2 Mhz */ >> + { 2 * 384, 2 * 1625 }, /* 26.0 Mhz */ >> + { 3 * 256, 3 * 1125 }, /* 27.0 Mhz */ >> + { 130 * 4, 130 * 25 }, /* 38.4 Mhz */ >> +}; >> + >> +/* >> + * The realtime counter also called master counter, is a free-running >> + * counter, which is related to real time. It produces the count used >> + * by the CPU local timer peripherals in teh MPU cluster. The timer counts >> + * at a rate of 6.144 MHz. Because the device operates on different clocks >> + * in different power modes, the master counter shifts operation between >> + * clocks, adjusting the increment per clock in hardware accordingly to >> + * maintain a constant count rate. >> + */ >> +static int omap5_init_time(void) >> +{ >> + void __iomem *ckgen_prm_base; >> + void __iomem *rt_ct_base; >> + unsigned int sys_clksel; >> + unsigned int num, den, frac1, frac2; >> + >> + ckgen_prm_base = ioremap_attr(OMAP5_CKGEN_PRM_BASE, >> + 0x20, PAGE_HYPERVISOR_NOCACHE); >> + if (!ckgen_prm_base) { >> + dprintk(XENLOG_ERR, "%s: PRM_BASE ioremap failed\n", __func__); >> + return -ENOMEM; >> + } >> + >> + sys_clksel = ioreadl(ckgen_prm_base + OMAP5_CM_CLKSEL_SYS) & >> + ~SYS_CLKSEL_MASK; >> + >> + iounmap(ckgen_prm_base); >> + >> + rt_ct_base = ioremap_attr(REALTIME_COUNTER_BASE, >> + 0x20, PAGE_HYPERVISOR_NOCACHE); >> + if (!rt_ct_base) { >> + dprintk(XENLOG_ERR, "%s: REALTIME_COUNTER_BASE ioremap failed\n", >> __func__); >> + return -ENOMEM; >> + } >> + >> + frac1 = ioreadl(rt_ct_base + INCREMENTER_NUMERATOR_OFFSET); >> + num = frac1 & ~NUMERATOR_DENUMERATOR_MASK; >> + if (num_den[sys_clksel][0] != num) { >> + frac1 &= NUMERATOR_DENUMERATOR_MASK; >> + frac1 |= num_den[sys_clksel][0]; >> + } >> + >> + frac2 = ioreadl(rt_ct_base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); >> + den = frac2 & ~NUMERATOR_DENUMERATOR_MASK; >> + if (num_den[sys_clksel][1] != num) { >> + frac2 &= NUMERATOR_DENUMERATOR_MASK; >> + frac2 |= num_den[sys_clksel][1]; >> + } >> + >> + iowritel(rt_ct_base + INCREMENTER_NUMERATOR_OFFSET, frac1); >> + iowritel(rt_ct_base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET, >> + frac2 | PRM_FRAC_INCREMENTER_DENUMERATOR_RELOAD); >> + >> + iounmap(rt_ct_base); >> + >> + return 0; >> +} >> >> static const char const *omap5_dt_compat[] __initdata = >> { >> @@ -29,6 +100,7 @@ static const char const *omap5_dt_compat[] __initdata = >> >> PLATFORM_START(omap5, "TI OMAP5") >> .compatible = omap5_dt_compat, >> + .init_time = omap5_init_time, >> PLATFORM_END >> >> /* >> diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c >> index 4ed7882..6ca030a 100644 >> --- a/xen/arch/arm/time.c >> +++ b/xen/arch/arm/time.c >> @@ -104,6 +104,7 @@ int __init init_xen_time(void) >> struct dt_device_node *dev; >> int res; >> unsigned int i; >> + const __be32 *rate; >> >> dev = dt_find_compatible_node(NULL, NULL, "arm,armv7-timer"); >> if ( !dev ) >> @@ -134,7 +135,11 @@ int __init init_xen_time(void) >> if ( !cpu_has_gentimer ) >> panic("CPU does not support the Generic Timer v1 interface.\n"); >> >> - cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000; >> + rate = dt_get_property(dev, "clock-frequency", NULL); > > You need to check if the length match the size of rate. > Perhaps, you can add an helper dt_property_read_u32 (see > linux/include/linux/of.h). OK. > >> + if (rate) >> + cpu_khz = be32_to_cpup(rate) / 1000; >> + else >> + cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000; >> >> boot_count = READ_SYSREG64(CNTPCT_EL0); >> printk("Using generic timer at %lu KHz\n", cpu_khz); >> diff --git a/xen/include/asm-arm/platforms/omap5.h >> b/xen/include/asm-arm/platforms/omap5.h >> index fa825b7..41d178e 100644 >> --- a/xen/include/asm-arm/platforms/omap5.h >> +++ b/xen/include/asm-arm/platforms/omap5.h >> @@ -1,6 +1,21 @@ >> #ifndef __ASM_ARM_PLATFORMS_OMAP5_H >> #define __ASM_ASM_PLATFORMS_OMAP5_H >> >> +#define REALTIME_COUNTER_BASE 0x48243200 >> +#define INCREMENTER_NUMERATOR_OFFSET 0x10 >> +#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 >> +#define NUMERATOR_DENUMERATOR_MASK 0xfffff000 >> +#define PRM_FRAC_INCREMENTER_DENUMERATOR_RELOAD 0x00010000 >> + >> +#define OMAP5_L4_WKUP 0x4AE00000 >> +#define OMAP5_PRM_BASE (OMAP5_L4_WKUP + 0x6000) >> +#define OMAP5_CKGEN_PRM_BASE (OMAP5_PRM_BASE + 0x100) >> +#define OMAP5_CM_CLKSEL_SYS 0x10 >> +#define SYS_CLKSEL_MASK 0xfffffff8 >> + >> +/* Timer's frequency */ >> +#define OMAP5_TIMER_FREQUENCY 6144000 /* 6.144 Mhz*/ > > Do you use this define somewhere? Oh, sorry. It is used at initial version of this patch. I should have removed it when switching to DTS value. Cheers, Baozi _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |