1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
4 */
5
6 #include <linux/clk.h>
7 #include <linux/gpio/consumer.h>
8 #include <linux/mfd/syscon.h>
9 #include <linux/module.h>
10 #include <linux/of_gpio.h>
11 #include <linux/platform_device.h>
12 #include <linux/phy/phy.h>
13 #include <linux/regmap.h>
14 #include <linux/pm_runtime.h>
15
16 #include <drm/drm_of.h>
17 #include <drm/drm_crtc_helper.h>
18 #include <drm/drm_dsc.h>
19 #include <drm/drm_edid.h>
20 #include <drm/bridge/dw_hdmi.h>
21 #include <drm/drm_edid.h>
22 #include <drm/drm_of.h>
23 #include <drm/drm_probe_helper.h>
24 #include <drm/drm_simple_kms_helper.h>
25
26 #include <uapi/linux/videodev2.h>
27
28 #include "rockchip_drm_drv.h"
29 #include "rockchip_drm_vop.h"
30
31 #define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
32
33 #define RK3228_GRF_SOC_CON2 0x0408
34 #define RK3228_HDMI_SDAIN_MSK BIT(14)
35 #define RK3228_HDMI_SCLIN_MSK BIT(13)
36 #define RK3228_GRF_SOC_CON6 0x0418
37 #define RK3228_HDMI_HPD_VSEL BIT(6)
38 #define RK3228_HDMI_SDA_VSEL BIT(5)
39 #define RK3228_HDMI_SCL_VSEL BIT(4)
40
41 #define RK3288_GRF_SOC_CON6 0x025C
42 #define RK3288_HDMI_LCDC_SEL BIT(4)
43 #define RK3288_GRF_SOC_CON16 0x03a8
44 #define RK3288_HDMI_LCDC0_YUV420 BIT(2)
45 #define RK3288_HDMI_LCDC1_YUV420 BIT(3)
46
47 #define RK3328_GRF_SOC_CON2 0x0408
48 #define RK3328_HDMI_SDAIN_MSK BIT(11)
49 #define RK3328_HDMI_SCLIN_MSK BIT(10)
50 #define RK3328_HDMI_HPD_IOE BIT(2)
51 #define RK3328_GRF_SOC_CON3 0x040c
52 /* need to be unset if hdmi or i2c should control voltage */
53 #define RK3328_HDMI_SDA5V_GRF BIT(15)
54 #define RK3328_HDMI_SCL5V_GRF BIT(14)
55 #define RK3328_HDMI_HPD5V_GRF BIT(13)
56 #define RK3328_HDMI_CEC5V_GRF BIT(12)
57 #define RK3328_GRF_SOC_CON4 0x0410
58 #define RK3328_HDMI_HPD_SARADC BIT(13)
59 #define RK3328_HDMI_CEC_5V BIT(11)
60 #define RK3328_HDMI_SDA_5V BIT(10)
61 #define RK3328_HDMI_SCL_5V BIT(9)
62 #define RK3328_HDMI_HPD_5V BIT(8)
63
64 #define RK3399_GRF_SOC_CON20 0x6250
65 #define RK3399_HDMI_LCDC_SEL BIT(6)
66
67 #define RK3528_VO_GRF_HDMI_MASK 0x60014
68 #define RK3528_HDMI_SNKDET_SEL BIT(6)
69 #define RK3528_HDMI_SNKDET BIT(5)
70 #define RK3528_HDMI_CECIN_MSK BIT(2)
71 #define RK3528_HDMI_SDAIN_MSK BIT(1)
72 #define RK3528_HDMI_SCLIN_MSK BIT(0)
73
74 #define RK3528PMU_GRF_SOC_CON6 0x70018
75 #define RK3528_HDMI_SDA5V_GRF BIT(6)
76 #define RK3528_HDMI_SCL5V_GRF BIT(5)
77 #define RK3528_HDMI_CEC5V_GRF BIT(4)
78 #define RK3528_HDMI_HPD5V_GRF BIT(3)
79
80 #define RK3528_GPIO_SWPORT_DR_L 0x0000
81 #define RK3528_GPIO0_A2_DR BIT(2)
82
83 #define RK3568_GRF_VO_CON1 0x0364
84 #define RK3568_HDMI_SDAIN_MSK BIT(15)
85 #define RK3568_HDMI_SCLIN_MSK BIT(14)
86
87 #define RK3588_GRF_SOC_CON2 0x0308
88 #define RK3588_HDMI1_HPD_INT_MSK BIT(15)
89 #define RK3588_HDMI1_HPD_INT_CLR BIT(14)
90 #define RK3588_HDMI0_HPD_INT_MSK BIT(13)
91 #define RK3588_HDMI0_HPD_INT_CLR BIT(12)
92 #define RK3588_GRF_SOC_CON7 0x031c
93 #define RK3588_SET_HPD_PATH_MASK (0x3 << 12)
94 #define RK3588_GRF_SOC_STATUS1 0x0384
95 #define RK3588_HDMI0_LOW_MORETHAN100MS BIT(20)
96 #define RK3588_HDMI0_HPD_PORT_LEVEL BIT(19)
97 #define RK3588_HDMI0_IHPD_PORT BIT(18)
98 #define RK3588_HDMI0_OHPD_INT BIT(17)
99 #define RK3588_HDMI0_LEVEL_INT BIT(16)
100 #define RK3588_HDMI0_INTR_CHANGE_CNT (0x7 << 13)
101 #define RK3588_HDMI1_LOW_MORETHAN100MS BIT(28)
102 #define RK3588_HDMI1_HPD_PORT_LEVEL BIT(27)
103 #define RK3588_HDMI1_IHPD_PORT BIT(26)
104 #define RK3588_HDMI1_OHPD_INT BIT(25)
105 #define RK3588_HDMI1_LEVEL_INT BIT(24)
106 #define RK3588_HDMI1_INTR_CHANGE_CNT (0x7 << 21)
107
108 #define RK3588_GRF_VO1_CON3 0x000c
109 #define RK3588_COLOR_FORMAT_MASK 0xf
110 #define RK3588_RGB 0
111 #define RK3588_YUV422 0x1
112 #define RK3588_YUV444 0x2
113 #define RK3588_YUV420 0x3
114 #define RK3588_COMPRESSED_DATA 0xb
115 #define RK3588_COLOR_DEPTH_MASK (0xf << 4)
116 #define RK3588_8BPC 0
117 #define RK3588_10BPC (0x6 << 4)
118 #define RK3588_CECIN_MASK BIT(8)
119 #define RK3588_SCLIN_MASK BIT(9)
120 #define RK3588_SDAIN_MASK BIT(10)
121 #define RK3588_MODE_MASK BIT(11)
122 #define RK3588_COMPRESS_MODE_MASK BIT(12)
123 #define RK3588_I2S_SEL_MASK BIT(13)
124 #define RK3588_SPDIF_SEL_MASK BIT(14)
125 #define RK3588_GRF_VO1_CON4 0x0010
126 #define RK3588_HDMI21_MASK BIT(0)
127 #define RK3588_GRF_VO1_CON9 0x0024
128 #define RK3588_HDMI0_GRANT_SEL BIT(10)
129 #define RK3588_HDMI0_GRANT_SW BIT(11)
130 #define RK3588_HDMI1_GRANT_SEL BIT(12)
131 #define RK3588_HDMI1_GRANT_SW BIT(13)
132 #define RK3588_GRF_VO1_CON6 0x0018
133 #define RK3588_GRF_VO1_CON7 0x001c
134
135 #define COLOR_DEPTH_10BIT BIT(31)
136 #define HDMI_FRL_MODE BIT(30)
137 #define HDMI_EARC_MODE BIT(29)
138 #define DATA_RATE_MASK 0xFFFFFFF
139
140 #define HDMI20_MAX_RATE 600000
141 #define HDMI_8K60_RATE 2376000
142
143 /**
144 * struct rockchip_hdmi_chip_data - splite the grf setting of kind of chips
145 * @lcdsel_grf_reg: grf register offset of lcdc select
146 * @ddc_en_reg: grf register offset of hdmi ddc enable
147 * @lcdsel_big: reg value of selecting vop big for HDMI
148 * @lcdsel_lit: reg value of selecting vop little for HDMI
149 */
150 struct rockchip_hdmi_chip_data {
151 int lcdsel_grf_reg;
152 int ddc_en_reg;
153 u32 lcdsel_big;
154 u32 lcdsel_lit;
155 bool split_mode;
156 };
157
158 enum hdmi_frl_rate_per_lane {
159 FRL_12G_PER_LANE = 12,
160 FRL_10G_PER_LANE = 10,
161 FRL_8G_PER_LANE = 8,
162 FRL_6G_PER_LANE = 6,
163 FRL_3G_PER_LANE = 3,
164 };
165
166 struct rockchip_hdmi {
167 struct device *dev;
168 struct regmap *regmap;
169 struct regmap *vo1_regmap;
170 void __iomem *gpio_base;
171 struct drm_encoder encoder;
172 struct drm_device *drm_dev;
173 const struct rockchip_hdmi_chip_data *chip_data;
174 struct dw_hdmi_plat_data *plat_data;
175 struct clk *aud_clk;
176 struct clk *phyref_clk;
177 struct clk *grf_clk;
178 struct clk *hclk_vio;
179 struct clk *hclk_vo1;
180 struct clk *hclk_vop;
181 struct clk *hpd_clk;
182 struct clk *pclk;
183 struct clk *earc_clk;
184 struct clk *hdmitx_ref;
185 struct clk *link_clk;
186 struct dw_hdmi *hdmi;
187 struct dw_hdmi_qp *hdmi_qp;
188
189 struct phy *phy;
190
191 u32 max_tmdsclk;
192 bool unsupported_yuv_input;
193 bool unsupported_deep_color;
194 bool skip_check_420_mode;
195 bool hpd_wake_en;
196 u8 force_output;
197 u8 id;
198 bool hpd_stat;
199 bool is_hdmi_qp;
200
201 unsigned long bus_format;
202 unsigned long output_bus_format;
203 unsigned long enc_out_encoding;
204 unsigned long prev_bus_format;
205 int color_changed;
206 int hpd_irq;
207
208 struct drm_property *color_depth_property;
209 struct drm_property *hdmi_output_property;
210 struct drm_property *colordepth_capacity;
211 struct drm_property *outputmode_capacity;
212 struct drm_property *quant_range;
213 struct drm_property *hdr_panel_metadata_property;
214 struct drm_property *next_hdr_sink_data_property;
215 struct drm_property *output_hdmi_dvi;
216 struct drm_property *output_type_capacity;
217 struct drm_property *allm_capacity;
218 struct drm_property *allm_enable;
219
220 struct drm_property_blob *hdr_panel_blob_ptr;
221 struct drm_property_blob *next_hdr_data_ptr;
222
223 unsigned int colordepth;
224 unsigned int colorimetry;
225 unsigned int hdmi_quant_range;
226 unsigned int phy_bus_width;
227 unsigned int enable_allm;
228 enum rk_if_color_format hdmi_output;
229 struct rockchip_drm_sub_dev sub_dev;
230
231 u8 max_frl_rate_per_lane;
232 u8 max_lanes;
233 u8 add_func;
234 u8 edid_colorimetry;
235 struct rockchip_drm_dsc_cap dsc_cap;
236 struct next_hdr_sink_data next_hdr_data;
237 struct dw_hdmi_link_config link_cfg;
238 struct gpio_desc *enable_gpio;
239
240 struct delayed_work work;
241 struct workqueue_struct *workqueue;
242 struct gpio_desc *hpd_gpiod;
243 struct pinctrl *p;
244 struct pinctrl_state *idle_state;
245 struct pinctrl_state *default_state;
246 };
247
248 #define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x)
249
250 /*
251 * There are some rates that would be ranged for better clock jitter at
252 * Chrome OS tree, like 25.175Mhz would range to 25.170732Mhz. But due
253 * to the clock is aglined to KHz in struct drm_display_mode, this would
254 * bring some inaccurate error if we still run the compute_n math, so
255 * let's just code an const table for it until we can actually get the
256 * right clock rate.
257 */
258 static const struct dw_hdmi_audio_tmds_n rockchip_werid_tmds_n_table[] = {
259 /* 25176471 for 25.175 MHz = 428000000 / 17. */
260 { .tmds = 25177000, .n_32k = 4352, .n_44k1 = 14994, .n_48k = 6528, },
261 /* 57290323 for 57.284 MHz */
262 { .tmds = 57291000, .n_32k = 3968, .n_44k1 = 4557, .n_48k = 5952, },
263 /* 74437500 for 74.44 MHz = 297750000 / 4 */
264 { .tmds = 74438000, .n_32k = 8192, .n_44k1 = 18816, .n_48k = 4096, },
265 /* 118666667 for 118.68 MHz */
266 { .tmds = 118667000, .n_32k = 4224, .n_44k1 = 5292, .n_48k = 6336, },
267 /* 121714286 for 121.75 MHz */
268 { .tmds = 121715000, .n_32k = 4480, .n_44k1 = 6174, .n_48k = 6272, },
269 /* 136800000 for 136.75 MHz */
270 { .tmds = 136800000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, },
271 /* End of table */
272 { .tmds = 0, .n_32k = 0, .n_44k1 = 0, .n_48k = 0, },
273 };
274
275 static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
276 {
277 30666000, {
278 { 0x00b3, 0x0000 },
279 { 0x2153, 0x0000 },
280 { 0x40f3, 0x0000 },
281 },
282 }, {
283 36800000, {
284 { 0x00b3, 0x0000 },
285 { 0x2153, 0x0000 },
286 { 0x40a2, 0x0001 },
287 },
288 }, {
289 46000000, {
290 { 0x00b3, 0x0000 },
291 { 0x2142, 0x0001 },
292 { 0x40a2, 0x0001 },
293 },
294 }, {
295 61333000, {
296 { 0x0072, 0x0001 },
297 { 0x2142, 0x0001 },
298 { 0x40a2, 0x0001 },
299 },
300 }, {
301 73600000, {
302 { 0x0072, 0x0001 },
303 { 0x2142, 0x0001 },
304 { 0x4061, 0x0002 },
305 },
306 }, {
307 92000000, {
308 { 0x0072, 0x0001 },
309 { 0x2145, 0x0002 },
310 { 0x4061, 0x0002 },
311 },
312 }, {
313 122666000, {
314 { 0x0051, 0x0002 },
315 { 0x2145, 0x0002 },
316 { 0x4061, 0x0002 },
317 },
318 }, {
319 147200000, {
320 { 0x0051, 0x0002 },
321 { 0x2145, 0x0002 },
322 { 0x4064, 0x0003 },
323 },
324 }, {
325 184000000, {
326 { 0x0051, 0x0002 },
327 { 0x214c, 0x0003 },
328 { 0x4064, 0x0003 },
329 },
330 }, {
331 226666000, {
332 { 0x0040, 0x0003 },
333 { 0x214c, 0x0003 },
334 { 0x4064, 0x0003 },
335 },
336 }, {
337 272000000, {
338 { 0x0040, 0x0003 },
339 { 0x214c, 0x0003 },
340 { 0x5a64, 0x0003 },
341 },
342 }, {
343 340000000, {
344 { 0x0040, 0x0003 },
345 { 0x3b4c, 0x0003 },
346 { 0x5a64, 0x0003 },
347 },
348 }, {
349 600000000, {
350 { 0x1a40, 0x0003 },
351 { 0x3b4c, 0x0003 },
352 { 0x5a64, 0x0003 },
353 },
354 }, {
355 ~0UL, {
356 { 0x0000, 0x0000 },
357 { 0x0000, 0x0000 },
358 { 0x0000, 0x0000 },
359 },
360 }
361 };
362
363 static const struct dw_hdmi_mpll_config rockchip_mpll_cfg_420[] = {
364 {
365 30666000, {
366 { 0x00b7, 0x0000 },
367 { 0x2157, 0x0000 },
368 { 0x40f7, 0x0000 },
369 },
370 }, {
371 92000000, {
372 { 0x00b7, 0x0000 },
373 { 0x2143, 0x0001 },
374 { 0x40a3, 0x0001 },
375 },
376 }, {
377 184000000, {
378 { 0x0073, 0x0001 },
379 { 0x2146, 0x0002 },
380 { 0x4062, 0x0002 },
381 },
382 }, {
383 340000000, {
384 { 0x0052, 0x0003 },
385 { 0x214d, 0x0003 },
386 { 0x4065, 0x0003 },
387 },
388 }, {
389 600000000, {
390 { 0x0041, 0x0003 },
391 { 0x3b4d, 0x0003 },
392 { 0x5a65, 0x0003 },
393 },
394 }, {
395 ~0UL, {
396 { 0x0000, 0x0000 },
397 { 0x0000, 0x0000 },
398 { 0x0000, 0x0000 },
399 },
400 }
401 };
402
403 static const struct dw_hdmi_mpll_config rockchip_rk3288w_mpll_cfg_420[] = {
404 {
405 30666000, {
406 { 0x00b7, 0x0000 },
407 { 0x2157, 0x0000 },
408 { 0x40f7, 0x0000 },
409 },
410 }, {
411 92000000, {
412 { 0x00b7, 0x0000 },
413 { 0x2143, 0x0001 },
414 { 0x40a3, 0x0001 },
415 },
416 }, {
417 184000000, {
418 { 0x0073, 0x0001 },
419 { 0x2146, 0x0002 },
420 { 0x4062, 0x0002 },
421 },
422 }, {
423 340000000, {
424 { 0x0052, 0x0003 },
425 { 0x214d, 0x0003 },
426 { 0x4065, 0x0003 },
427 },
428 }, {
429 600000000, {
430 { 0x0040, 0x0003 },
431 { 0x3b4c, 0x0003 },
432 { 0x5a65, 0x0003 },
433 },
434 }, {
435 ~0UL, {
436 { 0x0000, 0x0000 },
437 { 0x0000, 0x0000 },
438 { 0x0000, 0x0000 },
439 },
440 }
441 };
442
443 static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
444 /* pixelclk bpp8 bpp10 bpp12 */
445 {
446 600000000, { 0x0000, 0x0000, 0x0000 },
447 }, {
448 ~0UL, { 0x0000, 0x0000, 0x0000},
449 }
450 };
451
452 static struct dw_hdmi_phy_config rockchip_phy_config[] = {
453 /*pixelclk symbol term vlev*/
454 { 74250000, 0x8009, 0x0004, 0x0272},
455 { 165000000, 0x802b, 0x0004, 0x0209},
456 { 297000000, 0x8039, 0x0005, 0x028d},
457 { 594000000, 0x8039, 0x0000, 0x019d},
458 { ~0UL, 0x0000, 0x0000, 0x0000},
459 { ~0UL, 0x0000, 0x0000, 0x0000},
460 };
461
462 enum ROW_INDEX_BPP {
463 ROW_INDEX_6BPP = 0,
464 ROW_INDEX_8BPP,
465 ROW_INDEX_10BPP,
466 ROW_INDEX_12BPP,
467 ROW_INDEX_23BPP,
468 MAX_ROW_INDEX
469 };
470
471 enum COLUMN_INDEX_BPC {
472 COLUMN_INDEX_8BPC = 0,
473 COLUMN_INDEX_10BPC,
474 COLUMN_INDEX_12BPC,
475 COLUMN_INDEX_14BPC,
476 COLUMN_INDEX_16BPC,
477 MAX_COLUMN_INDEX
478 };
479
480 #define PPS_TABLE_LEN 8
481 #define PPS_BPP_LEN 4
482 #define PPS_BPC_LEN 2
483
484 struct pps_data {
485 u32 pic_width;
486 u32 pic_height;
487 u32 slice_width;
488 u32 slice_height;
489 bool convert_rgb;
490 u8 bpc;
491 u8 bpp;
492 u8 raw_pps[128];
493 };
494
495 /*
496 * Selected Rate Control Related Parameter Recommended Values
497 * from DSC_v1.11 spec & C Model release: DSC_model_20161212
498 */
499 static struct pps_data pps_datas[PPS_TABLE_LEN] = {
500 {
501 /* 7680x4320/960X96 rgb 8bpc 12bpp */
502 7680, 4320, 960, 96, 1, 8, 192,
503 {
504 0x12, 0x00, 0x00, 0x8d, 0x30, 0xc0, 0x10, 0xe0,
505 0x1e, 0x00, 0x00, 0x60, 0x03, 0xc0, 0x05, 0xa0,
506 0x01, 0x55, 0x03, 0x90, 0x00, 0x0a, 0x05, 0xc9,
507 0x00, 0xa0, 0x00, 0x0f, 0x01, 0x44, 0x01, 0xaa,
508 0x08, 0x00, 0x10, 0xf4, 0x03, 0x0c, 0x20, 0x00,
509 0x06, 0x0b, 0x0b, 0x33, 0x0e, 0x1c, 0x2a, 0x38,
510 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b,
511 0x7d, 0x7e, 0x00, 0x82, 0x00, 0xc0, 0x09, 0x00,
512 0x09, 0x7e, 0x19, 0xbc, 0x19, 0xba, 0x19, 0xf8,
513 0x1a, 0x38, 0x1a, 0x38, 0x1a, 0x76, 0x2a, 0x76,
514 0x2a, 0x76, 0x2a, 0x74, 0x3a, 0xb4, 0x52, 0xf4,
515 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
520 },
521 },
522 {
523 /* 7680x4320/960X96 rgb 8bpc 11bpp */
524 7680, 4320, 960, 96, 1, 8, 176,
525 {
526 0x12, 0x00, 0x00, 0x8d, 0x30, 0xb0, 0x10, 0xe0,
527 0x1e, 0x00, 0x00, 0x60, 0x03, 0xc0, 0x05, 0x28,
528 0x01, 0x74, 0x03, 0x40, 0x00, 0x0f, 0x06, 0xe0,
529 0x00, 0x2d, 0x00, 0x0f, 0x01, 0x44, 0x01, 0x33,
530 0x0f, 0x00, 0x10, 0xf4, 0x03, 0x0c, 0x20, 0x00,
531 0x06, 0x0b, 0x0b, 0x33, 0x0e, 0x1c, 0x2a, 0x38,
532 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b,
533 0x7d, 0x7e, 0x00, 0x82, 0x01, 0x00, 0x09, 0x40,
534 0x09, 0xbe, 0x19, 0xfc, 0x19, 0xfa, 0x19, 0xf8,
535 0x1a, 0x38, 0x1a, 0x38, 0x1a, 0x76, 0x2a, 0x76,
536 0x2a, 0x76, 0x2a, 0xb4, 0x3a, 0xb4, 0x52, 0xf4,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
542 },
543 },
544 {
545 /* 7680x4320/960X96 rgb 8bpc 10bpp */
546 7680, 4320, 960, 96, 1, 8, 160,
547 {
548 0x12, 0x00, 0x00, 0x8d, 0x30, 0xa0, 0x10, 0xe0,
549 0x1e, 0x00, 0x00, 0x60, 0x03, 0xc0, 0x04, 0xb0,
550 0x01, 0x9a, 0x02, 0xe0, 0x00, 0x19, 0x09, 0xb0,
551 0x00, 0x12, 0x00, 0x0f, 0x01, 0x44, 0x00, 0xbb,
552 0x16, 0x00, 0x10, 0xec, 0x03, 0x0c, 0x20, 0x00,
553 0x06, 0x0b, 0x0b, 0x33, 0x0e, 0x1c, 0x2a, 0x38,
554 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b,
555 0x7d, 0x7e, 0x00, 0xc2, 0x01, 0x00, 0x09, 0x40,
556 0x09, 0xbe, 0x19, 0xfc, 0x19, 0xfa, 0x19, 0xf8,
557 0x1a, 0x38, 0x1a, 0x78, 0x1a, 0x76, 0x2a, 0xb6,
558 0x2a, 0xb6, 0x2a, 0xf4, 0x3a, 0xf4, 0x5b, 0x34,
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
564 },
565 },
566 {
567 /* 7680x4320/960X96 rgb 8bpc 9bpp */
568 7680, 4320, 960, 96, 1, 8, 144,
569 {
570 0x12, 0x00, 0x00, 0x8d, 0x30, 0x90, 0x10, 0xe0,
571 0x1e, 0x00, 0x00, 0x60, 0x03, 0xc0, 0x04, 0x38,
572 0x01, 0xc7, 0x03, 0x16, 0x00, 0x1c, 0x08, 0xc7,
573 0x00, 0x10, 0x00, 0x0f, 0x01, 0x44, 0x00, 0xaa,
574 0x17, 0x00, 0x10, 0xf1, 0x03, 0x0c, 0x20, 0x00,
575 0x06, 0x0b, 0x0b, 0x33, 0x0e, 0x1c, 0x2a, 0x38,
576 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b,
577 0x7d, 0x7e, 0x00, 0xc2, 0x01, 0x00, 0x09, 0x40,
578 0x09, 0xbe, 0x19, 0xfc, 0x19, 0xfa, 0x19, 0xf8,
579 0x1a, 0x38, 0x1a, 0x78, 0x1a, 0x76, 0x2a, 0xb6,
580 0x2a, 0xb6, 0x2a, 0xf4, 0x3a, 0xf4, 0x63, 0x74,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
586 },
587 },
588 {
589 /* 7680x4320/960X96 rgb 10bpc 12bpp */
590 7680, 4320, 960, 96, 1, 10, 192,
591 {
592 0x12, 0x00, 0x00, 0xad, 0x30, 0xc0, 0x10, 0xe0,
593 0x1e, 0x00, 0x00, 0x60, 0x03, 0xc0, 0x05, 0xa0,
594 0x01, 0x55, 0x03, 0x90, 0x00, 0x0a, 0x05, 0xc9,
595 0x00, 0xa0, 0x00, 0x0f, 0x01, 0x44, 0x01, 0xaa,
596 0x08, 0x00, 0x10, 0xf4, 0x07, 0x10, 0x20, 0x00,
597 0x06, 0x0f, 0x0f, 0x33, 0x0e, 0x1c, 0x2a, 0x38,
598 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b,
599 0x7d, 0x7e, 0x01, 0x02, 0x11, 0x80, 0x22, 0x00,
600 0x22, 0x7e, 0x32, 0xbc, 0x32, 0xba, 0x3a, 0xf8,
601 0x3b, 0x38, 0x3b, 0x38, 0x3b, 0x76, 0x4b, 0x76,
602 0x4b, 0x76, 0x4b, 0x74, 0x5b, 0xb4, 0x73, 0xf4,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
608 },
609 },
610 {
611 /* 7680x4320/960X96 rgb 10bpc 11bpp */
612 7680, 4320, 960, 96, 1, 10, 176,
613 {
614 0x12, 0x00, 0x00, 0xad, 0x30, 0xb0, 0x10, 0xe0,
615 0x1e, 0x00, 0x00, 0x60, 0x03, 0xc0, 0x05, 0x28,
616 0x01, 0x74, 0x03, 0x40, 0x00, 0x0f, 0x06, 0xe0,
617 0x00, 0x2d, 0x00, 0x0f, 0x01, 0x44, 0x01, 0x33,
618 0x0f, 0x00, 0x10, 0xf4, 0x07, 0x10, 0x20, 0x00,
619 0x06, 0x0f, 0x0f, 0x33, 0x0e, 0x1c, 0x2a, 0x38,
620 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b,
621 0x7d, 0x7e, 0x01, 0x42, 0x19, 0xc0, 0x2a, 0x40,
622 0x2a, 0xbe, 0x3a, 0xfc, 0x3a, 0xfa, 0x3a, 0xf8,
623 0x3b, 0x38, 0x3b, 0x38, 0x3b, 0x76, 0x4b, 0x76,
624 0x4b, 0x76, 0x4b, 0xb4, 0x5b, 0xb4, 0x73, 0xf4,
625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
630 },
631 },
632 {
633 /* 7680x4320/960X96 rgb 10bpc 10bpp */
634 7680, 4320, 960, 96, 1, 10, 160,
635 {
636 0x12, 0x00, 0x00, 0xad, 0x30, 0xa0, 0x10, 0xe0,
637 0x1e, 0x00, 0x00, 0x60, 0x03, 0xc0, 0x04, 0xb0,
638 0x01, 0x9a, 0x02, 0xe0, 0x00, 0x19, 0x09, 0xb0,
639 0x00, 0x12, 0x00, 0x0f, 0x01, 0x44, 0x00, 0xbb,
640 0x16, 0x00, 0x10, 0xec, 0x07, 0x10, 0x20, 0x00,
641 0x06, 0x0f, 0x0f, 0x33, 0x0e, 0x1c, 0x2a, 0x38,
642 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b,
643 0x7d, 0x7e, 0x01, 0xc2, 0x22, 0x00, 0x2a, 0x40,
644 0x2a, 0xbe, 0x3a, 0xfc, 0x3a, 0xfa, 0x3a, 0xf8,
645 0x3b, 0x38, 0x3b, 0x78, 0x3b, 0x76, 0x4b, 0xb6,
646 0x4b, 0xb6, 0x4b, 0xf4, 0x63, 0xf4, 0x7c, 0x34,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
652 },
653 },
654 {
655 /* 7680x4320/960X96 rgb 10bpc 9bpp */
656 7680, 4320, 960, 96, 1, 10, 144,
657 {
658 0x12, 0x00, 0x00, 0xad, 0x30, 0x90, 0x10, 0xe0,
659 0x1e, 0x00, 0x00, 0x60, 0x03, 0xc0, 0x04, 0x38,
660 0x01, 0xc7, 0x03, 0x16, 0x00, 0x1c, 0x08, 0xc7,
661 0x00, 0x10, 0x00, 0x0f, 0x01, 0x44, 0x00, 0xaa,
662 0x17, 0x00, 0x10, 0xf1, 0x07, 0x10, 0x20, 0x00,
663 0x06, 0x0f, 0x0f, 0x33, 0x0e, 0x1c, 0x2a, 0x38,
664 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b,
665 0x7d, 0x7e, 0x01, 0xc2, 0x22, 0x00, 0x2a, 0x40,
666 0x2a, 0xbe, 0x3a, 0xfc, 0x3a, 0xfa, 0x3a, 0xf8,
667 0x3b, 0x38, 0x3b, 0x78, 0x3b, 0x76, 0x4b, 0xb6,
668 0x4b, 0xb6, 0x4b, 0xf4, 0x63, 0xf4, 0x84, 0x74,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
674 },
675 },
676 };
677
hdmi_bus_fmt_is_rgb(unsigned int bus_format)678 static bool hdmi_bus_fmt_is_rgb(unsigned int bus_format)
679 {
680 switch (bus_format) {
681 case MEDIA_BUS_FMT_RGB888_1X24:
682 case MEDIA_BUS_FMT_RGB101010_1X30:
683 case MEDIA_BUS_FMT_RGB121212_1X36:
684 case MEDIA_BUS_FMT_RGB161616_1X48:
685 return true;
686
687 default:
688 return false;
689 }
690 }
691
hdmi_bus_fmt_is_yuv444(unsigned int bus_format)692 static bool hdmi_bus_fmt_is_yuv444(unsigned int bus_format)
693 {
694 switch (bus_format) {
695 case MEDIA_BUS_FMT_YUV8_1X24:
696 case MEDIA_BUS_FMT_YUV10_1X30:
697 case MEDIA_BUS_FMT_YUV12_1X36:
698 case MEDIA_BUS_FMT_YUV16_1X48:
699 return true;
700
701 default:
702 return false;
703 }
704 }
705
hdmi_bus_fmt_is_yuv422(unsigned int bus_format)706 static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format)
707 {
708 switch (bus_format) {
709 case MEDIA_BUS_FMT_UYVY8_1X16:
710 case MEDIA_BUS_FMT_UYVY10_1X20:
711 case MEDIA_BUS_FMT_UYVY12_1X24:
712 case MEDIA_BUS_FMT_YUYV8_1X16:
713 case MEDIA_BUS_FMT_YUYV10_1X20:
714 case MEDIA_BUS_FMT_YUYV12_1X24:
715 return true;
716
717 default:
718 return false;
719 }
720 }
721
hdmi_bus_fmt_is_yuv420(unsigned int bus_format)722 static bool hdmi_bus_fmt_is_yuv420(unsigned int bus_format)
723 {
724 switch (bus_format) {
725 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
726 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
727 case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
728 case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
729 return true;
730
731 default:
732 return false;
733 }
734 }
735
hdmi_bus_fmt_color_depth(unsigned int bus_format)736 static int hdmi_bus_fmt_color_depth(unsigned int bus_format)
737 {
738 switch (bus_format) {
739 case MEDIA_BUS_FMT_RGB888_1X24:
740 case MEDIA_BUS_FMT_YUV8_1X24:
741 case MEDIA_BUS_FMT_UYVY8_1X16:
742 case MEDIA_BUS_FMT_YUYV8_1X16:
743 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
744 return 8;
745
746 case MEDIA_BUS_FMT_RGB101010_1X30:
747 case MEDIA_BUS_FMT_YUV10_1X30:
748 case MEDIA_BUS_FMT_UYVY10_1X20:
749 case MEDIA_BUS_FMT_YUYV10_1X20:
750 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
751 return 10;
752
753 case MEDIA_BUS_FMT_RGB121212_1X36:
754 case MEDIA_BUS_FMT_YUV12_1X36:
755 case MEDIA_BUS_FMT_UYVY12_1X24:
756 case MEDIA_BUS_FMT_YUYV12_1X24:
757 case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
758 return 12;
759
760 case MEDIA_BUS_FMT_RGB161616_1X48:
761 case MEDIA_BUS_FMT_YUV16_1X48:
762 case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
763 return 16;
764
765 default:
766 return 0;
767 }
768 }
769
hdmi_bus_fmt_to_color_format(unsigned int bus_format)770 static int hdmi_bus_fmt_to_color_format(unsigned int bus_format)
771 {
772 switch (bus_format) {
773 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
774 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
775 case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
776 case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
777 return RK_IF_FORMAT_YCBCR420;
778
779 case MEDIA_BUS_FMT_YUV8_1X24:
780 case MEDIA_BUS_FMT_YUV10_1X30:
781 case MEDIA_BUS_FMT_YUV12_1X36:
782 case MEDIA_BUS_FMT_YUV16_1X48:
783 return RK_IF_FORMAT_YCBCR444;
784
785 case MEDIA_BUS_FMT_UYVY8_1X16:
786 case MEDIA_BUS_FMT_YUYV8_1X16:
787 case MEDIA_BUS_FMT_UYVY10_1X20:
788 case MEDIA_BUS_FMT_YUYV10_1X20:
789 case MEDIA_BUS_FMT_UYVY12_1X24:
790 case MEDIA_BUS_FMT_YVYU12_1X24:
791 return RK_IF_FORMAT_YCBCR422;
792
793 case MEDIA_BUS_FMT_RGB888_1X24:
794 case MEDIA_BUS_FMT_RGB101010_1X30:
795 case MEDIA_BUS_FMT_RGB121212_1X36:
796 case MEDIA_BUS_FMT_RGB161616_1X48:
797 default:
798 return RK_IF_FORMAT_RGB;
799 }
800 }
801
802 static unsigned int
hdmi_get_tmdsclock(struct rockchip_hdmi * hdmi,unsigned long pixelclock)803 hdmi_get_tmdsclock(struct rockchip_hdmi *hdmi, unsigned long pixelclock)
804 {
805 unsigned int tmdsclock = pixelclock;
806 unsigned int depth =
807 hdmi_bus_fmt_color_depth(hdmi->output_bus_format);
808
809 if (!hdmi_bus_fmt_is_yuv422(hdmi->output_bus_format)) {
810 switch (depth) {
811 case 16:
812 tmdsclock = pixelclock * 2;
813 break;
814 case 12:
815 tmdsclock = pixelclock * 3 / 2;
816 break;
817 case 10:
818 tmdsclock = pixelclock * 5 / 4;
819 break;
820 default:
821 break;
822 }
823 }
824
825 return tmdsclock;
826 }
827
rockchip_hdmi_match_by_id(struct device * dev,const void * data)828 static int rockchip_hdmi_match_by_id(struct device *dev, const void *data)
829 {
830 struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
831 const unsigned int *id = data;
832
833 return hdmi->id == *id;
834 }
835
836 static struct rockchip_hdmi *
rockchip_hdmi_find_by_id(struct device_driver * drv,unsigned int id)837 rockchip_hdmi_find_by_id(struct device_driver *drv, unsigned int id)
838 {
839 struct device *dev;
840
841 dev = driver_find_device(drv, NULL, &id, rockchip_hdmi_match_by_id);
842 if (!dev)
843 return NULL;
844
845 return dev_get_drvdata(dev);
846 }
847
hdmi_select_link_config(struct rockchip_hdmi * hdmi,struct drm_crtc_state * crtc_state,unsigned int tmdsclk)848 static void hdmi_select_link_config(struct rockchip_hdmi *hdmi,
849 struct drm_crtc_state *crtc_state,
850 unsigned int tmdsclk)
851 {
852 struct drm_display_mode mode;
853 int max_lanes, max_rate_per_lane;
854 int max_dsc_lanes, max_dsc_rate_per_lane;
855 unsigned long max_frl_rate;
856
857 drm_mode_copy(&mode, &crtc_state->mode);
858 if (hdmi->plat_data->split_mode)
859 drm_mode_convert_to_origin_mode(&mode);
860
861 max_lanes = hdmi->max_lanes;
862 max_rate_per_lane = hdmi->max_frl_rate_per_lane;
863 max_frl_rate = max_lanes * max_rate_per_lane * 1000000;
864
865 hdmi->link_cfg.dsc_mode = false;
866 hdmi->link_cfg.frl_lanes = max_lanes;
867 hdmi->link_cfg.rate_per_lane = max_rate_per_lane;
868 hdmi->link_cfg.add_func = hdmi->add_func;
869
870 if (!max_frl_rate || (tmdsclk < HDMI20_MAX_RATE && mode.clock < HDMI20_MAX_RATE)) {
871 dev_info(hdmi->dev, "use tmds mode\n");
872 hdmi->link_cfg.frl_mode = false;
873 return;
874 }
875
876 hdmi->link_cfg.frl_mode = true;
877
878 if (!hdmi->dsc_cap.v_1p2)
879 return;
880
881 max_dsc_lanes = hdmi->dsc_cap.max_lanes;
882 max_dsc_rate_per_lane =
883 hdmi->dsc_cap.max_frl_rate_per_lane;
884
885 if (mode.clock >= HDMI_8K60_RATE &&
886 !hdmi_bus_fmt_is_yuv420(hdmi->bus_format) &&
887 !hdmi_bus_fmt_is_yuv422(hdmi->bus_format)) {
888 hdmi->link_cfg.dsc_mode = true;
889 hdmi->link_cfg.frl_lanes = max_dsc_lanes;
890 hdmi->link_cfg.rate_per_lane = max_dsc_rate_per_lane;
891 } else {
892 hdmi->link_cfg.dsc_mode = false;
893 hdmi->link_cfg.frl_lanes = max_lanes;
894 hdmi->link_cfg.rate_per_lane = max_rate_per_lane;
895 }
896 }
897
898 /////////////////////////////////////////////////////////////////////////////////////
899
hdmi_dsc_get_slice_height(int vactive)900 static int hdmi_dsc_get_slice_height(int vactive)
901 {
902 int slice_height;
903
904 /*
905 * Slice Height determination : HDMI2.1 Section 7.7.5.2
906 * Select smallest slice height >=96, that results in a valid PPS and
907 * requires minimum padding lines required for final slice.
908 *
909 * Assumption : Vactive is even.
910 */
911 for (slice_height = 96; slice_height <= vactive; slice_height += 2)
912 if (vactive % slice_height == 0)
913 return slice_height;
914
915 return 0;
916 }
917
hdmi_dsc_get_num_slices(struct rockchip_hdmi * hdmi,struct drm_crtc_state * crtc_state,int src_max_slices,int src_max_slice_width,int hdmi_max_slices,int hdmi_throughput)918 static int hdmi_dsc_get_num_slices(struct rockchip_hdmi *hdmi,
919 struct drm_crtc_state *crtc_state,
920 int src_max_slices, int src_max_slice_width,
921 int hdmi_max_slices, int hdmi_throughput)
922 {
923 /* Pixel rates in KPixels/sec */
924 #define HDMI_DSC_PEAK_PIXEL_RATE 2720000
925 /*
926 * Rates at which the source and sink are required to process pixels in each
927 * slice, can be two levels: either at least 340000KHz or at least 40000KHz.
928 */
929 #define HDMI_DSC_MAX_ENC_THROUGHPUT_0 340000
930 #define HDMI_DSC_MAX_ENC_THROUGHPUT_1 400000
931
932 /* Spec limits the slice width to 2720 pixels */
933 #define MAX_HDMI_SLICE_WIDTH 2720
934 int kslice_adjust;
935 int adjusted_clk_khz;
936 int min_slices;
937 int target_slices;
938 int max_throughput; /* max clock freq. in khz per slice */
939 int max_slice_width;
940 int slice_width;
941 int pixel_clock = crtc_state->mode.clock;
942
943 if (!hdmi_throughput)
944 return 0;
945
946 /*
947 * Slice Width determination : HDMI2.1 Section 7.7.5.1
948 * kslice_adjust factor for 4:2:0, and 4:2:2 formats is 0.5, where as
949 * for 4:4:4 is 1.0. Multiplying these factors by 10 and later
950 * dividing adjusted clock value by 10.
951 */
952 if (hdmi_bus_fmt_is_yuv444(hdmi->output_bus_format) ||
953 hdmi_bus_fmt_is_rgb(hdmi->output_bus_format))
954 kslice_adjust = 10;
955 else
956 kslice_adjust = 5;
957
958 /*
959 * As per spec, the rate at which the source and the sink process
960 * the pixels per slice are at two levels: at least 340Mhz or 400Mhz.
961 * This depends upon the pixel clock rate and output formats
962 * (kslice adjust).
963 * If pixel clock * kslice adjust >= 2720MHz slices can be processed
964 * at max 340MHz, otherwise they can be processed at max 400MHz.
965 */
966
967 adjusted_clk_khz = DIV_ROUND_UP(kslice_adjust * pixel_clock, 10);
968
969 if (adjusted_clk_khz <= HDMI_DSC_PEAK_PIXEL_RATE)
970 max_throughput = HDMI_DSC_MAX_ENC_THROUGHPUT_0;
971 else
972 max_throughput = HDMI_DSC_MAX_ENC_THROUGHPUT_1;
973
974 /*
975 * Taking into account the sink's capability for maximum
976 * clock per slice (in MHz) as read from HF-VSDB.
977 */
978 max_throughput = min(max_throughput, hdmi_throughput * 1000);
979
980 min_slices = DIV_ROUND_UP(adjusted_clk_khz, max_throughput);
981 max_slice_width = min(MAX_HDMI_SLICE_WIDTH, src_max_slice_width);
982
983 /*
984 * Keep on increasing the num of slices/line, starting from min_slices
985 * per line till we get such a number, for which the slice_width is
986 * just less than max_slice_width. The slices/line selected should be
987 * less than or equal to the max horizontal slices that the combination
988 * of PCON encoder and HDMI decoder can support.
989 */
990 do {
991 if (min_slices <= 1 && src_max_slices >= 1 && hdmi_max_slices >= 1)
992 target_slices = 1;
993 else if (min_slices <= 2 && src_max_slices >= 2 && hdmi_max_slices >= 2)
994 target_slices = 2;
995 else if (min_slices <= 4 && src_max_slices >= 4 && hdmi_max_slices >= 4)
996 target_slices = 4;
997 else if (min_slices <= 8 && src_max_slices >= 8 && hdmi_max_slices >= 8)
998 target_slices = 8;
999 else if (min_slices <= 12 && src_max_slices >= 12 && hdmi_max_slices >= 12)
1000 target_slices = 12;
1001 else if (min_slices <= 16 && src_max_slices >= 16 && hdmi_max_slices >= 16)
1002 target_slices = 16;
1003 else
1004 return 0;
1005
1006 slice_width = DIV_ROUND_UP(crtc_state->mode.hdisplay, target_slices);
1007 if (slice_width > max_slice_width)
1008 min_slices = target_slices + 1;
1009 } while (slice_width > max_slice_width);
1010
1011 return target_slices;
1012 }
1013
hdmi_dsc_slices(struct rockchip_hdmi * hdmi,struct drm_crtc_state * crtc_state)1014 static int hdmi_dsc_slices(struct rockchip_hdmi *hdmi,
1015 struct drm_crtc_state *crtc_state)
1016 {
1017 int hdmi_throughput = hdmi->dsc_cap.clk_per_slice;
1018 int hdmi_max_slices = hdmi->dsc_cap.max_slices;
1019 int rk_max_slices = 8;
1020 int rk_max_slice_width = 2048;
1021
1022 return hdmi_dsc_get_num_slices(hdmi, crtc_state, rk_max_slices,
1023 rk_max_slice_width,
1024 hdmi_max_slices, hdmi_throughput);
1025 }
1026
1027 static int
hdmi_dsc_get_bpp(struct rockchip_hdmi * hdmi,int src_fractional_bpp,int slice_width,int num_slices,bool hdmi_all_bpp,int hdmi_max_chunk_bytes)1028 hdmi_dsc_get_bpp(struct rockchip_hdmi *hdmi, int src_fractional_bpp,
1029 int slice_width, int num_slices, bool hdmi_all_bpp,
1030 int hdmi_max_chunk_bytes)
1031 {
1032 int max_dsc_bpp, min_dsc_bpp;
1033 int target_bytes;
1034 bool bpp_found = false;
1035 int bpp_decrement_x16;
1036 int bpp_target;
1037 int bpp_target_x16;
1038
1039 /*
1040 * Get min bpp and max bpp as per Table 7.23, in HDMI2.1 spec
1041 * Start with the max bpp and keep on decrementing with
1042 * fractional bpp, if supported by PCON DSC encoder
1043 *
1044 * for each bpp we check if no of bytes can be supported by HDMI sink
1045 */
1046
1047 /* only 9\10\12 bpp was tested */
1048 min_dsc_bpp = 9;
1049 max_dsc_bpp = 12;
1050
1051 /*
1052 * Taking into account if all dsc_all_bpp supported by HDMI2.1 sink
1053 * Section 7.7.34 : Source shall not enable compressed Video
1054 * Transport with bpp_target settings above 12 bpp unless
1055 * DSC_all_bpp is set to 1.
1056 */
1057 if (!hdmi_all_bpp)
1058 max_dsc_bpp = min(max_dsc_bpp, 12);
1059
1060 /*
1061 * The Sink has a limit of compressed data in bytes for a scanline,
1062 * as described in max_chunk_bytes field in HFVSDB block of edid.
1063 * The no. of bytes depend on the target bits per pixel that the
1064 * source configures. So we start with the max_bpp and calculate
1065 * the target_chunk_bytes. We keep on decrementing the target_bpp,
1066 * till we get the target_chunk_bytes just less than what the sink's
1067 * max_chunk_bytes, or else till we reach the min_dsc_bpp.
1068 *
1069 * The decrement is according to the fractional support from PCON DSC
1070 * encoder. For fractional BPP we use bpp_target as a multiple of 16.
1071 *
1072 * bpp_target_x16 = bpp_target * 16
1073 * So we need to decrement by {1, 2, 4, 8, 16} for fractional bpps
1074 * {1/16, 1/8, 1/4, 1/2, 1} respectively.
1075 */
1076
1077 bpp_target = max_dsc_bpp;
1078
1079 /* src does not support fractional bpp implies decrement by 16 for bppx16 */
1080 if (!src_fractional_bpp)
1081 src_fractional_bpp = 1;
1082 bpp_decrement_x16 = DIV_ROUND_UP(16, src_fractional_bpp);
1083 bpp_target_x16 = bpp_target * 16;
1084
1085 while (bpp_target_x16 > (min_dsc_bpp * 16)) {
1086 int bpp;
1087
1088 bpp = DIV_ROUND_UP(bpp_target_x16, 16);
1089 target_bytes = DIV_ROUND_UP((num_slices * slice_width * bpp), 8);
1090 if (target_bytes <= hdmi_max_chunk_bytes) {
1091 bpp_found = true;
1092 break;
1093 }
1094 bpp_target_x16 -= bpp_decrement_x16;
1095 }
1096 if (bpp_found)
1097 return bpp_target_x16;
1098
1099 return 0;
1100 }
1101
1102 static int
dw_hdmi_dsc_bpp(struct rockchip_hdmi * hdmi,int num_slices,int slice_width)1103 dw_hdmi_dsc_bpp(struct rockchip_hdmi *hdmi,
1104 int num_slices, int slice_width)
1105 {
1106 bool hdmi_all_bpp = hdmi->dsc_cap.all_bpp;
1107 int fractional_bpp = 0;
1108 int hdmi_max_chunk_bytes = hdmi->dsc_cap.total_chunk_kbytes * 1024;
1109
1110 return hdmi_dsc_get_bpp(hdmi, fractional_bpp, slice_width,
1111 num_slices, hdmi_all_bpp,
1112 hdmi_max_chunk_bytes);
1113 }
1114
dw_hdmi_qp_set_link_cfg(struct rockchip_hdmi * hdmi,u16 pic_width,u16 pic_height,u16 slice_width,u16 slice_height,u16 bits_per_pixel,u8 bits_per_component)1115 static int dw_hdmi_qp_set_link_cfg(struct rockchip_hdmi *hdmi,
1116 u16 pic_width, u16 pic_height,
1117 u16 slice_width, u16 slice_height,
1118 u16 bits_per_pixel, u8 bits_per_component)
1119 {
1120 int i;
1121
1122 for (i = 0; i < PPS_TABLE_LEN; i++)
1123 if (pic_width == pps_datas[i].pic_width &&
1124 pic_height == pps_datas[i].pic_height &&
1125 slice_width == pps_datas[i].slice_width &&
1126 slice_height == pps_datas[i].slice_height &&
1127 bits_per_component == pps_datas[i].bpc &&
1128 bits_per_pixel == pps_datas[i].bpp &&
1129 hdmi_bus_fmt_is_rgb(hdmi->output_bus_format) == pps_datas[i].convert_rgb)
1130 break;
1131
1132 if (i == PPS_TABLE_LEN) {
1133 dev_err(hdmi->dev, "can't find pps cfg!\n");
1134 return -EINVAL;
1135 }
1136
1137 memcpy(hdmi->link_cfg.pps_payload, pps_datas[i].raw_pps, 128);
1138 hdmi->link_cfg.hcactive = DIV_ROUND_UP(slice_width * (bits_per_pixel / 16), 8) *
1139 (pic_width / slice_width);
1140
1141 return 0;
1142 }
1143
dw_hdmi_qp_dsc_configure(struct rockchip_hdmi * hdmi,struct rockchip_crtc_state * s,struct drm_crtc_state * crtc_state)1144 static void dw_hdmi_qp_dsc_configure(struct rockchip_hdmi *hdmi,
1145 struct rockchip_crtc_state *s,
1146 struct drm_crtc_state *crtc_state)
1147 {
1148 int ret;
1149 int slice_height;
1150 int slice_width;
1151 int bits_per_pixel;
1152 int slice_count;
1153 bool hdmi_is_dsc_1_2;
1154 unsigned int depth = hdmi_bus_fmt_color_depth(hdmi->output_bus_format);
1155
1156 if (!crtc_state)
1157 return;
1158
1159 hdmi_is_dsc_1_2 = hdmi->dsc_cap.v_1p2;
1160
1161 if (!hdmi_is_dsc_1_2)
1162 return;
1163
1164 slice_height = hdmi_dsc_get_slice_height(crtc_state->mode.vdisplay);
1165 if (!slice_height)
1166 return;
1167
1168 slice_count = hdmi_dsc_slices(hdmi, crtc_state);
1169 if (!slice_count)
1170 return;
1171
1172 slice_width = DIV_ROUND_UP(crtc_state->mode.hdisplay, slice_count);
1173
1174 bits_per_pixel = dw_hdmi_dsc_bpp(hdmi, slice_count, slice_width);
1175 if (!bits_per_pixel)
1176 return;
1177
1178 ret = dw_hdmi_qp_set_link_cfg(hdmi, crtc_state->mode.hdisplay,
1179 crtc_state->mode.vdisplay, slice_width,
1180 slice_height, bits_per_pixel, depth);
1181
1182 if (ret) {
1183 dev_err(hdmi->dev, "set vdsc cfg failed\n");
1184 return;
1185 }
1186 dev_info(hdmi->dev, "dsc_enable\n");
1187 s->dsc_enable = 1;
1188 s->dsc_sink_cap.version_major = 1;
1189 s->dsc_sink_cap.version_minor = 2;
1190 s->dsc_sink_cap.slice_width = slice_width;
1191 s->dsc_sink_cap.slice_height = slice_height;
1192 s->dsc_sink_cap.target_bits_per_pixel_x16 = bits_per_pixel;
1193 s->dsc_sink_cap.block_pred = 1;
1194 s->dsc_sink_cap.native_420 = 0;
1195
1196 memcpy(&s->pps, hdmi->link_cfg.pps_payload, 128);
1197 }
1198 /////////////////////////////////////////////////////////////////////////////////////////
1199
rockchip_hdmi_update_phy_table(struct rockchip_hdmi * hdmi,u32 * config,int phy_table_size)1200 static int rockchip_hdmi_update_phy_table(struct rockchip_hdmi *hdmi,
1201 u32 *config,
1202 int phy_table_size)
1203 {
1204 int i;
1205
1206 if (phy_table_size > ARRAY_SIZE(rockchip_phy_config)) {
1207 dev_err(hdmi->dev, "phy table array number is out of range\n");
1208 return -E2BIG;
1209 }
1210
1211 for (i = 0; i < phy_table_size; i++) {
1212 if (config[i * 4] != 0)
1213 rockchip_phy_config[i].mpixelclock = (u64)config[i * 4];
1214 else
1215 rockchip_phy_config[i].mpixelclock = ~0UL;
1216 rockchip_phy_config[i].sym_ctr = (u16)config[i * 4 + 1];
1217 rockchip_phy_config[i].term = (u16)config[i * 4 + 2];
1218 rockchip_phy_config[i].vlev_ctr = (u16)config[i * 4 + 3];
1219 }
1220
1221 return 0;
1222 }
1223
repo_hpd_event(struct work_struct * p_work)1224 static void repo_hpd_event(struct work_struct *p_work)
1225 {
1226 struct rockchip_hdmi *hdmi = container_of(p_work, struct rockchip_hdmi, work.work);
1227 bool change;
1228
1229 change = drm_helper_hpd_irq_event(hdmi->drm_dev);
1230 if (change) {
1231 dev_dbg(hdmi->dev, "hpd stat changed:%d\n", hdmi->hpd_stat);
1232 dw_hdmi_qp_cec_set_hpd(hdmi->hdmi_qp, hdmi->hpd_stat, change);
1233 }
1234 }
1235
rockchip_hdmi_hardirq(int irq,void * dev_id)1236 static irqreturn_t rockchip_hdmi_hardirq(int irq, void *dev_id)
1237 {
1238 struct rockchip_hdmi *hdmi = dev_id;
1239 u32 intr_stat, val;
1240
1241 regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat);
1242
1243 if (intr_stat) {
1244 dev_dbg(hdmi->dev, "hpd irq %#x\n", intr_stat);
1245
1246 if (!hdmi->id)
1247 val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK,
1248 RK3588_HDMI0_HPD_INT_MSK);
1249 else
1250 val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK,
1251 RK3588_HDMI1_HPD_INT_MSK);
1252 regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
1253 return IRQ_WAKE_THREAD;
1254 }
1255
1256 return IRQ_NONE;
1257 }
1258
rockchip_hdmi_irq(int irq,void * dev_id)1259 static irqreturn_t rockchip_hdmi_irq(int irq, void *dev_id)
1260 {
1261 struct rockchip_hdmi *hdmi = dev_id;
1262 u32 intr_stat, val;
1263 int msecs;
1264 bool stat;
1265
1266 regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat);
1267
1268 if (!intr_stat)
1269 return IRQ_NONE;
1270
1271 if (!hdmi->id) {
1272 val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
1273 RK3588_HDMI0_HPD_INT_CLR);
1274 if (intr_stat & RK3588_HDMI0_LEVEL_INT)
1275 stat = true;
1276 else
1277 stat = false;
1278 } else {
1279 val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR,
1280 RK3588_HDMI1_HPD_INT_CLR);
1281 if (intr_stat & RK3588_HDMI1_LEVEL_INT)
1282 stat = true;
1283 else
1284 stat = false;
1285 }
1286
1287 regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
1288
1289 if (stat) {
1290 hdmi->hpd_stat = true;
1291 msecs = 150;
1292 } else {
1293 hdmi->hpd_stat = false;
1294 msecs = 20;
1295 }
1296 mod_delayed_work(hdmi->workqueue, &hdmi->work, msecs_to_jiffies(msecs));
1297
1298 if (!hdmi->id) {
1299 val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
1300 RK3588_HDMI0_HPD_INT_CLR) |
1301 HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK);
1302 } else {
1303 val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR,
1304 RK3588_HDMI1_HPD_INT_CLR) |
1305 HIWORD_UPDATE(0, RK3588_HDMI1_HPD_INT_MSK);
1306 }
1307
1308 regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
1309
1310 return IRQ_HANDLED;
1311 }
1312
init_hpd_work(struct rockchip_hdmi * hdmi)1313 static void init_hpd_work(struct rockchip_hdmi *hdmi)
1314 {
1315 hdmi->workqueue = create_workqueue("hpd_queue");
1316 INIT_DELAYED_WORK(&hdmi->work, repo_hpd_event);
1317 }
1318
rockchip_hdmi_hpd_irq_handler(int irq,void * arg)1319 static irqreturn_t rockchip_hdmi_hpd_irq_handler(int irq, void *arg)
1320 {
1321 u32 val;
1322 struct rockchip_hdmi *hdmi = arg;
1323
1324 val = gpiod_get_value(hdmi->hpd_gpiod);
1325 if (val) {
1326 val = HIWORD_UPDATE(RK3528_HDMI_SNKDET, RK3528_HDMI_SNKDET);
1327 if (hdmi->hdmi && hdmi->hpd_wake_en && hdmi->hpd_gpiod)
1328 dw_hdmi_set_hpd_wake(hdmi->hdmi);
1329 } else {
1330 val = HIWORD_UPDATE(0, RK3528_HDMI_SNKDET);
1331 }
1332 regmap_write(hdmi->regmap, RK3528_VO_GRF_HDMI_MASK, val);
1333
1334 return IRQ_HANDLED;
1335 }
1336
dw_hdmi_rk3528_gpio_hpd_init(struct rockchip_hdmi * hdmi)1337 static void dw_hdmi_rk3528_gpio_hpd_init(struct rockchip_hdmi *hdmi)
1338 {
1339 u32 val;
1340
1341 if (hdmi->hpd_gpiod) {
1342 /* gpio0_a2's input enable is controlled by gpio output data bit */
1343 val = HIWORD_UPDATE(RK3528_GPIO0_A2_DR, RK3528_GPIO0_A2_DR);
1344 writel(val, hdmi->gpio_base + RK3528_GPIO_SWPORT_DR_L);
1345
1346 val = HIWORD_UPDATE(RK3528_HDMI_SNKDET_SEL | RK3528_HDMI_SDAIN_MSK |
1347 RK3528_HDMI_SCLIN_MSK,
1348 RK3528_HDMI_SNKDET_SEL | RK3528_HDMI_SDAIN_MSK |
1349 RK3528_HDMI_SCLIN_MSK);
1350 } else {
1351 val = HIWORD_UPDATE(RK3528_HDMI_SDAIN_MSK | RK3528_HDMI_SCLIN_MSK,
1352 RK3528_HDMI_SDAIN_MSK | RK3528_HDMI_SCLIN_MSK);
1353 }
1354
1355 regmap_write(hdmi->regmap, RK3528_VO_GRF_HDMI_MASK, val);
1356
1357 val = gpiod_get_value(hdmi->hpd_gpiod);
1358 if (val) {
1359 val = HIWORD_UPDATE(RK3528_HDMI_SNKDET, RK3528_HDMI_SNKDET);
1360 if (hdmi->hdmi && hdmi->hpd_wake_en && hdmi->hpd_gpiod)
1361 dw_hdmi_set_hpd_wake(hdmi->hdmi);
1362 } else {
1363 val = HIWORD_UPDATE(0, RK3528_HDMI_SNKDET);
1364 }
1365 regmap_write(hdmi->regmap, RK3528_VO_GRF_HDMI_MASK, val);
1366 }
1367
rockchip_hdmi_parse_dt(struct rockchip_hdmi * hdmi)1368 static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
1369 {
1370 int ret, val, phy_table_size;
1371 u32 *phy_config;
1372 struct device_node *np = hdmi->dev->of_node;
1373
1374 hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
1375 if (IS_ERR(hdmi->regmap)) {
1376 DRM_DEV_ERROR(hdmi->dev, "Unable to get rockchip,grf\n");
1377 return PTR_ERR(hdmi->regmap);
1378 }
1379
1380 if (hdmi->is_hdmi_qp) {
1381 hdmi->vo1_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,vo1_grf");
1382 if (IS_ERR(hdmi->vo1_regmap)) {
1383 DRM_DEV_ERROR(hdmi->dev, "Unable to get rockchip,vo1_grf\n");
1384 return PTR_ERR(hdmi->vo1_regmap);
1385 }
1386 }
1387
1388 hdmi->phyref_clk = devm_clk_get(hdmi->dev, "vpll");
1389 if (PTR_ERR(hdmi->phyref_clk) == -ENOENT)
1390 hdmi->phyref_clk = devm_clk_get(hdmi->dev, "ref");
1391
1392 if (PTR_ERR(hdmi->phyref_clk) == -ENOENT) {
1393 hdmi->phyref_clk = NULL;
1394 } else if (PTR_ERR(hdmi->phyref_clk) == -EPROBE_DEFER) {
1395 return -EPROBE_DEFER;
1396 } else if (IS_ERR(hdmi->phyref_clk)) {
1397 DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
1398 return PTR_ERR(hdmi->phyref_clk);
1399 }
1400
1401 hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf");
1402 if (PTR_ERR(hdmi->grf_clk) == -ENOENT) {
1403 hdmi->grf_clk = NULL;
1404 } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) {
1405 return -EPROBE_DEFER;
1406 } else if (IS_ERR(hdmi->grf_clk)) {
1407 DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
1408 return PTR_ERR(hdmi->grf_clk);
1409 }
1410
1411 hdmi->hclk_vio = devm_clk_get(hdmi->dev, "hclk_vio");
1412 if (PTR_ERR(hdmi->hclk_vio) == -ENOENT) {
1413 hdmi->hclk_vio = NULL;
1414 } else if (PTR_ERR(hdmi->hclk_vio) == -EPROBE_DEFER) {
1415 return -EPROBE_DEFER;
1416 } else if (IS_ERR(hdmi->hclk_vio)) {
1417 dev_err(hdmi->dev, "failed to get hclk_vio clock\n");
1418 return PTR_ERR(hdmi->hclk_vio);
1419 }
1420
1421 hdmi->hclk_vop = devm_clk_get(hdmi->dev, "hclk");
1422 if (PTR_ERR(hdmi->hclk_vop) == -ENOENT) {
1423 hdmi->hclk_vop = NULL;
1424 } else if (PTR_ERR(hdmi->hclk_vop) == -EPROBE_DEFER) {
1425 return -EPROBE_DEFER;
1426 } else if (IS_ERR(hdmi->hclk_vop)) {
1427 dev_err(hdmi->dev, "failed to get hclk_vop clock\n");
1428 return PTR_ERR(hdmi->hclk_vop);
1429 }
1430
1431 hdmi->aud_clk = devm_clk_get_optional(hdmi->dev, "aud");
1432 if (IS_ERR(hdmi->aud_clk)) {
1433 dev_err_probe(hdmi->dev, PTR_ERR(hdmi->aud_clk),
1434 "failed to get aud_clk clock\n");
1435 return PTR_ERR(hdmi->aud_clk);
1436 }
1437
1438 hdmi->hpd_clk = devm_clk_get_optional(hdmi->dev, "hpd");
1439 if (IS_ERR(hdmi->hpd_clk)) {
1440 dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hpd_clk),
1441 "failed to get hpd_clk clock\n");
1442 return PTR_ERR(hdmi->hpd_clk);
1443 }
1444
1445 hdmi->hclk_vo1 = devm_clk_get_optional(hdmi->dev, "hclk_vo1");
1446 if (IS_ERR(hdmi->hclk_vo1)) {
1447 dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hclk_vo1),
1448 "failed to get hclk_vo1 clock\n");
1449 return PTR_ERR(hdmi->hclk_vo1);
1450 }
1451
1452 hdmi->earc_clk = devm_clk_get_optional(hdmi->dev, "earc");
1453 if (IS_ERR(hdmi->earc_clk)) {
1454 dev_err_probe(hdmi->dev, PTR_ERR(hdmi->earc_clk),
1455 "failed to get earc_clk clock\n");
1456 return PTR_ERR(hdmi->earc_clk);
1457 }
1458
1459 hdmi->hdmitx_ref = devm_clk_get_optional(hdmi->dev, "hdmitx_ref");
1460 if (IS_ERR(hdmi->hdmitx_ref)) {
1461 dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hdmitx_ref),
1462 "failed to get hdmitx_ref clock\n");
1463 return PTR_ERR(hdmi->hdmitx_ref);
1464 }
1465
1466 hdmi->pclk = devm_clk_get_optional(hdmi->dev, "pclk");
1467 if (IS_ERR(hdmi->pclk)) {
1468 dev_err_probe(hdmi->dev, PTR_ERR(hdmi->pclk),
1469 "failed to get pclk clock\n");
1470 return PTR_ERR(hdmi->pclk);
1471 }
1472
1473 hdmi->link_clk = devm_clk_get_optional(hdmi->dev, "link_clk");
1474 if (IS_ERR(hdmi->link_clk)) {
1475 dev_err_probe(hdmi->dev, PTR_ERR(hdmi->link_clk),
1476 "failed to get link_clk clock\n");
1477 return PTR_ERR(hdmi->link_clk);
1478 }
1479
1480 hdmi->enable_gpio = devm_gpiod_get_optional(hdmi->dev, "enable",
1481 GPIOD_OUT_HIGH);
1482 if (IS_ERR(hdmi->enable_gpio)) {
1483 ret = PTR_ERR(hdmi->enable_gpio);
1484 dev_err(hdmi->dev, "failed to request enable GPIO: %d\n", ret);
1485 return ret;
1486 }
1487
1488 hdmi->skip_check_420_mode =
1489 of_property_read_bool(np, "skip-check-420-mode");
1490
1491 if (of_get_property(np, "rockchip,phy-table", &val)) {
1492 phy_config = kmalloc(val, GFP_KERNEL);
1493 if (!phy_config) {
1494 /* use default table when kmalloc failed. */
1495 dev_err(hdmi->dev, "kmalloc phy table failed\n");
1496
1497 return -ENOMEM;
1498 }
1499 phy_table_size = val / 16;
1500 of_property_read_u32_array(np, "rockchip,phy-table",
1501 phy_config, val / sizeof(u32));
1502 ret = rockchip_hdmi_update_phy_table(hdmi, phy_config,
1503 phy_table_size);
1504 if (ret) {
1505 kfree(phy_config);
1506 return ret;
1507 }
1508 kfree(phy_config);
1509 } else {
1510 dev_dbg(hdmi->dev, "use default hdmi phy table\n");
1511 }
1512
1513 hdmi->hpd_gpiod = devm_gpiod_get_optional(hdmi->dev, "hpd", GPIOD_IN);
1514
1515 if (IS_ERR(hdmi->hpd_gpiod)) {
1516 dev_err(hdmi->dev, "error getting HDP GPIO: %ld\n",
1517 PTR_ERR(hdmi->hpd_gpiod));
1518 return PTR_ERR(hdmi->hpd_gpiod);
1519 }
1520
1521 if (hdmi->hpd_gpiod) {
1522 struct resource *res;
1523 struct platform_device *pdev = to_platform_device(hdmi->dev);
1524
1525 /* gpio interrupt reflects hpd status */
1526 hdmi->hpd_irq = gpiod_to_irq(hdmi->hpd_gpiod);
1527 if (hdmi->hpd_irq < 0)
1528 return -EINVAL;
1529
1530 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1531 if (!res) {
1532 DRM_DEV_ERROR(hdmi->dev, "failed to get gpio regs\n");
1533 return -EINVAL;
1534 }
1535
1536 hdmi->gpio_base = devm_ioremap(hdmi->dev, res->start, resource_size(res));
1537 if (IS_ERR(hdmi->gpio_base)) {
1538 DRM_DEV_ERROR(hdmi->dev, "Unable to get gpio ioregmap\n");
1539 return PTR_ERR(hdmi->gpio_base);
1540 }
1541
1542 dw_hdmi_rk3528_gpio_hpd_init(hdmi);
1543 ret = devm_request_threaded_irq(hdmi->dev, hdmi->hpd_irq, NULL,
1544 rockchip_hdmi_hpd_irq_handler,
1545 IRQF_TRIGGER_RISING |
1546 IRQF_TRIGGER_FALLING |
1547 IRQF_ONESHOT,
1548 "hdmi-hpd", hdmi);
1549 if (ret) {
1550 dev_err(hdmi->dev, "failed to request hpd IRQ: %d\n", ret);
1551 return ret;
1552 }
1553
1554 hdmi->hpd_wake_en = device_property_read_bool(hdmi->dev, "hpd-wake-up");
1555 if (hdmi->hpd_wake_en)
1556 enable_irq_wake(hdmi->hpd_irq);
1557 }
1558
1559 hdmi->p = devm_pinctrl_get(hdmi->dev);
1560 if (IS_ERR(hdmi->p)) {
1561 dev_err(hdmi->dev, "could not get pinctrl\n");
1562 return PTR_ERR(hdmi->p);
1563 }
1564
1565 hdmi->idle_state = pinctrl_lookup_state(hdmi->p, "idle");
1566 if (IS_ERR(hdmi->idle_state)) {
1567 dev_dbg(hdmi->dev, "idle state is not defined\n");
1568 return 0;
1569 }
1570
1571 hdmi->default_state = pinctrl_lookup_state(hdmi->p, "default");
1572 if (IS_ERR(hdmi->default_state)) {
1573 dev_err(hdmi->dev, "could not find default state\n");
1574 return PTR_ERR(hdmi->default_state);
1575 }
1576
1577 return 0;
1578 }
1579
1580 static enum drm_mode_status
dw_hdmi_rockchip_mode_valid(struct dw_hdmi * dw_hdmi,void * data,const struct drm_display_info * info,const struct drm_display_mode * mode)1581 dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
1582 const struct drm_display_info *info,
1583 const struct drm_display_mode *mode)
1584 {
1585 struct drm_connector *connector = container_of(info, struct drm_connector, display_info);
1586 struct drm_encoder *encoder = connector->encoder;
1587 enum drm_mode_status status = MODE_OK;
1588 struct drm_device *dev = connector->dev;
1589 struct rockchip_drm_private *priv = dev->dev_private;
1590 struct drm_crtc *crtc;
1591 struct rockchip_hdmi *hdmi;
1592
1593 /*
1594 * Pixel clocks we support are always < 2GHz and so fit in an
1595 * int. We should make sure source rate does too so we don't get
1596 * overflow when we multiply by 1000.
1597 */
1598 if (mode->clock > INT_MAX / 1000)
1599 return MODE_BAD;
1600
1601 if (!encoder) {
1602 const struct drm_connector_helper_funcs *funcs;
1603
1604 funcs = connector->helper_private;
1605 if (funcs->atomic_best_encoder)
1606 encoder = funcs->atomic_best_encoder(connector,
1607 connector->state);
1608 else
1609 encoder = funcs->best_encoder(connector);
1610 }
1611
1612 if (!encoder || !encoder->possible_crtcs)
1613 return MODE_BAD;
1614
1615 hdmi = to_rockchip_hdmi(encoder);
1616
1617 /*
1618 * If sink max TMDS clock < 340MHz, we should check the mode pixel
1619 * clock > 340MHz is YCbCr420 or not and whether the platform supports
1620 * YCbCr420.
1621 */
1622 if (!hdmi->skip_check_420_mode) {
1623 if (mode->clock > 340000 &&
1624 connector->display_info.max_tmds_clock < 340000 &&
1625 (!drm_mode_is_420(&connector->display_info, mode) ||
1626 !connector->ycbcr_420_allowed))
1627 return MODE_BAD;
1628
1629 if (hdmi->max_tmdsclk <= 340000 && mode->clock > 340000 &&
1630 !drm_mode_is_420(&connector->display_info, mode))
1631 return MODE_BAD;
1632 };
1633
1634 if (hdmi->phy) {
1635 if (hdmi->is_hdmi_qp)
1636 phy_set_bus_width(hdmi->phy, mode->clock * 10);
1637 else
1638 phy_set_bus_width(hdmi->phy, 8);
1639 }
1640
1641 /*
1642 * ensure all drm display mode can work, if someone want support more
1643 * resolutions, please limit the possible_crtc, only connect to
1644 * needed crtc.
1645 */
1646 drm_for_each_crtc(crtc, connector->dev) {
1647 int pipe = drm_crtc_index(crtc);
1648 const struct rockchip_crtc_funcs *funcs =
1649 priv->crtc_funcs[pipe];
1650
1651 if (!(encoder->possible_crtcs & drm_crtc_mask(crtc)))
1652 continue;
1653 if (!funcs || !funcs->mode_valid)
1654 continue;
1655
1656 status = funcs->mode_valid(crtc, mode,
1657 DRM_MODE_CONNECTOR_HDMIA);
1658 if (status != MODE_OK)
1659 return status;
1660 }
1661
1662 return status;
1663 }
1664
dw_hdmi_rockchip_encoder_disable(struct drm_encoder * encoder)1665 static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder)
1666 {
1667 struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
1668 struct drm_crtc *crtc = encoder->crtc;
1669 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
1670
1671 if (WARN_ON(!crtc || !crtc->state))
1672 return;
1673
1674 if (crtc->state->active_changed) {
1675 if (hdmi->plat_data->split_mode) {
1676 s->output_if &= ~(VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1);
1677 } else {
1678 if (!hdmi->id)
1679 s->output_if &= ~VOP_OUTPUT_IF_HDMI0;
1680 else
1681 s->output_if &= ~VOP_OUTPUT_IF_HDMI1;
1682 }
1683 }
1684 /*
1685 * when plug out hdmi it will be switch cvbs and then phy bus width
1686 * must be set as 8
1687 */
1688 if (hdmi->phy)
1689 phy_set_bus_width(hdmi->phy, 8);
1690 }
1691
dw_hdmi_rockchip_encoder_enable(struct drm_encoder * encoder)1692 static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
1693 {
1694 struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
1695 struct drm_crtc *crtc = encoder->crtc;
1696 u32 val;
1697 int mux;
1698 int ret;
1699
1700 if (WARN_ON(!crtc || !crtc->state))
1701 return;
1702
1703 if (hdmi->phy)
1704 phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width);
1705
1706 clk_set_rate(hdmi->phyref_clk,
1707 crtc->state->adjusted_mode.crtc_clock * 1000);
1708
1709 if (hdmi->is_hdmi_qp) {
1710 if (hdmi->link_cfg.frl_mode)
1711 gpiod_set_value(hdmi->enable_gpio, 0);
1712 else
1713 gpiod_set_value(hdmi->enable_gpio, 1);
1714 }
1715
1716 if (hdmi->chip_data->lcdsel_grf_reg < 0)
1717 return;
1718
1719 mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
1720 if (mux)
1721 val = hdmi->chip_data->lcdsel_lit;
1722 else
1723 val = hdmi->chip_data->lcdsel_big;
1724
1725 ret = clk_prepare_enable(hdmi->grf_clk);
1726 if (ret < 0) {
1727 DRM_DEV_ERROR(hdmi->dev, "failed to enable grfclk %d\n", ret);
1728 return;
1729 }
1730
1731 ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
1732 if (ret != 0)
1733 DRM_DEV_ERROR(hdmi->dev, "Could not write to GRF: %d\n", ret);
1734
1735 if (hdmi->chip_data->lcdsel_grf_reg == RK3288_GRF_SOC_CON6) {
1736 struct rockchip_crtc_state *s =
1737 to_rockchip_crtc_state(crtc->state);
1738 u32 mode_mask = mux ? RK3288_HDMI_LCDC1_YUV420 :
1739 RK3288_HDMI_LCDC0_YUV420;
1740
1741 if (s->output_mode == ROCKCHIP_OUT_MODE_YUV420)
1742 val = HIWORD_UPDATE(mode_mask, mode_mask);
1743 else
1744 val = HIWORD_UPDATE(0, mode_mask);
1745
1746 regmap_write(hdmi->regmap, RK3288_GRF_SOC_CON16, val);
1747 }
1748
1749 clk_disable_unprepare(hdmi->grf_clk);
1750 DRM_DEV_DEBUG(hdmi->dev, "vop %s output to hdmi\n",
1751 ret ? "LIT" : "BIG");
1752 }
1753
_dw_hdmi_rockchip_encoder_loader_protect(struct rockchip_hdmi * hdmi,bool on)1754 static int _dw_hdmi_rockchip_encoder_loader_protect(struct rockchip_hdmi *hdmi, bool on)
1755 {
1756 int ret;
1757
1758 if (on) {
1759 if (hdmi->is_hdmi_qp) {
1760 ret = clk_prepare_enable(hdmi->link_clk);
1761 if (ret < 0) {
1762 DRM_DEV_ERROR(hdmi->dev, "failed to enable link_clk %d\n", ret);
1763 return ret;
1764 }
1765 }
1766
1767 hdmi->phy->power_count++;
1768 } else {
1769 clk_disable_unprepare(hdmi->link_clk);
1770 hdmi->phy->power_count--;
1771 }
1772
1773 return 0;
1774 }
1775
dw_hdmi_rockchip_encoder_loader_protect(struct drm_encoder * encoder,bool on)1776 static int dw_hdmi_rockchip_encoder_loader_protect(struct drm_encoder *encoder, bool on)
1777 {
1778 struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
1779 struct rockchip_hdmi *secondary;
1780
1781 _dw_hdmi_rockchip_encoder_loader_protect(hdmi, on);
1782 if (hdmi->plat_data->right) {
1783 secondary = rockchip_hdmi_find_by_id(hdmi->dev->driver, !hdmi->id);
1784 _dw_hdmi_rockchip_encoder_loader_protect(secondary, on);
1785 }
1786
1787 return 0;
1788 }
1789
rk3588_set_link_mode(struct rockchip_hdmi * hdmi)1790 static void rk3588_set_link_mode(struct rockchip_hdmi *hdmi)
1791 {
1792 int val;
1793 bool is_hdmi0;
1794
1795 if (!hdmi->id)
1796 is_hdmi0 = true;
1797 else
1798 is_hdmi0 = false;
1799
1800 if (!hdmi->link_cfg.frl_mode) {
1801 val = HIWORD_UPDATE(0, RK3588_HDMI21_MASK);
1802 if (is_hdmi0)
1803 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON4, val);
1804 else
1805 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON7, val);
1806
1807 val = HIWORD_UPDATE(0, RK3588_COMPRESS_MODE_MASK | RK3588_COLOR_FORMAT_MASK);
1808 if (is_hdmi0)
1809 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
1810 else
1811 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
1812
1813 return;
1814 }
1815
1816 val = HIWORD_UPDATE(RK3588_HDMI21_MASK, RK3588_HDMI21_MASK);
1817 if (is_hdmi0)
1818 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON4, val);
1819 else
1820 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON7, val);
1821
1822 if (hdmi->link_cfg.dsc_mode) {
1823 val = HIWORD_UPDATE(RK3588_COMPRESS_MODE_MASK | RK3588_COMPRESSED_DATA,
1824 RK3588_COMPRESS_MODE_MASK | RK3588_COLOR_FORMAT_MASK);
1825 if (is_hdmi0)
1826 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
1827 else
1828 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
1829 } else {
1830 val = HIWORD_UPDATE(0, RK3588_COMPRESS_MODE_MASK | RK3588_COLOR_FORMAT_MASK);
1831 if (is_hdmi0)
1832 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
1833 else
1834 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
1835 }
1836 }
1837
rk3588_set_color_format(struct rockchip_hdmi * hdmi,u64 bus_format,u32 depth)1838 static void rk3588_set_color_format(struct rockchip_hdmi *hdmi, u64 bus_format,
1839 u32 depth)
1840 {
1841 u32 val = 0;
1842
1843 switch (bus_format) {
1844 case MEDIA_BUS_FMT_RGB888_1X24:
1845 case MEDIA_BUS_FMT_RGB101010_1X30:
1846 val = HIWORD_UPDATE(0, RK3588_COLOR_FORMAT_MASK);
1847 break;
1848 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1849 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
1850 val = HIWORD_UPDATE(RK3588_YUV420, RK3588_COLOR_FORMAT_MASK);
1851 break;
1852 case MEDIA_BUS_FMT_YUV8_1X24:
1853 case MEDIA_BUS_FMT_YUV10_1X30:
1854 val = HIWORD_UPDATE(RK3588_YUV444, RK3588_COLOR_FORMAT_MASK);
1855 break;
1856 case MEDIA_BUS_FMT_YUYV10_1X20:
1857 case MEDIA_BUS_FMT_YUYV8_1X16:
1858 val = HIWORD_UPDATE(RK3588_YUV422, RK3588_COLOR_FORMAT_MASK);
1859 break;
1860 default:
1861 dev_err(hdmi->dev, "can't set correct color format\n");
1862 return;
1863 }
1864
1865 if (hdmi->link_cfg.dsc_mode)
1866 val = HIWORD_UPDATE(RK3588_COMPRESSED_DATA, RK3588_COLOR_FORMAT_MASK);
1867
1868 if (depth == 8 || bus_format == MEDIA_BUS_FMT_YUYV10_1X20)
1869 val |= HIWORD_UPDATE(RK3588_8BPC, RK3588_COLOR_DEPTH_MASK);
1870 else
1871 val |= HIWORD_UPDATE(RK3588_10BPC, RK3588_COLOR_DEPTH_MASK);
1872
1873 if (!hdmi->id)
1874 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
1875 else
1876 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
1877 }
1878
rk3588_set_grf_cfg(void * data)1879 static void rk3588_set_grf_cfg(void *data)
1880 {
1881 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
1882 int color_depth;
1883
1884 rk3588_set_link_mode(hdmi);
1885 color_depth = hdmi_bus_fmt_color_depth(hdmi->bus_format);
1886 rk3588_set_color_format(hdmi, hdmi->bus_format, color_depth);
1887 }
1888
rk3588_get_grf_color_fmt(void * data)1889 static u64 rk3588_get_grf_color_fmt(void *data)
1890 {
1891 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
1892 u32 val, depth;
1893 u64 bus_format;
1894
1895 if (!hdmi->id)
1896 regmap_read(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, &val);
1897 else
1898 regmap_read(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, &val);
1899
1900 depth = (val & RK3588_COLOR_DEPTH_MASK) >> 4;
1901
1902 switch (val & RK3588_COLOR_FORMAT_MASK) {
1903 case RK3588_YUV444:
1904 if (!depth)
1905 bus_format = MEDIA_BUS_FMT_YUV8_1X24;
1906 else
1907 bus_format = MEDIA_BUS_FMT_YUV10_1X30;
1908 break;
1909 case RK3588_YUV422:
1910 bus_format = MEDIA_BUS_FMT_YUYV10_1X20;
1911 break;
1912 case RK3588_YUV420:
1913 if (!depth)
1914 bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
1915 else
1916 bus_format = MEDIA_BUS_FMT_UYYVYY10_0_5X30;
1917 break;
1918 case RK3588_RGB:
1919 if (!depth)
1920 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
1921 else
1922 bus_format = MEDIA_BUS_FMT_RGB101010_1X30;
1923 break;
1924 default:
1925 dev_err(hdmi->dev, "can't get correct color format\n");
1926 bus_format = MEDIA_BUS_FMT_YUV8_1X24;
1927 break;
1928 }
1929
1930 return bus_format;
1931 }
1932
1933 static void
dw_hdmi_rockchip_select_output(struct drm_connector_state * conn_state,struct drm_crtc_state * crtc_state,struct rockchip_hdmi * hdmi,unsigned int * color_format,unsigned int * output_mode,unsigned long * bus_format,unsigned int * bus_width,unsigned long * enc_out_encoding,unsigned int * eotf)1934 dw_hdmi_rockchip_select_output(struct drm_connector_state *conn_state,
1935 struct drm_crtc_state *crtc_state,
1936 struct rockchip_hdmi *hdmi,
1937 unsigned int *color_format,
1938 unsigned int *output_mode,
1939 unsigned long *bus_format,
1940 unsigned int *bus_width,
1941 unsigned long *enc_out_encoding,
1942 unsigned int *eotf)
1943 {
1944 struct drm_display_info *info = &conn_state->connector->display_info;
1945 struct drm_display_mode mode;
1946 struct hdr_output_metadata *hdr_metadata;
1947 u32 vic;
1948 unsigned long tmdsclock, pixclock;
1949 unsigned int color_depth;
1950 bool support_dc = false;
1951 bool sink_is_hdmi = true;
1952 bool yuv422_out = false;
1953 u32 max_tmds_clock = info->max_tmds_clock;
1954 int output_eotf;
1955
1956 drm_mode_copy(&mode, &crtc_state->mode);
1957 pixclock = mode.crtc_clock;
1958 if (hdmi->plat_data->split_mode) {
1959 drm_mode_convert_to_origin_mode(&mode);
1960 pixclock /= 2;
1961 }
1962
1963 vic = drm_match_cea_mode(&mode);
1964
1965 if (!hdmi->is_hdmi_qp)
1966 sink_is_hdmi = dw_hdmi_get_output_whether_hdmi(hdmi->hdmi);
1967 else
1968 sink_is_hdmi = dw_hdmi_qp_get_output_whether_hdmi(hdmi->hdmi_qp);
1969
1970 *color_format = RK_IF_FORMAT_RGB;
1971
1972 switch (hdmi->hdmi_output) {
1973 case RK_IF_FORMAT_YCBCR_HQ:
1974 if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
1975 *color_format = RK_IF_FORMAT_YCBCR444;
1976 else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
1977 *color_format = RK_IF_FORMAT_YCBCR422;
1978 else if (conn_state->connector->ycbcr_420_allowed &&
1979 drm_mode_is_420(info, &mode) &&
1980 (pixclock >= 594000 && !hdmi->is_hdmi_qp))
1981 *color_format = RK_IF_FORMAT_YCBCR420;
1982 break;
1983 case RK_IF_FORMAT_YCBCR_LQ:
1984 if (conn_state->connector->ycbcr_420_allowed &&
1985 drm_mode_is_420(info, &mode) && pixclock >= 594000)
1986 *color_format = RK_IF_FORMAT_YCBCR420;
1987 else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
1988 *color_format = RK_IF_FORMAT_YCBCR422;
1989 else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
1990 *color_format = RK_IF_FORMAT_YCBCR444;
1991 break;
1992 case RK_IF_FORMAT_YCBCR420:
1993 if (conn_state->connector->ycbcr_420_allowed &&
1994 drm_mode_is_420(info, &mode) && pixclock >= 594000)
1995 *color_format = RK_IF_FORMAT_YCBCR420;
1996 break;
1997 case RK_IF_FORMAT_YCBCR422:
1998 if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
1999 *color_format = RK_IF_FORMAT_YCBCR422;
2000 break;
2001 case RK_IF_FORMAT_YCBCR444:
2002 if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
2003 *color_format = RK_IF_FORMAT_YCBCR444;
2004 break;
2005 case RK_IF_FORMAT_RGB:
2006 default:
2007 break;
2008 }
2009
2010 if (*color_format == RK_IF_FORMAT_RGB &&
2011 info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30)
2012 support_dc = true;
2013 if (*color_format == RK_IF_FORMAT_YCBCR444 &&
2014 info->edid_hdmi_dc_modes &
2015 (DRM_EDID_HDMI_DC_Y444 | DRM_EDID_HDMI_DC_30))
2016 support_dc = true;
2017 if (*color_format == RK_IF_FORMAT_YCBCR422)
2018 support_dc = true;
2019 if (*color_format == RK_IF_FORMAT_YCBCR420 &&
2020 info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
2021 support_dc = true;
2022
2023 if (hdmi->colordepth > 8 && support_dc)
2024 color_depth = 10;
2025 else
2026 color_depth = 8;
2027
2028 if (!sink_is_hdmi) {
2029 *color_format = RK_IF_FORMAT_RGB;
2030 color_depth = 8;
2031 }
2032
2033 *eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
2034 if (conn_state->hdr_output_metadata) {
2035 hdr_metadata = (struct hdr_output_metadata *)
2036 conn_state->hdr_output_metadata->data;
2037 output_eotf = hdr_metadata->hdmi_metadata_type1.eotf;
2038 if (output_eotf > HDMI_EOTF_TRADITIONAL_GAMMA_SDR &&
2039 output_eotf <= HDMI_EOTF_BT_2100_HLG)
2040 *eotf = output_eotf;
2041 }
2042
2043 hdmi->colorimetry = conn_state->colorspace;
2044
2045 /* bt2020 sdr/hdr output */
2046 if ((hdmi->colorimetry >= DRM_MODE_COLORIMETRY_BT2020_CYCC) &&
2047 (hdmi->colorimetry <= DRM_MODE_COLORIMETRY_BT2020_YCC) &&
2048 hdmi->edid_colorimetry & (BIT(6) | BIT(7))) {
2049 *enc_out_encoding = V4L2_YCBCR_ENC_BT2020;
2050 yuv422_out = true;
2051 /* bt709 hdr output */
2052 } else if ((hdmi->colorimetry <= DRM_MODE_COLORIMETRY_BT2020_CYCC) &&
2053 (hdmi->colorimetry >= DRM_MODE_COLORIMETRY_BT2020_YCC) &&
2054 (conn_state->connector->hdr_sink_metadata.hdmi_type1.eotf & BIT(*eotf) &&
2055 *eotf > HDMI_EOTF_TRADITIONAL_GAMMA_SDR)) {
2056 *enc_out_encoding = V4L2_YCBCR_ENC_709;
2057 yuv422_out = true;
2058 } else if ((vic == 6) || (vic == 7) || (vic == 21) || (vic == 22) ||
2059 (vic == 2) || (vic == 3) || (vic == 17) || (vic == 18)) {
2060 *enc_out_encoding = V4L2_YCBCR_ENC_601;
2061 } else {
2062 *enc_out_encoding = V4L2_YCBCR_ENC_709;
2063 }
2064
2065 if ((yuv422_out || hdmi->hdmi_output == RK_IF_FORMAT_YCBCR_HQ) && color_depth == 10 &&
2066 (hdmi_bus_fmt_color_depth(hdmi->prev_bus_format) == 8 ||
2067 hdmi_bus_fmt_to_color_format(hdmi->prev_bus_format) == RK_IF_FORMAT_YCBCR422)) {
2068 /* We prefer use YCbCr422 to send hdr 10bit */
2069 if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
2070 *color_format = RK_IF_FORMAT_YCBCR422;
2071 }
2072
2073 if (mode.flags & DRM_MODE_FLAG_DBLCLK)
2074 pixclock *= 2;
2075 if ((mode.flags & DRM_MODE_FLAG_3D_MASK) ==
2076 DRM_MODE_FLAG_3D_FRAME_PACKING)
2077 pixclock *= 2;
2078
2079 if (hdmi->is_hdmi_qp && mode.clock >= 600000)
2080 *color_format = RK_IF_FORMAT_YCBCR420;
2081
2082 if (*color_format == RK_IF_FORMAT_YCBCR422 || color_depth == 8)
2083 tmdsclock = pixclock;
2084 else
2085 tmdsclock = pixclock * (color_depth) / 8;
2086
2087 if (*color_format == RK_IF_FORMAT_YCBCR420)
2088 tmdsclock /= 2;
2089
2090 /* XXX: max_tmds_clock of some sink is 0, we think it is 340MHz. */
2091 if (!max_tmds_clock)
2092 max_tmds_clock = 340000;
2093
2094 max_tmds_clock = min(max_tmds_clock, hdmi->max_tmdsclk);
2095
2096 if (hdmi->is_hdmi_qp && hdmi->link_cfg.rate_per_lane && mode.clock > 600000)
2097 max_tmds_clock =
2098 hdmi->link_cfg.frl_lanes * hdmi->link_cfg.rate_per_lane * 1000000;
2099
2100 if (tmdsclock > max_tmds_clock) {
2101 if (max_tmds_clock >= 594000) {
2102 color_depth = 8;
2103 } else if (max_tmds_clock > 340000) {
2104 if (drm_mode_is_420(info, &mode) || tmdsclock >= 594000)
2105 *color_format = RK_IF_FORMAT_YCBCR420;
2106 } else {
2107 color_depth = 8;
2108 if (drm_mode_is_420(info, &mode) || tmdsclock >= 594000)
2109 *color_format = RK_IF_FORMAT_YCBCR420;
2110 }
2111 }
2112
2113 if (*color_format == RK_IF_FORMAT_YCBCR420) {
2114 *output_mode = ROCKCHIP_OUT_MODE_YUV420;
2115 if (color_depth > 8)
2116 *bus_format = MEDIA_BUS_FMT_UYYVYY10_0_5X30;
2117 else
2118 *bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
2119 *bus_width = color_depth / 2;
2120 } else {
2121 *output_mode = ROCKCHIP_OUT_MODE_AAAA;
2122 if (color_depth > 8) {
2123 if (*color_format != RK_IF_FORMAT_RGB &&
2124 !hdmi->unsupported_yuv_input)
2125 *bus_format = MEDIA_BUS_FMT_YUV10_1X30;
2126 else
2127 *bus_format = MEDIA_BUS_FMT_RGB101010_1X30;
2128 } else {
2129 if (*color_format != RK_IF_FORMAT_RGB &&
2130 !hdmi->unsupported_yuv_input)
2131 *bus_format = MEDIA_BUS_FMT_YUV8_1X24;
2132 else
2133 *bus_format = MEDIA_BUS_FMT_RGB888_1X24;
2134 }
2135 if (*color_format == RK_IF_FORMAT_YCBCR422)
2136 *bus_width = 8;
2137 else
2138 *bus_width = color_depth;
2139 }
2140
2141 hdmi->bus_format = *bus_format;
2142
2143 if (*color_format == RK_IF_FORMAT_YCBCR422) {
2144 if (hdmi->is_hdmi_qp) {
2145 if (color_depth == 12)
2146 hdmi->output_bus_format = MEDIA_BUS_FMT_YUYV12_1X24;
2147 else if (color_depth == 10)
2148 hdmi->output_bus_format = MEDIA_BUS_FMT_YUYV10_1X20;
2149 else
2150 hdmi->output_bus_format = MEDIA_BUS_FMT_YUYV8_1X16;
2151
2152 *bus_format = hdmi->output_bus_format;
2153 hdmi->bus_format = *bus_format;
2154 *output_mode = ROCKCHIP_OUT_MODE_YUV422;
2155 } else {
2156 if (color_depth == 12)
2157 hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY12_1X24;
2158 else if (color_depth == 10)
2159 hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY10_1X20;
2160 else
2161 hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY8_1X16;
2162 }
2163 } else {
2164 hdmi->output_bus_format = *bus_format;
2165 }
2166 }
2167
2168 static bool
dw_hdmi_rockchip_check_color(struct drm_connector_state * conn_state,struct rockchip_hdmi * hdmi)2169 dw_hdmi_rockchip_check_color(struct drm_connector_state *conn_state,
2170 struct rockchip_hdmi *hdmi)
2171 {
2172 struct drm_crtc_state *crtc_state = conn_state->crtc->state;
2173 unsigned int colorformat;
2174 unsigned long bus_format;
2175 unsigned long output_bus_format = hdmi->output_bus_format;
2176 unsigned long enc_out_encoding = hdmi->enc_out_encoding;
2177 unsigned int eotf, bus_width;
2178 unsigned int output_mode;
2179
2180 dw_hdmi_rockchip_select_output(conn_state, crtc_state, hdmi,
2181 &colorformat,
2182 &output_mode, &bus_format, &bus_width,
2183 &hdmi->enc_out_encoding, &eotf);
2184
2185 if (output_bus_format != hdmi->output_bus_format ||
2186 enc_out_encoding != hdmi->enc_out_encoding)
2187 return true;
2188 else
2189 return false;
2190 }
2191
2192 static int
dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder * encoder,struct drm_crtc_state * crtc_state,struct drm_connector_state * conn_state)2193 dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
2194 struct drm_crtc_state *crtc_state,
2195 struct drm_connector_state *conn_state)
2196 {
2197 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
2198 struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
2199 unsigned int colorformat, bus_width, tmdsclk;
2200 struct drm_display_mode mode;
2201 unsigned int output_mode;
2202 unsigned long bus_format;
2203 int color_depth;
2204 bool secondary = false;
2205
2206 /*
2207 * There are two hdmi but only one encoder in split mode,
2208 * so we need to check twice.
2209 */
2210 secondary:
2211 drm_mode_copy(&mode, &crtc_state->mode);
2212
2213 if (hdmi->plat_data->split_mode)
2214 drm_mode_convert_to_origin_mode(&mode);
2215
2216 dw_hdmi_rockchip_select_output(conn_state, crtc_state, hdmi,
2217 &colorformat,
2218 &output_mode, &bus_format, &bus_width,
2219 &hdmi->enc_out_encoding, &s->eotf);
2220
2221 s->bus_format = bus_format;
2222 if (hdmi->is_hdmi_qp) {
2223 color_depth = hdmi_bus_fmt_color_depth(bus_format);
2224 tmdsclk = hdmi_get_tmdsclock(hdmi, crtc_state->mode.clock);
2225 if (hdmi_bus_fmt_is_yuv420(hdmi->output_bus_format))
2226 tmdsclk /= 2;
2227 hdmi_select_link_config(hdmi, crtc_state, tmdsclk);
2228
2229 if (hdmi->link_cfg.frl_mode) {
2230 /* in the current version, support max 40G frl */
2231 if (hdmi->link_cfg.rate_per_lane >= 10) {
2232 hdmi->link_cfg.frl_lanes = 4;
2233 hdmi->link_cfg.rate_per_lane = 10;
2234 }
2235 bus_width = hdmi->link_cfg.frl_lanes *
2236 hdmi->link_cfg.rate_per_lane * 1000000;
2237 /* 10 bit color depth and frl mode */
2238 if (color_depth == 10)
2239 bus_width |=
2240 COLOR_DEPTH_10BIT | HDMI_FRL_MODE;
2241 else
2242 bus_width |= HDMI_FRL_MODE;
2243 } else {
2244 bus_width = hdmi_get_tmdsclock(hdmi, mode.clock * 10);
2245 if (hdmi_bus_fmt_is_yuv420(hdmi->output_bus_format))
2246 bus_width /= 2;
2247
2248 if (color_depth == 10 && !hdmi_bus_fmt_is_yuv422(hdmi->output_bus_format))
2249 bus_width |= COLOR_DEPTH_10BIT;
2250 }
2251 }
2252
2253 hdmi->phy_bus_width = bus_width;
2254
2255 if (hdmi->phy)
2256 phy_set_bus_width(hdmi->phy, bus_width);
2257
2258 s->output_type = DRM_MODE_CONNECTOR_HDMIA;
2259 s->tv_state = &conn_state->tv;
2260
2261 if (hdmi->plat_data->split_mode) {
2262 s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
2263 if (hdmi->plat_data->right && hdmi->id)
2264 s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
2265 s->output_if |= VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1;
2266 } else {
2267 if (!hdmi->id)
2268 s->output_if |= VOP_OUTPUT_IF_HDMI0;
2269 else
2270 s->output_if |= VOP_OUTPUT_IF_HDMI1;
2271 }
2272
2273 s->output_mode = output_mode;
2274 hdmi->bus_format = s->bus_format;
2275
2276 if (hdmi->enc_out_encoding == V4L2_YCBCR_ENC_BT2020)
2277 s->color_space = V4L2_COLORSPACE_BT2020;
2278 else if (colorformat == RK_IF_FORMAT_RGB)
2279 s->color_space = V4L2_COLORSPACE_DEFAULT;
2280 else if (hdmi->enc_out_encoding == V4L2_YCBCR_ENC_709)
2281 s->color_space = V4L2_COLORSPACE_REC709;
2282 else
2283 s->color_space = V4L2_COLORSPACE_SMPTE170M;
2284
2285 if (hdmi->plat_data->split_mode && !secondary) {
2286 hdmi = rockchip_hdmi_find_by_id(hdmi->dev->driver, !hdmi->id);
2287 secondary = true;
2288 goto secondary;
2289 }
2290
2291 return 0;
2292 }
2293
2294
2295 static unsigned long
dw_hdmi_rockchip_get_input_bus_format(void * data)2296 dw_hdmi_rockchip_get_input_bus_format(void *data)
2297 {
2298 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2299
2300 return hdmi->bus_format;
2301 }
2302
2303 static unsigned long
dw_hdmi_rockchip_get_output_bus_format(void * data)2304 dw_hdmi_rockchip_get_output_bus_format(void *data)
2305 {
2306 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2307
2308 return hdmi->output_bus_format;
2309 }
2310
2311 static unsigned long
dw_hdmi_rockchip_get_enc_in_encoding(void * data)2312 dw_hdmi_rockchip_get_enc_in_encoding(void *data)
2313 {
2314 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2315
2316 return hdmi->enc_out_encoding;
2317 }
2318
2319 static unsigned long
dw_hdmi_rockchip_get_enc_out_encoding(void * data)2320 dw_hdmi_rockchip_get_enc_out_encoding(void *data)
2321 {
2322 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2323
2324 return hdmi->enc_out_encoding;
2325 }
2326
2327 static unsigned long
dw_hdmi_rockchip_get_quant_range(void * data)2328 dw_hdmi_rockchip_get_quant_range(void *data)
2329 {
2330 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2331
2332 return hdmi->hdmi_quant_range;
2333 }
2334
2335 static struct drm_property *
dw_hdmi_rockchip_get_hdr_property(void * data)2336 dw_hdmi_rockchip_get_hdr_property(void *data)
2337 {
2338 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2339
2340 return hdmi->hdr_panel_metadata_property;
2341 }
2342
2343 static struct drm_property_blob *
dw_hdmi_rockchip_get_hdr_blob(void * data)2344 dw_hdmi_rockchip_get_hdr_blob(void *data)
2345 {
2346 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2347
2348 return hdmi->hdr_panel_blob_ptr;
2349 }
2350
dw_hdmi_rockchip_update_color_format(struct drm_connector_state * conn_state,void * data)2351 static void dw_hdmi_rockchip_update_color_format(struct drm_connector_state *conn_state,
2352 void *data)
2353 {
2354 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2355
2356 dw_hdmi_rockchip_check_color(conn_state, hdmi);
2357 }
2358
2359 static bool
dw_hdmi_rockchip_get_color_changed(void * data)2360 dw_hdmi_rockchip_get_color_changed(void *data)
2361 {
2362 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2363 bool ret = false;
2364
2365 if (hdmi->color_changed)
2366 ret = true;
2367 hdmi->color_changed = 0;
2368
2369 return ret;
2370 }
2371
2372 static int
dw_hdmi_rockchip_get_yuv422_format(struct drm_connector * connector,struct edid * edid)2373 dw_hdmi_rockchip_get_yuv422_format(struct drm_connector *connector,
2374 struct edid *edid)
2375 {
2376 if (!connector || !edid)
2377 return -EINVAL;
2378
2379 return rockchip_drm_get_yuv422_format(connector, edid);
2380 }
2381
2382 static int
dw_hdmi_rockchip_get_edid_dsc_info(void * data,struct edid * edid)2383 dw_hdmi_rockchip_get_edid_dsc_info(void *data, struct edid *edid)
2384 {
2385 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2386
2387 if (!edid)
2388 return -EINVAL;
2389
2390 memset(&hdmi->dsc_cap, 0, sizeof(hdmi->dsc_cap));
2391 hdmi->max_frl_rate_per_lane = 0;
2392 hdmi->max_lanes = 0;
2393 hdmi->add_func = 0;
2394
2395 return rockchip_drm_parse_cea_ext(&hdmi->dsc_cap,
2396 &hdmi->max_frl_rate_per_lane,
2397 &hdmi->max_lanes, &hdmi->add_func, edid);
2398 }
2399
2400 static int
dw_hdmi_rockchip_get_next_hdr_data(void * data,struct edid * edid,struct drm_connector * connector)2401 dw_hdmi_rockchip_get_next_hdr_data(void *data, struct edid *edid,
2402 struct drm_connector *connector)
2403 {
2404 int ret;
2405 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2406 struct next_hdr_sink_data *sink_data = &hdmi->next_hdr_data;
2407 size_t size = sizeof(*sink_data);
2408 struct drm_property *property = hdmi->next_hdr_sink_data_property;
2409 struct drm_property_blob *blob = hdmi->hdr_panel_blob_ptr;
2410
2411 if (!edid)
2412 return -EINVAL;
2413
2414 rockchip_drm_parse_next_hdr(sink_data, edid);
2415
2416 ret = drm_property_replace_global_blob(connector->dev, &blob, size, sink_data,
2417 &connector->base, property);
2418
2419 return ret;
2420 };
2421
dw_hdmi_rockchip_get_colorimetry(void * data,struct edid * edid)2422 static int dw_hdmi_rockchip_get_colorimetry(void *data, struct edid *edid)
2423 {
2424 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2425
2426 return rockchip_drm_parse_colorimetry_data_block(&hdmi->edid_colorimetry, edid);
2427 }
2428
2429 static
dw_hdmi_rockchip_get_link_cfg(void * data)2430 struct dw_hdmi_link_config *dw_hdmi_rockchip_get_link_cfg(void *data)
2431 {
2432 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2433
2434 return &hdmi->link_cfg;
2435 }
2436
dw_hdmi_rockchip_get_vp_id(struct drm_crtc_state * crtc_state)2437 static int dw_hdmi_rockchip_get_vp_id(struct drm_crtc_state *crtc_state)
2438 {
2439 struct rockchip_crtc_state *s;
2440
2441 s = to_rockchip_crtc_state(crtc_state);
2442
2443 return s->vp_id;
2444 }
2445
dw_hdmi_dclk_set(void * data,bool enable,int vp_id)2446 static int dw_hdmi_dclk_set(void *data, bool enable, int vp_id)
2447 {
2448 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2449 char clk_name[16];
2450 struct clk *dclk;
2451 int ret;
2452
2453 snprintf(clk_name, sizeof(clk_name), "dclk_vp%d", vp_id);
2454
2455 dclk = devm_clk_get_optional(hdmi->dev, clk_name);
2456 if (IS_ERR(dclk)) {
2457 DRM_DEV_ERROR(hdmi->dev, "failed to get %s\n", clk_name);
2458 return PTR_ERR(dclk);
2459 } else if (!dclk) {
2460 if (hdmi->is_hdmi_qp) {
2461 DRM_DEV_ERROR(hdmi->dev, "failed to get %s\n", clk_name);
2462 return -ENOENT;
2463 }
2464
2465 return 0;
2466 }
2467
2468 if (enable) {
2469 ret = clk_prepare_enable(dclk);
2470 if (ret < 0)
2471 DRM_DEV_ERROR(hdmi->dev, "failed to enable dclk for video port%d - %d\n",
2472 vp_id, ret);
2473 } else {
2474 clk_disable_unprepare(dclk);
2475 }
2476
2477 return 0;
2478 }
2479
dw_hdmi_link_clk_set(void * data,bool enable)2480 static int dw_hdmi_link_clk_set(void *data, bool enable)
2481 {
2482 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2483 u64 phy_clk = hdmi->phy_bus_width;
2484 int ret;
2485
2486 if (enable) {
2487 ret = clk_prepare_enable(hdmi->link_clk);
2488 if (ret < 0) {
2489 DRM_DEV_ERROR(hdmi->dev, "failed to enable link_clk %d\n", ret);
2490 return ret;
2491 }
2492
2493 if (((phy_clk & DATA_RATE_MASK) <= 6000000) &&
2494 (phy_clk & COLOR_DEPTH_10BIT))
2495 phy_clk = (phy_clk & DATA_RATE_MASK) * 10 * 8;
2496 else
2497 phy_clk = (phy_clk & DATA_RATE_MASK) * 100;
2498
2499 /*
2500 * To be compatible with vop dclk usage scenarios, hdmi phy pll clk
2501 * is set according to dclk rate.
2502 * But phy pll actual frequency will varies according to the color depth.
2503 * So we should get the actual frequency or clk_set_rate may not change
2504 * pll frequency when 8/10 bit switch.
2505 */
2506 clk_get_rate(hdmi->link_clk);
2507 clk_set_rate(hdmi->link_clk, phy_clk);
2508 } else {
2509 clk_disable_unprepare(hdmi->link_clk);
2510 }
2511 return 0;
2512 }
2513
2514 static bool
dw_hdmi_rockchip_check_hdr_color_change(struct drm_connector_state * conn_state,void * data)2515 dw_hdmi_rockchip_check_hdr_color_change(struct drm_connector_state *conn_state,
2516 void *data)
2517 {
2518 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2519
2520 if (!conn_state || !data)
2521 return false;
2522
2523 if (dw_hdmi_rockchip_check_color(conn_state, hdmi))
2524 return true;
2525
2526 return false;
2527 }
2528
dw_hdmi_rockchip_set_prev_bus_format(void * data,unsigned long bus_format)2529 static void dw_hdmi_rockchip_set_prev_bus_format(void *data, unsigned long bus_format)
2530 {
2531 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2532
2533 hdmi->prev_bus_format = bus_format;
2534 }
2535
dw_hdmi_rockchip_set_ddc_io(void * data,bool enable)2536 static void dw_hdmi_rockchip_set_ddc_io(void *data, bool enable)
2537 {
2538 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2539
2540 if (!hdmi->p || !hdmi->idle_state || !hdmi->default_state)
2541 return;
2542
2543 if (!enable) {
2544 if (pinctrl_select_state(hdmi->p, hdmi->idle_state))
2545 dev_err(hdmi->dev, "could not select idle state\n");
2546 } else {
2547 if (pinctrl_select_state(hdmi->p, hdmi->default_state))
2548 dev_err(hdmi->dev, "could not select default state\n");
2549 }
2550 }
2551
2552 static const struct drm_prop_enum_list color_depth_enum_list[] = {
2553 { 0, "Automatic" }, /* Prefer highest color depth */
2554 { 8, "24bit" },
2555 { 10, "30bit" },
2556 };
2557
2558 static const struct drm_prop_enum_list drm_hdmi_output_enum_list[] = {
2559 { RK_IF_FORMAT_RGB, "rgb" },
2560 { RK_IF_FORMAT_YCBCR444, "ycbcr444" },
2561 { RK_IF_FORMAT_YCBCR422, "ycbcr422" },
2562 { RK_IF_FORMAT_YCBCR420, "ycbcr420" },
2563 { RK_IF_FORMAT_YCBCR_HQ, "ycbcr_high_subsampling" },
2564 { RK_IF_FORMAT_YCBCR_LQ, "ycbcr_low_subsampling" },
2565 { RK_IF_FORMAT_MAX, "invalid_output" },
2566 };
2567
2568 static const struct drm_prop_enum_list quant_range_enum_list[] = {
2569 { HDMI_QUANTIZATION_RANGE_DEFAULT, "default" },
2570 { HDMI_QUANTIZATION_RANGE_LIMITED, "limit" },
2571 { HDMI_QUANTIZATION_RANGE_FULL, "full" },
2572 };
2573
2574 static const struct drm_prop_enum_list output_hdmi_dvi_enum_list[] = {
2575 { 0, "auto" },
2576 { 1, "force_hdmi" },
2577 { 2, "force_dvi" },
2578 };
2579
2580 static const struct drm_prop_enum_list output_type_cap_list[] = {
2581 { 0, "DVI" },
2582 { 1, "HDMI" },
2583 };
2584
2585 static const struct drm_prop_enum_list allm_enable_list[] = {
2586 { 0, "disable" },
2587 { 1, "enable" },
2588 };
2589
2590 static void
dw_hdmi_rockchip_attach_properties(struct drm_connector * connector,unsigned int color,int version,void * data,bool allm_en)2591 dw_hdmi_rockchip_attach_properties(struct drm_connector *connector,
2592 unsigned int color, int version,
2593 void *data, bool allm_en)
2594 {
2595 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2596 struct drm_property *prop;
2597 struct rockchip_drm_private *private = connector->dev->dev_private;
2598
2599 switch (color) {
2600 case MEDIA_BUS_FMT_RGB101010_1X30:
2601 hdmi->hdmi_output = RK_IF_FORMAT_RGB;
2602 hdmi->colordepth = 10;
2603 break;
2604 case MEDIA_BUS_FMT_YUV8_1X24:
2605 hdmi->hdmi_output = RK_IF_FORMAT_YCBCR444;
2606 hdmi->colordepth = 8;
2607 break;
2608 case MEDIA_BUS_FMT_YUV10_1X30:
2609 hdmi->hdmi_output = RK_IF_FORMAT_YCBCR444;
2610 hdmi->colordepth = 10;
2611 break;
2612 case MEDIA_BUS_FMT_UYVY10_1X20:
2613 case MEDIA_BUS_FMT_YUYV10_1X20:
2614 hdmi->hdmi_output = RK_IF_FORMAT_YCBCR422;
2615 hdmi->colordepth = 10;
2616 break;
2617 case MEDIA_BUS_FMT_UYVY8_1X16:
2618 case MEDIA_BUS_FMT_YUYV8_1X16:
2619 hdmi->hdmi_output = RK_IF_FORMAT_YCBCR422;
2620 hdmi->colordepth = 8;
2621 break;
2622 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
2623 hdmi->hdmi_output = RK_IF_FORMAT_YCBCR420;
2624 hdmi->colordepth = 8;
2625 break;
2626 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
2627 hdmi->hdmi_output = RK_IF_FORMAT_YCBCR420;
2628 hdmi->colordepth = 10;
2629 break;
2630 default:
2631 hdmi->hdmi_output = RK_IF_FORMAT_RGB;
2632 hdmi->colordepth = 8;
2633 }
2634
2635 hdmi->bus_format = color;
2636 hdmi->prev_bus_format = color;
2637
2638 if (hdmi->hdmi_output == RK_IF_FORMAT_YCBCR422) {
2639 if (hdmi->is_hdmi_qp) {
2640 if (hdmi->colordepth == 12)
2641 hdmi->output_bus_format = MEDIA_BUS_FMT_YUYV12_1X24;
2642 else if (hdmi->colordepth == 10)
2643 hdmi->output_bus_format = MEDIA_BUS_FMT_YUYV10_1X20;
2644 else
2645 hdmi->output_bus_format = MEDIA_BUS_FMT_YUYV8_1X16;
2646 } else {
2647 if (hdmi->colordepth == 12)
2648 hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY12_1X24;
2649 else if (hdmi->colordepth == 10)
2650 hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY10_1X20;
2651 else
2652 hdmi->output_bus_format = MEDIA_BUS_FMT_UYVY8_1X16;
2653 }
2654 } else {
2655 hdmi->output_bus_format = hdmi->bus_format;
2656 }
2657
2658 /* RK3368 does not support deep color mode */
2659 if (!hdmi->color_depth_property && !hdmi->unsupported_deep_color) {
2660 prop = drm_property_create_enum(connector->dev, 0,
2661 RK_IF_PROP_COLOR_DEPTH,
2662 color_depth_enum_list,
2663 ARRAY_SIZE(color_depth_enum_list));
2664 if (prop) {
2665 hdmi->color_depth_property = prop;
2666 drm_object_attach_property(&connector->base, prop, 0);
2667 }
2668 }
2669
2670 prop = drm_property_create_enum(connector->dev, 0, RK_IF_PROP_COLOR_FORMAT,
2671 drm_hdmi_output_enum_list,
2672 ARRAY_SIZE(drm_hdmi_output_enum_list));
2673 if (prop) {
2674 hdmi->hdmi_output_property = prop;
2675 drm_object_attach_property(&connector->base, prop, 0);
2676 }
2677
2678 prop = drm_property_create_range(connector->dev, 0,
2679 RK_IF_PROP_COLOR_DEPTH_CAPS,
2680 0, 0xff);
2681 if (prop) {
2682 hdmi->colordepth_capacity = prop;
2683 drm_object_attach_property(&connector->base, prop, 0);
2684 }
2685
2686 prop = drm_property_create_range(connector->dev, 0,
2687 RK_IF_PROP_COLOR_FORMAT_CAPS,
2688 0, 0xf);
2689 if (prop) {
2690 hdmi->outputmode_capacity = prop;
2691 drm_object_attach_property(&connector->base, prop, 0);
2692 }
2693
2694 prop = drm_property_create(connector->dev,
2695 DRM_MODE_PROP_BLOB |
2696 DRM_MODE_PROP_IMMUTABLE,
2697 "HDR_PANEL_METADATA", 0);
2698 if (prop) {
2699 hdmi->hdr_panel_metadata_property = prop;
2700 drm_object_attach_property(&connector->base, prop, 0);
2701 }
2702
2703 prop = drm_property_create(connector->dev,
2704 DRM_MODE_PROP_BLOB |
2705 DRM_MODE_PROP_IMMUTABLE,
2706 "NEXT_HDR_SINK_DATA", 0);
2707 if (prop) {
2708 hdmi->next_hdr_sink_data_property = prop;
2709 drm_object_attach_property(&connector->base, prop, 0);
2710 }
2711
2712 prop = drm_property_create_bool(connector->dev, 0, "allm_capacity");
2713 if (prop) {
2714 hdmi->allm_capacity = prop;
2715 drm_object_attach_property(&connector->base, prop,
2716 !!(hdmi->add_func & SUPPORT_HDMI_ALLM));
2717 }
2718
2719 prop = drm_property_create_enum(connector->dev, 0,
2720 "allm_enable",
2721 allm_enable_list,
2722 ARRAY_SIZE(allm_enable_list));
2723 if (prop) {
2724 hdmi->allm_enable = prop;
2725 drm_object_attach_property(&connector->base, prop, 0);
2726 }
2727 hdmi->enable_allm = allm_en;
2728
2729 prop = drm_property_create_enum(connector->dev, 0,
2730 "output_hdmi_dvi",
2731 output_hdmi_dvi_enum_list,
2732 ARRAY_SIZE(output_hdmi_dvi_enum_list));
2733 if (prop) {
2734 hdmi->output_hdmi_dvi = prop;
2735 drm_object_attach_property(&connector->base, prop, 0);
2736 }
2737
2738 prop = drm_property_create_enum(connector->dev, 0,
2739 "output_type_capacity",
2740 output_type_cap_list,
2741 ARRAY_SIZE(output_type_cap_list));
2742 if (prop) {
2743 hdmi->output_type_capacity = prop;
2744 drm_object_attach_property(&connector->base, prop, 0);
2745 }
2746
2747 if (!hdmi->is_hdmi_qp) {
2748 prop = drm_property_create_enum(connector->dev, 0,
2749 "hdmi_quant_range",
2750 quant_range_enum_list,
2751 ARRAY_SIZE(quant_range_enum_list));
2752 if (prop) {
2753 hdmi->quant_range = prop;
2754 drm_object_attach_property(&connector->base, prop, 0);
2755 }
2756 }
2757
2758 prop = connector->dev->mode_config.hdr_output_metadata_property;
2759 if (hdmi->is_hdmi_qp)
2760 drm_object_attach_property(&connector->base, prop, 0);
2761
2762 if (!drm_mode_create_hdmi_colorspace_property(connector))
2763 drm_object_attach_property(&connector->base,
2764 connector->colorspace_property, 0);
2765 drm_object_attach_property(&connector->base, private->connector_id_prop, hdmi->id);
2766 }
2767
2768 static void
dw_hdmi_rockchip_destroy_properties(struct drm_connector * connector,void * data)2769 dw_hdmi_rockchip_destroy_properties(struct drm_connector *connector,
2770 void *data)
2771 {
2772 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2773
2774 if (hdmi->color_depth_property) {
2775 drm_property_destroy(connector->dev,
2776 hdmi->color_depth_property);
2777 hdmi->color_depth_property = NULL;
2778 }
2779
2780 if (hdmi->hdmi_output_property) {
2781 drm_property_destroy(connector->dev,
2782 hdmi->hdmi_output_property);
2783 hdmi->hdmi_output_property = NULL;
2784 }
2785
2786 if (hdmi->colordepth_capacity) {
2787 drm_property_destroy(connector->dev,
2788 hdmi->colordepth_capacity);
2789 hdmi->colordepth_capacity = NULL;
2790 }
2791
2792 if (hdmi->outputmode_capacity) {
2793 drm_property_destroy(connector->dev,
2794 hdmi->outputmode_capacity);
2795 hdmi->outputmode_capacity = NULL;
2796 }
2797
2798 if (hdmi->quant_range) {
2799 drm_property_destroy(connector->dev,
2800 hdmi->quant_range);
2801 hdmi->quant_range = NULL;
2802 }
2803
2804 if (hdmi->hdr_panel_metadata_property) {
2805 drm_property_destroy(connector->dev,
2806 hdmi->hdr_panel_metadata_property);
2807 hdmi->hdr_panel_metadata_property = NULL;
2808 }
2809
2810 if (hdmi->next_hdr_sink_data_property) {
2811 drm_property_destroy(connector->dev,
2812 hdmi->next_hdr_sink_data_property);
2813 hdmi->next_hdr_sink_data_property = NULL;
2814 }
2815
2816 if (hdmi->output_hdmi_dvi) {
2817 drm_property_destroy(connector->dev,
2818 hdmi->output_hdmi_dvi);
2819 hdmi->output_hdmi_dvi = NULL;
2820 }
2821
2822 if (hdmi->output_type_capacity) {
2823 drm_property_destroy(connector->dev,
2824 hdmi->output_type_capacity);
2825 hdmi->output_type_capacity = NULL;
2826 }
2827
2828 if (hdmi->allm_capacity) {
2829 drm_property_destroy(connector->dev,
2830 hdmi->allm_capacity);
2831 hdmi->allm_capacity = NULL;
2832 }
2833
2834 if (hdmi->allm_enable) {
2835 drm_property_destroy(connector->dev, hdmi->allm_enable);
2836 hdmi->allm_enable = NULL;
2837 }
2838 }
2839
2840 static int
dw_hdmi_rockchip_set_property(struct drm_connector * connector,struct drm_connector_state * state,struct drm_property * property,u64 val,void * data)2841 dw_hdmi_rockchip_set_property(struct drm_connector *connector,
2842 struct drm_connector_state *state,
2843 struct drm_property *property,
2844 u64 val,
2845 void *data)
2846 {
2847 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2848 struct drm_mode_config *config = &connector->dev->mode_config;
2849
2850 if (property == hdmi->color_depth_property) {
2851 hdmi->colordepth = val;
2852 /* If hdmi is disconnected, state->crtc is null */
2853 if (!state->crtc)
2854 return 0;
2855 if (dw_hdmi_rockchip_check_color(state, hdmi))
2856 hdmi->color_changed++;
2857 return 0;
2858 } else if (property == hdmi->hdmi_output_property) {
2859 hdmi->hdmi_output = val;
2860 if (!state->crtc)
2861 return 0;
2862 if (dw_hdmi_rockchip_check_color(state, hdmi))
2863 hdmi->color_changed++;
2864 return 0;
2865 } else if (property == hdmi->quant_range) {
2866 u64 quant_range = hdmi->hdmi_quant_range;
2867
2868 hdmi->hdmi_quant_range = val;
2869 if (quant_range != hdmi->hdmi_quant_range)
2870 dw_hdmi_set_quant_range(hdmi->hdmi);
2871 return 0;
2872 } else if (property == config->hdr_output_metadata_property) {
2873 return 0;
2874 } else if (property == hdmi->output_hdmi_dvi) {
2875 if (!hdmi->is_hdmi_qp) {
2876 if (hdmi->force_output != val)
2877 hdmi->color_changed++;
2878 hdmi->force_output = val;
2879 dw_hdmi_set_output_type(hdmi->hdmi, val);
2880 } else {
2881 hdmi->force_output = val;
2882 dw_hdmi_qp_set_output_type(hdmi->hdmi_qp, val);
2883 }
2884 return 0;
2885 } else if (property == hdmi->colordepth_capacity) {
2886 return 0;
2887 } else if (property == hdmi->outputmode_capacity) {
2888 return 0;
2889 } else if (property == hdmi->output_type_capacity) {
2890 return 0;
2891 } else if (property == hdmi->allm_capacity) {
2892 return 0;
2893 } else if (property == hdmi->allm_enable) {
2894 u64 allm_enable = hdmi->enable_allm;
2895
2896 hdmi->enable_allm = val;
2897 if (allm_enable != hdmi->enable_allm)
2898 dw_hdmi_qp_set_allm_enable(hdmi->hdmi_qp, hdmi->enable_allm);
2899 return 0;
2900 }
2901
2902 DRM_ERROR("Unknown property [PROP:%d:%s]\n",
2903 property->base.id, property->name);
2904
2905 return -EINVAL;
2906 }
2907
2908 static int
dw_hdmi_rockchip_get_property(struct drm_connector * connector,const struct drm_connector_state * state,struct drm_property * property,u64 * val,void * data)2909 dw_hdmi_rockchip_get_property(struct drm_connector *connector,
2910 const struct drm_connector_state *state,
2911 struct drm_property *property,
2912 u64 *val,
2913 void *data)
2914 {
2915 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2916 struct drm_display_info *info = &connector->display_info;
2917 struct drm_mode_config *config = &connector->dev->mode_config;
2918
2919 if (property == hdmi->color_depth_property) {
2920 *val = hdmi->colordepth;
2921 return 0;
2922 } else if (property == hdmi->hdmi_output_property) {
2923 *val = hdmi->hdmi_output;
2924 return 0;
2925 } else if (property == hdmi->colordepth_capacity) {
2926 *val = BIT(RK_IF_DEPTH_8);
2927 /* RK3368 only support 8bit */
2928 if (hdmi->unsupported_deep_color)
2929 return 0;
2930 if (info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30)
2931 *val |= BIT(RK_IF_DEPTH_10);
2932 if (info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36)
2933 *val |= BIT(RK_IF_DEPTH_12);
2934 if (info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_48)
2935 *val |= BIT(RK_IF_DEPTH_16);
2936 if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
2937 *val |= BIT(RK_IF_DEPTH_420_10);
2938 if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
2939 *val |= BIT(RK_IF_DEPTH_420_12);
2940 if (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)
2941 *val |= BIT(RK_IF_DEPTH_420_16);
2942 return 0;
2943 } else if (property == hdmi->outputmode_capacity) {
2944 *val = BIT(RK_IF_FORMAT_RGB);
2945 if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
2946 *val |= BIT(RK_IF_FORMAT_YCBCR444);
2947 if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
2948 *val |= BIT(RK_IF_FORMAT_YCBCR422);
2949 if (connector->ycbcr_420_allowed &&
2950 info->color_formats & DRM_COLOR_FORMAT_YCRCB420)
2951 *val |= BIT(RK_IF_FORMAT_YCBCR420);
2952 return 0;
2953 } else if (property == hdmi->quant_range) {
2954 *val = hdmi->hdmi_quant_range;
2955 return 0;
2956 } else if (property == config->hdr_output_metadata_property) {
2957 *val = state->hdr_output_metadata ?
2958 state->hdr_output_metadata->base.id : 0;
2959 return 0;
2960 } else if (property == hdmi->output_hdmi_dvi) {
2961 *val = hdmi->force_output;
2962 return 0;
2963 } else if (property == hdmi->output_type_capacity) {
2964 if (!hdmi->is_hdmi_qp)
2965 *val = dw_hdmi_get_output_type_cap(hdmi->hdmi);
2966 else
2967 *val = dw_hdmi_qp_get_output_type_cap(hdmi->hdmi_qp);
2968 return 0;
2969 } else if (property == hdmi->allm_capacity) {
2970 *val = !!(hdmi->add_func & SUPPORT_HDMI_ALLM);
2971 return 0;
2972 } else if (property == hdmi->allm_enable) {
2973 *val = hdmi->enable_allm;
2974 return 0;
2975 }
2976
2977 DRM_ERROR("Unknown property [PROP:%d:%s]\n",
2978 property->base.id, property->name);
2979
2980 return -EINVAL;
2981 }
2982
2983 static const struct dw_hdmi_property_ops dw_hdmi_rockchip_property_ops = {
2984 .attach_properties = dw_hdmi_rockchip_attach_properties,
2985 .destroy_properties = dw_hdmi_rockchip_destroy_properties,
2986 .set_property = dw_hdmi_rockchip_set_property,
2987 .get_property = dw_hdmi_rockchip_get_property,
2988 };
2989
dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder * encoder,struct drm_display_mode * mode,struct drm_display_mode * adj)2990 static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
2991 struct drm_display_mode *mode,
2992 struct drm_display_mode *adj)
2993 {
2994 struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
2995 struct drm_crtc *crtc;
2996 struct rockchip_crtc_state *s;
2997
2998 if (!encoder->crtc)
2999 return;
3000 crtc = encoder->crtc;
3001
3002 if (!crtc->state)
3003 return;
3004 s = to_rockchip_crtc_state(crtc->state);
3005
3006 if (!s)
3007 return;
3008
3009 if (hdmi->is_hdmi_qp) {
3010 s->dsc_enable = 0;
3011 if (hdmi->link_cfg.dsc_mode)
3012 dw_hdmi_qp_dsc_configure(hdmi, s, crtc->state);
3013
3014 phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width);
3015 }
3016
3017 clk_set_rate(hdmi->phyref_clk, adj->crtc_clock * 1000);
3018 }
3019
3020 static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
3021 .enable = dw_hdmi_rockchip_encoder_enable,
3022 .disable = dw_hdmi_rockchip_encoder_disable,
3023 .atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
3024 .mode_set = dw_hdmi_rockchip_encoder_mode_set,
3025 };
3026
3027 static void
dw_hdmi_rockchip_genphy_disable(struct dw_hdmi * dw_hdmi,void * data)3028 dw_hdmi_rockchip_genphy_disable(struct dw_hdmi *dw_hdmi, void *data)
3029 {
3030 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
3031
3032 while (hdmi->phy->power_count > 0)
3033 phy_power_off(hdmi->phy);
3034 }
3035
3036 static int
dw_hdmi_rockchip_genphy_init(struct dw_hdmi * dw_hdmi,void * data,const struct drm_display_info * display,const struct drm_display_mode * mode)3037 dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
3038 const struct drm_display_info *display,
3039 const struct drm_display_mode *mode)
3040 {
3041 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
3042
3043 dw_hdmi_rockchip_genphy_disable(dw_hdmi, data);
3044 dw_hdmi_set_high_tmds_clock_ratio(dw_hdmi, display);
3045 return phy_power_on(hdmi->phy);
3046 }
3047
dw_hdmi_rk3228_setup_hpd(struct dw_hdmi * dw_hdmi,void * data)3048 static void dw_hdmi_rk3228_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
3049 {
3050 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
3051
3052 dw_hdmi_phy_setup_hpd(dw_hdmi, data);
3053
3054 regmap_write(hdmi->regmap,
3055 RK3228_GRF_SOC_CON6,
3056 HIWORD_UPDATE(RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL |
3057 RK3228_HDMI_SCL_VSEL,
3058 RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL |
3059 RK3228_HDMI_SCL_VSEL));
3060
3061 regmap_write(hdmi->regmap,
3062 RK3228_GRF_SOC_CON2,
3063 HIWORD_UPDATE(RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK,
3064 RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK));
3065 }
3066
3067 static enum drm_connector_status
dw_hdmi_rk3328_read_hpd(struct dw_hdmi * dw_hdmi,void * data)3068 dw_hdmi_rk3328_read_hpd(struct dw_hdmi *dw_hdmi, void *data)
3069 {
3070 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
3071 enum drm_connector_status status;
3072
3073 status = dw_hdmi_phy_read_hpd(dw_hdmi, data);
3074
3075 if (status == connector_status_connected)
3076 regmap_write(hdmi->regmap,
3077 RK3328_GRF_SOC_CON4,
3078 HIWORD_UPDATE(RK3328_HDMI_SDA_5V | RK3328_HDMI_SCL_5V,
3079 RK3328_HDMI_SDA_5V | RK3328_HDMI_SCL_5V));
3080 else
3081 regmap_write(hdmi->regmap,
3082 RK3328_GRF_SOC_CON4,
3083 HIWORD_UPDATE(0, RK3328_HDMI_SDA_5V |
3084 RK3328_HDMI_SCL_5V));
3085 return status;
3086 }
3087
dw_hdmi_rk3328_setup_hpd(struct dw_hdmi * dw_hdmi,void * data)3088 static void dw_hdmi_rk3328_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
3089 {
3090 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
3091
3092 dw_hdmi_phy_setup_hpd(dw_hdmi, data);
3093
3094 /* Enable and map pins to 3V grf-controlled io-voltage */
3095 regmap_write(hdmi->regmap,
3096 RK3328_GRF_SOC_CON4,
3097 HIWORD_UPDATE(0, RK3328_HDMI_HPD_SARADC | RK3328_HDMI_CEC_5V |
3098 RK3328_HDMI_SDA_5V | RK3328_HDMI_SCL_5V |
3099 RK3328_HDMI_HPD_5V));
3100 regmap_write(hdmi->regmap,
3101 RK3328_GRF_SOC_CON3,
3102 HIWORD_UPDATE(0, RK3328_HDMI_SDA5V_GRF | RK3328_HDMI_SCL5V_GRF |
3103 RK3328_HDMI_HPD5V_GRF |
3104 RK3328_HDMI_CEC5V_GRF));
3105 regmap_write(hdmi->regmap,
3106 RK3328_GRF_SOC_CON2,
3107 HIWORD_UPDATE(RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK,
3108 RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK |
3109 RK3328_HDMI_HPD_IOE));
3110 }
3111
dw_hdmi_qp_rockchip_phy_disable(struct dw_hdmi_qp * dw_hdmi,void * data)3112 static void dw_hdmi_qp_rockchip_phy_disable(struct dw_hdmi_qp *dw_hdmi,
3113 void *data)
3114 {
3115 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
3116
3117 while (hdmi->phy->power_count > 0)
3118 phy_power_off(hdmi->phy);
3119 }
3120
dw_hdmi_qp_rockchip_genphy_init(struct dw_hdmi_qp * dw_hdmi,void * data,struct drm_display_mode * mode)3121 static int dw_hdmi_qp_rockchip_genphy_init(struct dw_hdmi_qp *dw_hdmi, void *data,
3122 struct drm_display_mode *mode)
3123 {
3124 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
3125
3126 dw_hdmi_qp_rockchip_phy_disable(dw_hdmi, data);
3127
3128 return phy_power_on(hdmi->phy);
3129 }
3130
3131 static enum drm_connector_status
dw_hdmi_rk3588_read_hpd(struct dw_hdmi_qp * dw_hdmi,void * data)3132 dw_hdmi_rk3588_read_hpd(struct dw_hdmi_qp *dw_hdmi, void *data)
3133 {
3134 u32 val;
3135 int ret;
3136 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
3137
3138 regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &val);
3139
3140 if (!hdmi->id) {
3141 if (val & RK3588_HDMI0_LEVEL_INT) {
3142 hdmi->hpd_stat = true;
3143 ret = connector_status_connected;
3144 } else {
3145 hdmi->hpd_stat = false;
3146 ret = connector_status_disconnected;
3147 }
3148 } else {
3149 if (val & RK3588_HDMI1_LEVEL_INT) {
3150 hdmi->hpd_stat = true;
3151 ret = connector_status_connected;
3152 } else {
3153 hdmi->hpd_stat = false;
3154 ret = connector_status_disconnected;
3155 }
3156 }
3157
3158 return ret;
3159 }
3160
dw_hdmi_rk3588_setup_hpd(struct dw_hdmi_qp * dw_hdmi,void * data)3161 static void dw_hdmi_rk3588_setup_hpd(struct dw_hdmi_qp *dw_hdmi, void *data)
3162 {
3163 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
3164 u32 val;
3165
3166 if (!hdmi->id) {
3167 val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
3168 RK3588_HDMI0_HPD_INT_CLR) |
3169 HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK);
3170 } else {
3171 val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR,
3172 RK3588_HDMI1_HPD_INT_CLR) |
3173 HIWORD_UPDATE(0, RK3588_HDMI1_HPD_INT_MSK);
3174 }
3175
3176 regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
3177 }
3178
dw_hdmi_rk3588_phy_set_mode(struct dw_hdmi_qp * dw_hdmi,void * data,u32 mode_mask,bool enable)3179 static void dw_hdmi_rk3588_phy_set_mode(struct dw_hdmi_qp *dw_hdmi, void *data,
3180 u32 mode_mask, bool enable)
3181 {
3182 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
3183
3184 if (!hdmi->phy)
3185 return;
3186
3187 /* set phy earc/frl mode */
3188 if (enable)
3189 hdmi->phy_bus_width |= mode_mask;
3190 else
3191 hdmi->phy_bus_width &= ~mode_mask;
3192
3193 phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width);
3194 }
3195
3196 static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = {
3197 .init = dw_hdmi_rockchip_genphy_init,
3198 .disable = dw_hdmi_rockchip_genphy_disable,
3199 .read_hpd = dw_hdmi_phy_read_hpd,
3200 .update_hpd = dw_hdmi_phy_update_hpd,
3201 .setup_hpd = dw_hdmi_rk3228_setup_hpd,
3202 };
3203
3204 static struct rockchip_hdmi_chip_data rk3228_chip_data = {
3205 .lcdsel_grf_reg = -1,
3206 };
3207
3208 static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
3209 .mode_valid = dw_hdmi_rockchip_mode_valid,
3210 .mpll_cfg = rockchip_mpll_cfg,
3211 .cur_ctr = rockchip_cur_ctr,
3212 .phy_config = rockchip_phy_config,
3213 .phy_data = &rk3228_chip_data,
3214 .phy_ops = &rk3228_hdmi_phy_ops,
3215 .phy_name = "inno_dw_hdmi_phy2",
3216 .phy_force_vendor = true,
3217 .max_tmdsclk = 371250,
3218 .ycbcr_420_allowed = true,
3219 };
3220
3221 static struct rockchip_hdmi_chip_data rk3288_chip_data = {
3222 .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
3223 .lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL),
3224 .lcdsel_lit = HIWORD_UPDATE(RK3288_HDMI_LCDC_SEL, RK3288_HDMI_LCDC_SEL),
3225 };
3226
3227 static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = {
3228 .mode_valid = dw_hdmi_rockchip_mode_valid,
3229 .mpll_cfg = rockchip_mpll_cfg,
3230 .mpll_cfg_420 = rockchip_rk3288w_mpll_cfg_420,
3231 .cur_ctr = rockchip_cur_ctr,
3232 .phy_config = rockchip_phy_config,
3233 .phy_data = &rk3288_chip_data,
3234 .tmds_n_table = rockchip_werid_tmds_n_table,
3235 .unsupported_yuv_input = true,
3236 .ycbcr_420_allowed = true,
3237 };
3238
3239 static const struct dw_hdmi_phy_ops rk3328_hdmi_phy_ops = {
3240 .init = dw_hdmi_rockchip_genphy_init,
3241 .disable = dw_hdmi_rockchip_genphy_disable,
3242 .read_hpd = dw_hdmi_rk3328_read_hpd,
3243 .update_hpd = dw_hdmi_phy_update_hpd,
3244 .setup_hpd = dw_hdmi_rk3328_setup_hpd,
3245 };
3246
3247 static enum drm_connector_status
dw_hdmi_rk3528_read_hpd(struct dw_hdmi * dw_hdmi,void * data)3248 dw_hdmi_rk3528_read_hpd(struct dw_hdmi *dw_hdmi, void *data)
3249 {
3250 return dw_hdmi_phy_read_hpd(dw_hdmi, data);
3251 }
3252
3253 static const struct dw_hdmi_phy_ops rk3528_hdmi_phy_ops = {
3254 .init = dw_hdmi_rockchip_genphy_init,
3255 .disable = dw_hdmi_rockchip_genphy_disable,
3256 .read_hpd = dw_hdmi_rk3528_read_hpd,
3257 .update_hpd = dw_hdmi_phy_update_hpd,
3258 .setup_hpd = dw_hdmi_phy_setup_hpd,
3259 };
3260
3261 static struct rockchip_hdmi_chip_data rk3328_chip_data = {
3262 .lcdsel_grf_reg = -1,
3263 };
3264
3265 static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
3266 .mode_valid = dw_hdmi_rockchip_mode_valid,
3267 .mpll_cfg = rockchip_mpll_cfg,
3268 .cur_ctr = rockchip_cur_ctr,
3269 .phy_config = rockchip_phy_config,
3270 .phy_data = &rk3328_chip_data,
3271 .phy_ops = &rk3328_hdmi_phy_ops,
3272 .phy_name = "inno_dw_hdmi_phy2",
3273 .phy_force_vendor = true,
3274 .use_drm_infoframe = true,
3275 .max_tmdsclk = 371250,
3276 .ycbcr_420_allowed = true,
3277 };
3278
3279 static struct rockchip_hdmi_chip_data rk3368_chip_data = {
3280 .lcdsel_grf_reg = -1,
3281 };
3282
3283 static const struct dw_hdmi_plat_data rk3368_hdmi_drv_data = {
3284 .mode_valid = dw_hdmi_rockchip_mode_valid,
3285 .mpll_cfg = rockchip_mpll_cfg,
3286 .mpll_cfg_420 = rockchip_mpll_cfg_420,
3287 .cur_ctr = rockchip_cur_ctr,
3288 .phy_config = rockchip_phy_config,
3289 .phy_data = &rk3368_chip_data,
3290 .unsupported_deep_color = true,
3291 .max_tmdsclk = 340000,
3292 .ycbcr_420_allowed = true,
3293 };
3294
3295 static struct rockchip_hdmi_chip_data rk3399_chip_data = {
3296 .lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
3297 .lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL),
3298 .lcdsel_lit = HIWORD_UPDATE(RK3399_HDMI_LCDC_SEL, RK3399_HDMI_LCDC_SEL),
3299 };
3300
3301 static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
3302 .mode_valid = dw_hdmi_rockchip_mode_valid,
3303 .mpll_cfg = rockchip_mpll_cfg,
3304 .mpll_cfg_420 = rockchip_mpll_cfg_420,
3305 .cur_ctr = rockchip_cur_ctr,
3306 .phy_config = rockchip_phy_config,
3307 .phy_data = &rk3399_chip_data,
3308 .use_drm_infoframe = true,
3309 .ycbcr_420_allowed = true,
3310 };
3311
3312 static struct rockchip_hdmi_chip_data rk3528_chip_data = {
3313 .lcdsel_grf_reg = -1,
3314 };
3315
3316 static const struct dw_hdmi_plat_data rk3528_hdmi_drv_data = {
3317 .mode_valid = dw_hdmi_rockchip_mode_valid,
3318 .mpll_cfg = rockchip_mpll_cfg,
3319 .cur_ctr = rockchip_cur_ctr,
3320 .phy_config = rockchip_phy_config,
3321 .phy_data = &rk3528_chip_data,
3322 .phy_ops = &rk3528_hdmi_phy_ops,
3323 .phy_name = "inno_dw_hdmi_phy2",
3324 .phy_force_vendor = true,
3325 .use_drm_infoframe = true,
3326 .ycbcr_420_allowed = true,
3327 };
3328
3329 static struct rockchip_hdmi_chip_data rk3568_chip_data = {
3330 .lcdsel_grf_reg = -1,
3331 .ddc_en_reg = RK3568_GRF_VO_CON1,
3332 };
3333
3334 static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
3335 .mode_valid = dw_hdmi_rockchip_mode_valid,
3336 .mpll_cfg = rockchip_mpll_cfg,
3337 .mpll_cfg_420 = rockchip_mpll_cfg_420,
3338 .cur_ctr = rockchip_cur_ctr,
3339 .phy_config = rockchip_phy_config,
3340 .phy_data = &rk3568_chip_data,
3341 .ycbcr_420_allowed = true,
3342 .use_drm_infoframe = true,
3343 };
3344
3345 static const struct dw_hdmi_qp_phy_ops rk3588_hdmi_phy_ops = {
3346 .init = dw_hdmi_qp_rockchip_genphy_init,
3347 .disable = dw_hdmi_qp_rockchip_phy_disable,
3348 .read_hpd = dw_hdmi_rk3588_read_hpd,
3349 .setup_hpd = dw_hdmi_rk3588_setup_hpd,
3350 .set_mode = dw_hdmi_rk3588_phy_set_mode,
3351 };
3352
3353 struct rockchip_hdmi_chip_data rk3588_hdmi_chip_data = {
3354 .lcdsel_grf_reg = -1,
3355 .ddc_en_reg = RK3588_GRF_VO1_CON3,
3356 .split_mode = true,
3357 };
3358
3359 static const struct dw_hdmi_plat_data rk3588_hdmi_drv_data = {
3360 .phy_data = &rk3588_hdmi_chip_data,
3361 .qp_phy_ops = &rk3588_hdmi_phy_ops,
3362 .phy_name = "samsung_hdptx_phy",
3363 .phy_force_vendor = true,
3364 .ycbcr_420_allowed = true,
3365 .is_hdmi_qp = true,
3366 .use_drm_infoframe = true,
3367 };
3368
3369 static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
3370 { .compatible = "rockchip,rk3228-dw-hdmi",
3371 .data = &rk3228_hdmi_drv_data
3372 },
3373 { .compatible = "rockchip,rk3288-dw-hdmi",
3374 .data = &rk3288_hdmi_drv_data
3375 },
3376 { .compatible = "rockchip,rk3328-dw-hdmi",
3377 .data = &rk3328_hdmi_drv_data
3378 },
3379 {
3380 .compatible = "rockchip,rk3368-dw-hdmi",
3381 .data = &rk3368_hdmi_drv_data
3382 },
3383 { .compatible = "rockchip,rk3399-dw-hdmi",
3384 .data = &rk3399_hdmi_drv_data
3385 },
3386 { .compatible = "rockchip,rk3528-dw-hdmi",
3387 .data = &rk3528_hdmi_drv_data
3388 },
3389 { .compatible = "rockchip,rk3568-dw-hdmi",
3390 .data = &rk3568_hdmi_drv_data
3391 },
3392 { .compatible = "rockchip,rk3588-dw-hdmi",
3393 .data = &rk3588_hdmi_drv_data
3394 },
3395 {},
3396 };
3397 MODULE_DEVICE_TABLE(of, dw_hdmi_rockchip_dt_ids);
3398
dw_hdmi_rockchip_bind(struct device * dev,struct device * master,void * data)3399 static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
3400 void *data)
3401 {
3402 struct platform_device *pdev = to_platform_device(dev);
3403 struct drm_device *drm = data;
3404 struct drm_encoder *encoder;
3405 struct rockchip_hdmi *hdmi;
3406 struct dw_hdmi_plat_data *plat_data;
3407 struct rockchip_hdmi *secondary;
3408 int ret;
3409 u32 val;
3410
3411 if (!pdev->dev.of_node)
3412 return -ENODEV;
3413
3414 hdmi = platform_get_drvdata(pdev);
3415 if (!hdmi)
3416 return -ENOMEM;
3417
3418 plat_data = hdmi->plat_data;
3419 hdmi->drm_dev = drm;
3420
3421 plat_data->phy_data = hdmi;
3422 plat_data->get_input_bus_format =
3423 dw_hdmi_rockchip_get_input_bus_format;
3424 plat_data->get_output_bus_format =
3425 dw_hdmi_rockchip_get_output_bus_format;
3426 plat_data->get_enc_in_encoding =
3427 dw_hdmi_rockchip_get_enc_in_encoding;
3428 plat_data->get_enc_out_encoding =
3429 dw_hdmi_rockchip_get_enc_out_encoding;
3430 plat_data->get_quant_range =
3431 dw_hdmi_rockchip_get_quant_range;
3432 plat_data->get_hdr_property =
3433 dw_hdmi_rockchip_get_hdr_property;
3434 plat_data->get_hdr_blob =
3435 dw_hdmi_rockchip_get_hdr_blob;
3436 plat_data->get_color_changed =
3437 dw_hdmi_rockchip_get_color_changed;
3438 plat_data->get_yuv422_format =
3439 dw_hdmi_rockchip_get_yuv422_format;
3440 plat_data->get_edid_dsc_info =
3441 dw_hdmi_rockchip_get_edid_dsc_info;
3442 plat_data->get_next_hdr_data =
3443 dw_hdmi_rockchip_get_next_hdr_data;
3444 plat_data->get_colorimetry =
3445 dw_hdmi_rockchip_get_colorimetry;
3446 plat_data->get_link_cfg = dw_hdmi_rockchip_get_link_cfg;
3447 plat_data->set_grf_cfg = rk3588_set_grf_cfg;
3448 plat_data->get_grf_color_fmt = rk3588_get_grf_color_fmt;
3449 plat_data->convert_to_split_mode = drm_mode_convert_to_split_mode;
3450 plat_data->convert_to_origin_mode = drm_mode_convert_to_origin_mode;
3451 plat_data->dclk_set = dw_hdmi_dclk_set;
3452 plat_data->link_clk_set = dw_hdmi_link_clk_set;
3453 plat_data->get_vp_id = dw_hdmi_rockchip_get_vp_id;
3454 plat_data->update_color_format =
3455 dw_hdmi_rockchip_update_color_format;
3456 plat_data->check_hdr_color_change =
3457 dw_hdmi_rockchip_check_hdr_color_change;
3458 plat_data->set_prev_bus_format =
3459 dw_hdmi_rockchip_set_prev_bus_format;
3460 plat_data->set_ddc_io =
3461 dw_hdmi_rockchip_set_ddc_io;
3462 plat_data->property_ops = &dw_hdmi_rockchip_property_ops;
3463
3464 secondary = rockchip_hdmi_find_by_id(dev->driver, !hdmi->id);
3465 /* If don't enable hdmi0 and hdmi1, we don't enable split mode */
3466 if (hdmi->chip_data->split_mode && secondary) {
3467
3468 /*
3469 * hdmi can only attach bridge and init encoder/connector in the
3470 * last bind hdmi in split mode, or hdmi->hdmi_qp will not be initialized
3471 * and plat_data->left/right will be null pointer. we must check if split
3472 * mode is on and determine the sequence of hdmi bind.
3473 */
3474 if (device_property_read_bool(dev, "split-mode") ||
3475 device_property_read_bool(secondary->dev, "split-mode")) {
3476 plat_data->split_mode = true;
3477 secondary->plat_data->split_mode = true;
3478 if (!secondary->plat_data->first_screen)
3479 plat_data->first_screen = true;
3480 }
3481 }
3482
3483 if (!plat_data->first_screen) {
3484 encoder = &hdmi->encoder;
3485 encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm, dev->of_node);
3486 /*
3487 * If we failed to find the CRTC(s) which this encoder is
3488 * supposed to be connected to, it's because the CRTC has
3489 * not been registered yet. Defer probing, and hope that
3490 * the required CRTC is added later.
3491 */
3492 if (encoder->possible_crtcs == 0)
3493 return -EPROBE_DEFER;
3494
3495 drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
3496 drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
3497 }
3498
3499 if (!plat_data->max_tmdsclk)
3500 hdmi->max_tmdsclk = 594000;
3501 else
3502 hdmi->max_tmdsclk = plat_data->max_tmdsclk;
3503
3504 hdmi->is_hdmi_qp = plat_data->is_hdmi_qp;
3505
3506 hdmi->unsupported_yuv_input = plat_data->unsupported_yuv_input;
3507 hdmi->unsupported_deep_color = plat_data->unsupported_deep_color;
3508
3509 ret = rockchip_hdmi_parse_dt(hdmi);
3510 if (ret) {
3511 DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n");
3512 return ret;
3513 }
3514
3515 ret = clk_prepare_enable(hdmi->aud_clk);
3516 if (ret) {
3517 dev_err(hdmi->dev, "Failed to enable HDMI aud_clk: %d\n", ret);
3518 return ret;
3519 }
3520
3521 ret = clk_prepare_enable(hdmi->hpd_clk);
3522 if (ret) {
3523 dev_err(hdmi->dev, "Failed to enable HDMI hpd_clk: %d\n", ret);
3524 return ret;
3525 }
3526
3527 ret = clk_prepare_enable(hdmi->hclk_vo1);
3528 if (ret) {
3529 dev_err(hdmi->dev, "Failed to enable HDMI hclk_vo1: %d\n", ret);
3530 return ret;
3531 }
3532
3533 ret = clk_prepare_enable(hdmi->earc_clk);
3534 if (ret) {
3535 dev_err(hdmi->dev, "Failed to enable HDMI earc_clk: %d\n", ret);
3536 return ret;
3537 }
3538
3539 ret = clk_prepare_enable(hdmi->hdmitx_ref);
3540 if (ret) {
3541 dev_err(hdmi->dev, "Failed to enable HDMI hdmitx_ref: %d\n",
3542 ret);
3543 return ret;
3544 }
3545
3546 ret = clk_prepare_enable(hdmi->pclk);
3547 if (ret) {
3548 dev_err(hdmi->dev, "Failed to enable HDMI pclk: %d\n", ret);
3549 return ret;
3550 }
3551
3552 if (hdmi->chip_data->ddc_en_reg == RK3568_GRF_VO_CON1) {
3553 regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1,
3554 HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK |
3555 RK3568_HDMI_SCLIN_MSK,
3556 RK3568_HDMI_SDAIN_MSK |
3557 RK3568_HDMI_SCLIN_MSK));
3558 }
3559
3560 if (hdmi->is_hdmi_qp) {
3561 if (!hdmi->id) {
3562 val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) |
3563 HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
3564 HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
3565 HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
3566 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
3567
3568 val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
3569 RK3588_SET_HPD_PATH_MASK);
3570 regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
3571
3572 val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
3573 RK3588_HDMI0_GRANT_SEL);
3574 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
3575 } else {
3576 val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) |
3577 HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
3578 HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
3579 HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
3580 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
3581
3582 val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
3583 RK3588_SET_HPD_PATH_MASK);
3584 regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
3585
3586 val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL,
3587 RK3588_HDMI1_GRANT_SEL);
3588 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
3589 }
3590 init_hpd_work(hdmi);
3591 }
3592
3593 ret = clk_prepare_enable(hdmi->phyref_clk);
3594 if (ret) {
3595 DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n",
3596 ret);
3597 return ret;
3598 }
3599
3600 ret = clk_prepare_enable(hdmi->hclk_vio);
3601 if (ret) {
3602 dev_err(hdmi->dev, "Failed to enable HDMI hclk_vio: %d\n",
3603 ret);
3604 return ret;
3605 }
3606
3607 ret = clk_prepare_enable(hdmi->hclk_vop);
3608 if (ret) {
3609 dev_err(hdmi->dev, "Failed to enable HDMI hclk_vop: %d\n",
3610 ret);
3611 return ret;
3612 }
3613
3614 if (hdmi->is_hdmi_qp) {
3615 if (!hdmi->id)
3616 val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK);
3617 else
3618 val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK, RK3588_HDMI1_HPD_INT_MSK);
3619 regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
3620
3621 hdmi->hpd_irq = platform_get_irq(pdev, 4);
3622 if (hdmi->hpd_irq < 0)
3623 return hdmi->hpd_irq;
3624
3625 ret = devm_request_threaded_irq(hdmi->dev, hdmi->hpd_irq,
3626 rockchip_hdmi_hardirq,
3627 rockchip_hdmi_irq,
3628 IRQF_SHARED, "dw-hdmi-qp-hpd",
3629 hdmi);
3630 if (ret)
3631 return ret;
3632 }
3633
3634 hdmi->phy = devm_phy_optional_get(dev, "hdmi");
3635 if (IS_ERR(hdmi->phy)) {
3636 hdmi->phy = devm_phy_optional_get(dev, "hdmi_phy");
3637 if (IS_ERR(hdmi->phy)) {
3638 ret = PTR_ERR(hdmi->phy);
3639 if (ret != -EPROBE_DEFER)
3640 DRM_DEV_ERROR(hdmi->dev, "failed to get phy\n");
3641 return ret;
3642 }
3643 }
3644
3645 if (hdmi->is_hdmi_qp) {
3646 hdmi->hdmi_qp = dw_hdmi_qp_bind(pdev, &hdmi->encoder, plat_data);
3647
3648 if (IS_ERR(hdmi->hdmi_qp)) {
3649 ret = PTR_ERR(hdmi->hdmi_qp);
3650 drm_encoder_cleanup(&hdmi->encoder);
3651 }
3652
3653 if (plat_data->connector) {
3654 hdmi->sub_dev.connector = plat_data->connector;
3655 hdmi->sub_dev.loader_protect = dw_hdmi_rockchip_encoder_loader_protect;
3656 if (secondary && device_property_read_bool(secondary->dev, "split-mode"))
3657 hdmi->sub_dev.of_node = secondary->dev->of_node;
3658 else
3659 hdmi->sub_dev.of_node = hdmi->dev->of_node;
3660
3661 rockchip_drm_register_sub_dev(&hdmi->sub_dev);
3662 }
3663
3664 if (plat_data->split_mode && secondary) {
3665 if (device_property_read_bool(dev, "split-mode")) {
3666 plat_data->right = secondary->hdmi_qp;
3667 secondary->plat_data->left = hdmi->hdmi_qp;
3668 } else {
3669 plat_data->left = secondary->hdmi_qp;
3670 secondary->plat_data->right = hdmi->hdmi_qp;
3671 }
3672 }
3673
3674 return ret;
3675 }
3676
3677 hdmi->hdmi = dw_hdmi_bind(pdev, &hdmi->encoder, plat_data);
3678
3679 /*
3680 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
3681 * which would have called the encoder cleanup. Do it manually.
3682 */
3683 if (IS_ERR(hdmi->hdmi)) {
3684 ret = PTR_ERR(hdmi->hdmi);
3685 drm_encoder_cleanup(&hdmi->encoder);
3686 clk_disable_unprepare(hdmi->aud_clk);
3687 clk_disable_unprepare(hdmi->phyref_clk);
3688 clk_disable_unprepare(hdmi->hclk_vop);
3689 clk_disable_unprepare(hdmi->hpd_clk);
3690 clk_disable_unprepare(hdmi->hclk_vo1);
3691 clk_disable_unprepare(hdmi->earc_clk);
3692 clk_disable_unprepare(hdmi->hdmitx_ref);
3693 clk_disable_unprepare(hdmi->pclk);
3694 }
3695
3696 if (plat_data->connector) {
3697 hdmi->sub_dev.connector = plat_data->connector;
3698 hdmi->sub_dev.of_node = dev->of_node;
3699 rockchip_drm_register_sub_dev(&hdmi->sub_dev);
3700 }
3701
3702 return ret;
3703 }
3704
dw_hdmi_rockchip_unbind(struct device * dev,struct device * master,void * data)3705 static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
3706 void *data)
3707 {
3708 struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
3709
3710 if (hdmi->is_hdmi_qp) {
3711 cancel_delayed_work(&hdmi->work);
3712 flush_workqueue(hdmi->workqueue);
3713 destroy_workqueue(hdmi->workqueue);
3714 }
3715
3716 if (hdmi->sub_dev.connector)
3717 rockchip_drm_unregister_sub_dev(&hdmi->sub_dev);
3718
3719 if (hdmi->is_hdmi_qp)
3720 dw_hdmi_qp_unbind(hdmi->hdmi_qp);
3721 else
3722 dw_hdmi_unbind(hdmi->hdmi);
3723 clk_disable_unprepare(hdmi->aud_clk);
3724 clk_disable_unprepare(hdmi->phyref_clk);
3725 clk_disable_unprepare(hdmi->hclk_vop);
3726 clk_disable_unprepare(hdmi->hpd_clk);
3727 clk_disable_unprepare(hdmi->hclk_vo1);
3728 clk_disable_unprepare(hdmi->earc_clk);
3729 clk_disable_unprepare(hdmi->hdmitx_ref);
3730 clk_disable_unprepare(hdmi->pclk);
3731 }
3732
3733 static const struct component_ops dw_hdmi_rockchip_ops = {
3734 .bind = dw_hdmi_rockchip_bind,
3735 .unbind = dw_hdmi_rockchip_unbind,
3736 };
3737
dw_hdmi_rockchip_probe(struct platform_device * pdev)3738 static int dw_hdmi_rockchip_probe(struct platform_device *pdev)
3739 {
3740 struct rockchip_hdmi *hdmi;
3741 const struct of_device_id *match;
3742 struct dw_hdmi_plat_data *plat_data;
3743 int id;
3744
3745 hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
3746 if (!hdmi)
3747 return -ENOMEM;
3748
3749 id = of_alias_get_id(pdev->dev.of_node, "hdmi");
3750 if (id < 0)
3751 id = 0;
3752
3753 hdmi->id = id;
3754 hdmi->dev = &pdev->dev;
3755
3756 match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node);
3757 plat_data = devm_kmemdup(&pdev->dev, match->data,
3758 sizeof(*plat_data), GFP_KERNEL);
3759 if (!plat_data)
3760 return -ENOMEM;
3761
3762 plat_data->id = hdmi->id;
3763 hdmi->plat_data = plat_data;
3764 hdmi->chip_data = plat_data->phy_data;
3765
3766 platform_set_drvdata(pdev, hdmi);
3767 pm_runtime_enable(&pdev->dev);
3768 pm_runtime_get_sync(&pdev->dev);
3769
3770 return component_add(&pdev->dev, &dw_hdmi_rockchip_ops);
3771 }
3772
dw_hdmi_rockchip_shutdown(struct platform_device * pdev)3773 static void dw_hdmi_rockchip_shutdown(struct platform_device *pdev)
3774 {
3775 struct rockchip_hdmi *hdmi = dev_get_drvdata(&pdev->dev);
3776
3777 if (!hdmi)
3778 return;
3779
3780 if (hdmi->is_hdmi_qp) {
3781 if (hdmi->hpd_irq)
3782 disable_irq(hdmi->hpd_irq);
3783 cancel_delayed_work(&hdmi->work);
3784 flush_workqueue(hdmi->workqueue);
3785 dw_hdmi_qp_suspend(hdmi->dev, hdmi->hdmi_qp);
3786 } else {
3787 if (hdmi->hpd_gpiod) {
3788 disable_irq(hdmi->hpd_irq);
3789 if (hdmi->hpd_wake_en)
3790 disable_irq_wake(hdmi->hpd_irq);
3791 }
3792 dw_hdmi_suspend(hdmi->hdmi);
3793 }
3794 pm_runtime_put_sync(&pdev->dev);
3795 }
3796
dw_hdmi_rockchip_remove(struct platform_device * pdev)3797 static int dw_hdmi_rockchip_remove(struct platform_device *pdev)
3798 {
3799 component_del(&pdev->dev, &dw_hdmi_rockchip_ops);
3800 pm_runtime_disable(&pdev->dev);
3801
3802 return 0;
3803 }
3804
dw_hdmi_rockchip_suspend(struct device * dev)3805 static int dw_hdmi_rockchip_suspend(struct device *dev)
3806 {
3807 struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
3808
3809 if (hdmi->is_hdmi_qp) {
3810 if (hdmi->hpd_irq)
3811 disable_irq(hdmi->hpd_irq);
3812 dw_hdmi_qp_suspend(dev, hdmi->hdmi_qp);
3813 } else {
3814 if (hdmi->hpd_gpiod)
3815 disable_irq(hdmi->hpd_irq);
3816 dw_hdmi_suspend(hdmi->hdmi);
3817 }
3818 pm_runtime_put_sync(dev);
3819
3820 return 0;
3821 }
3822
dw_hdmi_rockchip_resume(struct device * dev)3823 static int dw_hdmi_rockchip_resume(struct device *dev)
3824 {
3825 struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
3826 u32 val;
3827
3828 if (hdmi->is_hdmi_qp) {
3829 if (!hdmi->id) {
3830 val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) |
3831 HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
3832 HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
3833 HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
3834 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON3, val);
3835
3836 val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
3837 RK3588_SET_HPD_PATH_MASK);
3838 regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
3839
3840 val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL,
3841 RK3588_HDMI0_GRANT_SEL);
3842 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
3843 } else {
3844 val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) |
3845 HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
3846 HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
3847 HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
3848 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
3849
3850 val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK,
3851 RK3588_SET_HPD_PATH_MASK);
3852 regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
3853
3854 val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL,
3855 RK3588_HDMI1_GRANT_SEL);
3856 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON9, val);
3857 }
3858
3859 dw_hdmi_qp_resume(dev, hdmi->hdmi_qp);
3860 if (hdmi->hpd_irq)
3861 enable_irq(hdmi->hpd_irq);
3862 drm_helper_hpd_irq_event(hdmi->drm_dev);
3863 } else {
3864 if (hdmi->hpd_gpiod) {
3865 dw_hdmi_rk3528_gpio_hpd_init(hdmi);
3866 enable_irq(hdmi->hpd_irq);
3867 }
3868 dw_hdmi_resume(hdmi->hdmi);
3869 }
3870 pm_runtime_get_sync(dev);
3871
3872 return 0;
3873 }
3874
3875 static const struct dev_pm_ops dw_hdmi_rockchip_pm = {
3876 SET_SYSTEM_SLEEP_PM_OPS(dw_hdmi_rockchip_suspend,
3877 dw_hdmi_rockchip_resume)
3878 };
3879
3880 struct platform_driver dw_hdmi_rockchip_pltfm_driver = {
3881 .probe = dw_hdmi_rockchip_probe,
3882 .remove = dw_hdmi_rockchip_remove,
3883 .shutdown = dw_hdmi_rockchip_shutdown,
3884 .driver = {
3885 .name = "dwhdmi-rockchip",
3886 .pm = &dw_hdmi_rockchip_pm,
3887 .of_match_table = dw_hdmi_rockchip_dt_ids,
3888 },
3889 };
3890