cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

timer-armada-370-xp.c (10131B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Marvell Armada 370/XP SoC timer handling.
      4 *
      5 * Copyright (C) 2012 Marvell
      6 *
      7 * Lior Amsalem <alior@marvell.com>
      8 * Gregory CLEMENT <gregory.clement@free-electrons.com>
      9 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
     10 *
     11 * Timer 0 is used as free-running clocksource, while timer 1 is
     12 * used as clock_event_device.
     13 *
     14 * ---
     15 * Clocksource driver for Armada 370 and Armada XP SoC.
     16 * This driver implements one compatible string for each SoC, given
     17 * each has its own characteristics:
     18 *
     19 *   * Armada 370 has no 25 MHz fixed timer.
     20 *
     21 *   * Armada XP cannot work properly without such 25 MHz fixed timer as
     22 *     doing otherwise leads to using a clocksource whose frequency varies
     23 *     when doing cpufreq frequency changes.
     24 *
     25 * See Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt
     26 */
     27
     28#include <linux/init.h>
     29#include <linux/platform_device.h>
     30#include <linux/kernel.h>
     31#include <linux/clk.h>
     32#include <linux/cpu.h>
     33#include <linux/timer.h>
     34#include <linux/clockchips.h>
     35#include <linux/interrupt.h>
     36#include <linux/of.h>
     37#include <linux/of_irq.h>
     38#include <linux/of_address.h>
     39#include <linux/irq.h>
     40#include <linux/module.h>
     41#include <linux/sched_clock.h>
     42#include <linux/percpu.h>
     43#include <linux/syscore_ops.h>
     44
     45#include <asm/delay.h>
     46
     47/*
     48 * Timer block registers.
     49 */
     50#define TIMER_CTRL_OFF		0x0000
     51#define  TIMER0_EN		 BIT(0)
     52#define  TIMER0_RELOAD_EN	 BIT(1)
     53#define  TIMER0_25MHZ            BIT(11)
     54#define  TIMER0_DIV(div)         ((div) << 19)
     55#define  TIMER1_EN		 BIT(2)
     56#define  TIMER1_RELOAD_EN	 BIT(3)
     57#define  TIMER1_25MHZ            BIT(12)
     58#define  TIMER1_DIV(div)         ((div) << 22)
     59#define TIMER_EVENTS_STATUS	0x0004
     60#define  TIMER0_CLR_MASK         (~0x1)
     61#define  TIMER1_CLR_MASK         (~0x100)
     62#define TIMER0_RELOAD_OFF	0x0010
     63#define TIMER0_VAL_OFF		0x0014
     64#define TIMER1_RELOAD_OFF	0x0018
     65#define TIMER1_VAL_OFF		0x001c
     66
     67#define LCL_TIMER_EVENTS_STATUS	0x0028
     68/* Global timers are connected to the coherency fabric clock, and the
     69   below divider reduces their incrementing frequency. */
     70#define TIMER_DIVIDER_SHIFT     5
     71#define TIMER_DIVIDER           (1 << TIMER_DIVIDER_SHIFT)
     72
     73/*
     74 * SoC-specific data.
     75 */
     76static void __iomem *timer_base, *local_base;
     77static unsigned int timer_clk;
     78static bool timer25Mhz = true;
     79static u32 enable_mask;
     80
     81/*
     82 * Number of timer ticks per jiffy.
     83 */
     84static u32 ticks_per_jiffy;
     85
     86static struct clock_event_device __percpu *armada_370_xp_evt;
     87
     88static void local_timer_ctrl_clrset(u32 clr, u32 set)
     89{
     90	writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set,
     91		local_base + TIMER_CTRL_OFF);
     92}
     93
     94static u64 notrace armada_370_xp_read_sched_clock(void)
     95{
     96	return ~readl(timer_base + TIMER0_VAL_OFF);
     97}
     98
     99/*
    100 * Clockevent handling.
    101 */
    102static int
    103armada_370_xp_clkevt_next_event(unsigned long delta,
    104				struct clock_event_device *dev)
    105{
    106	/*
    107	 * Clear clockevent timer interrupt.
    108	 */
    109	writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS);
    110
    111	/*
    112	 * Setup new clockevent timer value.
    113	 */
    114	writel(delta, local_base + TIMER0_VAL_OFF);
    115
    116	/*
    117	 * Enable the timer.
    118	 */
    119	local_timer_ctrl_clrset(TIMER0_RELOAD_EN, enable_mask);
    120	return 0;
    121}
    122
    123static int armada_370_xp_clkevt_shutdown(struct clock_event_device *evt)
    124{
    125	/*
    126	 * Disable timer.
    127	 */
    128	local_timer_ctrl_clrset(TIMER0_EN, 0);
    129
    130	/*
    131	 * ACK pending timer interrupt.
    132	 */
    133	writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS);
    134	return 0;
    135}
    136
    137static int armada_370_xp_clkevt_set_periodic(struct clock_event_device *evt)
    138{
    139	/*
    140	 * Setup timer to fire at 1/HZ intervals.
    141	 */
    142	writel(ticks_per_jiffy - 1, local_base + TIMER0_RELOAD_OFF);
    143	writel(ticks_per_jiffy - 1, local_base + TIMER0_VAL_OFF);
    144
    145	/*
    146	 * Enable timer.
    147	 */
    148	local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | enable_mask);
    149	return 0;
    150}
    151
    152static int armada_370_xp_clkevt_irq;
    153
    154static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id)
    155{
    156	/*
    157	 * ACK timer interrupt and call event handler.
    158	 */
    159	struct clock_event_device *evt = dev_id;
    160
    161	writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS);
    162	evt->event_handler(evt);
    163
    164	return IRQ_HANDLED;
    165}
    166
    167/*
    168 * Setup the local clock events for a CPU.
    169 */
    170static int armada_370_xp_timer_starting_cpu(unsigned int cpu)
    171{
    172	struct clock_event_device *evt = per_cpu_ptr(armada_370_xp_evt, cpu);
    173	u32 clr = 0, set = 0;
    174
    175	if (timer25Mhz)
    176		set = TIMER0_25MHZ;
    177	else
    178		clr = TIMER0_25MHZ;
    179	local_timer_ctrl_clrset(clr, set);
    180
    181	evt->name		= "armada_370_xp_per_cpu_tick";
    182	evt->features		= CLOCK_EVT_FEAT_ONESHOT |
    183				  CLOCK_EVT_FEAT_PERIODIC;
    184	evt->shift		= 32;
    185	evt->rating		= 300;
    186	evt->set_next_event	= armada_370_xp_clkevt_next_event;
    187	evt->set_state_shutdown	= armada_370_xp_clkevt_shutdown;
    188	evt->set_state_periodic	= armada_370_xp_clkevt_set_periodic;
    189	evt->set_state_oneshot	= armada_370_xp_clkevt_shutdown;
    190	evt->tick_resume	= armada_370_xp_clkevt_shutdown;
    191	evt->irq		= armada_370_xp_clkevt_irq;
    192	evt->cpumask		= cpumask_of(cpu);
    193
    194	clockevents_config_and_register(evt, timer_clk, 1, 0xfffffffe);
    195	enable_percpu_irq(evt->irq, 0);
    196
    197	return 0;
    198}
    199
    200static int armada_370_xp_timer_dying_cpu(unsigned int cpu)
    201{
    202	struct clock_event_device *evt = per_cpu_ptr(armada_370_xp_evt, cpu);
    203
    204	evt->set_state_shutdown(evt);
    205	disable_percpu_irq(evt->irq);
    206	return 0;
    207}
    208
    209static u32 timer0_ctrl_reg, timer0_local_ctrl_reg;
    210
    211static int armada_370_xp_timer_suspend(void)
    212{
    213	timer0_ctrl_reg = readl(timer_base + TIMER_CTRL_OFF);
    214	timer0_local_ctrl_reg = readl(local_base + TIMER_CTRL_OFF);
    215	return 0;
    216}
    217
    218static void armada_370_xp_timer_resume(void)
    219{
    220	writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
    221	writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
    222	writel(timer0_ctrl_reg, timer_base + TIMER_CTRL_OFF);
    223	writel(timer0_local_ctrl_reg, local_base + TIMER_CTRL_OFF);
    224}
    225
    226static struct syscore_ops armada_370_xp_timer_syscore_ops = {
    227	.suspend	= armada_370_xp_timer_suspend,
    228	.resume		= armada_370_xp_timer_resume,
    229};
    230
    231static unsigned long armada_370_delay_timer_read(void)
    232{
    233	return ~readl(timer_base + TIMER0_VAL_OFF);
    234}
    235
    236static struct delay_timer armada_370_delay_timer = {
    237	.read_current_timer = armada_370_delay_timer_read,
    238};
    239
    240static int __init armada_370_xp_timer_common_init(struct device_node *np)
    241{
    242	u32 clr = 0, set = 0;
    243	int res;
    244
    245	timer_base = of_iomap(np, 0);
    246	if (!timer_base) {
    247		pr_err("Failed to iomap\n");
    248		return -ENXIO;
    249	}
    250
    251	local_base = of_iomap(np, 1);
    252	if (!local_base) {
    253		pr_err("Failed to iomap\n");
    254		return -ENXIO;
    255	}
    256
    257	if (timer25Mhz) {
    258		set = TIMER0_25MHZ;		
    259		enable_mask = TIMER0_EN;
    260	} else {
    261		clr = TIMER0_25MHZ;
    262		enable_mask = TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT);
    263	}
    264	atomic_io_modify(timer_base + TIMER_CTRL_OFF, clr | set, set);
    265	local_timer_ctrl_clrset(clr, set);
    266
    267	/*
    268	 * We use timer 0 as clocksource, and private(local) timer 0
    269	 * for clockevents
    270	 */
    271	armada_370_xp_clkevt_irq = irq_of_parse_and_map(np, 4);
    272
    273	ticks_per_jiffy = (timer_clk + HZ / 2) / HZ;
    274
    275	/*
    276	 * Setup free-running clocksource timer (interrupts
    277	 * disabled).
    278	 */
    279	writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
    280	writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
    281
    282	atomic_io_modify(timer_base + TIMER_CTRL_OFF,
    283		TIMER0_RELOAD_EN | enable_mask,
    284		TIMER0_RELOAD_EN | enable_mask);
    285
    286	armada_370_delay_timer.freq = timer_clk;
    287	register_current_timer_delay(&armada_370_delay_timer);
    288
    289	/*
    290	 * Set scale and timer for sched_clock.
    291	 */
    292	sched_clock_register(armada_370_xp_read_sched_clock, 32, timer_clk);
    293
    294	res = clocksource_mmio_init(timer_base + TIMER0_VAL_OFF,
    295				    "armada_370_xp_clocksource",
    296				    timer_clk, 300, 32, clocksource_mmio_readl_down);
    297	if (res) {
    298		pr_err("Failed to initialize clocksource mmio\n");
    299		return res;
    300	}
    301
    302	armada_370_xp_evt = alloc_percpu(struct clock_event_device);
    303	if (!armada_370_xp_evt)
    304		return -ENOMEM;
    305
    306	/*
    307	 * Setup clockevent timer (interrupt-driven).
    308	 */
    309	res = request_percpu_irq(armada_370_xp_clkevt_irq,
    310				armada_370_xp_timer_interrupt,
    311				"armada_370_xp_per_cpu_tick",
    312				armada_370_xp_evt);
    313	/* Immediately configure the timer on the boot CPU */
    314	if (res) {
    315		pr_err("Failed to request percpu irq\n");
    316		return res;
    317	}
    318
    319	res = cpuhp_setup_state(CPUHP_AP_ARMADA_TIMER_STARTING,
    320				"clockevents/armada:starting",
    321				armada_370_xp_timer_starting_cpu,
    322				armada_370_xp_timer_dying_cpu);
    323	if (res) {
    324		pr_err("Failed to setup hotplug state and timer\n");
    325		return res;
    326	}
    327
    328	register_syscore_ops(&armada_370_xp_timer_syscore_ops);
    329	
    330	return 0;
    331}
    332
    333static int __init armada_xp_timer_init(struct device_node *np)
    334{
    335	struct clk *clk = of_clk_get_by_name(np, "fixed");
    336	int ret;
    337
    338	if (IS_ERR(clk)) {
    339		pr_err("Failed to get clock\n");
    340		return PTR_ERR(clk);
    341	}
    342
    343	ret = clk_prepare_enable(clk);
    344	if (ret)
    345		return ret;
    346
    347	timer_clk = clk_get_rate(clk);
    348
    349	return armada_370_xp_timer_common_init(np);
    350}
    351TIMER_OF_DECLARE(armada_xp, "marvell,armada-xp-timer",
    352		       armada_xp_timer_init);
    353
    354static int __init armada_375_timer_init(struct device_node *np)
    355{
    356	struct clk *clk;
    357	int ret;
    358
    359	clk = of_clk_get_by_name(np, "fixed");
    360	if (!IS_ERR(clk)) {
    361		ret = clk_prepare_enable(clk);
    362		if (ret)
    363			return ret;
    364		timer_clk = clk_get_rate(clk);
    365	} else {
    366
    367		/*
    368		 * This fallback is required in order to retain proper
    369		 * devicetree backwards compatibility.
    370		 */
    371		clk = of_clk_get(np, 0);
    372
    373		/* Must have at least a clock */
    374		if (IS_ERR(clk)) {
    375			pr_err("Failed to get clock\n");
    376			return PTR_ERR(clk);
    377		}
    378
    379		ret = clk_prepare_enable(clk);
    380		if (ret)
    381			return ret;
    382
    383		timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
    384		timer25Mhz = false;
    385	}
    386
    387	return armada_370_xp_timer_common_init(np);
    388}
    389TIMER_OF_DECLARE(armada_375, "marvell,armada-375-timer",
    390		       armada_375_timer_init);
    391
    392static int __init armada_370_timer_init(struct device_node *np)
    393{
    394	struct clk *clk;
    395	int ret;
    396
    397	clk = of_clk_get(np, 0);
    398	if (IS_ERR(clk)) {
    399		pr_err("Failed to get clock\n");
    400		return PTR_ERR(clk);
    401	}
    402
    403	ret = clk_prepare_enable(clk);
    404	if (ret)
    405		return ret;
    406
    407	timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
    408	timer25Mhz = false;
    409
    410	return armada_370_xp_timer_common_init(np);
    411}
    412TIMER_OF_DECLARE(armada_370, "marvell,armada-370-timer",
    413		       armada_370_timer_init);