xref: /openbmc/linux/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c (revision e33bbe69149b802c0c77bfb822685772f85388ca)
1 /*
2  * Analogix DP (Display port) core register interface driver.
3  *
4  * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5  * Author: Jingoo Han <jg1.han@samsung.com>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2 of the License, or (at your
10  * option) any later version.
11  */
12 
13 #include <linux/delay.h>
14 #include <linux/device.h>
15 #include <linux/gpio.h>
16 #include <linux/io.h>
17 #include <linux/iopoll.h>
18 
19 #include <drm/bridge/analogix_dp.h>
20 
21 #include "analogix_dp_core.h"
22 #include "analogix_dp_reg.h"
23 
24 #define COMMON_INT_MASK_1	0
25 #define COMMON_INT_MASK_2	0
26 #define COMMON_INT_MASK_3	0
27 #define COMMON_INT_MASK_4	(HOTPLUG_CHG | HPD_LOST | PLUG)
28 #define INT_STA_MASK		INT_HPD
29 
30 void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable)
31 {
32 	u32 reg;
33 
34 	if (enable) {
35 		reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
36 		reg |= HDCP_VIDEO_MUTE;
37 		writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
38 	} else {
39 		reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
40 		reg &= ~HDCP_VIDEO_MUTE;
41 		writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
42 	}
43 }
44 
45 void analogix_dp_stop_video(struct analogix_dp_device *dp)
46 {
47 	u32 reg;
48 
49 	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
50 	reg &= ~VIDEO_EN;
51 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
52 }
53 
54 void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable)
55 {
56 	u32 reg;
57 
58 	if (enable)
59 		reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
60 		      LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
61 	else
62 		reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
63 		      LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
64 
65 	writel(reg, dp->reg_base + ANALOGIX_DP_LANE_MAP);
66 }
67 
68 void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
69 {
70 	u32 reg;
71 
72 	reg = TX_TERMINAL_CTRL_50_OHM;
73 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_1);
74 
75 	reg = SEL_24M | TX_DVDD_BIT_1_0625V;
76 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
77 
78 	if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
79 		reg = REF_CLK_24M;
80 		if (dp->plat_data->dev_type == RK3288_DP)
81 			reg ^= REF_CLK_MASK;
82 
83 		writel(reg, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
84 		writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
85 		writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
86 		writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
87 		writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
88 	}
89 
90 	reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
91 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
92 
93 	reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
94 		TX_CUR1_2X | TX_CUR_16_MA;
95 	writel(reg, dp->reg_base + ANALOGIX_DP_PLL_FILTER_CTL_1);
96 
97 	reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
98 		CH1_AMP_400_MV | CH0_AMP_400_MV;
99 	writel(reg, dp->reg_base + ANALOGIX_DP_TX_AMP_TUNING_CTL);
100 }
101 
102 void analogix_dp_init_interrupt(struct analogix_dp_device *dp)
103 {
104 	/* Set interrupt pin assertion polarity as high */
105 	writel(INT_POL1 | INT_POL0, dp->reg_base + ANALOGIX_DP_INT_CTL);
106 
107 	/* Clear pending regisers */
108 	writel(0xff, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
109 	writel(0x4f, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_2);
110 	writel(0xe0, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_3);
111 	writel(0xe7, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
112 	writel(0x63, dp->reg_base + ANALOGIX_DP_INT_STA);
113 
114 	/* 0:mask,1: unmask */
115 	writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
116 	writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
117 	writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
118 	writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
119 	writel(0x00, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
120 }
121 
122 void analogix_dp_reset(struct analogix_dp_device *dp)
123 {
124 	u32 reg;
125 
126 	analogix_dp_stop_video(dp);
127 	analogix_dp_enable_video_mute(dp, 0);
128 
129 	reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
130 		AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
131 		HDCP_FUNC_EN_N | SW_FUNC_EN_N;
132 	writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
133 
134 	reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
135 		SERDES_FIFO_FUNC_EN_N |
136 		LS_CLK_DOMAIN_FUNC_EN_N;
137 	writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
138 
139 	usleep_range(20, 30);
140 
141 	analogix_dp_lane_swap(dp, 0);
142 
143 	writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
144 	writel(0x40, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
145 	writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
146 	writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
147 
148 	writel(0x0, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
149 	writel(0x0, dp->reg_base + ANALOGIX_DP_HDCP_CTL);
150 
151 	writel(0x5e, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_L);
152 	writel(0x1a, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_H);
153 
154 	writel(0x10, dp->reg_base + ANALOGIX_DP_LINK_DEBUG_CTL);
155 
156 	writel(0x0, dp->reg_base + ANALOGIX_DP_PHY_TEST);
157 
158 	writel(0x0, dp->reg_base + ANALOGIX_DP_VIDEO_FIFO_THRD);
159 	writel(0x20, dp->reg_base + ANALOGIX_DP_AUDIO_MARGIN);
160 
161 	writel(0x4, dp->reg_base + ANALOGIX_DP_M_VID_GEN_FILTER_TH);
162 	writel(0x2, dp->reg_base + ANALOGIX_DP_M_AUD_GEN_FILTER_TH);
163 
164 	writel(0x00000101, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
165 }
166 
167 void analogix_dp_swreset(struct analogix_dp_device *dp)
168 {
169 	writel(RESET_DP_TX, dp->reg_base + ANALOGIX_DP_TX_SW_RESET);
170 }
171 
172 void analogix_dp_config_interrupt(struct analogix_dp_device *dp)
173 {
174 	u32 reg;
175 
176 	/* 0: mask, 1: unmask */
177 	reg = COMMON_INT_MASK_1;
178 	writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
179 
180 	reg = COMMON_INT_MASK_2;
181 	writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
182 
183 	reg = COMMON_INT_MASK_3;
184 	writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
185 
186 	reg = COMMON_INT_MASK_4;
187 	writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
188 
189 	reg = INT_STA_MASK;
190 	writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
191 }
192 
193 void analogix_dp_mute_hpd_interrupt(struct analogix_dp_device *dp)
194 {
195 	u32 reg;
196 
197 	/* 0: mask, 1: unmask */
198 	reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
199 	reg &= ~COMMON_INT_MASK_4;
200 	writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
201 
202 	reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
203 	reg &= ~INT_STA_MASK;
204 	writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
205 }
206 
207 void analogix_dp_unmute_hpd_interrupt(struct analogix_dp_device *dp)
208 {
209 	u32 reg;
210 
211 	/* 0: mask, 1: unmask */
212 	reg = COMMON_INT_MASK_4;
213 	writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
214 
215 	reg = INT_STA_MASK;
216 	writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
217 }
218 
219 enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp)
220 {
221 	u32 reg;
222 
223 	reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
224 	if (reg & PLL_LOCK)
225 		return PLL_LOCKED;
226 	else
227 		return PLL_UNLOCKED;
228 }
229 
230 void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable)
231 {
232 	u32 reg;
233 
234 	if (enable) {
235 		reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
236 		reg |= DP_PLL_PD;
237 		writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
238 	} else {
239 		reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
240 		reg &= ~DP_PLL_PD;
241 		writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
242 	}
243 }
244 
245 void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
246 				       enum analog_power_block block,
247 				       bool enable)
248 {
249 	u32 reg;
250 	u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
251 
252 	if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
253 		phy_pd_addr = ANALOGIX_DP_PD;
254 
255 	switch (block) {
256 	case AUX_BLOCK:
257 		if (enable) {
258 			reg = readl(dp->reg_base + phy_pd_addr);
259 			reg |= AUX_PD;
260 			writel(reg, dp->reg_base + phy_pd_addr);
261 		} else {
262 			reg = readl(dp->reg_base + phy_pd_addr);
263 			reg &= ~AUX_PD;
264 			writel(reg, dp->reg_base + phy_pd_addr);
265 		}
266 		break;
267 	case CH0_BLOCK:
268 		if (enable) {
269 			reg = readl(dp->reg_base + phy_pd_addr);
270 			reg |= CH0_PD;
271 			writel(reg, dp->reg_base + phy_pd_addr);
272 		} else {
273 			reg = readl(dp->reg_base + phy_pd_addr);
274 			reg &= ~CH0_PD;
275 			writel(reg, dp->reg_base + phy_pd_addr);
276 		}
277 		break;
278 	case CH1_BLOCK:
279 		if (enable) {
280 			reg = readl(dp->reg_base + phy_pd_addr);
281 			reg |= CH1_PD;
282 			writel(reg, dp->reg_base + phy_pd_addr);
283 		} else {
284 			reg = readl(dp->reg_base + phy_pd_addr);
285 			reg &= ~CH1_PD;
286 			writel(reg, dp->reg_base + phy_pd_addr);
287 		}
288 		break;
289 	case CH2_BLOCK:
290 		if (enable) {
291 			reg = readl(dp->reg_base + phy_pd_addr);
292 			reg |= CH2_PD;
293 			writel(reg, dp->reg_base + phy_pd_addr);
294 		} else {
295 			reg = readl(dp->reg_base + phy_pd_addr);
296 			reg &= ~CH2_PD;
297 			writel(reg, dp->reg_base + phy_pd_addr);
298 		}
299 		break;
300 	case CH3_BLOCK:
301 		if (enable) {
302 			reg = readl(dp->reg_base + phy_pd_addr);
303 			reg |= CH3_PD;
304 			writel(reg, dp->reg_base + phy_pd_addr);
305 		} else {
306 			reg = readl(dp->reg_base + phy_pd_addr);
307 			reg &= ~CH3_PD;
308 			writel(reg, dp->reg_base + phy_pd_addr);
309 		}
310 		break;
311 	case ANALOG_TOTAL:
312 		if (enable) {
313 			reg = readl(dp->reg_base + phy_pd_addr);
314 			reg |= DP_PHY_PD;
315 			writel(reg, dp->reg_base + phy_pd_addr);
316 		} else {
317 			reg = readl(dp->reg_base + phy_pd_addr);
318 			reg &= ~DP_PHY_PD;
319 			writel(reg, dp->reg_base + phy_pd_addr);
320 		}
321 		break;
322 	case POWER_ALL:
323 		if (enable) {
324 			reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
325 				CH1_PD | CH0_PD;
326 			writel(reg, dp->reg_base + phy_pd_addr);
327 		} else {
328 			writel(0x00, dp->reg_base + phy_pd_addr);
329 		}
330 		break;
331 	default:
332 		break;
333 	}
334 }
335 
336 void analogix_dp_init_analog_func(struct analogix_dp_device *dp)
337 {
338 	u32 reg;
339 	int timeout_loop = 0;
340 
341 	analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
342 
343 	reg = PLL_LOCK_CHG;
344 	writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
345 
346 	reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
347 	reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
348 	writel(reg, dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
349 
350 	/* Power up PLL */
351 	if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
352 		analogix_dp_set_pll_power_down(dp, 0);
353 
354 		while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
355 			timeout_loop++;
356 			if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
357 				dev_err(dp->dev, "failed to get pll lock status\n");
358 				return;
359 			}
360 			usleep_range(10, 20);
361 		}
362 	}
363 
364 	/* Enable Serdes FIFO function and Link symbol clock domain module */
365 	reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
366 	reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
367 		| AUX_FUNC_EN_N);
368 	writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
369 }
370 
371 void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp)
372 {
373 	u32 reg;
374 
375 	if (gpio_is_valid(dp->hpd_gpio))
376 		return;
377 
378 	reg = HOTPLUG_CHG | HPD_LOST | PLUG;
379 	writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
380 
381 	reg = INT_HPD;
382 	writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
383 }
384 
385 void analogix_dp_init_hpd(struct analogix_dp_device *dp)
386 {
387 	u32 reg;
388 
389 	if (gpio_is_valid(dp->hpd_gpio))
390 		return;
391 
392 	analogix_dp_clear_hotplug_interrupts(dp);
393 
394 	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
395 	reg &= ~(F_HPD | HPD_CTRL);
396 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
397 }
398 
399 void analogix_dp_force_hpd(struct analogix_dp_device *dp)
400 {
401 	u32 reg;
402 
403 	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
404 	reg = (F_HPD | HPD_CTRL);
405 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
406 }
407 
408 enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
409 {
410 	u32 reg;
411 
412 	if (gpio_is_valid(dp->hpd_gpio)) {
413 		reg = gpio_get_value(dp->hpd_gpio);
414 		if (reg)
415 			return DP_IRQ_TYPE_HP_CABLE_IN;
416 		else
417 			return DP_IRQ_TYPE_HP_CABLE_OUT;
418 	} else {
419 		/* Parse hotplug interrupt status register */
420 		reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
421 
422 		if (reg & PLUG)
423 			return DP_IRQ_TYPE_HP_CABLE_IN;
424 
425 		if (reg & HPD_LOST)
426 			return DP_IRQ_TYPE_HP_CABLE_OUT;
427 
428 		if (reg & HOTPLUG_CHG)
429 			return DP_IRQ_TYPE_HP_CHANGE;
430 
431 		return DP_IRQ_TYPE_UNKNOWN;
432 	}
433 }
434 
435 void analogix_dp_reset_aux(struct analogix_dp_device *dp)
436 {
437 	u32 reg;
438 
439 	/* Disable AUX channel module */
440 	reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
441 	reg |= AUX_FUNC_EN_N;
442 	writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
443 }
444 
445 void analogix_dp_init_aux(struct analogix_dp_device *dp)
446 {
447 	u32 reg;
448 
449 	/* Clear inerrupts related to AUX channel */
450 	reg = RPLY_RECEIV | AUX_ERR;
451 	writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
452 
453 	analogix_dp_reset_aux(dp);
454 
455 	/* Disable AUX transaction H/W retry */
456 	if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
457 		reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
458 		      AUX_HW_RETRY_COUNT_SEL(3) |
459 		      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
460 	else
461 		reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
462 		      AUX_HW_RETRY_COUNT_SEL(0) |
463 		      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
464 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
465 
466 	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
467 	reg = DEFER_CTRL_EN | DEFER_COUNT(1);
468 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_DEFER_CTL);
469 
470 	/* Enable AUX channel module */
471 	reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
472 	reg &= ~AUX_FUNC_EN_N;
473 	writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
474 }
475 
476 int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp)
477 {
478 	u32 reg;
479 
480 	if (gpio_is_valid(dp->hpd_gpio)) {
481 		if (gpio_get_value(dp->hpd_gpio))
482 			return 0;
483 	} else {
484 		reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
485 		if (reg & HPD_STATUS)
486 			return 0;
487 	}
488 
489 	return -EINVAL;
490 }
491 
492 void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
493 {
494 	u32 reg;
495 
496 	reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
497 	reg &= ~SW_FUNC_EN_N;
498 	writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
499 }
500 
501 int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp)
502 {
503 	int reg;
504 	int retval = 0;
505 	int timeout_loop = 0;
506 
507 	/* Enable AUX CH operation */
508 	reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
509 	reg |= AUX_EN;
510 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
511 
512 	/* Is AUX CH command reply received? */
513 	reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
514 	while (!(reg & RPLY_RECEIV)) {
515 		timeout_loop++;
516 		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
517 			dev_err(dp->dev, "AUX CH command reply failed!\n");
518 			return -ETIMEDOUT;
519 		}
520 		reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
521 		usleep_range(10, 11);
522 	}
523 
524 	/* Clear interrupt source for AUX CH command reply */
525 	writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
526 
527 	/* Clear interrupt source for AUX CH access error */
528 	reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
529 	if (reg & AUX_ERR) {
530 		writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
531 		return -EREMOTEIO;
532 	}
533 
534 	/* Check AUX CH error access status */
535 	reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
536 	if ((reg & AUX_STATUS_MASK) != 0) {
537 		dev_err(dp->dev, "AUX CH error happens: %d\n\n",
538 			reg & AUX_STATUS_MASK);
539 		return -EREMOTEIO;
540 	}
541 
542 	return retval;
543 }
544 
545 int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp,
546 				   unsigned int reg_addr,
547 				   unsigned char data)
548 {
549 	u32 reg;
550 	int i;
551 	int retval;
552 
553 	for (i = 0; i < 3; i++) {
554 		/* Clear AUX CH data buffer */
555 		reg = BUF_CLR;
556 		writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
557 
558 		/* Select DPCD device address */
559 		reg = AUX_ADDR_7_0(reg_addr);
560 		writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
561 		reg = AUX_ADDR_15_8(reg_addr);
562 		writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
563 		reg = AUX_ADDR_19_16(reg_addr);
564 		writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
565 
566 		/* Write data buffer */
567 		reg = (unsigned int)data;
568 		writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
569 
570 		/*
571 		 * Set DisplayPort transaction and write 1 byte
572 		 * If bit 3 is 1, DisplayPort transaction.
573 		 * If Bit 3 is 0, I2C transaction.
574 		 */
575 		reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
576 		writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
577 
578 		/* Start AUX transaction */
579 		retval = analogix_dp_start_aux_transaction(dp);
580 		if (retval == 0)
581 			break;
582 
583 		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
584 	}
585 
586 	return retval;
587 }
588 
589 void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
590 {
591 	u32 reg;
592 
593 	reg = bwtype;
594 	if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
595 		writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
596 }
597 
598 void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
599 {
600 	u32 reg;
601 
602 	reg = readl(dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
603 	*bwtype = reg;
604 }
605 
606 void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
607 {
608 	u32 reg;
609 
610 	reg = count;
611 	writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
612 }
613 
614 void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
615 {
616 	u32 reg;
617 
618 	reg = readl(dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
619 	*count = reg;
620 }
621 
622 void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
623 				      bool enable)
624 {
625 	u32 reg;
626 
627 	if (enable) {
628 		reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
629 		reg |= ENHANCED;
630 		writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
631 	} else {
632 		reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
633 		reg &= ~ENHANCED;
634 		writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
635 	}
636 }
637 
638 void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
639 				      enum pattern_set pattern)
640 {
641 	u32 reg;
642 
643 	switch (pattern) {
644 	case PRBS7:
645 		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
646 		writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
647 		break;
648 	case D10_2:
649 		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
650 		writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
651 		break;
652 	case TRAINING_PTN1:
653 		reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
654 		writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
655 		break;
656 	case TRAINING_PTN2:
657 		reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
658 		writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
659 		break;
660 	case DP_NONE:
661 		reg = SCRAMBLING_ENABLE |
662 			LINK_QUAL_PATTERN_SET_DISABLE |
663 			SW_TRAINING_PATTERN_SET_NORMAL;
664 		writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
665 		break;
666 	default:
667 		break;
668 	}
669 }
670 
671 void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
672 					u32 level)
673 {
674 	u32 reg;
675 
676 	reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
677 	reg &= ~PRE_EMPHASIS_SET_MASK;
678 	reg |= level << PRE_EMPHASIS_SET_SHIFT;
679 	writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
680 }
681 
682 void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
683 					u32 level)
684 {
685 	u32 reg;
686 
687 	reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
688 	reg &= ~PRE_EMPHASIS_SET_MASK;
689 	reg |= level << PRE_EMPHASIS_SET_SHIFT;
690 	writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
691 }
692 
693 void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
694 					u32 level)
695 {
696 	u32 reg;
697 
698 	reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
699 	reg &= ~PRE_EMPHASIS_SET_MASK;
700 	reg |= level << PRE_EMPHASIS_SET_SHIFT;
701 	writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
702 }
703 
704 void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
705 					u32 level)
706 {
707 	u32 reg;
708 
709 	reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
710 	reg &= ~PRE_EMPHASIS_SET_MASK;
711 	reg |= level << PRE_EMPHASIS_SET_SHIFT;
712 	writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
713 }
714 
715 void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
716 					 u32 training_lane)
717 {
718 	u32 reg;
719 
720 	reg = training_lane;
721 	writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
722 }
723 
724 void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
725 					 u32 training_lane)
726 {
727 	u32 reg;
728 
729 	reg = training_lane;
730 	writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
731 }
732 
733 void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
734 					 u32 training_lane)
735 {
736 	u32 reg;
737 
738 	reg = training_lane;
739 	writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
740 }
741 
742 void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
743 					 u32 training_lane)
744 {
745 	u32 reg;
746 
747 	reg = training_lane;
748 	writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
749 }
750 
751 u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp)
752 {
753 	return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
754 }
755 
756 u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp)
757 {
758 	return readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
759 }
760 
761 u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp)
762 {
763 	return readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
764 }
765 
766 u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp)
767 {
768 	return readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
769 }
770 
771 void analogix_dp_reset_macro(struct analogix_dp_device *dp)
772 {
773 	u32 reg;
774 
775 	reg = readl(dp->reg_base + ANALOGIX_DP_PHY_TEST);
776 	reg |= MACRO_RST;
777 	writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
778 
779 	/* 10 us is the minimum reset time. */
780 	usleep_range(10, 20);
781 
782 	reg &= ~MACRO_RST;
783 	writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
784 }
785 
786 void analogix_dp_init_video(struct analogix_dp_device *dp)
787 {
788 	u32 reg;
789 
790 	reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
791 	writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
792 
793 	reg = 0x0;
794 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
795 
796 	reg = CHA_CRI(4) | CHA_CTRL;
797 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
798 
799 	reg = 0x0;
800 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
801 
802 	reg = VID_HRES_TH(2) | VID_VRES_TH(0);
803 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_8);
804 }
805 
806 void analogix_dp_set_video_color_format(struct analogix_dp_device *dp)
807 {
808 	u32 reg;
809 
810 	/* Configure the input color depth, color space, dynamic range */
811 	reg = (dp->video_info.dynamic_range << IN_D_RANGE_SHIFT) |
812 		(dp->video_info.color_depth << IN_BPC_SHIFT) |
813 		(dp->video_info.color_space << IN_COLOR_F_SHIFT);
814 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2);
815 
816 	/* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
817 	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
818 	reg &= ~IN_YC_COEFFI_MASK;
819 	if (dp->video_info.ycbcr_coeff)
820 		reg |= IN_YC_COEFFI_ITU709;
821 	else
822 		reg |= IN_YC_COEFFI_ITU601;
823 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
824 }
825 
826 int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp)
827 {
828 	u32 reg;
829 
830 	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
831 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
832 
833 	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
834 
835 	if (!(reg & DET_STA)) {
836 		dev_dbg(dp->dev, "Input stream clock not detected.\n");
837 		return -EINVAL;
838 	}
839 
840 	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
841 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
842 
843 	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
844 	dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
845 
846 	if (reg & CHA_STA) {
847 		dev_dbg(dp->dev, "Input stream clk is changing\n");
848 		return -EINVAL;
849 	}
850 
851 	return 0;
852 }
853 
854 void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
855 				 enum clock_recovery_m_value_type type,
856 				 u32 m_value, u32 n_value)
857 {
858 	u32 reg;
859 
860 	if (type == REGISTER_M) {
861 		reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
862 		reg |= FIX_M_VID;
863 		writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
864 		reg = m_value & 0xff;
865 		writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_0);
866 		reg = (m_value >> 8) & 0xff;
867 		writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_1);
868 		reg = (m_value >> 16) & 0xff;
869 		writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_2);
870 
871 		reg = n_value & 0xff;
872 		writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_0);
873 		reg = (n_value >> 8) & 0xff;
874 		writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_1);
875 		reg = (n_value >> 16) & 0xff;
876 		writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_2);
877 	} else  {
878 		reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
879 		reg &= ~FIX_M_VID;
880 		writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
881 
882 		writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_0);
883 		writel(0x80, dp->reg_base + ANALOGIX_DP_N_VID_1);
884 		writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_2);
885 	}
886 }
887 
888 void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type)
889 {
890 	u32 reg;
891 
892 	if (type == VIDEO_TIMING_FROM_CAPTURE) {
893 		reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
894 		reg &= ~FORMAT_SEL;
895 		writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
896 	} else {
897 		reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
898 		reg |= FORMAT_SEL;
899 		writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
900 	}
901 }
902 
903 void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enable)
904 {
905 	u32 reg;
906 
907 	if (enable) {
908 		reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
909 		reg &= ~VIDEO_MODE_MASK;
910 		reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
911 		writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
912 	} else {
913 		reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
914 		reg &= ~VIDEO_MODE_MASK;
915 		reg |= VIDEO_MODE_SLAVE_MODE;
916 		writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
917 	}
918 }
919 
920 void analogix_dp_start_video(struct analogix_dp_device *dp)
921 {
922 	u32 reg;
923 
924 	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
925 	reg |= VIDEO_EN;
926 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
927 }
928 
929 int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp)
930 {
931 	u32 reg;
932 
933 	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
934 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
935 
936 	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
937 	if (!(reg & STRM_VALID)) {
938 		dev_dbg(dp->dev, "Input video stream is not detected.\n");
939 		return -EINVAL;
940 	}
941 
942 	return 0;
943 }
944 
945 void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
946 {
947 	u32 reg;
948 
949 	reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
950 	reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
951 	reg |= MASTER_VID_FUNC_EN_N;
952 	writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
953 
954 	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
955 	reg &= ~INTERACE_SCAN_CFG;
956 	reg |= (dp->video_info.interlaced << 2);
957 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
958 
959 	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
960 	reg &= ~VSYNC_POLARITY_CFG;
961 	reg |= (dp->video_info.v_sync_polarity << 1);
962 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
963 
964 	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
965 	reg &= ~HSYNC_POLARITY_CFG;
966 	reg |= (dp->video_info.h_sync_polarity << 0);
967 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
968 
969 	reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
970 	writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
971 }
972 
973 void analogix_dp_enable_scrambling(struct analogix_dp_device *dp)
974 {
975 	u32 reg;
976 
977 	reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
978 	reg &= ~SCRAMBLING_DISABLE;
979 	writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
980 }
981 
982 void analogix_dp_disable_scrambling(struct analogix_dp_device *dp)
983 {
984 	u32 reg;
985 
986 	reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
987 	reg |= SCRAMBLING_DISABLE;
988 	writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
989 }
990 
991 void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp)
992 {
993 	writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
994 }
995 
996 static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
997 {
998 	ssize_t val;
999 	u8 status;
1000 
1001 	val = drm_dp_dpcd_readb(&dp->aux, DP_PSR_STATUS, &status);
1002 	if (val < 0) {
1003 		dev_err(dp->dev, "PSR_STATUS read failed ret=%zd", val);
1004 		return val;
1005 	}
1006 	return status;
1007 }
1008 
1009 int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
1010 			     struct edp_vsc_psr *vsc, bool blocking)
1011 {
1012 	unsigned int val;
1013 	int ret;
1014 	ssize_t psr_status;
1015 
1016 	/* don't send info frame */
1017 	val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1018 	val &= ~IF_EN;
1019 	writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1020 
1021 	/* configure single frame update mode */
1022 	writel(PSR_FRAME_UP_TYPE_BURST | PSR_CRC_SEL_HARDWARE,
1023 	       dp->reg_base + ANALOGIX_DP_PSR_FRAME_UPDATE_CTRL);
1024 
1025 	/* configure VSC HB0~HB3 */
1026 	writel(vsc->sdp_header.HB0, dp->reg_base + ANALOGIX_DP_SPD_HB0);
1027 	writel(vsc->sdp_header.HB1, dp->reg_base + ANALOGIX_DP_SPD_HB1);
1028 	writel(vsc->sdp_header.HB2, dp->reg_base + ANALOGIX_DP_SPD_HB2);
1029 	writel(vsc->sdp_header.HB3, dp->reg_base + ANALOGIX_DP_SPD_HB3);
1030 
1031 	/* configure reused VSC PB0~PB3, magic number from vendor */
1032 	writel(0x00, dp->reg_base + ANALOGIX_DP_SPD_PB0);
1033 	writel(0x16, dp->reg_base + ANALOGIX_DP_SPD_PB1);
1034 	writel(0xCE, dp->reg_base + ANALOGIX_DP_SPD_PB2);
1035 	writel(0x5D, dp->reg_base + ANALOGIX_DP_SPD_PB3);
1036 
1037 	/* configure DB0 / DB1 values */
1038 	writel(vsc->DB0, dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB0);
1039 	writel(vsc->DB1, dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB1);
1040 
1041 	/* set reuse spd inforframe */
1042 	val = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
1043 	val |= REUSE_SPD_EN;
1044 	writel(val, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
1045 
1046 	/* mark info frame update */
1047 	val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1048 	val = (val | IF_UP) & ~IF_EN;
1049 	writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1050 
1051 	/* send info frame */
1052 	val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1053 	val |= IF_EN;
1054 	writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1055 
1056 	if (!blocking)
1057 		return 0;
1058 
1059 	ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
1060 		psr_status >= 0 &&
1061 		((vsc->DB1 && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
1062 		(!vsc->DB1 && psr_status == DP_PSR_SINK_INACTIVE)), 1500,
1063 		DP_TIMEOUT_PSR_LOOP_MS * 1000);
1064 	if (ret) {
1065 		dev_warn(dp->dev, "Failed to apply PSR %d\n", ret);
1066 		return ret;
1067 	}
1068 	return 0;
1069 }
1070 
1071 ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
1072 			     struct drm_dp_aux_msg *msg)
1073 {
1074 	u32 reg;
1075 	u8 *buffer = msg->buffer;
1076 	int timeout_loop = 0;
1077 	unsigned int i;
1078 	int num_transferred = 0;
1079 
1080 	/* Buffer size of AUX CH is 16 bytes */
1081 	if (WARN_ON(msg->size > 16))
1082 		return -E2BIG;
1083 
1084 	/* Clear AUX CH data buffer */
1085 	reg = BUF_CLR;
1086 	writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
1087 
1088 	switch (msg->request & ~DP_AUX_I2C_MOT) {
1089 	case DP_AUX_I2C_WRITE:
1090 		reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_I2C_TRANSACTION;
1091 		if (msg->request & DP_AUX_I2C_MOT)
1092 			reg |= AUX_TX_COMM_MOT;
1093 		break;
1094 
1095 	case DP_AUX_I2C_READ:
1096 		reg = AUX_TX_COMM_READ | AUX_TX_COMM_I2C_TRANSACTION;
1097 		if (msg->request & DP_AUX_I2C_MOT)
1098 			reg |= AUX_TX_COMM_MOT;
1099 		break;
1100 
1101 	case DP_AUX_NATIVE_WRITE:
1102 		reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_DP_TRANSACTION;
1103 		break;
1104 
1105 	case DP_AUX_NATIVE_READ:
1106 		reg = AUX_TX_COMM_READ | AUX_TX_COMM_DP_TRANSACTION;
1107 		break;
1108 
1109 	default:
1110 		return -EINVAL;
1111 	}
1112 
1113 	reg |= AUX_LENGTH(msg->size);
1114 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
1115 
1116 	/* Select DPCD device address */
1117 	reg = AUX_ADDR_7_0(msg->address);
1118 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
1119 	reg = AUX_ADDR_15_8(msg->address);
1120 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
1121 	reg = AUX_ADDR_19_16(msg->address);
1122 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
1123 
1124 	if (!(msg->request & DP_AUX_I2C_READ)) {
1125 		for (i = 0; i < msg->size; i++) {
1126 			reg = buffer[i];
1127 			writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
1128 			       4 * i);
1129 			num_transferred++;
1130 		}
1131 	}
1132 
1133 	/* Enable AUX CH operation */
1134 	reg = AUX_EN;
1135 
1136 	/* Zero-sized messages specify address-only transactions. */
1137 	if (msg->size < 1)
1138 		reg |= ADDR_ONLY;
1139 
1140 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
1141 
1142 	/* Is AUX CH command reply received? */
1143 	/* TODO: Wait for an interrupt instead of looping? */
1144 	reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
1145 	while (!(reg & RPLY_RECEIV)) {
1146 		timeout_loop++;
1147 		if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
1148 			dev_err(dp->dev, "AUX CH command reply failed!\n");
1149 			return -ETIMEDOUT;
1150 		}
1151 		reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
1152 		usleep_range(10, 11);
1153 	}
1154 
1155 	/* Clear interrupt source for AUX CH command reply */
1156 	writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
1157 
1158 	/* Clear interrupt source for AUX CH access error */
1159 	reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
1160 	if (reg & AUX_ERR) {
1161 		writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
1162 		return -EREMOTEIO;
1163 	}
1164 
1165 	/* Check AUX CH error access status */
1166 	reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
1167 	if ((reg & AUX_STATUS_MASK)) {
1168 		dev_err(dp->dev, "AUX CH error happened: %d\n\n",
1169 			reg & AUX_STATUS_MASK);
1170 		return -EREMOTEIO;
1171 	}
1172 
1173 	if (msg->request & DP_AUX_I2C_READ) {
1174 		for (i = 0; i < msg->size; i++) {
1175 			reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
1176 				    4 * i);
1177 			buffer[i] = (unsigned char)reg;
1178 			num_transferred++;
1179 		}
1180 	}
1181 
1182 	/* Check if Rx sends defer */
1183 	reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM);
1184 	if (reg == AUX_RX_COMM_AUX_DEFER)
1185 		msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
1186 	else if (reg == AUX_RX_COMM_I2C_DEFER)
1187 		msg->reply = DP_AUX_I2C_REPLY_DEFER;
1188 	else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE ||
1189 		 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_READ)
1190 		msg->reply = DP_AUX_I2C_REPLY_ACK;
1191 	else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE ||
1192 		 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
1193 		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
1194 
1195 	return num_transferred > 0 ? num_transferred : -EBUSY;
1196 }
1197