1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4 *
5 * Author: Guochun Huang <hero.huang@rock-chips.com>
6 */
7
8 #include "rk628.h"
9 #include "rk628_cru.h"
10 #include "rk628_rgb.h"
11 #include "panel.h"
12
rk628_rgbrx_parse(struct rk628 * rk628)13 int rk628_rgbrx_parse(struct rk628 *rk628)
14 {
15 /* input/output: bt1120 */
16 if ((rk628_input_is_bt1120(rk628) || rk628_output_is_bt1120(rk628)) &&
17 dev_read_bool(rk628->dev, "bt1120-dual-edge"))
18 rk628->rgb.bt1120_dual_edge = true;
19
20 /* input: bt1120 */
21 if (rk628_input_is_bt1120(rk628)) {
22 if (dev_read_bool(rk628->dev, "bt1120-yc-swap"))
23 rk628->rgb.bt1120_yc_swap = true;
24
25 if (dev_read_bool(rk628->dev, "bt1120-uv-swap"))
26 rk628->rgb.bt1120_uv_swap = true;
27 }
28
29
30 return 0;
31 }
32
rk628_rgbtx_parse(struct rk628 * rk628,ofnode rgb_np)33 int rk628_rgbtx_parse(struct rk628 *rk628, ofnode rgb_np)
34 {
35 int ret = 0;
36
37 /* input/output: rgb/bt1120 */
38 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, rk628->dev,
39 "vccio-rgb", &rk628->rgb.vccio_rgb);
40 if (ret && ret != -ENOENT)
41 return ret;
42
43 /* output: rgb/bt1120 */
44 if (rk628_output_is_bt1120(rk628) || rk628_output_is_rgb(rk628))
45 ret = rk628_panel_info_get(rk628, rgb_np);
46
47 return ret;
48 }
49
rk628_rgb_decoder_enable(struct rk628 * rk628)50 static void rk628_rgb_decoder_enable(struct rk628 *rk628)
51 {
52 /* config sw_input_mode RGB */
53 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_INPUT_MODE_MASK,
54 SW_INPUT_MODE(INPUT_MODE_RGB));
55
56 if (rk628->version == RK628F_VERSION) {
57 rk628_i2c_update_bits(rk628, GRF_RGB_RX_DBG_MEAS0,
58 RGB_RX_MODET_EN | RGB_RX_DCLK_EN,
59 RGB_RX_MODET_EN | RGB_RX_DCLK_EN);
60 rk628_i2c_update_bits(rk628, GRF_RGB_RX_DBG_MEAS3,
61 RGB_RX_CNT_EN_MASK, RGB_RX_CNT_EN(1));
62 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON0, 0x10000);
63 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON1, 0);
64 }
65
66 /* pinctrl for vop pin */
67 rk628_i2c_write(rk628, GRF_GPIO2AB_SEL_CON, 0xffffffff);
68 rk628_i2c_write(rk628, GRF_GPIO2C_SEL_CON, 0xffff5555);
69 rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x10b010b);
70 }
71
rk628_rgb_encoder_enable(struct rk628 * rk628)72 static void rk628_rgb_encoder_enable(struct rk628 *rk628)
73 {
74 int voltage = 0;
75 u32 d_strength, clk_strength;
76 u64 dclk_delay;
77
78 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
79 SW_BT_DATA_OEN_MASK | SW_OUTPUT_RGB_MODE_MASK,
80 SW_OUTPUT_RGB_MODE(OUTPUT_MODE_RGB >> 3));
81
82 if (rk628->version != RK628F_VERSION)
83 rk628_i2c_update_bits(rk628, GRF_POST_PROC_CON,
84 SW_DCLK_OUT_INV_EN, SW_DCLK_OUT_INV_EN);
85
86 /* pinctrl for vop pin */
87 rk628_i2c_write(rk628, GRF_GPIO2AB_SEL_CON, 0xffffffff);
88 rk628_i2c_write(rk628, GRF_GPIO2C_SEL_CON, 0xffff5555);
89 rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x10b010b);
90
91 /*
92 * Under the same drive strength and DCLK delay, the signal behaves
93 * differently under different voltage power domains. In order to
94 * center the eye diagram of the signal, have sufficient signal setup
95 * and hold time, and ensure that the signal does not overshoot, the
96 * drive strength and DCLK delay need to be set for the power domains
97 * of different voltages.
98 */
99 if (rk628->rgb.vccio_rgb)
100 voltage = regulator_get_value(rk628->rgb.vccio_rgb);
101
102 switch (voltage) {
103 case 1800000:
104 d_strength = 3;
105 clk_strength = 3;
106 dclk_delay = 0x10000000;
107 break;
108 case 3300000:
109 d_strength = 1;
110 clk_strength = 2;
111 dclk_delay = 0x100000000;
112 break;
113 default:
114 d_strength = 1;
115 clk_strength = 2;
116 dclk_delay = 0x100000000;
117 }
118
119 /* rk628: modify IO drive strength for RGB */
120 if (rk628->version == RK628F_VERSION)
121 d_strength = d_strength * 0x1111 | 0xffff0000;
122 else {
123 d_strength = 0xffff7777;
124 clk_strength = 7;
125 }
126
127 rk628_i2c_write(rk628, GRF_GPIO2A_D0_CON, d_strength);
128 rk628_i2c_write(rk628, GRF_GPIO2A_D1_CON, d_strength);
129 rk628_i2c_write(rk628, GRF_GPIO2B_D0_CON, d_strength);
130 rk628_i2c_write(rk628, GRF_GPIO2B_D1_CON, d_strength);
131 rk628_i2c_write(rk628, GRF_GPIO2C_D0_CON, d_strength);
132 rk628_i2c_write(rk628, GRF_GPIO2C_D1_CON, d_strength);
133 rk628_i2c_write(rk628, GRF_GPIO3A_D0_CON, d_strength & 0xf0fff0ff);
134 rk628_i2c_write(rk628, GRF_GPIO3B_D_CON, clk_strength | 0x000f0000);
135
136 /* rk628: modify DCLK delay for RGB */
137 if (rk628->version == RK628F_VERSION) {
138 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON0,
139 dclk_delay & 0xffffffff);
140 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON1,
141 dclk_delay >> 32);
142 }
143 }
144
rk628_rgb_encoder_disable(struct rk628 * rk628)145 static void rk628_rgb_encoder_disable(struct rk628 *rk628)
146 {
147 }
148
149
rk628_rgb_rx_enable(struct rk628 * rk628)150 void rk628_rgb_rx_enable(struct rk628 *rk628)
151 {
152
153 rk628_rgb_decoder_enable(rk628);
154
155 }
156
rk628_rgb_tx_enable(struct rk628 * rk628)157 void rk628_rgb_tx_enable(struct rk628 *rk628)
158 {
159 rk628_rgb_encoder_enable(rk628);
160
161 rk628_panel_prepare(rk628);
162 rk628_panel_enable(rk628);
163 }
164
rk628_rgb_tx_disable(struct rk628 * rk628)165 void rk628_rgb_tx_disable(struct rk628 *rk628)
166 {
167 rk628_panel_disable(rk628);
168 rk628_panel_unprepare(rk628);
169
170 rk628_rgb_encoder_disable(rk628);
171 }
172
rk628_bt1120_decoder_timing_cfg(struct rk628 * rk628)173 static void rk628_bt1120_decoder_timing_cfg(struct rk628 *rk628)
174 {
175 u32 src_hsync_len, src_hback_porch, src_hfront_porch, src_hactive;
176 u32 src_vsync_len, src_vback_porch, src_vfront_porch, src_vactive;
177 u32 dsp_htotal, dsp_hs_end, dsp_hact_st;
178 u32 dsp_vtotal, dsp_vs_end, dsp_vact_st;
179 u32 dsp_hbor_st, dsp_vbor_st;
180 u16 bor_left = 0, bor_up = 0;
181 struct drm_display_mode *src = &rk628->src_mode;
182
183 src_hactive = src->hdisplay;
184 src_hsync_len = src->hsync_end - src->hsync_start;
185 src_hback_porch = src->htotal - src->hsync_end;
186 src_hfront_porch = src->hsync_start - src->hdisplay;
187 src_vsync_len = src->vsync_end - src->vsync_start;
188 src_vback_porch = src->vtotal - src->vsync_end;
189 src_vfront_porch = src->vsync_start - src->vdisplay;
190 src_vactive = src->vdisplay;
191
192 dsp_htotal = src_hsync_len + src_hback_porch +
193 src_hactive + src_hfront_porch;
194 dsp_vtotal = src_vsync_len + src_vback_porch +
195 src_vactive + src_vfront_porch;
196 dsp_hs_end = src_hsync_len;
197 dsp_vs_end = src_vsync_len;
198 dsp_hbor_st = src_hsync_len + src_hback_porch;
199 dsp_vbor_st = src_vsync_len + src_vback_porch;
200 dsp_hact_st = dsp_hbor_st + bor_left;
201 dsp_vact_st = dsp_vbor_st + bor_up;
202
203 if (rk628->version == RK628F_VERSION)
204 rk628_i2c_update_bits(rk628, GRF_RGB_RX_DBG_MEAS0,
205 RGB_RX_MODET_EN | RGB_RX_DCLK_EN,
206 RGB_RX_MODET_EN | RGB_RX_DCLK_EN);
207
208 rk628_i2c_write(rk628, GRF_BT1120_TIMING_CTRL0, BT1120_DSP_HS_END(dsp_hs_end) |
209 BT1120_DSP_HTOTAL(dsp_htotal));
210 rk628_i2c_write(rk628, GRF_BT1120_TIMING_CTRL1, BT1120_DSP_HACT_ST(dsp_hact_st));
211 rk628_i2c_write(rk628, GRF_BT1120_TIMING_CTRL2, BT1120_DSP_VS_END(dsp_vs_end) |
212 BT1120_DSP_VTOTAL(dsp_vtotal));
213 rk628_i2c_write(rk628, GRF_BT1120_TIMING_CTRL3, BT1120_DSP_VACT_ST(dsp_vact_st));
214 }
215
rk628_bt1120_decoder_enable(struct rk628 * rk628)216 static void rk628_bt1120_decoder_enable(struct rk628 *rk628)
217 {
218 struct drm_display_mode *mode = &rk628->src_mode;
219 unsigned long dec_clk_rate;
220
221 rk628_set_input_bus_format(rk628, BUS_FMT_YUV422);
222
223 /* pinctrl for vop pin */
224 rk628_i2c_write(rk628, GRF_GPIO2AB_SEL_CON, 0xffffffff);
225 rk628_i2c_write(rk628, GRF_GPIO2C_SEL_CON, 0xffff5555);
226 rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x10b010b);
227
228 /* config sw_input_mode bt1120 */
229 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_INPUT_MODE_MASK,
230 SW_INPUT_MODE(INPUT_MODE_BT1120));
231
232 if (rk628->version == RK628F_VERSION)
233 rk628_bt1120_decoder_timing_cfg(rk628);
234
235 /* operation resetn_bt1120dec */
236 rk628_i2c_write(rk628, CRU_SOFTRST_CON00, 0x10001000);
237 rk628_i2c_write(rk628, CRU_SOFTRST_CON00, 0x10000000);
238
239 /*
240 * BT1120 dec clk is a 4-bit integer division, which is inaccurate in
241 * most resolutions. So if the frequency division is not accurate, apply
242 * for a fault tolerance of up 2% in frequency setting, so that the
243 * obtained frequency is slightly higher than the actual required clk,
244 * so that the deviation between the actual clk and the required clk
245 * frequency is not significant.
246 */
247 rk628_cru_clk_set_rate(rk628, CGU_BT1120DEC, mode->clock * 1000);
248 dec_clk_rate = rk628_cru_clk_get_rate(rk628, CGU_BT1120DEC);
249 if (dec_clk_rate < mode->clock * 1000)
250 rk628_cru_clk_set_rate(rk628, CGU_BT1120DEC, mode->clock * 1020);
251
252 if (rk628->rgb.bt1120_dual_edge) {
253 rk628_i2c_update_bits(rk628, GRF_RGB_DEC_CON0,
254 DEC_DUALEDGE_EN, DEC_DUALEDGE_EN);
255 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON0, 0x10000000);
256 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON1, 0);
257 } else {
258 if (rk628->version == RK628F_VERSION) {
259 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON0,
260 0x10000);
261 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON1, 0);
262 }
263 }
264
265 rk628_i2c_update_bits(rk628, GRF_RGB_DEC_CON1, SW_SET_X_MASK,
266 SW_SET_X(mode->hdisplay));
267 rk628_i2c_update_bits(rk628, GRF_RGB_DEC_CON2, SW_SET_Y_MASK,
268 SW_SET_Y(mode->vdisplay));
269
270 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
271 SW_BT_DATA_OEN_MASK | SW_INPUT_MODE_MASK,
272 SW_BT_DATA_OEN | SW_INPUT_MODE(INPUT_MODE_BT1120));
273
274 rk628_i2c_update_bits(rk628, GRF_RGB_DEC_CON0,
275 SW_CAP_EN_PSYNC | SW_CAP_EN_ASYNC |
276 SW_PROGRESS_EN |
277 SW_BT1120_YC_SWAP |
278 SW_BT1120_UV_SWAP,
279 SW_CAP_EN_PSYNC | SW_CAP_EN_ASYNC |
280 SW_PROGRESS_EN |
281 (rk628->rgb.bt1120_yc_swap ? SW_BT1120_YC_SWAP : 0) |
282 (rk628->rgb.bt1120_uv_swap ? SW_BT1120_UV_SWAP : 0));
283 }
284
rk628_bt1120_encoder_enable(struct rk628 * rk628)285 static void rk628_bt1120_encoder_enable(struct rk628 *rk628)
286 {
287 u32 val = 0;
288 int voltage = 0;
289 u32 strength;
290 u64 dclk_delay;
291
292 rk628_set_output_bus_format(rk628, BUS_FMT_YUV422);
293
294 /* pinctrl for vop pin */
295 rk628_i2c_write(rk628, GRF_GPIO2AB_SEL_CON, 0xffffffff);
296 rk628_i2c_write(rk628, GRF_GPIO2C_SEL_CON, 0xffff5555);
297 rk628_i2c_write(rk628, GRF_GPIO3AB_SEL_CON, 0x10b010b);
298
299 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
300 SW_BT_DATA_OEN_MASK | SW_OUTPUT_RGB_MODE_MASK,
301 SW_OUTPUT_RGB_MODE(OUTPUT_MODE_BT1120 >> 3));
302
303 if (rk628->version != RK628F_VERSION)
304 rk628_i2c_update_bits(rk628, GRF_POST_PROC_CON,
305 SW_DCLK_OUT_INV_EN, SW_DCLK_OUT_INV_EN);
306
307 /*
308 * Under the same drive strength and DCLK delay, the signal behaves
309 * differently under different voltage power domains. In order to
310 * center the eye diagram of the signal, have sufficient signal setup
311 * and hold time, and ensure that the signal does not overshoot, the
312 * drive strength and DCLK delay need to be set for the power domains
313 * of different voltages.
314 */
315 if (rk628->rgb.vccio_rgb)
316 voltage = regulator_get_value(rk628->rgb.vccio_rgb);
317
318 switch (voltage) {
319 case 1800000:
320 strength = 3;
321 dclk_delay = 0x100000000;
322 break;
323 case 3300000:
324 strength = 1;
325 dclk_delay = 0x1000000000;
326 break;
327 default:
328 strength = 1;
329 dclk_delay = 0x1000000000;
330 }
331
332 /* rk628: modify IO drive strength for BT1120 */
333 if (rk628->version == RK628F_VERSION)
334 strength = strength * 0x1111 | 0xffff0000;
335 else
336 strength = 0xffff1111;
337
338 rk628_i2c_write(rk628, GRF_GPIO2A_D0_CON, strength);
339 rk628_i2c_write(rk628, GRF_GPIO2A_D1_CON, strength);
340 rk628_i2c_write(rk628, GRF_GPIO2B_D0_CON, strength);
341 rk628_i2c_write(rk628, GRF_GPIO2B_D1_CON, strength);
342 rk628_i2c_write(rk628, GRF_GPIO2C_D0_CON, strength);
343 rk628_i2c_write(rk628, GRF_GPIO2C_D1_CON, strength);
344 rk628_i2c_write(rk628, GRF_GPIO3A_D0_CON, strength & 0xf0fff0ff);
345 rk628_i2c_write(rk628, GRF_GPIO3B_D_CON, strength & 0x000f000f);
346
347 /* rk628: modify DCLK delay for BT1120 */
348 if (rk628->rgb.bt1120_dual_edge) {
349 val |= ENC_DUALEDGE_EN(1);
350 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON0, 0x10000000);
351 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON1, 0);
352 } else {
353 if (rk628->version == RK628F_VERSION) {
354 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON0,
355 dclk_delay & 0xffffffff);
356 rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON1,
357 dclk_delay >> 32);
358 }
359 }
360
361 val |= BT1120_UV_SWAP(1);
362 rk628_i2c_write(rk628, GRF_RGB_ENC_CON, val);
363 }
364
rk628_bt1120_rx_enable(struct rk628 * rk628)365 void rk628_bt1120_rx_enable(struct rk628 *rk628)
366 {
367 rk628_bt1120_decoder_enable(rk628);
368 }
369
rk628_bt1120_tx_enable(struct rk628 * rk628)370 void rk628_bt1120_tx_enable(struct rk628 *rk628)
371 {
372 rk628_bt1120_encoder_enable(rk628);
373 }
374