xref: /rk3399_rockchip-uboot/drivers/timer/ae3xx_timer.c (revision b841b6e94662b3b21a56d6ecaab64dcdfb0d311c)
1*b841b6e9Srick /*
2*b841b6e9Srick  * Andestech ATCPIT100 timer driver
3*b841b6e9Srick  *
4*b841b6e9Srick  * (C) Copyright 2016
5*b841b6e9Srick  * Rick Chen, NDS32 Software Engineering, rick@andestech.com
6*b841b6e9Srick  *
7*b841b6e9Srick  * SPDX-License-Identifier:	GPL-2.0+
8*b841b6e9Srick  */
9*b841b6e9Srick #include <common.h>
10*b841b6e9Srick #include <dm.h>
11*b841b6e9Srick #include <errno.h>
12*b841b6e9Srick #include <timer.h>
13*b841b6e9Srick #include <linux/io.h>
14*b841b6e9Srick 
15*b841b6e9Srick DECLARE_GLOBAL_DATA_PTR;
16*b841b6e9Srick 
17*b841b6e9Srick #define REG32_TMR(x)	(*(unsigned long *)	((plat->regs) + (x>>2)))
18*b841b6e9Srick 
19*b841b6e9Srick /*
20*b841b6e9Srick  * Definition of register offsets
21*b841b6e9Srick  */
22*b841b6e9Srick 
23*b841b6e9Srick /* ID and Revision Register */
24*b841b6e9Srick #define ID_REV		0x0
25*b841b6e9Srick 
26*b841b6e9Srick /* Configuration Register */
27*b841b6e9Srick #define CFG		0x10
28*b841b6e9Srick 
29*b841b6e9Srick /* Interrupt Enable Register */
30*b841b6e9Srick #define INT_EN		0x14
31*b841b6e9Srick #define CH_INT_EN(c , i)	((1<<i)<<(4*c))
32*b841b6e9Srick 
33*b841b6e9Srick /* Interrupt Status Register */
34*b841b6e9Srick #define INT_STA		0x18
35*b841b6e9Srick #define CH_INT_STA(c , i)	((1<<i)<<(4*c))
36*b841b6e9Srick 
37*b841b6e9Srick /* Channel Enable Register */
38*b841b6e9Srick #define CH_EN		0x1C
39*b841b6e9Srick #define CH_TMR_EN(c , t)	((1<<t)<<(4*c))
40*b841b6e9Srick 
41*b841b6e9Srick /* Ch n Control REgister */
42*b841b6e9Srick #define CH_CTL(n)	(0x20+0x10*n)
43*b841b6e9Srick /* Channel clock source , bit 3 , 0:External clock , 1:APB clock */
44*b841b6e9Srick #define APB_CLK		(1<<3)
45*b841b6e9Srick /* Channel mode , bit 0~2 */
46*b841b6e9Srick #define TMR_32		1
47*b841b6e9Srick #define TMR_16		2
48*b841b6e9Srick #define TMR_8		3
49*b841b6e9Srick #define PWM		4
50*b841b6e9Srick 
51*b841b6e9Srick #define CH_REL(n)	(0x24+0x10*n)
52*b841b6e9Srick #define CH_CNT(n)	(0x28+0x10*n)
53*b841b6e9Srick 
54*b841b6e9Srick struct atctmr_timer_regs {
55*b841b6e9Srick 	u32	id_rev;		/* 0x00 */
56*b841b6e9Srick 	u32	reservd[3];	/* 0x04 ~ 0x0c */
57*b841b6e9Srick 	u32	cfg;		/* 0x10 */
58*b841b6e9Srick 	u32	int_en;		/* 0x14 */
59*b841b6e9Srick 	u32	int_st;		/* 0x18 */
60*b841b6e9Srick 	u32	ch_en;		/* 0x1c */
61*b841b6e9Srick 	u32	ch0_ctrl;	/* 0x20 */
62*b841b6e9Srick 	u32	ch0_reload;	/* 0x24 */
63*b841b6e9Srick 	u32	ch0_cntr;	/* 0x28 */
64*b841b6e9Srick 	u32	reservd1;	/* 0x2c */
65*b841b6e9Srick 	u32	ch1_ctrl;	/* 0x30 */
66*b841b6e9Srick 	u32	ch1_reload;	/* 0x34 */
67*b841b6e9Srick 	u32	int_mask;	/* 0x38 */
68*b841b6e9Srick };
69*b841b6e9Srick 
70*b841b6e9Srick struct atftmr_timer_platdata {
71*b841b6e9Srick 	unsigned long *regs;
72*b841b6e9Srick };
73*b841b6e9Srick 
74*b841b6e9Srick static int atftmr_timer_get_count(struct udevice *dev, u64 *count)
75*b841b6e9Srick {
76*b841b6e9Srick 	struct atftmr_timer_platdata *plat = dev->platdata;
77*b841b6e9Srick 	u32 val;
78*b841b6e9Srick 	val = ~(REG32_TMR(CH_CNT(1))+0xffffffff);
79*b841b6e9Srick 	*count = timer_conv_64(val);
80*b841b6e9Srick 	return 0;
81*b841b6e9Srick }
82*b841b6e9Srick 
83*b841b6e9Srick static int atctmr_timer_probe(struct udevice *dev)
84*b841b6e9Srick {
85*b841b6e9Srick 	struct atftmr_timer_platdata *plat = dev->platdata;
86*b841b6e9Srick 	REG32_TMR(CH_REL(1)) = 0xffffffff;
87*b841b6e9Srick 	REG32_TMR(CH_CTL(1)) = APB_CLK|TMR_32;
88*b841b6e9Srick 	REG32_TMR(CH_EN) |= CH_TMR_EN(1 , 0);
89*b841b6e9Srick 	return 0;
90*b841b6e9Srick }
91*b841b6e9Srick 
92*b841b6e9Srick static int atctme_timer_ofdata_to_platdata(struct udevice *dev)
93*b841b6e9Srick {
94*b841b6e9Srick 	struct atftmr_timer_platdata *plat = dev_get_platdata(dev);
95*b841b6e9Srick 	plat->regs = map_physmem(dev_get_addr(dev) , 0x100 , MAP_NOCACHE);
96*b841b6e9Srick 	return 0;
97*b841b6e9Srick }
98*b841b6e9Srick 
99*b841b6e9Srick static const struct timer_ops ag101p_timer_ops = {
100*b841b6e9Srick 	.get_count = atftmr_timer_get_count,
101*b841b6e9Srick };
102*b841b6e9Srick 
103*b841b6e9Srick static const struct udevice_id ag101p_timer_ids[] = {
104*b841b6e9Srick 	{ .compatible = "andestech,atcpit100" },
105*b841b6e9Srick 	{}
106*b841b6e9Srick };
107*b841b6e9Srick 
108*b841b6e9Srick U_BOOT_DRIVER(altera_timer) = {
109*b841b6e9Srick 	.name	= "ae3xx_timer",
110*b841b6e9Srick 	.id	= UCLASS_TIMER,
111*b841b6e9Srick 	.of_match = ag101p_timer_ids,
112*b841b6e9Srick 	.ofdata_to_platdata = atctme_timer_ofdata_to_platdata,
113*b841b6e9Srick 	.platdata_auto_alloc_size = sizeof(struct atftmr_timer_platdata),
114*b841b6e9Srick 	.probe = atctmr_timer_probe,
115*b841b6e9Srick 	.ops	= &ag101p_timer_ops,
116*b841b6e9Srick 	.flags = DM_FLAG_PRE_RELOC,
117*b841b6e9Srick };
118