1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Renesas Timer Support - OSTM 4 * 5 * Copyright (C) 2017 Renesas Electronics America, Inc. 6 * Copyright (C) 2017 Chris Brandt 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/clockchips.h> 11 #include <linux/interrupt.h> 12 #include <linux/sched_clock.h> 13 #include <linux/slab.h> 14 15 #include "timer-of.h" 16 17 /* 18 * The OSTM contains independent channels. 19 * The first OSTM channel probed will be set up as a free running 20 * clocksource. Additionally we will use this clocksource for the system 21 * schedule timer sched_clock(). 22 * 23 * The second (or more) channel probed will be set up as an interrupt 24 * driven clock event. 25 */ 26 27 static void __iomem *system_clock; /* For sched_clock() */ 28 29 /* OSTM REGISTERS */ 30 #define OSTM_CMP 0x000 /* RW,32 */ 31 #define OSTM_CNT 0x004 /* R,32 */ 32 #define OSTM_TE 0x010 /* R,8 */ 33 #define OSTM_TS 0x014 /* W,8 */ 34 #define OSTM_TT 0x018 /* W,8 */ 35 #define OSTM_CTL 0x020 /* RW,8 */ 36 37 #define TE 0x01 38 #define TS 0x01 39 #define TT 0x01 40 #define CTL_PERIODIC 0x00 41 #define CTL_ONESHOT 0x02 42 #define CTL_FREERUN 0x02 43 44 static void ostm_timer_stop(struct timer_of *to) 45 { 46 if (readb(timer_of_base(to) + OSTM_TE) & TE) { 47 writeb(TT, timer_of_base(to) + OSTM_TT); 48 49 /* 50 * Read back the register simply to confirm the write operation 51 * has completed since I/O writes can sometimes get queued by 52 * the bus architecture. 53 */ 54 while (readb(timer_of_base(to) + OSTM_TE) & TE) 55 ; 56 } 57 } 58 59 static int __init ostm_init_clksrc(struct timer_of *to) 60 { 61 ostm_timer_stop(to); 62 63 writel(0, timer_of_base(to) + OSTM_CMP); 64 writeb(CTL_FREERUN, timer_of_base(to) + OSTM_CTL); 65 writeb(TS, timer_of_base(to) + OSTM_TS); 66 67 return clocksource_mmio_init(timer_of_base(to) + OSTM_CNT, 68 to->np->full_name, timer_of_rate(to), 300, 69 32, clocksource_mmio_readl_up); 70 } 71 72 static u64 notrace ostm_read_sched_clock(void) 73 { 74 return readl(system_clock); 75 } 76 77 static void __init ostm_init_sched_clock(struct timer_of *to) 78 { 79 system_clock = timer_of_base(to) + OSTM_CNT; 80 sched_clock_register(ostm_read_sched_clock, 32, timer_of_rate(to)); 81 } 82 83 static int ostm_clock_event_next(unsigned long delta, 84 struct clock_event_device *ced) 85 { 86 struct timer_of *to = to_timer_of(ced); 87 88 ostm_timer_stop(to); 89 90 writel(delta, timer_of_base(to) + OSTM_CMP); 91 writeb(CTL_ONESHOT, timer_of_base(to) + OSTM_CTL); 92 writeb(TS, timer_of_base(to) + OSTM_TS); 93 94 return 0; 95 } 96 97 static int ostm_shutdown(struct clock_event_device *ced) 98 { 99 struct timer_of *to = to_timer_of(ced); 100 101 ostm_timer_stop(to); 102 103 return 0; 104 } 105 static int ostm_set_periodic(struct clock_event_device *ced) 106 { 107 struct timer_of *to = to_timer_of(ced); 108 109 if (clockevent_state_oneshot(ced) || clockevent_state_periodic(ced)) 110 ostm_timer_stop(to); 111 112 writel(timer_of_period(to) - 1, timer_of_base(to) + OSTM_CMP); 113 writeb(CTL_PERIODIC, timer_of_base(to) + OSTM_CTL); 114 writeb(TS, timer_of_base(to) + OSTM_TS); 115 116 return 0; 117 } 118 119 static int ostm_set_oneshot(struct clock_event_device *ced) 120 { 121 struct timer_of *to = to_timer_of(ced); 122 123 ostm_timer_stop(to); 124 125 return 0; 126 } 127 128 static irqreturn_t ostm_timer_interrupt(int irq, void *dev_id) 129 { 130 struct clock_event_device *ced = dev_id; 131 132 if (clockevent_state_oneshot(ced)) 133 ostm_timer_stop(to_timer_of(ced)); 134 135 /* notify clockevent layer */ 136 if (ced->event_handler) 137 ced->event_handler(ced); 138 139 return IRQ_HANDLED; 140 } 141 142 static int __init ostm_init_clkevt(struct timer_of *to) 143 { 144 struct clock_event_device *ced = &to->clkevt; 145 146 ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC; 147 ced->set_state_shutdown = ostm_shutdown; 148 ced->set_state_periodic = ostm_set_periodic; 149 ced->set_state_oneshot = ostm_set_oneshot; 150 ced->set_next_event = ostm_clock_event_next; 151 ced->shift = 32; 152 ced->rating = 300; 153 ced->cpumask = cpumask_of(0); 154 clockevents_config_and_register(ced, timer_of_rate(to), 0xf, 155 0xffffffff); 156 157 return 0; 158 } 159 160 static int __init ostm_init(struct device_node *np) 161 { 162 struct timer_of *to; 163 int ret; 164 165 to = kzalloc(sizeof(*to), GFP_KERNEL); 166 if (!to) 167 return -ENOMEM; 168 169 to->flags = TIMER_OF_BASE | TIMER_OF_CLOCK; 170 if (system_clock) { 171 /* 172 * clock sources don't use interrupts, clock events do 173 */ 174 to->flags |= TIMER_OF_IRQ; 175 to->of_irq.flags = IRQF_TIMER | IRQF_IRQPOLL; 176 to->of_irq.handler = ostm_timer_interrupt; 177 } 178 179 ret = timer_of_init(np, to); 180 if (ret) 181 goto err_free; 182 183 /* 184 * First probed device will be used as system clocksource. Any 185 * additional devices will be used as clock events. 186 */ 187 if (!system_clock) { 188 ret = ostm_init_clksrc(to); 189 if (ret) 190 goto err_cleanup; 191 192 ostm_init_sched_clock(to); 193 pr_info("%pOF: used for clocksource\n", np); 194 } else { 195 ret = ostm_init_clkevt(to); 196 if (ret) 197 goto err_cleanup; 198 199 pr_info("%pOF: used for clock events\n", np); 200 } 201 202 return 0; 203 204 err_cleanup: 205 timer_of_cleanup(to); 206 err_free: 207 kfree(to); 208 return ret; 209 } 210 211 TIMER_OF_DECLARE(ostm, "renesas,ostm", ostm_init); 212