1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2021 Daniel Palmer
6 * Copyright (C) 2021 Romain Perier
10 #include <linux/clk.h>
11 #include <linux/clockchips.h>
12 #include <linux/interrupt.h>
13 #include <linux/irq.h>
14 #include <linux/irqreturn.h>
15 #include <linux/sched_clock.h>
17 #include <linux/of_address.h>
18 #include <linux/of_irq.h>
21 #include <linux/delay.h>
26 #define TIMER_NAME "msc313e_timer"
28 #define MSC313E_REG_CTRL 0x00
29 #define MSC313E_REG_CTRL_TIMER_EN BIT(0)
30 #define MSC313E_REG_CTRL_TIMER_TRIG BIT(1)
31 #define MSC313E_REG_CTRL_TIMER_INT_EN BIT(8)
32 #define MSC313E_REG_TIMER_MAX_LOW 0x08
33 #define MSC313E_REG_TIMER_MAX_HIGH 0x0c
34 #define MSC313E_REG_COUNTER_LOW 0x10
35 #define MSC313E_REG_COUNTER_HIGH 0x14
36 #define MSC313E_REG_TIMER_DIVIDE 0x18
38 #define MSC313E_CLK_DIVIDER 9
39 #define TIMER_SYNC_TICKS 3
42 struct msc313e_delay
{
44 struct delay_timer delay
;
46 static struct msc313e_delay msc313e_delay
;
49 static void __iomem
*msc313e_clksrc
;
51 static void msc313e_timer_stop(void __iomem
*base
)
53 writew(0, base
+ MSC313E_REG_CTRL
);
56 static void msc313e_timer_start(void __iomem
*base
, bool periodic
)
60 reg
= readw(base
+ MSC313E_REG_CTRL
);
62 reg
|= MSC313E_REG_CTRL_TIMER_EN
;
64 reg
|= MSC313E_REG_CTRL_TIMER_TRIG
;
65 writew(reg
| MSC313E_REG_CTRL_TIMER_INT_EN
, base
+ MSC313E_REG_CTRL
);
68 static void msc313e_timer_setup(void __iomem
*base
, unsigned long delay
)
72 local_irq_save(flags
);
73 writew(delay
>> 16, base
+ MSC313E_REG_TIMER_MAX_HIGH
);
74 writew(delay
& 0xffff, base
+ MSC313E_REG_TIMER_MAX_LOW
);
75 local_irq_restore(flags
);
78 static unsigned long msc313e_timer_current_value(void __iomem
*base
)
83 local_irq_save(flags
);
84 l
= readw(base
+ MSC313E_REG_COUNTER_LOW
);
85 h
= readw(base
+ MSC313E_REG_COUNTER_HIGH
);
86 local_irq_restore(flags
);
88 return (((u32
)h
) << 16 | l
);
91 static int msc313e_timer_clkevt_shutdown(struct clock_event_device
*evt
)
93 struct timer_of
*timer
= to_timer_of(evt
);
95 msc313e_timer_stop(timer_of_base(timer
));
100 static int msc313e_timer_clkevt_set_oneshot(struct clock_event_device
*evt
)
102 struct timer_of
*timer
= to_timer_of(evt
);
104 msc313e_timer_stop(timer_of_base(timer
));
105 msc313e_timer_start(timer_of_base(timer
), false);
110 static int msc313e_timer_clkevt_set_periodic(struct clock_event_device
*evt
)
112 struct timer_of
*timer
= to_timer_of(evt
);
114 msc313e_timer_stop(timer_of_base(timer
));
115 msc313e_timer_setup(timer_of_base(timer
), timer_of_period(timer
));
116 msc313e_timer_start(timer_of_base(timer
), true);
121 static int msc313e_timer_clkevt_next_event(unsigned long evt
, struct clock_event_device
*clkevt
)
123 struct timer_of
*timer
= to_timer_of(clkevt
);
125 msc313e_timer_stop(timer_of_base(timer
));
126 msc313e_timer_setup(timer_of_base(timer
), evt
);
127 msc313e_timer_start(timer_of_base(timer
), false);
132 static irqreturn_t
msc313e_timer_clkevt_irq(int irq
, void *dev_id
)
134 struct clock_event_device
*evt
= dev_id
;
136 evt
->event_handler(evt
);
141 static u64
msc313e_timer_clksrc_read(struct clocksource
*cs
)
143 return msc313e_timer_current_value(msc313e_clksrc
) & cs
->mask
;
147 static unsigned long msc313e_read_delay_timer_read(void)
149 return msc313e_timer_current_value(msc313e_delay
.base
);
153 static u64
msc313e_timer_sched_clock_read(void)
155 return msc313e_timer_current_value(msc313e_clksrc
);
158 static struct clock_event_device msc313e_clkevt
= {
161 .features
= CLOCK_EVT_FEAT_PERIODIC
| CLOCK_EVT_FEAT_ONESHOT
,
162 .set_state_shutdown
= msc313e_timer_clkevt_shutdown
,
163 .set_state_periodic
= msc313e_timer_clkevt_set_periodic
,
164 .set_state_oneshot
= msc313e_timer_clkevt_set_oneshot
,
165 .tick_resume
= msc313e_timer_clkevt_shutdown
,
166 .set_next_event
= msc313e_timer_clkevt_next_event
,
169 static int __init
msc313e_clkevt_init(struct device_node
*np
)
174 to
= kzalloc(sizeof(*to
), GFP_KERNEL
);
178 to
->flags
= TIMER_OF_IRQ
| TIMER_OF_CLOCK
| TIMER_OF_BASE
;
179 to
->of_irq
.handler
= msc313e_timer_clkevt_irq
;
180 ret
= timer_of_init(np
, to
);
184 if (of_device_is_compatible(np
, "sstar,ssd20xd-timer")) {
185 to
->of_clk
.rate
= clk_get_rate(to
->of_clk
.clk
) / MSC313E_CLK_DIVIDER
;
186 to
->of_clk
.period
= DIV_ROUND_UP(to
->of_clk
.rate
, HZ
);
187 writew(MSC313E_CLK_DIVIDER
- 1, timer_of_base(to
) + MSC313E_REG_TIMER_DIVIDE
);
190 msc313e_clkevt
.cpumask
= cpu_possible_mask
;
191 msc313e_clkevt
.irq
= to
->of_irq
.irq
;
192 to
->clkevt
= msc313e_clkevt
;
194 clockevents_config_and_register(&to
->clkevt
, timer_of_rate(to
),
195 TIMER_SYNC_TICKS
, 0xffffffff);
199 static int __init
msc313e_clksrc_init(struct device_node
*np
)
201 struct timer_of to
= { 0 };
205 to
.flags
= TIMER_OF_BASE
| TIMER_OF_CLOCK
;
206 ret
= timer_of_init(np
, &to
);
210 msc313e_clksrc
= timer_of_base(&to
);
211 reg
= readw(msc313e_clksrc
+ MSC313E_REG_CTRL
);
212 reg
|= MSC313E_REG_CTRL_TIMER_EN
;
213 writew(reg
, msc313e_clksrc
+ MSC313E_REG_CTRL
);
216 msc313e_delay
.base
= timer_of_base(&to
);
217 msc313e_delay
.delay
.read_current_timer
= msc313e_read_delay_timer_read
;
218 msc313e_delay
.delay
.freq
= timer_of_rate(&to
);
220 register_current_timer_delay(&msc313e_delay
.delay
);
223 sched_clock_register(msc313e_timer_sched_clock_read
, 32, timer_of_rate(&to
));
224 return clocksource_mmio_init(timer_of_base(&to
), TIMER_NAME
, timer_of_rate(&to
), 300, 32,
225 msc313e_timer_clksrc_read
);
228 static int __init
msc313e_timer_init(struct device_node
*np
)
231 static int num_called
;
233 switch (num_called
) {
235 ret
= msc313e_clksrc_init(np
);
241 ret
= msc313e_clkevt_init(np
);
252 TIMER_OF_DECLARE(msc313
, "mstar,msc313e-timer", msc313e_timer_init
);
253 TIMER_OF_DECLARE(ssd20xd
, "sstar,ssd20xd-timer", msc313e_timer_init
);