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-fttmr010.c (12349B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Faraday Technology FTTMR010 timer driver
      4 * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
      5 *
      6 * Based on a rewrite of arch/arm/mach-gemini/timer.c:
      7 * Copyright (C) 2001-2006 Storlink, Corp.
      8 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
      9 */
     10#include <linux/interrupt.h>
     11#include <linux/io.h>
     12#include <linux/of.h>
     13#include <linux/of_address.h>
     14#include <linux/of_irq.h>
     15#include <linux/clockchips.h>
     16#include <linux/clocksource.h>
     17#include <linux/sched_clock.h>
     18#include <linux/clk.h>
     19#include <linux/slab.h>
     20#include <linux/bitops.h>
     21#include <linux/delay.h>
     22
     23/*
     24 * Register definitions common for all the timer variants.
     25 */
     26#define TIMER1_COUNT		(0x00)
     27#define TIMER1_LOAD		(0x04)
     28#define TIMER1_MATCH1		(0x08)
     29#define TIMER1_MATCH2		(0x0c)
     30#define TIMER2_COUNT		(0x10)
     31#define TIMER2_LOAD		(0x14)
     32#define TIMER2_MATCH1		(0x18)
     33#define TIMER2_MATCH2		(0x1c)
     34#define TIMER3_COUNT		(0x20)
     35#define TIMER3_LOAD		(0x24)
     36#define TIMER3_MATCH1		(0x28)
     37#define TIMER3_MATCH2		(0x2c)
     38#define TIMER_CR		(0x30)
     39
     40/*
     41 * Control register set to clear for ast2600 only.
     42 */
     43#define AST2600_TIMER_CR_CLR	(0x3c)
     44
     45/*
     46 * Control register (TMC30) bit fields for fttmr010/gemini/moxart timers.
     47 */
     48#define TIMER_1_CR_ENABLE	BIT(0)
     49#define TIMER_1_CR_CLOCK	BIT(1)
     50#define TIMER_1_CR_INT		BIT(2)
     51#define TIMER_2_CR_ENABLE	BIT(3)
     52#define TIMER_2_CR_CLOCK	BIT(4)
     53#define TIMER_2_CR_INT		BIT(5)
     54#define TIMER_3_CR_ENABLE	BIT(6)
     55#define TIMER_3_CR_CLOCK	BIT(7)
     56#define TIMER_3_CR_INT		BIT(8)
     57#define TIMER_1_CR_UPDOWN	BIT(9)
     58#define TIMER_2_CR_UPDOWN	BIT(10)
     59#define TIMER_3_CR_UPDOWN	BIT(11)
     60
     61/*
     62 * Control register (TMC30) bit fields for aspeed ast2400/ast2500 timers.
     63 * The aspeed timers move bits around in the control register and lacks
     64 * bits for setting the timer to count upwards.
     65 */
     66#define TIMER_1_CR_ASPEED_ENABLE	BIT(0)
     67#define TIMER_1_CR_ASPEED_CLOCK		BIT(1)
     68#define TIMER_1_CR_ASPEED_INT		BIT(2)
     69#define TIMER_2_CR_ASPEED_ENABLE	BIT(4)
     70#define TIMER_2_CR_ASPEED_CLOCK		BIT(5)
     71#define TIMER_2_CR_ASPEED_INT		BIT(6)
     72#define TIMER_3_CR_ASPEED_ENABLE	BIT(8)
     73#define TIMER_3_CR_ASPEED_CLOCK		BIT(9)
     74#define TIMER_3_CR_ASPEED_INT		BIT(10)
     75
     76/*
     77 * Interrupt status/mask register definitions for fttmr010/gemini/moxart
     78 * timers.
     79 * The registers don't exist and they are not needed on aspeed timers
     80 * because:
     81 *   - aspeed timer overflow interrupt is controlled by bits in Control
     82 *     Register (TMC30).
     83 *   - aspeed timers always generate interrupt when either one of the
     84 *     Match registers equals to Status register.
     85 */
     86#define TIMER_INTR_STATE	(0x34)
     87#define TIMER_INTR_MASK		(0x38)
     88#define TIMER_1_INT_MATCH1	BIT(0)
     89#define TIMER_1_INT_MATCH2	BIT(1)
     90#define TIMER_1_INT_OVERFLOW	BIT(2)
     91#define TIMER_2_INT_MATCH1	BIT(3)
     92#define TIMER_2_INT_MATCH2	BIT(4)
     93#define TIMER_2_INT_OVERFLOW	BIT(5)
     94#define TIMER_3_INT_MATCH1	BIT(6)
     95#define TIMER_3_INT_MATCH2	BIT(7)
     96#define TIMER_3_INT_OVERFLOW	BIT(8)
     97#define TIMER_INT_ALL_MASK	0x1ff
     98
     99struct fttmr010 {
    100	void __iomem *base;
    101	unsigned int tick_rate;
    102	bool is_aspeed;
    103	u32 t1_enable_val;
    104	struct clock_event_device clkevt;
    105	int (*timer_shutdown)(struct clock_event_device *evt);
    106#ifdef CONFIG_ARM
    107	struct delay_timer delay_timer;
    108#endif
    109};
    110
    111/*
    112 * A local singleton used by sched_clock and delay timer reads, which are
    113 * fast and stateless
    114 */
    115static struct fttmr010 *local_fttmr;
    116
    117static inline struct fttmr010 *to_fttmr010(struct clock_event_device *evt)
    118{
    119	return container_of(evt, struct fttmr010, clkevt);
    120}
    121
    122static unsigned long fttmr010_read_current_timer_up(void)
    123{
    124	return readl(local_fttmr->base + TIMER2_COUNT);
    125}
    126
    127static unsigned long fttmr010_read_current_timer_down(void)
    128{
    129	return ~readl(local_fttmr->base + TIMER2_COUNT);
    130}
    131
    132static u64 notrace fttmr010_read_sched_clock_up(void)
    133{
    134	return fttmr010_read_current_timer_up();
    135}
    136
    137static u64 notrace fttmr010_read_sched_clock_down(void)
    138{
    139	return fttmr010_read_current_timer_down();
    140}
    141
    142static int fttmr010_timer_set_next_event(unsigned long cycles,
    143				       struct clock_event_device *evt)
    144{
    145	struct fttmr010 *fttmr010 = to_fttmr010(evt);
    146	u32 cr;
    147
    148	/* Stop */
    149	fttmr010->timer_shutdown(evt);
    150
    151	if (fttmr010->is_aspeed) {
    152		/*
    153		 * ASPEED Timer Controller will load TIMER1_LOAD register
    154		 * into TIMER1_COUNT register when the timer is re-enabled.
    155		 */
    156		writel(cycles, fttmr010->base + TIMER1_LOAD);
    157	} else {
    158		/* Setup the match register forward in time */
    159		cr = readl(fttmr010->base + TIMER1_COUNT);
    160		writel(cr + cycles, fttmr010->base + TIMER1_MATCH1);
    161	}
    162
    163	/* Start */
    164	cr = readl(fttmr010->base + TIMER_CR);
    165	cr |= fttmr010->t1_enable_val;
    166	writel(cr, fttmr010->base + TIMER_CR);
    167
    168	return 0;
    169}
    170
    171static int ast2600_timer_shutdown(struct clock_event_device *evt)
    172{
    173	struct fttmr010 *fttmr010 = to_fttmr010(evt);
    174
    175	/* Stop */
    176	writel(fttmr010->t1_enable_val, fttmr010->base + AST2600_TIMER_CR_CLR);
    177
    178	return 0;
    179}
    180
    181static int fttmr010_timer_shutdown(struct clock_event_device *evt)
    182{
    183	struct fttmr010 *fttmr010 = to_fttmr010(evt);
    184	u32 cr;
    185
    186	/* Stop */
    187	cr = readl(fttmr010->base + TIMER_CR);
    188	cr &= ~fttmr010->t1_enable_val;
    189	writel(cr, fttmr010->base + TIMER_CR);
    190
    191	return 0;
    192}
    193
    194static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
    195{
    196	struct fttmr010 *fttmr010 = to_fttmr010(evt);
    197	u32 cr;
    198
    199	/* Stop */
    200	fttmr010->timer_shutdown(evt);
    201
    202	/* Setup counter start from 0 or ~0 */
    203	writel(0, fttmr010->base + TIMER1_COUNT);
    204	if (fttmr010->is_aspeed) {
    205		writel(~0, fttmr010->base + TIMER1_LOAD);
    206	} else {
    207		writel(0, fttmr010->base + TIMER1_LOAD);
    208
    209		/* Enable interrupt */
    210		cr = readl(fttmr010->base + TIMER_INTR_MASK);
    211		cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2);
    212		cr |= TIMER_1_INT_MATCH1;
    213		writel(cr, fttmr010->base + TIMER_INTR_MASK);
    214	}
    215
    216	return 0;
    217}
    218
    219static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
    220{
    221	struct fttmr010 *fttmr010 = to_fttmr010(evt);
    222	u32 period = DIV_ROUND_CLOSEST(fttmr010->tick_rate, HZ);
    223	u32 cr;
    224
    225	/* Stop */
    226	fttmr010->timer_shutdown(evt);
    227
    228	/* Setup timer to fire at 1/HZ intervals. */
    229	if (fttmr010->is_aspeed) {
    230		writel(period, fttmr010->base + TIMER1_LOAD);
    231	} else {
    232		cr = 0xffffffff - (period - 1);
    233		writel(cr, fttmr010->base + TIMER1_COUNT);
    234		writel(cr, fttmr010->base + TIMER1_LOAD);
    235
    236		/* Enable interrupt on overflow */
    237		cr = readl(fttmr010->base + TIMER_INTR_MASK);
    238		cr &= ~(TIMER_1_INT_MATCH1 | TIMER_1_INT_MATCH2);
    239		cr |= TIMER_1_INT_OVERFLOW;
    240		writel(cr, fttmr010->base + TIMER_INTR_MASK);
    241	}
    242
    243	/* Start the timer */
    244	cr = readl(fttmr010->base + TIMER_CR);
    245	cr |= fttmr010->t1_enable_val;
    246	writel(cr, fttmr010->base + TIMER_CR);
    247
    248	return 0;
    249}
    250
    251/*
    252 * IRQ handler for the timer
    253 */
    254static irqreturn_t fttmr010_timer_interrupt(int irq, void *dev_id)
    255{
    256	struct clock_event_device *evt = dev_id;
    257
    258	evt->event_handler(evt);
    259	return IRQ_HANDLED;
    260}
    261
    262static irqreturn_t ast2600_timer_interrupt(int irq, void *dev_id)
    263{
    264	struct clock_event_device *evt = dev_id;
    265	struct fttmr010 *fttmr010 = to_fttmr010(evt);
    266
    267	writel(0x1, fttmr010->base + TIMER_INTR_STATE);
    268
    269	evt->event_handler(evt);
    270	return IRQ_HANDLED;
    271}
    272
    273static int __init fttmr010_common_init(struct device_node *np,
    274				       bool is_aspeed, bool is_ast2600)
    275{
    276	struct fttmr010 *fttmr010;
    277	int irq;
    278	struct clk *clk;
    279	int ret;
    280	u32 val;
    281
    282	/*
    283	 * These implementations require a clock reference.
    284	 * FIXME: we currently only support clocking using PCLK
    285	 * and using EXTCLK is not supported in the driver.
    286	 */
    287	clk = of_clk_get_by_name(np, "PCLK");
    288	if (IS_ERR(clk)) {
    289		pr_err("could not get PCLK\n");
    290		return PTR_ERR(clk);
    291	}
    292	ret = clk_prepare_enable(clk);
    293	if (ret) {
    294		pr_err("failed to enable PCLK\n");
    295		return ret;
    296	}
    297
    298	fttmr010 = kzalloc(sizeof(*fttmr010), GFP_KERNEL);
    299	if (!fttmr010) {
    300		ret = -ENOMEM;
    301		goto out_disable_clock;
    302	}
    303	fttmr010->tick_rate = clk_get_rate(clk);
    304
    305	fttmr010->base = of_iomap(np, 0);
    306	if (!fttmr010->base) {
    307		pr_err("Can't remap registers\n");
    308		ret = -ENXIO;
    309		goto out_free;
    310	}
    311	/* IRQ for timer 1 */
    312	irq = irq_of_parse_and_map(np, 0);
    313	if (irq <= 0) {
    314		pr_err("Can't parse IRQ\n");
    315		ret = -EINVAL;
    316		goto out_unmap;
    317	}
    318
    319	/*
    320	 * The Aspeed timers move bits around in the control register.
    321	 */
    322	if (is_aspeed) {
    323		fttmr010->t1_enable_val = TIMER_1_CR_ASPEED_ENABLE |
    324			TIMER_1_CR_ASPEED_INT;
    325		fttmr010->is_aspeed = true;
    326	} else {
    327		fttmr010->t1_enable_val = TIMER_1_CR_ENABLE | TIMER_1_CR_INT;
    328
    329		/*
    330		 * Reset the interrupt mask and status
    331		 */
    332		writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
    333		writel(0, fttmr010->base + TIMER_INTR_STATE);
    334	}
    335
    336	/*
    337	 * Enable timer 1 count up, timer 2 count up, except on Aspeed,
    338	 * where everything just counts down.
    339	 */
    340	if (is_aspeed)
    341		val = TIMER_2_CR_ASPEED_ENABLE;
    342	else {
    343		val = TIMER_2_CR_ENABLE | TIMER_1_CR_UPDOWN |
    344			TIMER_2_CR_UPDOWN;
    345	}
    346	writel(val, fttmr010->base + TIMER_CR);
    347
    348	/*
    349	 * Setup free-running clocksource timer (interrupts
    350	 * disabled.)
    351	 */
    352	local_fttmr = fttmr010;
    353	writel(0, fttmr010->base + TIMER2_COUNT);
    354	writel(0, fttmr010->base + TIMER2_MATCH1);
    355	writel(0, fttmr010->base + TIMER2_MATCH2);
    356
    357	if (fttmr010->is_aspeed) {
    358		writel(~0, fttmr010->base + TIMER2_LOAD);
    359		clocksource_mmio_init(fttmr010->base + TIMER2_COUNT,
    360				      "FTTMR010-TIMER2",
    361				      fttmr010->tick_rate,
    362				      300, 32, clocksource_mmio_readl_down);
    363		sched_clock_register(fttmr010_read_sched_clock_down, 32,
    364				     fttmr010->tick_rate);
    365	} else {
    366		writel(0, fttmr010->base + TIMER2_LOAD);
    367		clocksource_mmio_init(fttmr010->base + TIMER2_COUNT,
    368				      "FTTMR010-TIMER2",
    369				      fttmr010->tick_rate,
    370				      300, 32, clocksource_mmio_readl_up);
    371		sched_clock_register(fttmr010_read_sched_clock_up, 32,
    372				     fttmr010->tick_rate);
    373	}
    374
    375	/*
    376	 * Setup clockevent timer (interrupt-driven) on timer 1.
    377	 */
    378	writel(0, fttmr010->base + TIMER1_COUNT);
    379	writel(0, fttmr010->base + TIMER1_LOAD);
    380	writel(0, fttmr010->base + TIMER1_MATCH1);
    381	writel(0, fttmr010->base + TIMER1_MATCH2);
    382
    383	if (is_ast2600) {
    384		fttmr010->timer_shutdown = ast2600_timer_shutdown;
    385		ret = request_irq(irq, ast2600_timer_interrupt,
    386				  IRQF_TIMER, "FTTMR010-TIMER1",
    387				  &fttmr010->clkevt);
    388	} else {
    389		fttmr010->timer_shutdown = fttmr010_timer_shutdown;
    390		ret = request_irq(irq, fttmr010_timer_interrupt,
    391				  IRQF_TIMER, "FTTMR010-TIMER1",
    392				  &fttmr010->clkevt);
    393	}
    394	if (ret) {
    395		pr_err("FTTMR010-TIMER1 no IRQ\n");
    396		goto out_unmap;
    397	}
    398
    399	fttmr010->clkevt.name = "FTTMR010-TIMER1";
    400	/* Reasonably fast and accurate clock event */
    401	fttmr010->clkevt.rating = 300;
    402	fttmr010->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
    403		CLOCK_EVT_FEAT_ONESHOT;
    404	fttmr010->clkevt.set_next_event = fttmr010_timer_set_next_event;
    405	fttmr010->clkevt.set_state_shutdown = fttmr010->timer_shutdown;
    406	fttmr010->clkevt.set_state_periodic = fttmr010_timer_set_periodic;
    407	fttmr010->clkevt.set_state_oneshot = fttmr010_timer_set_oneshot;
    408	fttmr010->clkevt.tick_resume = fttmr010->timer_shutdown;
    409	fttmr010->clkevt.cpumask = cpumask_of(0);
    410	fttmr010->clkevt.irq = irq;
    411	clockevents_config_and_register(&fttmr010->clkevt,
    412					fttmr010->tick_rate,
    413					1, 0xffffffff);
    414
    415#ifdef CONFIG_ARM
    416	/* Also use this timer for delays */
    417	if (fttmr010->is_aspeed)
    418		fttmr010->delay_timer.read_current_timer =
    419			fttmr010_read_current_timer_down;
    420	else
    421		fttmr010->delay_timer.read_current_timer =
    422			fttmr010_read_current_timer_up;
    423	fttmr010->delay_timer.freq = fttmr010->tick_rate;
    424	register_current_timer_delay(&fttmr010->delay_timer);
    425#endif
    426
    427	return 0;
    428
    429out_unmap:
    430	iounmap(fttmr010->base);
    431out_free:
    432	kfree(fttmr010);
    433out_disable_clock:
    434	clk_disable_unprepare(clk);
    435
    436	return ret;
    437}
    438
    439static __init int ast2600_timer_init(struct device_node *np)
    440{
    441	return fttmr010_common_init(np, true, true);
    442}
    443
    444static __init int aspeed_timer_init(struct device_node *np)
    445{
    446	return fttmr010_common_init(np, true, false);
    447}
    448
    449static __init int fttmr010_timer_init(struct device_node *np)
    450{
    451	return fttmr010_common_init(np, false, false);
    452}
    453
    454TIMER_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);
    455TIMER_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init);
    456TIMER_OF_DECLARE(moxart, "moxa,moxart-timer", fttmr010_timer_init);
    457TIMER_OF_DECLARE(ast2400, "aspeed,ast2400-timer", aspeed_timer_init);
    458TIMER_OF_DECLARE(ast2500, "aspeed,ast2500-timer", aspeed_timer_init);
    459TIMER_OF_DECLARE(ast2600, "aspeed,ast2600-timer", ast2600_timer_init);