1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * RDA8810PL SoC timer driver 4 * 5 * Copyright RDA Microelectronics Company Limited 6 * Copyright (c) 2017 Andreas Färber 7 * Copyright (c) 2018 Manivannan Sadhasivam 8 * 9 * RDA8810PL has two independent timers: OSTIMER (56 bit) and HWTIMER (64 bit). 10 * Each timer provides optional interrupt support. In this driver, OSTIMER is 11 * used for clockevents and HWTIMER is used for clocksource. 12 */ 13 14 #include <linux/init.h> 15 #include <linux/interrupt.h> 16 #include <linux/sched_clock.h> 17 18 #include "timer-of.h" 19 20 #define RDA_OSTIMER_LOADVAL_L 0x000 21 #define RDA_OSTIMER_CTRL 0x004 22 #define RDA_HWTIMER_LOCKVAL_L 0x024 23 #define RDA_HWTIMER_LOCKVAL_H 0x028 24 #define RDA_TIMER_IRQ_MASK_SET 0x02c 25 #define RDA_TIMER_IRQ_MASK_CLR 0x030 26 #define RDA_TIMER_IRQ_CLR 0x034 27 28 #define RDA_OSTIMER_CTRL_ENABLE BIT(24) 29 #define RDA_OSTIMER_CTRL_REPEAT BIT(28) 30 #define RDA_OSTIMER_CTRL_LOAD BIT(30) 31 32 #define RDA_TIMER_IRQ_MASK_OSTIMER BIT(0) 33 34 #define RDA_TIMER_IRQ_CLR_OSTIMER BIT(0) 35 36 static int rda_ostimer_start(void __iomem *base, bool periodic, u64 cycles) 37 { 38 u32 ctrl, load_l; 39 40 load_l = (u32)cycles; 41 ctrl = ((cycles >> 32) & 0xffffff); 42 ctrl |= RDA_OSTIMER_CTRL_LOAD | RDA_OSTIMER_CTRL_ENABLE; 43 if (periodic) 44 ctrl |= RDA_OSTIMER_CTRL_REPEAT; 45 46 /* Enable ostimer interrupt first */ 47 writel_relaxed(RDA_TIMER_IRQ_MASK_OSTIMER, 48 base + RDA_TIMER_IRQ_MASK_SET); 49 50 /* Write low 32 bits first, high 24 bits are with ctrl */ 51 writel_relaxed(load_l, base + RDA_OSTIMER_LOADVAL_L); 52 writel_relaxed(ctrl, base + RDA_OSTIMER_CTRL); 53 54 return 0; 55 } 56 57 static int rda_ostimer_stop(void __iomem *base) 58 { 59 /* Disable ostimer interrupt first */ 60 writel_relaxed(RDA_TIMER_IRQ_MASK_OSTIMER, 61 base + RDA_TIMER_IRQ_MASK_CLR); 62 63 writel_relaxed(0, base + RDA_OSTIMER_CTRL); 64 65 return 0; 66 } 67 68 static int rda_ostimer_set_state_shutdown(struct clock_event_device *evt) 69 { 70 struct timer_of *to = to_timer_of(evt); 71 72 rda_ostimer_stop(timer_of_base(to)); 73 74 return 0; 75 } 76 77 static int rda_ostimer_set_state_oneshot(struct clock_event_device *evt) 78 { 79 struct timer_of *to = to_timer_of(evt); 80 81 rda_ostimer_stop(timer_of_base(to)); 82 83 return 0; 84 } 85 86 static int rda_ostimer_set_state_periodic(struct clock_event_device *evt) 87 { 88 struct timer_of *to = to_timer_of(evt); 89 unsigned long cycles_per_jiffy; 90 91 rda_ostimer_stop(timer_of_base(to)); 92 93 cycles_per_jiffy = ((unsigned long long)NSEC_PER_SEC / HZ * 94 evt->mult) >> evt->shift; 95 rda_ostimer_start(timer_of_base(to), true, cycles_per_jiffy); 96 97 return 0; 98 } 99 100 static int rda_ostimer_tick_resume(struct clock_event_device *evt) 101 { 102 return 0; 103 } 104 105 static int rda_ostimer_set_next_event(unsigned long evt, 106 struct clock_event_device *ev) 107 { 108 struct timer_of *to = to_timer_of(ev); 109 110 rda_ostimer_start(timer_of_base(to), false, evt); 111 112 return 0; 113 } 114 115 static irqreturn_t rda_ostimer_interrupt(int irq, void *dev_id) 116 { 117 struct clock_event_device *evt = dev_id; 118 struct timer_of *to = to_timer_of(evt); 119 120 /* clear timer int */ 121 writel_relaxed(RDA_TIMER_IRQ_CLR_OSTIMER, 122 timer_of_base(to) + RDA_TIMER_IRQ_CLR); 123 124 if (evt->event_handler) 125 evt->event_handler(evt); 126 127 return IRQ_HANDLED; 128 } 129 130 static struct timer_of rda_ostimer_of = { 131 .flags = TIMER_OF_IRQ | TIMER_OF_BASE, 132 133 .clkevt = { 134 .name = "rda-ostimer", 135 .rating = 250, 136 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | 137 CLOCK_EVT_FEAT_DYNIRQ, 138 .set_state_shutdown = rda_ostimer_set_state_shutdown, 139 .set_state_oneshot = rda_ostimer_set_state_oneshot, 140 .set_state_periodic = rda_ostimer_set_state_periodic, 141 .tick_resume = rda_ostimer_tick_resume, 142 .set_next_event = rda_ostimer_set_next_event, 143 }, 144 145 .of_base = { 146 .name = "rda-timer", 147 .index = 0, 148 }, 149 150 .of_irq = { 151 .name = "ostimer", 152 .handler = rda_ostimer_interrupt, 153 .flags = IRQF_TIMER, 154 }, 155 }; 156 157 static u64 rda_hwtimer_clocksource_read(void) 158 { 159 void __iomem *base = timer_of_base(&rda_ostimer_of); 160 u32 lo, hi; 161 162 /* Always read low 32 bits first */ 163 do { 164 lo = readl_relaxed(base + RDA_HWTIMER_LOCKVAL_L); 165 hi = readl_relaxed(base + RDA_HWTIMER_LOCKVAL_H); 166 } while (hi != readl_relaxed(base + RDA_HWTIMER_LOCKVAL_H)); 167 168 return ((u64)hi << 32) | lo; 169 } 170 171 static u64 rda_hwtimer_read(struct clocksource *cs) 172 { 173 return rda_hwtimer_clocksource_read(); 174 } 175 176 static struct clocksource rda_hwtimer_clocksource = { 177 .name = "rda-timer", 178 .rating = 400, 179 .read = rda_hwtimer_read, 180 .mask = CLOCKSOURCE_MASK(64), 181 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 182 }; 183 184 static int __init rda_timer_init(struct device_node *np) 185 { 186 unsigned long rate = 2000000; 187 int ret; 188 189 ret = timer_of_init(np, &rda_ostimer_of); 190 if (ret) 191 return ret; 192 193 clocksource_register_hz(&rda_hwtimer_clocksource, rate); 194 sched_clock_register(rda_hwtimer_clocksource_read, 64, rate); 195 196 clockevents_config_and_register(&rda_ostimer_of.clkevt, rate, 197 0x2, UINT_MAX); 198 199 return 0; 200 } 201 202 TIMER_OF_DECLARE(rda8810pl, "rda,8810pl-timer", rda_timer_init); 203