1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (c) 2018 Rockchip Electronics Co. Ltd. |
4 | * |
5 | * Author: Wyon Bi <bivvy.bi@rock-chips.com> |
6 | */ |
7 | |
8 | #include <linux/bits.h> |
9 | #include <linux/kernel.h> |
10 | #include <linux/clk.h> |
11 | #include <linux/iopoll.h> |
12 | #include <linux/clk-provider.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/init.h> |
15 | #include <linux/mfd/syscon.h> |
16 | #include <linux/module.h> |
17 | #include <linux/of.h> |
18 | #include <linux/platform_device.h> |
19 | #include <linux/pm_runtime.h> |
20 | #include <linux/reset.h> |
21 | #include <linux/time64.h> |
22 | |
23 | #include <linux/phy/phy.h> |
24 | #include <linux/phy/phy-mipi-dphy.h> |
25 | |
26 | #define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l))) |
27 | |
28 | /* |
29 | * The offset address[7:0] is distributed two parts, one from the bit7 to bit5 |
30 | * is the first address, the other from the bit4 to bit0 is the second address. |
31 | * when you configure the registers, you must set both of them. The Clock Lane |
32 | * and Data Lane use the same registers with the same second address, but the |
33 | * first address is different. |
34 | */ |
35 | #define FIRST_ADDRESS(x) (((x) & 0x7) << 5) |
36 | #define SECOND_ADDRESS(x) (((x) & 0x1f) << 0) |
37 | #define PHY_REG(first, second) (FIRST_ADDRESS(first) | \ |
38 | SECOND_ADDRESS(second)) |
39 | |
40 | /* Analog Register Part: reg00 */ |
41 | #define BANDGAP_POWER_MASK BIT(7) |
42 | #define BANDGAP_POWER_DOWN BIT(7) |
43 | #define BANDGAP_POWER_ON 0 |
44 | #define LANE_EN_MASK GENMASK(6, 2) |
45 | #define LANE_EN_CK BIT(6) |
46 | #define LANE_EN_3 BIT(5) |
47 | #define LANE_EN_2 BIT(4) |
48 | #define LANE_EN_1 BIT(3) |
49 | #define LANE_EN_0 BIT(2) |
50 | #define POWER_WORK_MASK GENMASK(1, 0) |
51 | #define POWER_WORK_ENABLE UPDATE(1, 1, 0) |
52 | #define POWER_WORK_DISABLE UPDATE(2, 1, 0) |
53 | /* Analog Register Part: reg01 */ |
54 | #define REG_SYNCRST_MASK BIT(2) |
55 | #define REG_SYNCRST_RESET BIT(2) |
56 | #define REG_SYNCRST_NORMAL 0 |
57 | #define REG_LDOPD_MASK BIT(1) |
58 | #define REG_LDOPD_POWER_DOWN BIT(1) |
59 | #define REG_LDOPD_POWER_ON 0 |
60 | #define REG_PLLPD_MASK BIT(0) |
61 | #define REG_PLLPD_POWER_DOWN BIT(0) |
62 | #define REG_PLLPD_POWER_ON 0 |
63 | /* Analog Register Part: reg03 */ |
64 | #define REG_FBDIV_HI_MASK BIT(5) |
65 | #define REG_FBDIV_HI(x) UPDATE((x >> 8), 5, 5) |
66 | #define REG_PREDIV_MASK GENMASK(4, 0) |
67 | #define REG_PREDIV(x) UPDATE(x, 4, 0) |
68 | /* Analog Register Part: reg04 */ |
69 | #define REG_FBDIV_LO_MASK GENMASK(7, 0) |
70 | #define REG_FBDIV_LO(x) UPDATE(x, 7, 0) |
71 | /* Analog Register Part: reg05 */ |
72 | #define SAMPLE_CLOCK_PHASE_MASK GENMASK(6, 4) |
73 | #define SAMPLE_CLOCK_PHASE(x) UPDATE(x, 6, 4) |
74 | #define CLOCK_LANE_SKEW_PHASE_MASK GENMASK(2, 0) |
75 | #define CLOCK_LANE_SKEW_PHASE(x) UPDATE(x, 2, 0) |
76 | /* Analog Register Part: reg06 */ |
77 | #define DATA_LANE_3_SKEW_PHASE_MASK GENMASK(6, 4) |
78 | #define DATA_LANE_3_SKEW_PHASE(x) UPDATE(x, 6, 4) |
79 | #define DATA_LANE_2_SKEW_PHASE_MASK GENMASK(2, 0) |
80 | #define DATA_LANE_2_SKEW_PHASE(x) UPDATE(x, 2, 0) |
81 | /* Analog Register Part: reg07 */ |
82 | #define DATA_LANE_1_SKEW_PHASE_MASK GENMASK(6, 4) |
83 | #define DATA_LANE_1_SKEW_PHASE(x) UPDATE(x, 6, 4) |
84 | #define DATA_LANE_0_SKEW_PHASE_MASK GENMASK(2, 0) |
85 | #define DATA_LANE_0_SKEW_PHASE(x) UPDATE(x, 2, 0) |
86 | /* Analog Register Part: reg08 */ |
87 | #define PLL_POST_DIV_ENABLE_MASK BIT(5) |
88 | #define PLL_POST_DIV_ENABLE BIT(5) |
89 | #define SAMPLE_CLOCK_DIRECTION_MASK BIT(4) |
90 | #define SAMPLE_CLOCK_DIRECTION_REVERSE BIT(4) |
91 | #define SAMPLE_CLOCK_DIRECTION_FORWARD 0 |
92 | #define LOWFRE_EN_MASK BIT(5) |
93 | #define PLL_OUTPUT_FREQUENCY_DIV_BY_1 0 |
94 | #define PLL_OUTPUT_FREQUENCY_DIV_BY_2 1 |
95 | /* Analog Register Part: reg0b */ |
96 | #define CLOCK_LANE_VOD_RANGE_SET_MASK GENMASK(3, 0) |
97 | #define CLOCK_LANE_VOD_RANGE_SET(x) UPDATE(x, 3, 0) |
98 | #define VOD_MIN_RANGE 0x1 |
99 | #define VOD_MID_RANGE 0x3 |
100 | #define VOD_BIG_RANGE 0x7 |
101 | #define VOD_MAX_RANGE 0xf |
102 | /* Analog Register Part: reg1E */ |
103 | #define PLL_MODE_SEL_MASK GENMASK(6, 5) |
104 | #define PLL_MODE_SEL_LVDS_MODE 0 |
105 | #define PLL_MODE_SEL_MIPI_MODE BIT(5) |
106 | /* Digital Register Part: reg00 */ |
107 | #define REG_DIG_RSTN_MASK BIT(0) |
108 | #define REG_DIG_RSTN_NORMAL BIT(0) |
109 | #define REG_DIG_RSTN_RESET 0 |
110 | /* Digital Register Part: reg01 */ |
111 | #define INVERT_TXCLKESC_MASK BIT(1) |
112 | #define INVERT_TXCLKESC_ENABLE BIT(1) |
113 | #define INVERT_TXCLKESC_DISABLE 0 |
114 | #define INVERT_TXBYTECLKHS_MASK BIT(0) |
115 | #define INVERT_TXBYTECLKHS_ENABLE BIT(0) |
116 | #define INVERT_TXBYTECLKHS_DISABLE 0 |
117 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg05 */ |
118 | #define T_LPX_CNT_MASK GENMASK(5, 0) |
119 | #define T_LPX_CNT(x) UPDATE(x, 5, 0) |
120 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg06 */ |
121 | #define T_HS_ZERO_CNT_HI_MASK BIT(7) |
122 | #define T_HS_ZERO_CNT_HI(x) UPDATE(x, 7, 7) |
123 | #define T_HS_PREPARE_CNT_MASK GENMASK(6, 0) |
124 | #define T_HS_PREPARE_CNT(x) UPDATE(x, 6, 0) |
125 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg07 */ |
126 | #define T_HS_ZERO_CNT_LO_MASK GENMASK(5, 0) |
127 | #define T_HS_ZERO_CNT_LO(x) UPDATE(x, 5, 0) |
128 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg08 */ |
129 | #define T_HS_TRAIL_CNT_MASK GENMASK(6, 0) |
130 | #define T_HS_TRAIL_CNT(x) UPDATE(x, 6, 0) |
131 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg09 */ |
132 | #define T_HS_EXIT_CNT_LO_MASK GENMASK(4, 0) |
133 | #define T_HS_EXIT_CNT_LO(x) UPDATE(x, 4, 0) |
134 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0a */ |
135 | #define T_CLK_POST_CNT_LO_MASK GENMASK(3, 0) |
136 | #define T_CLK_POST_CNT_LO(x) UPDATE(x, 3, 0) |
137 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0c */ |
138 | #define LPDT_TX_PPI_SYNC_MASK BIT(2) |
139 | #define LPDT_TX_PPI_SYNC_ENABLE BIT(2) |
140 | #define LPDT_TX_PPI_SYNC_DISABLE 0 |
141 | #define T_WAKEUP_CNT_HI_MASK GENMASK(1, 0) |
142 | #define T_WAKEUP_CNT_HI(x) UPDATE(x, 1, 0) |
143 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0d */ |
144 | #define T_WAKEUP_CNT_LO_MASK GENMASK(7, 0) |
145 | #define T_WAKEUP_CNT_LO(x) UPDATE(x, 7, 0) |
146 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0e */ |
147 | #define T_CLK_PRE_CNT_MASK GENMASK(3, 0) |
148 | #define T_CLK_PRE_CNT(x) UPDATE(x, 3, 0) |
149 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg10 */ |
150 | #define T_CLK_POST_CNT_HI_MASK GENMASK(7, 6) |
151 | #define T_CLK_POST_CNT_HI(x) UPDATE(x, 7, 6) |
152 | #define T_TA_GO_CNT_MASK GENMASK(5, 0) |
153 | #define T_TA_GO_CNT(x) UPDATE(x, 5, 0) |
154 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg11 */ |
155 | #define T_HS_EXIT_CNT_HI_MASK BIT(6) |
156 | #define T_HS_EXIT_CNT_HI(x) UPDATE(x, 6, 6) |
157 | #define T_TA_SURE_CNT_MASK GENMASK(5, 0) |
158 | #define T_TA_SURE_CNT(x) UPDATE(x, 5, 0) |
159 | /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg12 */ |
160 | #define T_TA_WAIT_CNT_MASK GENMASK(5, 0) |
161 | #define T_TA_WAIT_CNT(x) UPDATE(x, 5, 0) |
162 | /* LVDS Register Part: reg00 */ |
163 | #define LVDS_DIGITAL_INTERNAL_RESET_MASK BIT(2) |
164 | #define LVDS_DIGITAL_INTERNAL_RESET_DISABLE BIT(2) |
165 | #define LVDS_DIGITAL_INTERNAL_RESET_ENABLE 0 |
166 | /* LVDS Register Part: reg01 */ |
167 | #define LVDS_DIGITAL_INTERNAL_ENABLE_MASK BIT(7) |
168 | #define LVDS_DIGITAL_INTERNAL_ENABLE BIT(7) |
169 | #define LVDS_DIGITAL_INTERNAL_DISABLE 0 |
170 | /* LVDS Register Part: reg03 */ |
171 | #define MODE_ENABLE_MASK GENMASK(2, 0) |
172 | #define TTL_MODE_ENABLE BIT(2) |
173 | #define LVDS_MODE_ENABLE BIT(1) |
174 | #define MIPI_MODE_ENABLE BIT(0) |
175 | /* LVDS Register Part: reg0b */ |
176 | #define LVDS_LANE_EN_MASK GENMASK(7, 3) |
177 | #define LVDS_DATA_LANE0_EN BIT(7) |
178 | #define LVDS_DATA_LANE1_EN BIT(6) |
179 | #define LVDS_DATA_LANE2_EN BIT(5) |
180 | #define LVDS_DATA_LANE3_EN BIT(4) |
181 | #define LVDS_CLK_LANE_EN BIT(3) |
182 | #define LVDS_PLL_POWER_MASK BIT(2) |
183 | #define LVDS_PLL_POWER_OFF BIT(2) |
184 | #define LVDS_PLL_POWER_ON 0 |
185 | #define LVDS_BANDGAP_POWER_MASK BIT(0) |
186 | #define LVDS_BANDGAP_POWER_DOWN BIT(0) |
187 | #define LVDS_BANDGAP_POWER_ON 0 |
188 | |
189 | #define DSI_PHY_RSTZ 0xa0 |
190 | #define PHY_ENABLECLK BIT(2) |
191 | #define DSI_PHY_STATUS 0xb0 |
192 | #define PHY_LOCK BIT(0) |
193 | |
194 | enum phy_max_rate { |
195 | MAX_1GHZ, |
196 | MAX_2_5GHZ, |
197 | }; |
198 | |
199 | struct inno_video_phy_plat_data { |
200 | const struct inno_mipi_dphy_timing *inno_mipi_dphy_timing_table; |
201 | const unsigned int num_timings; |
202 | enum phy_max_rate max_rate; |
203 | }; |
204 | |
205 | struct inno_dsidphy { |
206 | struct device *dev; |
207 | struct clk *ref_clk; |
208 | struct clk *pclk_phy; |
209 | struct clk *pclk_host; |
210 | const struct inno_video_phy_plat_data *pdata; |
211 | void __iomem *phy_base; |
212 | void __iomem *host_base; |
213 | struct reset_control *rst; |
214 | enum phy_mode mode; |
215 | struct phy_configure_opts_mipi_dphy dphy_cfg; |
216 | |
217 | struct clk *pll_clk; |
218 | struct { |
219 | struct clk_hw hw; |
220 | u8 prediv; |
221 | u16 fbdiv; |
222 | unsigned long rate; |
223 | } pll; |
224 | }; |
225 | |
226 | enum { |
227 | REGISTER_PART_ANALOG, |
228 | REGISTER_PART_DIGITAL, |
229 | REGISTER_PART_CLOCK_LANE, |
230 | REGISTER_PART_DATA0_LANE, |
231 | REGISTER_PART_DATA1_LANE, |
232 | REGISTER_PART_DATA2_LANE, |
233 | REGISTER_PART_DATA3_LANE, |
234 | REGISTER_PART_LVDS, |
235 | }; |
236 | |
237 | struct inno_mipi_dphy_timing { |
238 | unsigned long rate; |
239 | u8 lpx; |
240 | u8 hs_prepare; |
241 | u8 clk_lane_hs_zero; |
242 | u8 data_lane_hs_zero; |
243 | u8 hs_trail; |
244 | }; |
245 | |
246 | static const |
247 | struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_1ghz[] = { |
248 | { 110000000, 0x0, 0x20, 0x16, 0x02, 0x22}, |
249 | { 150000000, 0x0, 0x06, 0x16, 0x03, 0x45}, |
250 | { 200000000, 0x0, 0x18, 0x17, 0x04, 0x0b}, |
251 | { 250000000, 0x0, 0x05, 0x17, 0x05, 0x16}, |
252 | { 300000000, 0x0, 0x51, 0x18, 0x06, 0x2c}, |
253 | { 400000000, 0x0, 0x64, 0x19, 0x07, 0x33}, |
254 | { 500000000, 0x0, 0x20, 0x1b, 0x07, 0x4e}, |
255 | { 600000000, 0x0, 0x6a, 0x1d, 0x08, 0x3a}, |
256 | { 700000000, 0x0, 0x3e, 0x1e, 0x08, 0x6a}, |
257 | { 800000000, 0x0, 0x21, 0x1f, 0x09, 0x29}, |
258 | {1000000000, 0x0, 0x09, 0x20, 0x09, 0x27}, |
259 | }; |
260 | |
261 | static const |
262 | struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_2_5ghz[] = { |
263 | { 110000000, 0x02, 0x7f, 0x16, 0x02, 0x02}, |
264 | { 150000000, 0x02, 0x7f, 0x16, 0x03, 0x02}, |
265 | { 200000000, 0x02, 0x7f, 0x17, 0x04, 0x02}, |
266 | { 250000000, 0x02, 0x7f, 0x17, 0x05, 0x04}, |
267 | { 300000000, 0x02, 0x7f, 0x18, 0x06, 0x04}, |
268 | { 400000000, 0x03, 0x7e, 0x19, 0x07, 0x04}, |
269 | { 500000000, 0x03, 0x7c, 0x1b, 0x07, 0x08}, |
270 | { 600000000, 0x03, 0x70, 0x1d, 0x08, 0x10}, |
271 | { 700000000, 0x05, 0x40, 0x1e, 0x08, 0x30}, |
272 | { 800000000, 0x05, 0x02, 0x1f, 0x09, 0x30}, |
273 | {1000000000, 0x05, 0x08, 0x20, 0x09, 0x30}, |
274 | {1200000000, 0x06, 0x03, 0x32, 0x14, 0x0f}, |
275 | {1400000000, 0x09, 0x03, 0x32, 0x14, 0x0f}, |
276 | {1600000000, 0x0d, 0x42, 0x36, 0x0e, 0x0f}, |
277 | {1800000000, 0x0e, 0x47, 0x7a, 0x0e, 0x0f}, |
278 | {2000000000, 0x11, 0x64, 0x7a, 0x0e, 0x0b}, |
279 | {2200000000, 0x13, 0x64, 0x7e, 0x15, 0x0b}, |
280 | {2400000000, 0x13, 0x33, 0x7f, 0x15, 0x6a}, |
281 | {2500000000, 0x15, 0x54, 0x7f, 0x15, 0x6a}, |
282 | }; |
283 | |
284 | static void phy_update_bits(struct inno_dsidphy *inno, |
285 | u8 first, u8 second, u8 mask, u8 val) |
286 | { |
287 | u32 reg = PHY_REG(first, second) << 2; |
288 | unsigned int tmp, orig; |
289 | |
290 | orig = readl(addr: inno->phy_base + reg); |
291 | tmp = orig & ~mask; |
292 | tmp |= val & mask; |
293 | writel(val: tmp, addr: inno->phy_base + reg); |
294 | } |
295 | |
296 | static unsigned long inno_dsidphy_pll_calc_rate(struct inno_dsidphy *inno, |
297 | unsigned long rate) |
298 | { |
299 | unsigned long prate = clk_get_rate(clk: inno->ref_clk); |
300 | unsigned long best_freq = 0; |
301 | unsigned long fref, fout; |
302 | u8 min_prediv, max_prediv; |
303 | u8 _prediv, best_prediv = 1; |
304 | u16 _fbdiv, best_fbdiv = 1; |
305 | u32 min_delta = UINT_MAX; |
306 | |
307 | /* |
308 | * The PLL output frequency can be calculated using a simple formula: |
309 | * PLL_Output_Frequency = (FREF / PREDIV * FBDIV) / 2 |
310 | * PLL_Output_Frequency: it is equal to DDR-Clock-Frequency * 2 |
311 | */ |
312 | fref = prate / 2; |
313 | if (rate > 1000000000UL) |
314 | fout = 1000000000UL; |
315 | else |
316 | fout = rate; |
317 | |
318 | /* 5Mhz < Fref / prediv < 40MHz */ |
319 | min_prediv = DIV_ROUND_UP(fref, 40000000); |
320 | max_prediv = fref / 5000000; |
321 | |
322 | for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) { |
323 | u64 tmp; |
324 | u32 delta; |
325 | |
326 | tmp = (u64)fout * _prediv; |
327 | do_div(tmp, fref); |
328 | _fbdiv = tmp; |
329 | |
330 | /* |
331 | * The possible settings of feedback divider are |
332 | * 12, 13, 14, 16, ~ 511 |
333 | */ |
334 | if (_fbdiv == 15) |
335 | continue; |
336 | |
337 | if (_fbdiv < 12 || _fbdiv > 511) |
338 | continue; |
339 | |
340 | tmp = (u64)_fbdiv * fref; |
341 | do_div(tmp, _prediv); |
342 | |
343 | delta = abs(fout - tmp); |
344 | if (!delta) { |
345 | best_prediv = _prediv; |
346 | best_fbdiv = _fbdiv; |
347 | best_freq = tmp; |
348 | break; |
349 | } else if (delta < min_delta) { |
350 | best_prediv = _prediv; |
351 | best_fbdiv = _fbdiv; |
352 | best_freq = tmp; |
353 | min_delta = delta; |
354 | } |
355 | } |
356 | |
357 | if (best_freq) { |
358 | inno->pll.prediv = best_prediv; |
359 | inno->pll.fbdiv = best_fbdiv; |
360 | inno->pll.rate = best_freq; |
361 | } |
362 | |
363 | return best_freq; |
364 | } |
365 | |
366 | static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno) |
367 | { |
368 | struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg; |
369 | const struct inno_mipi_dphy_timing *timings; |
370 | u32 t_txbyteclkhs, t_txclkesc; |
371 | u32 txbyteclkhs, txclkesc, esc_clk_div; |
372 | u32 hs_exit, clk_post, clk_pre, wakeup, lpx, ta_go, ta_sure, ta_wait; |
373 | u32 hs_prepare, hs_trail, hs_zero, clk_lane_hs_zero, data_lane_hs_zero; |
374 | unsigned int i; |
375 | |
376 | timings = inno->pdata->inno_mipi_dphy_timing_table; |
377 | |
378 | inno_dsidphy_pll_calc_rate(inno, rate: cfg->hs_clk_rate); |
379 | |
380 | /* Select MIPI mode */ |
381 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x03, |
382 | MODE_ENABLE_MASK, MIPI_MODE_ENABLE); |
383 | /* Configure PLL */ |
384 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x03, |
385 | REG_PREDIV_MASK, REG_PREDIV(inno->pll.prediv)); |
386 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x03, |
387 | REG_FBDIV_HI_MASK, REG_FBDIV_HI(inno->pll.fbdiv)); |
388 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x04, |
389 | REG_FBDIV_LO_MASK, REG_FBDIV_LO(inno->pll.fbdiv)); |
390 | if (inno->pdata->max_rate == MAX_2_5GHZ) { |
391 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x08, |
392 | PLL_POST_DIV_ENABLE_MASK, PLL_POST_DIV_ENABLE); |
393 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x0b, |
394 | CLOCK_LANE_VOD_RANGE_SET_MASK, |
395 | CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE)); |
396 | } |
397 | /* Enable PLL and LDO */ |
398 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x01, |
399 | REG_LDOPD_MASK | REG_PLLPD_MASK, |
400 | REG_LDOPD_POWER_ON | REG_PLLPD_POWER_ON); |
401 | /* Reset analog */ |
402 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x01, |
403 | REG_SYNCRST_MASK, REG_SYNCRST_RESET); |
404 | udelay(1); |
405 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x01, |
406 | REG_SYNCRST_MASK, REG_SYNCRST_NORMAL); |
407 | /* Reset digital */ |
408 | phy_update_bits(inno, first: REGISTER_PART_DIGITAL, second: 0x00, |
409 | REG_DIG_RSTN_MASK, REG_DIG_RSTN_RESET); |
410 | udelay(1); |
411 | phy_update_bits(inno, first: REGISTER_PART_DIGITAL, second: 0x00, |
412 | REG_DIG_RSTN_MASK, REG_DIG_RSTN_NORMAL); |
413 | |
414 | txbyteclkhs = inno->pll.rate / 8; |
415 | t_txbyteclkhs = div_u64(PSEC_PER_SEC, divisor: txbyteclkhs); |
416 | |
417 | esc_clk_div = DIV_ROUND_UP(txbyteclkhs, 20000000); |
418 | txclkesc = txbyteclkhs / esc_clk_div; |
419 | t_txclkesc = div_u64(PSEC_PER_SEC, divisor: txclkesc); |
420 | |
421 | /* |
422 | * The value of counter for HS Ths-exit |
423 | * Ths-exit = Tpin_txbyteclkhs * value |
424 | */ |
425 | hs_exit = DIV_ROUND_UP(cfg->hs_exit, t_txbyteclkhs); |
426 | /* |
427 | * The value of counter for HS Tclk-post |
428 | * Tclk-post = Tpin_txbyteclkhs * value |
429 | */ |
430 | clk_post = DIV_ROUND_UP(cfg->clk_post, t_txbyteclkhs); |
431 | /* |
432 | * The value of counter for HS Tclk-pre |
433 | * Tclk-pre = Tpin_txbyteclkhs * value |
434 | */ |
435 | clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE); |
436 | |
437 | /* |
438 | * The value of counter for HS Tta-go |
439 | * Tta-go for turnaround |
440 | * Tta-go = Ttxclkesc * value |
441 | */ |
442 | ta_go = DIV_ROUND_UP(cfg->ta_go, t_txclkesc); |
443 | /* |
444 | * The value of counter for HS Tta-sure |
445 | * Tta-sure for turnaround |
446 | * Tta-sure = Ttxclkesc * value |
447 | */ |
448 | ta_sure = DIV_ROUND_UP(cfg->ta_sure, t_txclkesc); |
449 | /* |
450 | * The value of counter for HS Tta-wait |
451 | * Tta-wait for turnaround |
452 | * Tta-wait = Ttxclkesc * value |
453 | */ |
454 | ta_wait = DIV_ROUND_UP(cfg->ta_get, t_txclkesc); |
455 | |
456 | for (i = 0; i < inno->pdata->num_timings; i++) |
457 | if (inno->pll.rate <= timings[i].rate) |
458 | break; |
459 | |
460 | if (i == inno->pdata->num_timings) |
461 | --i; |
462 | |
463 | /* |
464 | * The value of counter for HS Tlpx Time |
465 | * Tlpx = Tpin_txbyteclkhs * (2 + value) |
466 | */ |
467 | if (inno->pdata->max_rate == MAX_1GHZ) { |
468 | lpx = DIV_ROUND_UP(cfg->lpx, t_txbyteclkhs); |
469 | if (lpx >= 2) |
470 | lpx -= 2; |
471 | } else |
472 | lpx = timings[i].lpx; |
473 | |
474 | hs_prepare = timings[i].hs_prepare; |
475 | hs_trail = timings[i].hs_trail; |
476 | clk_lane_hs_zero = timings[i].clk_lane_hs_zero; |
477 | data_lane_hs_zero = timings[i].data_lane_hs_zero; |
478 | wakeup = 0x3ff; |
479 | |
480 | for (i = REGISTER_PART_CLOCK_LANE; i <= REGISTER_PART_DATA3_LANE; i++) { |
481 | if (i == REGISTER_PART_CLOCK_LANE) |
482 | hs_zero = clk_lane_hs_zero; |
483 | else |
484 | hs_zero = data_lane_hs_zero; |
485 | |
486 | phy_update_bits(inno, first: i, second: 0x05, T_LPX_CNT_MASK, |
487 | T_LPX_CNT(lpx)); |
488 | phy_update_bits(inno, first: i, second: 0x06, T_HS_PREPARE_CNT_MASK, |
489 | T_HS_PREPARE_CNT(hs_prepare)); |
490 | if (inno->pdata->max_rate == MAX_2_5GHZ) |
491 | phy_update_bits(inno, first: i, second: 0x06, T_HS_ZERO_CNT_HI_MASK, |
492 | T_HS_ZERO_CNT_HI(hs_zero >> 6)); |
493 | phy_update_bits(inno, first: i, second: 0x07, T_HS_ZERO_CNT_LO_MASK, |
494 | T_HS_ZERO_CNT_LO(hs_zero)); |
495 | phy_update_bits(inno, first: i, second: 0x08, T_HS_TRAIL_CNT_MASK, |
496 | T_HS_TRAIL_CNT(hs_trail)); |
497 | if (inno->pdata->max_rate == MAX_2_5GHZ) |
498 | phy_update_bits(inno, first: i, second: 0x11, T_HS_EXIT_CNT_HI_MASK, |
499 | T_HS_EXIT_CNT_HI(hs_exit >> 5)); |
500 | phy_update_bits(inno, first: i, second: 0x09, T_HS_EXIT_CNT_LO_MASK, |
501 | T_HS_EXIT_CNT_LO(hs_exit)); |
502 | if (inno->pdata->max_rate == MAX_2_5GHZ) |
503 | phy_update_bits(inno, first: i, second: 0x10, T_CLK_POST_CNT_HI_MASK, |
504 | T_CLK_POST_CNT_HI(clk_post >> 4)); |
505 | phy_update_bits(inno, first: i, second: 0x0a, T_CLK_POST_CNT_LO_MASK, |
506 | T_CLK_POST_CNT_LO(clk_post)); |
507 | phy_update_bits(inno, first: i, second: 0x0e, T_CLK_PRE_CNT_MASK, |
508 | T_CLK_PRE_CNT(clk_pre)); |
509 | phy_update_bits(inno, first: i, second: 0x0c, T_WAKEUP_CNT_HI_MASK, |
510 | T_WAKEUP_CNT_HI(wakeup >> 8)); |
511 | phy_update_bits(inno, first: i, second: 0x0d, T_WAKEUP_CNT_LO_MASK, |
512 | T_WAKEUP_CNT_LO(wakeup)); |
513 | phy_update_bits(inno, first: i, second: 0x10, T_TA_GO_CNT_MASK, |
514 | T_TA_GO_CNT(ta_go)); |
515 | phy_update_bits(inno, first: i, second: 0x11, T_TA_SURE_CNT_MASK, |
516 | T_TA_SURE_CNT(ta_sure)); |
517 | phy_update_bits(inno, first: i, second: 0x12, T_TA_WAIT_CNT_MASK, |
518 | T_TA_WAIT_CNT(ta_wait)); |
519 | } |
520 | |
521 | /* Enable all lanes on analog part */ |
522 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x00, |
523 | LANE_EN_MASK, LANE_EN_CK | LANE_EN_3 | LANE_EN_2 | |
524 | LANE_EN_1 | LANE_EN_0); |
525 | } |
526 | |
527 | static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno) |
528 | { |
529 | u8 prediv = 2; |
530 | u16 fbdiv = 28; |
531 | |
532 | /* Sample clock reverse direction */ |
533 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x08, |
534 | SAMPLE_CLOCK_DIRECTION_MASK | LOWFRE_EN_MASK, |
535 | SAMPLE_CLOCK_DIRECTION_REVERSE | |
536 | PLL_OUTPUT_FREQUENCY_DIV_BY_1); |
537 | |
538 | /* Select LVDS mode */ |
539 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x03, |
540 | MODE_ENABLE_MASK, LVDS_MODE_ENABLE); |
541 | /* Configure PLL */ |
542 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x03, |
543 | REG_PREDIV_MASK, REG_PREDIV(prediv)); |
544 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x03, |
545 | REG_FBDIV_HI_MASK, REG_FBDIV_HI(fbdiv)); |
546 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x04, |
547 | REG_FBDIV_LO_MASK, REG_FBDIV_LO(fbdiv)); |
548 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x08, mask: 0xff, val: 0xfc); |
549 | /* Enable PLL and Bandgap */ |
550 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x0b, |
551 | LVDS_PLL_POWER_MASK | LVDS_BANDGAP_POWER_MASK, |
552 | LVDS_PLL_POWER_ON | LVDS_BANDGAP_POWER_ON); |
553 | |
554 | msleep(msecs: 20); |
555 | |
556 | /* Select PLL mode */ |
557 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x1e, |
558 | PLL_MODE_SEL_MASK, PLL_MODE_SEL_LVDS_MODE); |
559 | |
560 | /* Reset LVDS digital logic */ |
561 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x00, |
562 | LVDS_DIGITAL_INTERNAL_RESET_MASK, |
563 | LVDS_DIGITAL_INTERNAL_RESET_ENABLE); |
564 | udelay(1); |
565 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x00, |
566 | LVDS_DIGITAL_INTERNAL_RESET_MASK, |
567 | LVDS_DIGITAL_INTERNAL_RESET_DISABLE); |
568 | /* Enable LVDS digital logic */ |
569 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x01, |
570 | LVDS_DIGITAL_INTERNAL_ENABLE_MASK, |
571 | LVDS_DIGITAL_INTERNAL_ENABLE); |
572 | /* Enable LVDS analog driver */ |
573 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x0b, |
574 | LVDS_LANE_EN_MASK, LVDS_CLK_LANE_EN | |
575 | LVDS_DATA_LANE0_EN | LVDS_DATA_LANE1_EN | |
576 | LVDS_DATA_LANE2_EN | LVDS_DATA_LANE3_EN); |
577 | } |
578 | |
579 | static int inno_dsidphy_power_on(struct phy *phy) |
580 | { |
581 | struct inno_dsidphy *inno = phy_get_drvdata(phy); |
582 | |
583 | clk_prepare_enable(clk: inno->pclk_phy); |
584 | clk_prepare_enable(clk: inno->ref_clk); |
585 | pm_runtime_get_sync(dev: inno->dev); |
586 | |
587 | /* Bandgap power on */ |
588 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x00, |
589 | BANDGAP_POWER_MASK, BANDGAP_POWER_ON); |
590 | /* Enable power work */ |
591 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x00, |
592 | POWER_WORK_MASK, POWER_WORK_ENABLE); |
593 | |
594 | switch (inno->mode) { |
595 | case PHY_MODE_MIPI_DPHY: |
596 | inno_dsidphy_mipi_mode_enable(inno); |
597 | break; |
598 | case PHY_MODE_LVDS: |
599 | inno_dsidphy_lvds_mode_enable(inno); |
600 | break; |
601 | default: |
602 | return -EINVAL; |
603 | } |
604 | |
605 | return 0; |
606 | } |
607 | |
608 | static int inno_dsidphy_power_off(struct phy *phy) |
609 | { |
610 | struct inno_dsidphy *inno = phy_get_drvdata(phy); |
611 | |
612 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x00, LANE_EN_MASK, val: 0); |
613 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x01, |
614 | REG_LDOPD_MASK | REG_PLLPD_MASK, |
615 | REG_LDOPD_POWER_DOWN | REG_PLLPD_POWER_DOWN); |
616 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x00, |
617 | POWER_WORK_MASK, POWER_WORK_DISABLE); |
618 | phy_update_bits(inno, first: REGISTER_PART_ANALOG, second: 0x00, |
619 | BANDGAP_POWER_MASK, BANDGAP_POWER_DOWN); |
620 | |
621 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x0b, LVDS_LANE_EN_MASK, val: 0); |
622 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x01, |
623 | LVDS_DIGITAL_INTERNAL_ENABLE_MASK, |
624 | LVDS_DIGITAL_INTERNAL_DISABLE); |
625 | phy_update_bits(inno, first: REGISTER_PART_LVDS, second: 0x0b, |
626 | LVDS_PLL_POWER_MASK | LVDS_BANDGAP_POWER_MASK, |
627 | LVDS_PLL_POWER_OFF | LVDS_BANDGAP_POWER_DOWN); |
628 | |
629 | pm_runtime_put(dev: inno->dev); |
630 | clk_disable_unprepare(clk: inno->ref_clk); |
631 | clk_disable_unprepare(clk: inno->pclk_phy); |
632 | |
633 | return 0; |
634 | } |
635 | |
636 | static int inno_dsidphy_set_mode(struct phy *phy, enum phy_mode mode, |
637 | int submode) |
638 | { |
639 | struct inno_dsidphy *inno = phy_get_drvdata(phy); |
640 | |
641 | switch (mode) { |
642 | case PHY_MODE_MIPI_DPHY: |
643 | case PHY_MODE_LVDS: |
644 | inno->mode = mode; |
645 | break; |
646 | default: |
647 | return -EINVAL; |
648 | } |
649 | |
650 | return 0; |
651 | } |
652 | |
653 | static int inno_dsidphy_configure(struct phy *phy, |
654 | union phy_configure_opts *opts) |
655 | { |
656 | struct inno_dsidphy *inno = phy_get_drvdata(phy); |
657 | int ret; |
658 | |
659 | if (inno->mode != PHY_MODE_MIPI_DPHY) |
660 | return -EINVAL; |
661 | |
662 | ret = phy_mipi_dphy_config_validate(cfg: &opts->mipi_dphy); |
663 | if (ret) |
664 | return ret; |
665 | |
666 | memcpy(&inno->dphy_cfg, &opts->mipi_dphy, sizeof(inno->dphy_cfg)); |
667 | |
668 | return 0; |
669 | } |
670 | |
671 | static const struct phy_ops inno_dsidphy_ops = { |
672 | .configure = inno_dsidphy_configure, |
673 | .set_mode = inno_dsidphy_set_mode, |
674 | .power_on = inno_dsidphy_power_on, |
675 | .power_off = inno_dsidphy_power_off, |
676 | .owner = THIS_MODULE, |
677 | }; |
678 | |
679 | static const struct inno_video_phy_plat_data max_1ghz_video_phy_plat_data = { |
680 | .inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_1ghz, |
681 | .num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_1ghz), |
682 | .max_rate = MAX_1GHZ, |
683 | }; |
684 | |
685 | static const struct inno_video_phy_plat_data max_2_5ghz_video_phy_plat_data = { |
686 | .inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_2_5ghz, |
687 | .num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_2_5ghz), |
688 | .max_rate = MAX_2_5GHZ, |
689 | }; |
690 | |
691 | static int inno_dsidphy_probe(struct platform_device *pdev) |
692 | { |
693 | struct device *dev = &pdev->dev; |
694 | struct inno_dsidphy *inno; |
695 | struct phy_provider *phy_provider; |
696 | struct phy *phy; |
697 | int ret; |
698 | |
699 | inno = devm_kzalloc(dev, size: sizeof(*inno), GFP_KERNEL); |
700 | if (!inno) |
701 | return -ENOMEM; |
702 | |
703 | inno->dev = dev; |
704 | inno->pdata = of_device_get_match_data(dev: inno->dev); |
705 | platform_set_drvdata(pdev, data: inno); |
706 | |
707 | inno->phy_base = devm_platform_ioremap_resource(pdev, index: 0); |
708 | if (IS_ERR(ptr: inno->phy_base)) |
709 | return PTR_ERR(ptr: inno->phy_base); |
710 | |
711 | inno->ref_clk = devm_clk_get(dev, id: "ref" ); |
712 | if (IS_ERR(ptr: inno->ref_clk)) { |
713 | ret = PTR_ERR(ptr: inno->ref_clk); |
714 | dev_err(dev, "failed to get ref clock: %d\n" , ret); |
715 | return ret; |
716 | } |
717 | |
718 | inno->pclk_phy = devm_clk_get(dev, id: "pclk" ); |
719 | if (IS_ERR(ptr: inno->pclk_phy)) { |
720 | ret = PTR_ERR(ptr: inno->pclk_phy); |
721 | dev_err(dev, "failed to get phy pclk: %d\n" , ret); |
722 | return ret; |
723 | } |
724 | |
725 | inno->rst = devm_reset_control_get(dev, id: "apb" ); |
726 | if (IS_ERR(ptr: inno->rst)) { |
727 | ret = PTR_ERR(ptr: inno->rst); |
728 | dev_err(dev, "failed to get system reset control: %d\n" , ret); |
729 | return ret; |
730 | } |
731 | |
732 | phy = devm_phy_create(dev, NULL, ops: &inno_dsidphy_ops); |
733 | if (IS_ERR(ptr: phy)) { |
734 | ret = PTR_ERR(ptr: phy); |
735 | dev_err(dev, "failed to create phy: %d\n" , ret); |
736 | return ret; |
737 | } |
738 | |
739 | phy_set_drvdata(phy, data: inno); |
740 | |
741 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); |
742 | if (IS_ERR(ptr: phy_provider)) { |
743 | ret = PTR_ERR(ptr: phy_provider); |
744 | dev_err(dev, "failed to register phy provider: %d\n" , ret); |
745 | return ret; |
746 | } |
747 | |
748 | pm_runtime_enable(dev); |
749 | |
750 | return 0; |
751 | } |
752 | |
753 | static void inno_dsidphy_remove(struct platform_device *pdev) |
754 | { |
755 | struct inno_dsidphy *inno = platform_get_drvdata(pdev); |
756 | |
757 | pm_runtime_disable(dev: inno->dev); |
758 | } |
759 | |
760 | static const struct of_device_id inno_dsidphy_of_match[] = { |
761 | { |
762 | .compatible = "rockchip,px30-dsi-dphy" , |
763 | .data = &max_1ghz_video_phy_plat_data, |
764 | }, { |
765 | .compatible = "rockchip,rk3128-dsi-dphy" , |
766 | .data = &max_1ghz_video_phy_plat_data, |
767 | }, { |
768 | .compatible = "rockchip,rk3368-dsi-dphy" , |
769 | .data = &max_1ghz_video_phy_plat_data, |
770 | }, { |
771 | .compatible = "rockchip,rk3568-dsi-dphy" , |
772 | .data = &max_2_5ghz_video_phy_plat_data, |
773 | }, { |
774 | .compatible = "rockchip,rv1126-dsi-dphy" , |
775 | .data = &max_2_5ghz_video_phy_plat_data, |
776 | }, |
777 | {} |
778 | }; |
779 | MODULE_DEVICE_TABLE(of, inno_dsidphy_of_match); |
780 | |
781 | static struct platform_driver inno_dsidphy_driver = { |
782 | .driver = { |
783 | .name = "inno-dsidphy" , |
784 | .of_match_table = of_match_ptr(inno_dsidphy_of_match), |
785 | }, |
786 | .probe = inno_dsidphy_probe, |
787 | .remove_new = inno_dsidphy_remove, |
788 | }; |
789 | module_platform_driver(inno_dsidphy_driver); |
790 | |
791 | MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>" ); |
792 | MODULE_DESCRIPTION("Innosilicon MIPI/LVDS/TTL Video Combo PHY driver" ); |
793 | MODULE_LICENSE("GPL v2" ); |
794 | |