| /* | |
| * This file is subject to the terms and conditions of the GNU General Public | |
| * License. See the file "COPYING" in the main directory of this archive | |
| * for more details. | |
| * | |
| * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | |
| */ | |
| #include <linux/clocksource.h> | |
| #include <linux/init.h> | |
| #include <asm/time.h> | |
| #include <asm/gic.h> | |
| static cycle_t gic_hpt_read(struct clocksource *cs) | |
| { | |
| unsigned int hi, hi2, lo; | |
| do { | |
| GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi); | |
| GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo); | |
| GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2); | |
| } while (hi2 != hi); | |
| return (((cycle_t) hi) << 32) + lo; | |
| } | |
| static struct clocksource gic_clocksource = { | |
| .name = "GIC", | |
| .read = gic_hpt_read, | |
| .flags = CLOCK_SOURCE_IS_CONTINUOUS, | |
| }; | |
| void __init gic_clocksource_init(unsigned int frequency) | |
| { | |
| unsigned int config, bits; | |
| /* Calculate the clocksource mask. */ | |
| GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config); | |
| bits = 32 + ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >> | |
| (GIC_SH_CONFIG_COUNTBITS_SHF - 2)); | |
| /* Set clocksource mask. */ | |
| gic_clocksource.mask = CLOCKSOURCE_MASK(bits); | |
| /* Calculate a somewhat reasonable rating value. */ | |
| gic_clocksource.rating = 200 + frequency / 10000000; | |
| clocksource_register_hz(&gic_clocksource, frequency); | |
| } |