]> Git Repo - linux.git/blob - drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[linux.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 <[email protected]>
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 void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
528 {
529         u32 reg;
530
531         reg = bwtype;
532         if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
533                 writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
534 }
535
536 void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
537 {
538         u32 reg;
539
540         reg = readl(dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
541         *bwtype = reg;
542 }
543
544 void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
545 {
546         u32 reg;
547
548         reg = count;
549         writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
550 }
551
552 void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
553 {
554         u32 reg;
555
556         reg = readl(dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
557         *count = reg;
558 }
559
560 void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
561                                       bool enable)
562 {
563         u32 reg;
564
565         if (enable) {
566                 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
567                 reg |= ENHANCED;
568                 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
569         } else {
570                 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
571                 reg &= ~ENHANCED;
572                 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
573         }
574 }
575
576 void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
577                                       enum pattern_set pattern)
578 {
579         u32 reg;
580
581         switch (pattern) {
582         case PRBS7:
583                 reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
584                 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
585                 break;
586         case D10_2:
587                 reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
588                 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
589                 break;
590         case TRAINING_PTN1:
591                 reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
592                 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
593                 break;
594         case TRAINING_PTN2:
595                 reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
596                 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
597                 break;
598         case DP_NONE:
599                 reg = SCRAMBLING_ENABLE |
600                         LINK_QUAL_PATTERN_SET_DISABLE |
601                         SW_TRAINING_PATTERN_SET_NORMAL;
602                 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
603                 break;
604         default:
605                 break;
606         }
607 }
608
609 void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
610                                         u32 level)
611 {
612         u32 reg;
613
614         reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
615         reg &= ~PRE_EMPHASIS_SET_MASK;
616         reg |= level << PRE_EMPHASIS_SET_SHIFT;
617         writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
618 }
619
620 void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
621                                         u32 level)
622 {
623         u32 reg;
624
625         reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
626         reg &= ~PRE_EMPHASIS_SET_MASK;
627         reg |= level << PRE_EMPHASIS_SET_SHIFT;
628         writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
629 }
630
631 void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
632                                         u32 level)
633 {
634         u32 reg;
635
636         reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
637         reg &= ~PRE_EMPHASIS_SET_MASK;
638         reg |= level << PRE_EMPHASIS_SET_SHIFT;
639         writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
640 }
641
642 void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
643                                         u32 level)
644 {
645         u32 reg;
646
647         reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
648         reg &= ~PRE_EMPHASIS_SET_MASK;
649         reg |= level << PRE_EMPHASIS_SET_SHIFT;
650         writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
651 }
652
653 void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
654                                          u32 training_lane)
655 {
656         u32 reg;
657
658         reg = training_lane;
659         writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
660 }
661
662 void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
663                                          u32 training_lane)
664 {
665         u32 reg;
666
667         reg = training_lane;
668         writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
669 }
670
671 void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
672                                          u32 training_lane)
673 {
674         u32 reg;
675
676         reg = training_lane;
677         writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
678 }
679
680 void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
681                                          u32 training_lane)
682 {
683         u32 reg;
684
685         reg = training_lane;
686         writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
687 }
688
689 u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp)
690 {
691         return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
692 }
693
694 u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp)
695 {
696         return readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
697 }
698
699 u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp)
700 {
701         return readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
702 }
703
704 u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp)
705 {
706         return readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
707 }
708
709 void analogix_dp_reset_macro(struct analogix_dp_device *dp)
710 {
711         u32 reg;
712
713         reg = readl(dp->reg_base + ANALOGIX_DP_PHY_TEST);
714         reg |= MACRO_RST;
715         writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
716
717         /* 10 us is the minimum reset time. */
718         usleep_range(10, 20);
719
720         reg &= ~MACRO_RST;
721         writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
722 }
723
724 void analogix_dp_init_video(struct analogix_dp_device *dp)
725 {
726         u32 reg;
727
728         reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
729         writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
730
731         reg = 0x0;
732         writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
733
734         reg = CHA_CRI(4) | CHA_CTRL;
735         writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
736
737         reg = 0x0;
738         writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
739
740         reg = VID_HRES_TH(2) | VID_VRES_TH(0);
741         writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_8);
742 }
743
744 void analogix_dp_set_video_color_format(struct analogix_dp_device *dp)
745 {
746         u32 reg;
747
748         /* Configure the input color depth, color space, dynamic range */
749         reg = (dp->video_info.dynamic_range << IN_D_RANGE_SHIFT) |
750                 (dp->video_info.color_depth << IN_BPC_SHIFT) |
751                 (dp->video_info.color_space << IN_COLOR_F_SHIFT);
752         writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2);
753
754         /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
755         reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
756         reg &= ~IN_YC_COEFFI_MASK;
757         if (dp->video_info.ycbcr_coeff)
758                 reg |= IN_YC_COEFFI_ITU709;
759         else
760                 reg |= IN_YC_COEFFI_ITU601;
761         writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
762 }
763
764 int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp)
765 {
766         u32 reg;
767
768         reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
769         writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
770
771         reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
772
773         if (!(reg & DET_STA)) {
774                 dev_dbg(dp->dev, "Input stream clock not detected.\n");
775                 return -EINVAL;
776         }
777
778         reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
779         writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
780
781         reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
782         dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
783
784         if (reg & CHA_STA) {
785                 dev_dbg(dp->dev, "Input stream clk is changing\n");
786                 return -EINVAL;
787         }
788
789         return 0;
790 }
791
792 void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
793                                  enum clock_recovery_m_value_type type,
794                                  u32 m_value, u32 n_value)
795 {
796         u32 reg;
797
798         if (type == REGISTER_M) {
799                 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
800                 reg |= FIX_M_VID;
801                 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
802                 reg = m_value & 0xff;
803                 writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_0);
804                 reg = (m_value >> 8) & 0xff;
805                 writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_1);
806                 reg = (m_value >> 16) & 0xff;
807                 writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_2);
808
809                 reg = n_value & 0xff;
810                 writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_0);
811                 reg = (n_value >> 8) & 0xff;
812                 writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_1);
813                 reg = (n_value >> 16) & 0xff;
814                 writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_2);
815         } else  {
816                 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
817                 reg &= ~FIX_M_VID;
818                 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
819
820                 writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_0);
821                 writel(0x80, dp->reg_base + ANALOGIX_DP_N_VID_1);
822                 writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_2);
823         }
824 }
825
826 void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type)
827 {
828         u32 reg;
829
830         if (type == VIDEO_TIMING_FROM_CAPTURE) {
831                 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
832                 reg &= ~FORMAT_SEL;
833                 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
834         } else {
835                 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
836                 reg |= FORMAT_SEL;
837                 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
838         }
839 }
840
841 void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enable)
842 {
843         u32 reg;
844
845         if (enable) {
846                 reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
847                 reg &= ~VIDEO_MODE_MASK;
848                 reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
849                 writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
850         } else {
851                 reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
852                 reg &= ~VIDEO_MODE_MASK;
853                 reg |= VIDEO_MODE_SLAVE_MODE;
854                 writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
855         }
856 }
857
858 void analogix_dp_start_video(struct analogix_dp_device *dp)
859 {
860         u32 reg;
861
862         reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
863         reg |= VIDEO_EN;
864         writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
865 }
866
867 int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp)
868 {
869         u32 reg;
870
871         reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
872         writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
873
874         reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
875         if (!(reg & STRM_VALID)) {
876                 dev_dbg(dp->dev, "Input video stream is not detected.\n");
877                 return -EINVAL;
878         }
879
880         return 0;
881 }
882
883 void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
884 {
885         u32 reg;
886
887         reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
888         if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
889                 reg &= ~(RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N);
890         } else {
891                 reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
892                 reg |= MASTER_VID_FUNC_EN_N;
893         }
894         writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
895
896         reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
897         reg &= ~INTERACE_SCAN_CFG;
898         reg |= (dp->video_info.interlaced << 2);
899         writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
900
901         reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
902         reg &= ~VSYNC_POLARITY_CFG;
903         reg |= (dp->video_info.v_sync_polarity << 1);
904         writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
905
906         reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
907         reg &= ~HSYNC_POLARITY_CFG;
908         reg |= (dp->video_info.h_sync_polarity << 0);
909         writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
910
911         reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
912         writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
913 }
914
915 void analogix_dp_enable_scrambling(struct analogix_dp_device *dp)
916 {
917         u32 reg;
918
919         reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
920         reg &= ~SCRAMBLING_DISABLE;
921         writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
922 }
923
924 void analogix_dp_disable_scrambling(struct analogix_dp_device *dp)
925 {
926         u32 reg;
927
928         reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
929         reg |= SCRAMBLING_DISABLE;
930         writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
931 }
932
933 void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp)
934 {
935         writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
936 }
937
938 static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
939 {
940         ssize_t val;
941         u8 status;
942
943         val = drm_dp_dpcd_readb(&dp->aux, DP_PSR_STATUS, &status);
944         if (val < 0) {
945                 dev_err(dp->dev, "PSR_STATUS read failed ret=%zd", val);
946                 return val;
947         }
948         return status;
949 }
950
951 int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
952                              struct dp_sdp *vsc, bool blocking)
953 {
954         unsigned int val;
955         int ret;
956         ssize_t psr_status;
957
958         /* don't send info frame */
959         val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
960         val &= ~IF_EN;
961         writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
962
963         /* configure single frame update mode */
964         writel(PSR_FRAME_UP_TYPE_BURST | PSR_CRC_SEL_HARDWARE,
965                dp->reg_base + ANALOGIX_DP_PSR_FRAME_UPDATE_CTRL);
966
967         /* configure VSC HB0~HB3 */
968         writel(vsc->sdp_header.HB0, dp->reg_base + ANALOGIX_DP_SPD_HB0);
969         writel(vsc->sdp_header.HB1, dp->reg_base + ANALOGIX_DP_SPD_HB1);
970         writel(vsc->sdp_header.HB2, dp->reg_base + ANALOGIX_DP_SPD_HB2);
971         writel(vsc->sdp_header.HB3, dp->reg_base + ANALOGIX_DP_SPD_HB3);
972
973         /* configure reused VSC PB0~PB3, magic number from vendor */
974         writel(0x00, dp->reg_base + ANALOGIX_DP_SPD_PB0);
975         writel(0x16, dp->reg_base + ANALOGIX_DP_SPD_PB1);
976         writel(0xCE, dp->reg_base + ANALOGIX_DP_SPD_PB2);
977         writel(0x5D, dp->reg_base + ANALOGIX_DP_SPD_PB3);
978
979         /* configure DB0 / DB1 values */
980         writel(vsc->db[0], dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB0);
981         writel(vsc->db[1], dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB1);
982
983         /* set reuse spd inforframe */
984         val = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
985         val |= REUSE_SPD_EN;
986         writel(val, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
987
988         /* mark info frame update */
989         val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
990         val = (val | IF_UP) & ~IF_EN;
991         writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
992
993         /* send info frame */
994         val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
995         val |= IF_EN;
996         writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
997
998         if (!blocking)
999                 return 0;
1000
1001         /*
1002          * db[1]!=0: entering PSR, wait for fully active remote frame buffer.
1003          * db[1]==0: exiting PSR, wait for either
1004          *  (a) ACTIVE_RESYNC - the sink "must display the
1005          *      incoming active frames from the Source device with no visible
1006          *      glitches and/or artifacts", even though timings may still be
1007          *      re-synchronizing; or
1008          *  (b) INACTIVE - the transition is fully complete.
1009          */
1010         ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
1011                 psr_status >= 0 &&
1012                 ((vsc->db[1] && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
1013                 (!vsc->db[1] && (psr_status == DP_PSR_SINK_ACTIVE_RESYNC ||
1014                                  psr_status == DP_PSR_SINK_INACTIVE))),
1015                 1500, DP_TIMEOUT_PSR_LOOP_MS * 1000);
1016         if (ret) {
1017                 dev_warn(dp->dev, "Failed to apply PSR %d\n", ret);
1018                 return ret;
1019         }
1020         return 0;
1021 }
1022
1023 ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
1024                              struct drm_dp_aux_msg *msg)
1025 {
1026         u32 reg;
1027         u32 status_reg;
1028         u8 *buffer = msg->buffer;
1029         unsigned int i;
1030         int num_transferred = 0;
1031         int ret;
1032
1033         /* Buffer size of AUX CH is 16 bytes */
1034         if (WARN_ON(msg->size > 16))
1035                 return -E2BIG;
1036
1037         /* Clear AUX CH data buffer */
1038         reg = BUF_CLR;
1039         writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
1040
1041         switch (msg->request & ~DP_AUX_I2C_MOT) {
1042         case DP_AUX_I2C_WRITE:
1043                 reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_I2C_TRANSACTION;
1044                 if (msg->request & DP_AUX_I2C_MOT)
1045                         reg |= AUX_TX_COMM_MOT;
1046                 break;
1047
1048         case DP_AUX_I2C_READ:
1049                 reg = AUX_TX_COMM_READ | AUX_TX_COMM_I2C_TRANSACTION;
1050                 if (msg->request & DP_AUX_I2C_MOT)
1051                         reg |= AUX_TX_COMM_MOT;
1052                 break;
1053
1054         case DP_AUX_NATIVE_WRITE:
1055                 reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_DP_TRANSACTION;
1056                 break;
1057
1058         case DP_AUX_NATIVE_READ:
1059                 reg = AUX_TX_COMM_READ | AUX_TX_COMM_DP_TRANSACTION;
1060                 break;
1061
1062         default:
1063                 return -EINVAL;
1064         }
1065
1066         reg |= AUX_LENGTH(msg->size);
1067         writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
1068
1069         /* Select DPCD device address */
1070         reg = AUX_ADDR_7_0(msg->address);
1071         writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
1072         reg = AUX_ADDR_15_8(msg->address);
1073         writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
1074         reg = AUX_ADDR_19_16(msg->address);
1075         writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
1076
1077         if (!(msg->request & DP_AUX_I2C_READ)) {
1078                 for (i = 0; i < msg->size; i++) {
1079                         reg = buffer[i];
1080                         writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
1081                                4 * i);
1082                         num_transferred++;
1083                 }
1084         }
1085
1086         /* Enable AUX CH operation */
1087         reg = AUX_EN;
1088
1089         /* Zero-sized messages specify address-only transactions. */
1090         if (msg->size < 1)
1091                 reg |= ADDR_ONLY;
1092
1093         writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
1094
1095         ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2,
1096                                  reg, !(reg & AUX_EN), 25, 500 * 1000);
1097         if (ret) {
1098                 dev_err(dp->dev, "AUX CH enable timeout!\n");
1099                 goto aux_error;
1100         }
1101
1102         /* TODO: Wait for an interrupt instead of looping? */
1103         /* Is AUX CH command reply received? */
1104         ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_INT_STA,
1105                                  reg, reg & RPLY_RECEIV, 10, 20 * 1000);
1106         if (ret) {
1107                 dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
1108                 goto aux_error;
1109         }
1110
1111         /* Clear interrupt source for AUX CH command reply */
1112         writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
1113
1114         /* Clear interrupt source for AUX CH access error */
1115         reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
1116         status_reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
1117         if ((reg & AUX_ERR) || (status_reg & AUX_STATUS_MASK)) {
1118                 writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
1119
1120                 dev_warn(dp->dev, "AUX CH error happened: %#x (%d)\n",
1121                          status_reg & AUX_STATUS_MASK, !!(reg & AUX_ERR));
1122                 goto aux_error;
1123         }
1124
1125         if (msg->request & DP_AUX_I2C_READ) {
1126                 for (i = 0; i < msg->size; i++) {
1127                         reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
1128                                     4 * i);
1129                         buffer[i] = (unsigned char)reg;
1130                         num_transferred++;
1131                 }
1132         }
1133
1134         /* Check if Rx sends defer */
1135         reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM);
1136         if (reg == AUX_RX_COMM_AUX_DEFER)
1137                 msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
1138         else if (reg == AUX_RX_COMM_I2C_DEFER)
1139                 msg->reply = DP_AUX_I2C_REPLY_DEFER;
1140         else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE ||
1141                  (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_READ)
1142                 msg->reply = DP_AUX_I2C_REPLY_ACK;
1143         else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE ||
1144                  (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
1145                 msg->reply = DP_AUX_NATIVE_REPLY_ACK;
1146
1147         return num_transferred > 0 ? num_transferred : -EBUSY;
1148
1149 aux_error:
1150         /* if aux err happen, reset aux */
1151         analogix_dp_init_aux(dp);
1152
1153         return -EREMOTEIO;
1154 }
This page took 0.107355 seconds and 4 git commands to generate.