1 // SPDX-License-Identifier: GPL-2.0-only
3 #include <linux/clockchips.h>
4 #include <linux/init.h>
7 #include <linux/interrupt.h>
8 #include <linux/of_address.h>
9 #include <linux/of_irq.h>
10 #include <linux/sched_clock.h>
12 #include <mach-rtl83xx.h>
16 * the RTL9300/9310 SoCs have 6 timers, each register block 0x10 apart
18 #define RTL9300_TC_DATA 0x0
19 #define RTL9300_TC_CNT 0x4
20 #define RTL9300_TC_CTRL 0x8
21 #define RTL9300_TC_CTRL_MODE BIT(24)
22 #define RTL9300_TC_CTRL_EN BIT(28)
23 #define RTL9300_TC_INT 0xc
24 #define RTL9300_TC_INT_IP BIT(16)
25 #define RTL9300_TC_INT_IE BIT(20)
28 #define TIMER_MODE_REPEAT 1
29 #define TIMER_MODE_ONCE 0
31 // Minimum divider is 2
32 #define DIVISOR_RTL9300 2
36 #define RTL9300_CLOCK_RATE 87500000
38 struct rtl9300_clk_dev
{
39 struct clock_event_device clkdev
;
43 static void __iomem
*rtl9300_tc_base(struct clock_event_device
*clk
)
45 struct rtl9300_clk_dev
*rtl_clk
= container_of(clk
, struct rtl9300_clk_dev
, clkdev
);
50 static irqreturn_t
rtl9300_timer_interrupt(int irq
, void *dev_id
)
52 struct rtl9300_clk_dev
*rtl_clk
= dev_id
;
53 struct clock_event_device
*clk
= &rtl_clk
->clkdev
;
55 u32 v
= readl(rtl_clk
->base
+ RTL9300_TC_INT
);
57 // Acknowledge the IRQ
58 v
|= RTL9300_TC_INT_IP
;
59 writel(v
, rtl_clk
->base
+ RTL9300_TC_INT
);
61 clk
->event_handler(clk
);
66 static void rtl9300_clock_stop(void __iomem
*base
)
70 writel(0, base
+ RTL9300_TC_CTRL
);
72 // Acknowledge possibly pending IRQ
73 v
= readl(base
+ RTL9300_TC_INT
);
74 writel(v
| RTL9300_TC_INT_IP
, base
+ RTL9300_TC_INT
);
77 static void rtl9300_timer_start(void __iomem
*base
, bool periodic
)
79 u32 v
= (periodic
? RTL9300_TC_CTRL_MODE
: 0) | RTL9300_TC_CTRL_EN
| DIVISOR_RTL9300
;
81 writel(0, base
+ RTL9300_TC_CNT
);
82 pr_debug("------------- starting timer base %08x\n", (u32
)base
);
83 writel(v
, base
+ RTL9300_TC_CTRL
);
86 static int rtl9300_next_event(unsigned long delta
, struct clock_event_device
*clk
)
88 void __iomem
*base
= rtl9300_tc_base(clk
);
90 rtl9300_clock_stop(base
);
91 writel(delta
, base
+ RTL9300_TC_DATA
);
92 rtl9300_timer_start(base
, TIMER_MODE_ONCE
);
97 static int rtl9300_state_periodic(struct clock_event_device
*clk
)
99 void __iomem
*base
= rtl9300_tc_base(clk
);
101 pr_debug("------------- rtl9300_state_periodic %08x\n", (u32
)base
);
102 rtl9300_clock_stop(base
);
103 writel(RTL9300_CLOCK_RATE
/ HZ
, base
+ RTL9300_TC_DATA
);
104 rtl9300_timer_start(base
, TIMER_MODE_REPEAT
);
109 static int rtl9300_state_oneshot(struct clock_event_device
*clk
)
111 void __iomem
*base
= rtl9300_tc_base(clk
);
113 pr_debug("------------- rtl9300_state_oneshot %08x\n", (u32
)base
);
114 rtl9300_clock_stop(base
);
115 writel(RTL9300_CLOCK_RATE
/ HZ
, base
+ RTL9300_TC_DATA
);
116 rtl9300_timer_start(base
, TIMER_MODE_ONCE
);
121 static int rtl9300_shutdown(struct clock_event_device
*clk
)
123 void __iomem
*base
= rtl9300_tc_base(clk
);
125 pr_debug("------------- rtl9300_shutdown %08x\n", (u32
)base
);
126 rtl9300_clock_stop(base
);
131 static void rtl9300_clock_setup(void __iomem
*base
)
136 writel(0, base
+ RTL9300_TC_CTRL
);
138 // Acknowledge possibly pending IRQ
139 v
= readl(base
+ RTL9300_TC_INT
);
140 writel(v
| RTL9300_TC_INT_IP
, base
+ RTL9300_TC_INT
);
142 // Setup maximum period (for use as clock-source)
143 writel(0x0fffffff, base
+ RTL9300_TC_DATA
);
146 static DEFINE_PER_CPU(struct rtl9300_clk_dev
, rtl9300_clockevent
);
147 static DEFINE_PER_CPU(char [18], rtl9300_clock_name
);
149 void rtl9300_clockevent_init(void)
151 int cpu
= smp_processor_id();
153 struct rtl9300_clk_dev
*rtl_clk
= &per_cpu(rtl9300_clockevent
, cpu
);
154 struct clock_event_device
*cd
= &rtl_clk
->clkdev
;
155 unsigned char *name
= per_cpu(rtl9300_clock_name
, cpu
);
156 unsigned long flags
= IRQF_PERCPU
| IRQF_TIMER
;
157 struct device_node
*node
;
159 pr_info("%s called for cpu%d\n", __func__
, cpu
);
160 BUG_ON(cpu
> 3); /* Only have 4 general purpose timers */
162 node
= of_find_compatible_node(NULL
, NULL
, "realtek,rtl9300clock");
164 pr_err("No DT entry found for realtek,rtl9300clock\n");
168 irq
= irq_of_parse_and_map(node
, cpu
);
169 pr_info("%s using IRQ %d\n", __func__
, irq
);
171 rtl_clk
->base
= of_iomap(node
, cpu
);
172 if (!rtl_clk
->base
) {
173 pr_err("cannot map timer for cpu %d", cpu
);
177 rtl9300_clock_setup(rtl_clk
->base
);
179 sprintf(name
, "rtl9300-counter-%d", cpu
);
181 cd
->features
= CLOCK_EVT_FEAT_PERIODIC
| CLOCK_EVT_FEAT_ONESHOT
;
183 clockevent_set_clock(cd
, RTL9300_CLOCK_RATE
);
185 cd
->max_delta_ns
= clockevent_delta2ns(0x0fffffff, cd
);
186 cd
->max_delta_ticks
= 0x0fffffff;
187 cd
->min_delta_ns
= clockevent_delta2ns(0x20, cd
);
188 cd
->min_delta_ticks
= 0x20;
191 cd
->cpumask
= cpumask_of(cpu
);
192 cd
->set_next_event
= rtl9300_next_event
;
193 cd
->set_state_shutdown
= rtl9300_shutdown
;
194 cd
->set_state_periodic
= rtl9300_state_periodic
;
195 cd
->set_state_oneshot
= rtl9300_state_oneshot
;
196 clockevents_register_device(cd
);
198 irq_set_affinity(irq
, cd
->cpumask
);
200 if (request_irq(irq
, rtl9300_timer_interrupt
, flags
, name
, rtl_clk
))
201 pr_err("Failed to request irq %d (%s)\n", irq
, name
);
203 writel(RTL9300_TC_INT_IE
, rtl_clk
->base
+ RTL9300_TC_INT
);