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
);
65 static void rtl9300_clock_stop(void __iomem
*base
)
69 writel(0, base
+ RTL9300_TC_CTRL
);
71 // Acknowledge possibly pending IRQ
72 v
= readl(base
+ RTL9300_TC_INT
);
73 writel(v
| RTL9300_TC_INT_IP
, base
+ RTL9300_TC_INT
);
76 static void rtl9300_timer_start(void __iomem
*base
, bool periodic
)
78 u32 v
= (periodic
? RTL9300_TC_CTRL_MODE
: 0) | RTL9300_TC_CTRL_EN
| DIVISOR_RTL9300
;
80 writel(0, base
+ RTL9300_TC_CNT
);
81 pr_debug("------------- starting timer base %08x\n", (u32
)base
);
82 writel(v
, base
+ RTL9300_TC_CTRL
);
85 static int rtl9300_next_event(unsigned long delta
, struct clock_event_device
*clk
)
87 void __iomem
*base
= rtl9300_tc_base(clk
);
89 rtl9300_clock_stop(base
);
90 writel(delta
, base
+ RTL9300_TC_DATA
);
91 rtl9300_timer_start(base
, TIMER_MODE_ONCE
);
96 static int rtl9300_state_periodic(struct clock_event_device
*clk
)
98 void __iomem
*base
= rtl9300_tc_base(clk
);
100 pr_debug("------------- rtl9300_state_periodic %08x\n", (u32
)base
);
101 rtl9300_clock_stop(base
);
102 writel(RTL9300_CLOCK_RATE
/ HZ
, base
+ RTL9300_TC_DATA
);
103 rtl9300_timer_start(base
, TIMER_MODE_REPEAT
);
107 static int rtl9300_state_oneshot(struct clock_event_device
*clk
)
109 void __iomem
*base
= rtl9300_tc_base(clk
);
111 pr_debug("------------- rtl9300_state_oneshot %08x\n", (u32
)base
);
112 rtl9300_clock_stop(base
);
113 writel(RTL9300_CLOCK_RATE
/ HZ
, base
+ RTL9300_TC_DATA
);
114 rtl9300_timer_start(base
, TIMER_MODE_ONCE
);
118 static int rtl9300_shutdown(struct clock_event_device
*clk
)
120 void __iomem
*base
= rtl9300_tc_base(clk
);
122 pr_debug("------------- rtl9300_shutdown %08x\n", (u32
)base
);
123 rtl9300_clock_stop(base
);
127 static void rtl9300_clock_setup(void __iomem
*base
)
132 writel(0, base
+ RTL9300_TC_CTRL
);
134 // Acknowledge possibly pending IRQ
135 v
= readl(base
+ RTL9300_TC_INT
);
136 writel(v
| RTL9300_TC_INT_IP
, base
+ RTL9300_TC_INT
);
138 // Setup maximum period (for use as clock-source)
139 writel(0x0fffffff, base
+ RTL9300_TC_DATA
);
142 static DEFINE_PER_CPU(struct rtl9300_clk_dev
, rtl9300_clockevent
);
143 static DEFINE_PER_CPU(char [18], rtl9300_clock_name
);
145 void rtl9300_clockevent_init(void)
147 int cpu
= smp_processor_id();
149 struct rtl9300_clk_dev
*rtl_clk
= &per_cpu(rtl9300_clockevent
, cpu
);
150 struct clock_event_device
*cd
= &rtl_clk
->clkdev
;
151 unsigned char *name
= per_cpu(rtl9300_clock_name
, cpu
);
152 unsigned long flags
= IRQF_PERCPU
| IRQF_TIMER
;
153 struct device_node
*node
;
155 pr_info("%s called for cpu%d\n", __func__
, cpu
);
156 BUG_ON(cpu
> 3); /* Only have 4 general purpose timers */
158 node
= of_find_compatible_node(NULL
, NULL
, "realtek,rtl9300clock");
160 pr_err("No DT entry found for realtek,rtl9300clock\n");
164 irq
= irq_of_parse_and_map(node
, cpu
);
165 pr_info("%s using IRQ %d\n", __func__
, irq
);
167 rtl_clk
->base
= of_iomap(node
, cpu
);
168 if (!rtl_clk
->base
) {
169 pr_err("cannot map timer for cpu %d", cpu
);
173 rtl9300_clock_setup(rtl_clk
->base
);
175 sprintf(name
, "rtl9300-counter-%d", cpu
);
177 cd
->features
= CLOCK_EVT_FEAT_PERIODIC
| CLOCK_EVT_FEAT_ONESHOT
;
179 clockevent_set_clock(cd
, RTL9300_CLOCK_RATE
);
181 cd
->max_delta_ns
= clockevent_delta2ns(0x0fffffff, cd
);
182 cd
->max_delta_ticks
= 0x0fffffff;
183 cd
->min_delta_ns
= clockevent_delta2ns(0x20, cd
);
184 cd
->min_delta_ticks
= 0x20;
187 cd
->cpumask
= cpumask_of(cpu
);
188 cd
->set_next_event
= rtl9300_next_event
;
189 cd
->set_state_shutdown
= rtl9300_shutdown
;
190 cd
->set_state_periodic
= rtl9300_state_periodic
;
191 cd
->set_state_oneshot
= rtl9300_state_oneshot
;
192 clockevents_register_device(cd
);
194 irq_set_affinity(irq
, cd
->cpumask
);
196 if (request_irq(irq
, rtl9300_timer_interrupt
, flags
, name
, rtl_clk
))
197 pr_err("Failed to request irq %d (%s)\n", irq
, name
);
199 writel(RTL9300_TC_INT_IE
, rtl_clk
->base
+ RTL9300_TC_INT
);