1 /*
2 * (C) Copyright 2015 Google, Inc
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7 #ifndef _ASM_ARCH_CLOCK_H
8 #define _ASM_ARCH_CLOCK_H
9
10 /* define pll mode */
11 #define RKCLK_PLL_MODE_SLOW 0
12 #define RKCLK_PLL_MODE_NORMAL 1
13 #define RKCLK_PLL_MODE_DEEP 2
14
15 /*
16 * PLL flags
17 */
18 #define ROCKCHIP_PLL_SYNC_RATE BIT(0)
19 /* normal mode only. now only for pll_rk3036, pll_rk3328 type */
20 #define ROCKCHIP_PLL_FIXED_MODE BIT(1)
21
22 enum {
23 ROCKCHIP_SYSCON_NOC,
24 ROCKCHIP_SYSCON_GRF,
25 ROCKCHIP_SYSCON_SGRF,
26 ROCKCHIP_SYSCON_PMU,
27 ROCKCHIP_SYSCON_PMUGRF,
28 ROCKCHIP_SYSCON_PMUSGRF,
29 ROCKCHIP_SYSCON_CIC,
30 ROCKCHIP_SYSCON_MSCH,
31 ROCKCHIP_SYSCON_USBGRF,
32 ROCKCHIP_SYSCON_PCIE30_PHY_GRF,
33 ROCKCHIP_SYSCON_PHP_GRF,
34 ROCKCHIP_SYSCON_PIPE_PHY0_GRF,
35 ROCKCHIP_SYSCON_PIPE_PHY1_GRF,
36 ROCKCHIP_SYSCON_PIPE_PHY2_GRF,
37 ROCKCHIP_SYSCON_VOP_GRF,
38 ROCKCHIP_SYSCON_VO_GRF,
39 ROCKCHIP_SYSCON_IOC,
40 };
41
42 /* Standard Rockchip clock numbers */
43 enum rk_clk_id {
44 CLK_OSC,
45 CLK_ARM,
46 CLK_DDR,
47 CLK_CODEC,
48 CLK_GENERAL,
49 CLK_NEW,
50
51 CLK_COUNT,
52 };
53
54 #define PLL(_type, _id, _con, _mode, _mshift, \
55 _lshift, _pflags, _rtable) \
56 { \
57 .id = _id, \
58 .type = _type, \
59 .con_offset = _con, \
60 .mode_offset = _mode, \
61 .mode_shift = _mshift, \
62 .lock_shift = _lshift, \
63 .pll_flags = _pflags, \
64 .rate_table = _rtable, \
65 }
66
67 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \
68 _postdiv2, _dsmpd, _frac) \
69 { \
70 .rate = _rate##U, \
71 .fbdiv = _fbdiv, \
72 .postdiv1 = _postdiv1, \
73 .refdiv = _refdiv, \
74 .postdiv2 = _postdiv2, \
75 .dsmpd = _dsmpd, \
76 .frac = _frac, \
77 }
78
79 #define RK3588_PLL_RATE(_rate, _p, _m, _s, _k) \
80 { \
81 .rate = _rate##U, \
82 .p = _p, \
83 .m = _m, \
84 .s = _s, \
85 .k = _k, \
86 }
87
88 struct rockchip_pll_rate_table {
89 unsigned long rate;
90 unsigned int nr;
91 unsigned int nf;
92 unsigned int no;
93 unsigned int nb;
94 /* for RK3036/RK3399 */
95 unsigned int fbdiv;
96 unsigned int postdiv1;
97 unsigned int refdiv;
98 unsigned int postdiv2;
99 unsigned int dsmpd;
100 unsigned int frac;
101 /* for RK3588 */
102 unsigned int m;
103 unsigned int p;
104 unsigned int s;
105 unsigned int k;
106 };
107
108 enum rockchip_pll_type {
109 pll_rk3036,
110 pll_rk3066,
111 pll_rk3328,
112 pll_rk3366,
113 pll_rk3399,
114 pll_rk3588,
115 };
116
117 struct rockchip_pll_clock {
118 unsigned int id;
119 unsigned int con_offset;
120 unsigned int mode_offset;
121 unsigned int mode_shift;
122 unsigned int lock_shift;
123 enum rockchip_pll_type type;
124 unsigned int pll_flags;
125 struct rockchip_pll_rate_table *rate_table;
126 unsigned int mode_mask;
127 };
128
129 struct rockchip_cpu_rate_table {
130 unsigned long rate;
131 unsigned int aclk_div;
132 unsigned int pclk_div;
133 };
134
135 #ifdef CONFIG_ROCKCHIP_IMAGE_TINY
rockchip_pll_get_rate(struct rockchip_pll_clock * pll,void __iomem * base,ulong pll_id)136 static inline ulong rockchip_pll_get_rate(struct rockchip_pll_clock *pll,
137 void __iomem *base,
138 ulong pll_id)
139 {
140 return 0;
141 }
142
rockchip_pll_set_rate(struct rockchip_pll_clock * pll,void __iomem * base,ulong pll_id,ulong drate)143 static inline int rockchip_pll_set_rate(struct rockchip_pll_clock *pll,
144 void __iomem *base, ulong pll_id,
145 ulong drate)
146 {
147 return 0;
148 }
149
150 static inline const struct rockchip_cpu_rate_table *
rockchip_get_cpu_settings(struct rockchip_cpu_rate_table * cpu_table,ulong rate)151 rockchip_get_cpu_settings(struct rockchip_cpu_rate_table *cpu_table,
152 ulong rate)
153 {
154 return NULL;
155 }
156 #else
157 int rockchip_pll_set_rate(struct rockchip_pll_clock *pll,
158 void __iomem *base, ulong clk_id,
159 ulong drate);
160 ulong rockchip_pll_get_rate(struct rockchip_pll_clock *pll,
161 void __iomem *base, ulong clk_id);
162 const struct rockchip_cpu_rate_table *
163 rockchip_get_cpu_settings(struct rockchip_cpu_rate_table *cpu_table,
164 ulong rate);
165 #endif
166
rk_pll_id(enum rk_clk_id clk_id)167 static inline int rk_pll_id(enum rk_clk_id clk_id)
168 {
169 return clk_id - 1;
170 }
171
172 struct sysreset_reg {
173 unsigned int glb_srst_fst_value;
174 unsigned int glb_srst_snd_value;
175 };
176
177 struct softreset_reg {
178 void __iomem *base;
179 unsigned int sf_reset_offset;
180 unsigned int sf_reset_num;
181 };
182
183 /**
184 * clk_get_divisor() - Calculate the required clock divisior
185 *
186 * Given an input rate and a required output_rate, calculate the Rockchip
187 * divisor needed to achieve this.
188 *
189 * @input_rate: Input clock rate in Hz
190 * @output_rate: Output clock rate in Hz
191 * @return divisor register value to use
192 */
clk_get_divisor(ulong input_rate,uint output_rate)193 static inline u32 clk_get_divisor(ulong input_rate, uint output_rate)
194 {
195 uint clk_div;
196
197 clk_div = input_rate / output_rate;
198 clk_div = (clk_div + 1) & 0xfffe;
199
200 return clk_div;
201 }
202
203 /**
204 * rockchip_get_cru() - get a pointer to the clock/reset unit registers
205 *
206 * @return pointer to registers, or -ve error on error
207 */
208 void *rockchip_get_cru(void);
209
210 /**
211 * rockchip_get_pmucru() - get a pointer to the clock/reset unit registers
212 *
213 * @return pointer to registers, or -ve error on error
214 */
215 void *rockchip_get_pmucru(void);
216
217 struct rk3288_cru;
218 struct rk3288_grf;
219
220 void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf);
221
222 int rockchip_get_clk(struct udevice **devp);
223
224 int rockchip_get_scmi_clk(struct udevice **devp);
225
226 #endif
227