xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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