#include <linux/interrupt.h>
#define TIMER_NAME "sprd_timer"
#define TIMER_LOAD_LO 0x0
#define TIMER_LOAD_HI 0x4
#define TIMER_VALUE_LO 0x8
#define TIMER_VALUE_HI 0xc
#define TIMER_CTL_PERIOD_MODE BIT(0)
#define TIMER_CTL_ENABLE BIT(1)
#define TIMER_CTL_64BIT_WIDTH BIT(16)
#define TIMER_INT_EN BIT(0)
#define TIMER_INT_RAW_STS BIT(1)
#define TIMER_INT_MASK_STS BIT(2)
#define TIMER_INT_CLR BIT(3)
#define TIMER_VALUE_SHDW_LO 0x18
#define TIMER_VALUE_SHDW_HI 0x1c
#define TIMER_VALUE_LO_MASK GENMASK(31, 0)
static void sprd_timer_enable(void __iomem *base, u32 flag)
u32 val = readl_relaxed(base + TIMER_CTL);
if (flag & TIMER_CTL_64BIT_WIDTH)
val |= TIMER_CTL_64BIT_WIDTH;
val &= ~TIMER_CTL_64BIT_WIDTH;
if (flag & TIMER_CTL_PERIOD_MODE)
val |= TIMER_CTL_PERIOD_MODE;
val &= ~TIMER_CTL_PERIOD_MODE;
writel_relaxed(val, base + TIMER_CTL);
static void sprd_timer_disable(void __iomem *base)
u32 val = readl_relaxed(base + TIMER_CTL);
val &= ~TIMER_CTL_ENABLE;
writel_relaxed(val, base + TIMER_CTL);
static void sprd_timer_update_counter(void __iomem *base, unsigned long cycles)
writel_relaxed(cycles & TIMER_VALUE_LO_MASK, base + TIMER_LOAD_LO);
writel_relaxed(0, base + TIMER_LOAD_HI);