xref: /OK3568_Linux_fs/kernel/drivers/rtc/rtc-rk-timer.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2018, Fuzhou Rockchip Electronics Co., Ltd
4*4882a593Smuzhiyun  * Author:  Jeffy Chen <jeffy.chen@rock-chips.com>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Base on the Rockchip timer driver drivers/clocksource/rockchip_timer.c by
7*4882a593Smuzhiyun  * Daniel Lezcano <daniel.lezcano@linaro.org>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/clk.h>
11*4882a593Smuzhiyun #include <linux/kernel.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/of.h>
14*4882a593Smuzhiyun #include <linux/of_device.h>
15*4882a593Smuzhiyun #include <linux/platform_device.h>
16*4882a593Smuzhiyun #include <linux/regmap.h>
17*4882a593Smuzhiyun #include <linux/rtc.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define DRV_NAME		"rk-timer-rtc"
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #define TIMER_LOAD_COUNT0	0x00
22*4882a593Smuzhiyun #define TIMER_LOAD_COUNT1	0x04
23*4882a593Smuzhiyun #define TIMER_CURRENT_VALUE0	0x08
24*4882a593Smuzhiyun #define TIMER_CURRENT_VALUE1	0x0C
25*4882a593Smuzhiyun #define TIMER_CONTROL_REG3288	0x10
26*4882a593Smuzhiyun #define TIMER_INT_STATUS	0x18
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define TIMER_ENABLE			BIT(0)
29*4882a593Smuzhiyun #define TIMER_MODE_USER_DEFINED_COUNT	BIT(1)
30*4882a593Smuzhiyun #define TIMER_INT_UNMASK		BIT(2)
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /* Forbid any alarms which would trigger inside the threshold */
33*4882a593Smuzhiyun #define TIMER_ALARM_THRESHOLD_MS	10
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #if !defined(UINT64_MAX)
36*4882a593Smuzhiyun 	#define UINT64_MAX ((u64)-1)
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /**
40*4882a593Smuzhiyun  * struct rk_timer_rtc_data - Differences between SoC variants
41*4882a593Smuzhiyun  *
42*4882a593Smuzhiyun  * @ctrl_reg_offset: The offset of timer control register
43*4882a593Smuzhiyun  */
44*4882a593Smuzhiyun struct rk_timer_rtc_data {
45*4882a593Smuzhiyun 	int ctrl_reg_offset;
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /**
49*4882a593Smuzhiyun  * struct rk_timer_rtc - Driver data for Rockchip timer RTC
50*4882a593Smuzhiyun  *
51*4882a593Smuzhiyun  * @data: Pointer to rk_timer_rtc_data
52*4882a593Smuzhiyun  * @regmap: Register map of the timer
53*4882a593Smuzhiyun  * @rtc: Pointer to RTC device
54*4882a593Smuzhiyun  * @clk: The timer clock
55*4882a593Smuzhiyun  * @pclk: The peripheral clock
56*4882a593Smuzhiyun  * @freq: The freq of timer clock
57*4882a593Smuzhiyun  * @timebase: The base time of the timer RTC
58*4882a593Smuzhiyun  * @alarm_irq_enabled: Whether to report alarm irqs
59*4882a593Smuzhiyun  * @irq: The timer IRQ number
60*4882a593Smuzhiyun  */
61*4882a593Smuzhiyun struct rk_timer_rtc {
62*4882a593Smuzhiyun 	const struct rk_timer_rtc_data *data;
63*4882a593Smuzhiyun 	struct regmap *regmap;
64*4882a593Smuzhiyun 	struct rtc_device *rtc;
65*4882a593Smuzhiyun 	struct clk *clk;
66*4882a593Smuzhiyun 	struct clk *pclk;
67*4882a593Smuzhiyun 	u32 freq;
68*4882a593Smuzhiyun 	u64 timebase;
69*4882a593Smuzhiyun 	int alarm_irq_enabled;
70*4882a593Smuzhiyun 	int irq;
71*4882a593Smuzhiyun };
72*4882a593Smuzhiyun 
tick_to_sec(struct rk_timer_rtc * rk_timer_rtc,u64 tick)73*4882a593Smuzhiyun static inline u64 tick_to_sec(struct rk_timer_rtc *rk_timer_rtc, u64 tick)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun 	do_div(tick, rk_timer_rtc->freq);
76*4882a593Smuzhiyun 	return tick;
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun 
ms_to_tick(struct rk_timer_rtc * rk_timer_rtc,int ms)79*4882a593Smuzhiyun static inline u64 ms_to_tick(struct rk_timer_rtc *rk_timer_rtc, int ms)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	return ms * rk_timer_rtc->freq / 1000;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
tick_to_time64(struct rk_timer_rtc * rk_timer_rtc,u64 tick)84*4882a593Smuzhiyun static inline u64 tick_to_time64(struct rk_timer_rtc *rk_timer_rtc, u64 tick)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun 	return tick_to_sec(rk_timer_rtc, tick) + rk_timer_rtc->timebase;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
time64_to_tick(struct rk_timer_rtc * rk_timer_rtc,u64 time)89*4882a593Smuzhiyun static inline u64 time64_to_tick(struct rk_timer_rtc *rk_timer_rtc, u64 time)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun 	return (time - rk_timer_rtc->timebase) * rk_timer_rtc->freq;
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun 
rk_timer_rtc_write64(struct rk_timer_rtc * rk_timer_rtc,u32 reg,u64 val)94*4882a593Smuzhiyun static inline int rk_timer_rtc_write64(struct rk_timer_rtc *rk_timer_rtc,
95*4882a593Smuzhiyun 				       u32 reg, u64 val)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun 	return regmap_bulk_write(rk_timer_rtc->regmap, reg, &val, 2);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
rk_timer_rtc_read64(struct rk_timer_rtc * rk_timer_rtc,u32 reg,u64 * val)100*4882a593Smuzhiyun static inline int rk_timer_rtc_read64(struct rk_timer_rtc *rk_timer_rtc,
101*4882a593Smuzhiyun 				      u32 reg, u64 *val)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun 	u32 val_lo, val_hi, tmp_hi;
104*4882a593Smuzhiyun 	int ret;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	do {
107*4882a593Smuzhiyun 		ret = regmap_read(rk_timer_rtc->regmap, reg + 4, &val_hi);
108*4882a593Smuzhiyun 		if (ret)
109*4882a593Smuzhiyun 			return ret;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 		ret = regmap_read(rk_timer_rtc->regmap, reg, &val_lo);
112*4882a593Smuzhiyun 		if (ret)
113*4882a593Smuzhiyun 			return ret;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 		ret = regmap_read(rk_timer_rtc->regmap, reg + 4, &tmp_hi);
116*4882a593Smuzhiyun 		if (ret)
117*4882a593Smuzhiyun 			return ret;
118*4882a593Smuzhiyun 	} while (val_hi != tmp_hi);
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	*val = ((u64) val_hi << 32) | val_lo;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	return 0;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
rk_timer_rtc_irq_clear(struct rk_timer_rtc * rk_timer_rtc)125*4882a593Smuzhiyun static inline int rk_timer_rtc_irq_clear(struct rk_timer_rtc *rk_timer_rtc)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun 	return regmap_write(rk_timer_rtc->regmap, TIMER_INT_STATUS, 1);
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
rk_timer_rtc_irq_enable(struct rk_timer_rtc * rk_timer_rtc,unsigned int enabled)130*4882a593Smuzhiyun static inline int rk_timer_rtc_irq_enable(struct rk_timer_rtc *rk_timer_rtc,
131*4882a593Smuzhiyun 					  unsigned int enabled)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	/* Clear any pending irq before enable it */
134*4882a593Smuzhiyun 	if (enabled)
135*4882a593Smuzhiyun 		rk_timer_rtc_irq_clear(rk_timer_rtc);
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	return regmap_update_bits(rk_timer_rtc->regmap,
138*4882a593Smuzhiyun 				  rk_timer_rtc->data->ctrl_reg_offset,
139*4882a593Smuzhiyun 				  TIMER_INT_UNMASK,
140*4882a593Smuzhiyun 				  enabled ? TIMER_INT_UNMASK : 0);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
rk_timer_rtc_reset(struct rk_timer_rtc * rk_timer_rtc)143*4882a593Smuzhiyun static int rk_timer_rtc_reset(struct rk_timer_rtc *rk_timer_rtc)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	int ret;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	ret = regmap_write(rk_timer_rtc->regmap,
148*4882a593Smuzhiyun 			   rk_timer_rtc->data->ctrl_reg_offset, 0);
149*4882a593Smuzhiyun 	if (ret)
150*4882a593Smuzhiyun 		return ret;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	/* Init load count to UINT64_MAX to keep timer running */
153*4882a593Smuzhiyun 	ret = rk_timer_rtc_write64(rk_timer_rtc, TIMER_LOAD_COUNT0, UINT64_MAX);
154*4882a593Smuzhiyun 	if (ret)
155*4882a593Smuzhiyun 		return ret;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	/* Clear any pending irq before enable it */
158*4882a593Smuzhiyun 	rk_timer_rtc_irq_clear(rk_timer_rtc);
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	/* Enable timer in user-defined count mode with irq unmasked */
161*4882a593Smuzhiyun 	return regmap_write(rk_timer_rtc->regmap,
162*4882a593Smuzhiyun 			    rk_timer_rtc->data->ctrl_reg_offset,
163*4882a593Smuzhiyun 			    TIMER_ENABLE | TIMER_MODE_USER_DEFINED_COUNT |
164*4882a593Smuzhiyun 				TIMER_INT_UNMASK);
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun 
rk_timer_rtc_read_time(struct device * dev,struct rtc_time * tm)167*4882a593Smuzhiyun static int rk_timer_rtc_read_time(struct device *dev, struct rtc_time *tm)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun 	struct rk_timer_rtc *rk_timer_rtc = dev_get_drvdata(dev);
170*4882a593Smuzhiyun 	int ret;
171*4882a593Smuzhiyun 	u64 tick;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	ret = rk_timer_rtc_read64(rk_timer_rtc, TIMER_CURRENT_VALUE0, &tick);
174*4882a593Smuzhiyun 	if (ret)
175*4882a593Smuzhiyun 		return ret;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	rtc_time64_to_tm(tick_to_time64(rk_timer_rtc, tick), tm);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	dev_dbg(dev, "Read RTC: %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
180*4882a593Smuzhiyun 		1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
181*4882a593Smuzhiyun 		tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	return rtc_valid_tm(tm);
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun 
rk_timer_rtc_set_time(struct device * dev,struct rtc_time * tm)186*4882a593Smuzhiyun static int rk_timer_rtc_set_time(struct device *dev, struct rtc_time *tm)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun 	struct rk_timer_rtc *rk_timer_rtc = dev_get_drvdata(dev);
189*4882a593Smuzhiyun 	int ret;
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	dev_dbg(dev, "Set RTC:%4d-%02d-%02d(%d) %02d:%02d:%02d\n",
192*4882a593Smuzhiyun 		1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
193*4882a593Smuzhiyun 		tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	ret = rtc_valid_tm(tm);
196*4882a593Smuzhiyun 	if (ret)
197*4882a593Smuzhiyun 		return ret;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	rk_timer_rtc->timebase = rtc_tm_to_time64(tm);
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	dev_dbg(dev, "Setting new timebase:%lld\n", rk_timer_rtc->timebase);
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	/* Restart timer for new timebase */
204*4882a593Smuzhiyun 	ret = rk_timer_rtc_reset(rk_timer_rtc);
205*4882a593Smuzhiyun 	if (ret) {
206*4882a593Smuzhiyun 		dev_err(dev, "Failed to reset timer:%d\n", ret);
207*4882a593Smuzhiyun 		return ret;
208*4882a593Smuzhiyun 	}
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	/* Tell framework to check alarms */
211*4882a593Smuzhiyun 	rtc_update_irq(rk_timer_rtc->rtc, 1, RTC_IRQF | RTC_AF);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	return 0;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun 
rk_timer_rtc_read_alarm(struct device * dev,struct rtc_wkalrm * alrm)216*4882a593Smuzhiyun static int rk_timer_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun 	struct rk_timer_rtc *rk_timer_rtc = dev_get_drvdata(dev);
219*4882a593Smuzhiyun 	int ret;
220*4882a593Smuzhiyun 	u64 tick;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	ret = rk_timer_rtc_read64(rk_timer_rtc, TIMER_LOAD_COUNT0, &tick);
223*4882a593Smuzhiyun 	if (ret)
224*4882a593Smuzhiyun 		return ret;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	rtc_time64_to_tm(tick_to_time64(rk_timer_rtc, tick), &alrm->time);
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	dev_dbg(dev, "Read alarm: %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
229*4882a593Smuzhiyun 		1900 + alrm->time.tm_year, alrm->time.tm_mon + 1,
230*4882a593Smuzhiyun 		alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
231*4882a593Smuzhiyun 		alrm->time.tm_min, alrm->time.tm_sec);
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	return rtc_valid_tm(&alrm->time);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
rk_timer_rtc_set_alarm(struct device * dev,struct rtc_wkalrm * alrm)236*4882a593Smuzhiyun static int rk_timer_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	struct rk_timer_rtc *rk_timer_rtc = dev_get_drvdata(dev);
239*4882a593Smuzhiyun 	int ret;
240*4882a593Smuzhiyun 	u64 alarm_tick, alarm_threshold_tick, cur_tick;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	dev_dbg(dev, "Set alarm:%4d-%02d-%02d(%d) %02d:%02d:%02d\n",
243*4882a593Smuzhiyun 		1900 + alrm->time.tm_year, alrm->time.tm_mon + 1,
244*4882a593Smuzhiyun 		alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour,
245*4882a593Smuzhiyun 		alrm->time.tm_min, alrm->time.tm_sec);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	ret = rtc_valid_tm(&alrm->time);
248*4882a593Smuzhiyun 	if (ret)
249*4882a593Smuzhiyun 		return ret;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	rk_timer_rtc->alarm_irq_enabled = false;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	alarm_tick = time64_to_tick(rk_timer_rtc,
254*4882a593Smuzhiyun 				    rtc_tm_to_time64(&alrm->time));
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	ret = rk_timer_rtc_read64(rk_timer_rtc, TIMER_CURRENT_VALUE0,
257*4882a593Smuzhiyun 				  &cur_tick);
258*4882a593Smuzhiyun 	if (ret)
259*4882a593Smuzhiyun 		return ret;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	/* Don't set an alarm in the past or about to pass */
262*4882a593Smuzhiyun 	alarm_threshold_tick = ms_to_tick(rk_timer_rtc,
263*4882a593Smuzhiyun 					  TIMER_ALARM_THRESHOLD_MS);
264*4882a593Smuzhiyun 	if (alarm_tick <= (cur_tick + alarm_threshold_tick))
265*4882a593Smuzhiyun 		return -ETIME;
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	/*
268*4882a593Smuzhiyun 	 * When the current value counts up to the load count, the timer will
269*4882a593Smuzhiyun 	 * stop and generate an irq.
270*4882a593Smuzhiyun 	 */
271*4882a593Smuzhiyun 	ret = rk_timer_rtc_write64(rk_timer_rtc, TIMER_LOAD_COUNT0, alarm_tick);
272*4882a593Smuzhiyun 	if (ret)
273*4882a593Smuzhiyun 		return ret;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	dev_dbg(dev, "New alarm enabled:%d\n", alrm->enabled);
276*4882a593Smuzhiyun 	rk_timer_rtc->alarm_irq_enabled = alrm->enabled;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	return 0;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun 
rk_timer_rtc_alarm_irq_enable(struct device * dev,unsigned int enabled)281*4882a593Smuzhiyun static int rk_timer_rtc_alarm_irq_enable(struct device *dev,
282*4882a593Smuzhiyun 					 unsigned int enabled)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 	struct rk_timer_rtc *rk_timer_rtc = dev_get_drvdata(dev);
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	dev_dbg(dev, "Set alarm irq enabled:%d\n", enabled);
287*4882a593Smuzhiyun 	rk_timer_rtc->alarm_irq_enabled = enabled;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	return 0;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun 
rk_timer_rtc_alarm_irq(int irq,void * data)292*4882a593Smuzhiyun static irqreturn_t rk_timer_rtc_alarm_irq(int irq, void *data)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun 	struct device *dev = data;
295*4882a593Smuzhiyun 	struct rk_timer_rtc *rk_timer_rtc = dev_get_drvdata(dev);
296*4882a593Smuzhiyun 	int ret;
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	dev_dbg(dev, "Received timer irq, alarm_irq_enabled:%d\n",
299*4882a593Smuzhiyun 		rk_timer_rtc->alarm_irq_enabled);
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	/* The timer is stopped now, reset the load count to start it again */
302*4882a593Smuzhiyun 	ret = rk_timer_rtc_write64(rk_timer_rtc, TIMER_LOAD_COUNT0, UINT64_MAX);
303*4882a593Smuzhiyun 	if (ret)
304*4882a593Smuzhiyun 		dev_err(dev, "Failed to set load count:%d\n", ret);
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	ret = regmap_write(rk_timer_rtc->regmap, TIMER_INT_STATUS, 1);
307*4882a593Smuzhiyun 	if (ret)
308*4882a593Smuzhiyun 		dev_err(dev, "Failed to clear irq:%d\n", ret);
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	/* Only report rtc irq when alarm irq is enabled */
311*4882a593Smuzhiyun 	if (rk_timer_rtc->alarm_irq_enabled)
312*4882a593Smuzhiyun 		rtc_update_irq(rk_timer_rtc->rtc, 1, RTC_IRQF | RTC_AF);
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	return IRQ_HANDLED;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun static const struct rtc_class_ops rk_timer_rtc_ops = {
318*4882a593Smuzhiyun 	.read_time = rk_timer_rtc_read_time,
319*4882a593Smuzhiyun 	.set_time = rk_timer_rtc_set_time,
320*4882a593Smuzhiyun 	.read_alarm = rk_timer_rtc_read_alarm,
321*4882a593Smuzhiyun 	.set_alarm = rk_timer_rtc_set_alarm,
322*4882a593Smuzhiyun 	.alarm_irq_enable = rk_timer_rtc_alarm_irq_enable,
323*4882a593Smuzhiyun };
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun static struct regmap_config rk_timer_regmap_config = {
326*4882a593Smuzhiyun 	.name		= DRV_NAME,
327*4882a593Smuzhiyun 	.reg_bits	= 32,
328*4882a593Smuzhiyun 	.val_bits	= 32,
329*4882a593Smuzhiyun 	.reg_stride	= 4,
330*4882a593Smuzhiyun };
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun static const struct of_device_id rk_timer_rtc_dt_match[];
333*4882a593Smuzhiyun 
rk_timer_rtc_probe(struct platform_device * pdev)334*4882a593Smuzhiyun static int rk_timer_rtc_probe(struct platform_device *pdev)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun 	const struct of_device_id *match;
337*4882a593Smuzhiyun 	struct device *dev = &pdev->dev;
338*4882a593Smuzhiyun 	struct rk_timer_rtc *rk_timer_rtc;
339*4882a593Smuzhiyun 	void __iomem *base;
340*4882a593Smuzhiyun 	resource_size_t size;
341*4882a593Smuzhiyun 	int ret;
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	rk_timer_rtc = devm_kzalloc(dev, sizeof(*rk_timer_rtc), GFP_KERNEL);
344*4882a593Smuzhiyun 	if (!rk_timer_rtc)
345*4882a593Smuzhiyun 		return -ENOMEM;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	match = of_match_node(rk_timer_rtc_dt_match, dev->of_node);
348*4882a593Smuzhiyun 	rk_timer_rtc->data = match->data;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	platform_set_drvdata(pdev, rk_timer_rtc);
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	base = devm_of_iomap(dev, dev->of_node, 0, &size);
353*4882a593Smuzhiyun 	if (!base) {
354*4882a593Smuzhiyun 		dev_err(dev, "Failed to iomap\n");
355*4882a593Smuzhiyun 		return -EINVAL;
356*4882a593Smuzhiyun 	}
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	rk_timer_regmap_config.max_register = size - 4;
359*4882a593Smuzhiyun 	rk_timer_rtc->regmap = devm_regmap_init_mmio(dev, base,
360*4882a593Smuzhiyun 						     &rk_timer_regmap_config);
361*4882a593Smuzhiyun 	if (IS_ERR(rk_timer_rtc->regmap)) {
362*4882a593Smuzhiyun 		ret = PTR_ERR(rk_timer_rtc->regmap);
363*4882a593Smuzhiyun 		dev_err(dev, "Failed to init regmap:%d\n", ret);
364*4882a593Smuzhiyun 		return ret;
365*4882a593Smuzhiyun 	}
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	rk_timer_rtc->irq = platform_get_irq(pdev, 0);
368*4882a593Smuzhiyun 	if (rk_timer_rtc->irq < 0) {
369*4882a593Smuzhiyun 		ret = rk_timer_rtc->irq;
370*4882a593Smuzhiyun 		dev_err(dev, "Failed to get irq:%d\n", ret);
371*4882a593Smuzhiyun 		return ret;
372*4882a593Smuzhiyun 	}
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	ret = devm_request_irq(dev, rk_timer_rtc->irq, rk_timer_rtc_alarm_irq,
375*4882a593Smuzhiyun 			       0, dev_name(dev), dev);
376*4882a593Smuzhiyun 	if (ret) {
377*4882a593Smuzhiyun 		dev_err(dev, "Failed to request irq:%d\n", ret);
378*4882a593Smuzhiyun 		return ret;
379*4882a593Smuzhiyun 	}
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	rk_timer_rtc->pclk = devm_clk_get(dev, "pclk");
382*4882a593Smuzhiyun 	if (IS_ERR(rk_timer_rtc->pclk)) {
383*4882a593Smuzhiyun 		ret = PTR_ERR(rk_timer_rtc->pclk);
384*4882a593Smuzhiyun 		pr_err("Failed to get timer pclk:%d\n", ret);
385*4882a593Smuzhiyun 		return ret;
386*4882a593Smuzhiyun 	}
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	ret = clk_prepare_enable(rk_timer_rtc->pclk);
389*4882a593Smuzhiyun 	if (ret) {
390*4882a593Smuzhiyun 		dev_err(dev, "Failed to enable pclk:%d\n", ret);
391*4882a593Smuzhiyun 		return ret;
392*4882a593Smuzhiyun 	}
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	rk_timer_rtc->clk = devm_clk_get(dev, "timer");
395*4882a593Smuzhiyun 	if (IS_ERR(rk_timer_rtc->clk)) {
396*4882a593Smuzhiyun 		ret = PTR_ERR(rk_timer_rtc->clk);
397*4882a593Smuzhiyun 		pr_err("Failed to get timer clk:%d\n", ret);
398*4882a593Smuzhiyun 		goto err_disable_pclk;
399*4882a593Smuzhiyun 	}
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	ret = clk_prepare_enable(rk_timer_rtc->clk);
402*4882a593Smuzhiyun 	if (ret) {
403*4882a593Smuzhiyun 		dev_err(dev, "Failed to enable timer clk:%d\n", ret);
404*4882a593Smuzhiyun 		goto err_disable_pclk;
405*4882a593Smuzhiyun 	}
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	rk_timer_rtc->freq = clk_get_rate(rk_timer_rtc->clk);
408*4882a593Smuzhiyun 	dev_dbg(dev, "RTC timer freq:%d\n", rk_timer_rtc->freq);
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	ret = rk_timer_rtc_reset(rk_timer_rtc);
411*4882a593Smuzhiyun 	if (ret) {
412*4882a593Smuzhiyun 		dev_err(dev, "Failed to reset timer:%d\n", ret);
413*4882a593Smuzhiyun 		goto err_disable_clk;
414*4882a593Smuzhiyun 	}
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	ret = device_init_wakeup(dev, true);
417*4882a593Smuzhiyun 	if (ret) {
418*4882a593Smuzhiyun 		dev_err(dev, "Failed to init wakeup:%d\n", ret);
419*4882a593Smuzhiyun 		goto err_disable_irq;
420*4882a593Smuzhiyun 	}
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	rk_timer_rtc->rtc = devm_rtc_device_register(dev, DRV_NAME,
423*4882a593Smuzhiyun 						     &rk_timer_rtc_ops,
424*4882a593Smuzhiyun 						     THIS_MODULE);
425*4882a593Smuzhiyun 	if (IS_ERR(rk_timer_rtc->rtc)) {
426*4882a593Smuzhiyun 		ret = PTR_ERR(rk_timer_rtc->rtc);
427*4882a593Smuzhiyun 		dev_err(dev, "Failed to register rtc:%d\n", ret);
428*4882a593Smuzhiyun 		goto err_uninit_wakeup;
429*4882a593Smuzhiyun 	}
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 	return 0;
432*4882a593Smuzhiyun err_uninit_wakeup:
433*4882a593Smuzhiyun 	device_init_wakeup(&pdev->dev, false);
434*4882a593Smuzhiyun err_disable_irq:
435*4882a593Smuzhiyun 	rk_timer_rtc_irq_enable(rk_timer_rtc, false);
436*4882a593Smuzhiyun err_disable_clk:
437*4882a593Smuzhiyun 	clk_disable_unprepare(rk_timer_rtc->clk);
438*4882a593Smuzhiyun err_disable_pclk:
439*4882a593Smuzhiyun 	clk_disable_unprepare(rk_timer_rtc->pclk);
440*4882a593Smuzhiyun 	return ret;
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun 
rk_timer_rtc_remove(struct platform_device * pdev)443*4882a593Smuzhiyun static int rk_timer_rtc_remove(struct platform_device *pdev)
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun 	struct rk_timer_rtc *rk_timer_rtc = dev_get_drvdata(&pdev->dev);
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	device_init_wakeup(&pdev->dev, false);
448*4882a593Smuzhiyun 	rk_timer_rtc_irq_enable(rk_timer_rtc, false);
449*4882a593Smuzhiyun 	clk_disable_unprepare(rk_timer_rtc->clk);
450*4882a593Smuzhiyun 	clk_disable_unprepare(rk_timer_rtc->pclk);
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 	return 0;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
rk_timer_rtc_suspend(struct device * dev)456*4882a593Smuzhiyun static int rk_timer_rtc_suspend(struct device *dev)
457*4882a593Smuzhiyun {
458*4882a593Smuzhiyun 	struct rk_timer_rtc *rk_timer_rtc = dev_get_drvdata(dev);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	if (device_may_wakeup(dev))
461*4882a593Smuzhiyun 		enable_irq_wake(rk_timer_rtc->irq);
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	return 0;
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun 
rk_timer_rtc_resume(struct device * dev)466*4882a593Smuzhiyun static int rk_timer_rtc_resume(struct device *dev)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun 	struct rk_timer_rtc *rk_timer_rtc = dev_get_drvdata(dev);
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	if (device_may_wakeup(dev))
471*4882a593Smuzhiyun 		disable_irq_wake(rk_timer_rtc->irq);
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	return 0;
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun #endif
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(rk_timer_rtc_pm_ops, rk_timer_rtc_suspend,
478*4882a593Smuzhiyun 			 rk_timer_rtc_resume);
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun static const struct rk_timer_rtc_data rk3288_timer_rtc_data = {
481*4882a593Smuzhiyun 	.ctrl_reg_offset = TIMER_CONTROL_REG3288,
482*4882a593Smuzhiyun };
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun static const struct of_device_id rk_timer_rtc_dt_match[] = {
485*4882a593Smuzhiyun 	{
486*4882a593Smuzhiyun 		.compatible = "rockchip,rk3308-timer-rtc",
487*4882a593Smuzhiyun 		.data = &rk3288_timer_rtc_data,
488*4882a593Smuzhiyun 	},
489*4882a593Smuzhiyun 	{ /* sentinel */ }
490*4882a593Smuzhiyun };
491*4882a593Smuzhiyun MODULE_DEVICE_TABLE(platform, rk_timer_rtc_dt_match);
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun static struct platform_driver rk_timer_rtc_driver = {
494*4882a593Smuzhiyun 	.probe = rk_timer_rtc_probe,
495*4882a593Smuzhiyun 	.remove = rk_timer_rtc_remove,
496*4882a593Smuzhiyun 	.driver = {
497*4882a593Smuzhiyun 		.name = DRV_NAME,
498*4882a593Smuzhiyun 		.pm = &rk_timer_rtc_pm_ops,
499*4882a593Smuzhiyun 		.of_match_table = of_match_ptr(rk_timer_rtc_dt_match),
500*4882a593Smuzhiyun 	},
501*4882a593Smuzhiyun };
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun module_platform_driver(rk_timer_rtc_driver);
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun MODULE_DESCRIPTION("RTC driver for the rockchip timer");
506*4882a593Smuzhiyun MODULE_AUTHOR("Jeffy Chen <jeffy.chen@rock-chips.com>");
507*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
508*4882a593Smuzhiyun MODULE_ALIAS("platform:" DRV_NAME);
509