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