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