1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
4 */
5
6 #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
7
8 #include <linux/types.h>
9 #include <linux/clk.h>
10 #include <linux/completion.h>
11 #include <linux/delay.h>
12 #include <linux/iopoll.h>
13 #include <linux/phy/phy.h>
14 #include <linux/phy/phy-dp.h>
15 #include <linux/pm_opp.h>
16 #include <linux/rational.h>
17 #include <linux/string_choices.h>
18
19 #include <drm/display/drm_dp_helper.h>
20 #include <drm/drm_device.h>
21 #include <drm/drm_fixed.h>
22 #include <drm/drm_print.h>
23
24 #include "dp_reg.h"
25 #include "dp_ctrl.h"
26 #include "dp_link.h"
27
28 #define POLLING_SLEEP_US 1000
29 #define POLLING_TIMEOUT_US 10000
30
31 #define DP_KHZ_TO_HZ 1000
32 #define IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES (30 * HZ / 1000) /* 30 ms */
33 #define PSR_OPERATION_COMPLETION_TIMEOUT_JIFFIES (300 * HZ / 1000) /* 300 ms */
34 #define WAIT_FOR_VIDEO_READY_TIMEOUT_JIFFIES (HZ / 2)
35
36 #define DP_INTERRUPT_STATUS_ACK_SHIFT 1
37 #define DP_INTERRUPT_STATUS_MASK_SHIFT 2
38
39 #define DP_INTERRUPT_STATUS1 \
40 (DP_INTR_AUX_XFER_DONE| \
41 DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
42 DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \
43 DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \
44 DP_INTR_PLL_UNLOCKED | DP_INTR_AUX_ERROR)
45
46 #define DP_INTERRUPT_STATUS1_ACK \
47 (DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_ACK_SHIFT)
48 #define DP_INTERRUPT_STATUS1_MASK \
49 (DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_MASK_SHIFT)
50
51 #define DP_INTERRUPT_STATUS2 \
52 (DP_INTR_READY_FOR_VIDEO | DP_INTR_IDLE_PATTERN_SENT | \
53 DP_INTR_FRAME_END | DP_INTR_CRC_UPDATED)
54
55 #define DP_INTERRUPT_STATUS2_ACK \
56 (DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_ACK_SHIFT)
57 #define DP_INTERRUPT_STATUS2_MASK \
58 (DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
59
60 #define DP_INTERRUPT_STATUS4 \
61 (PSR_UPDATE_INT | PSR_CAPTURE_INT | PSR_EXIT_INT | \
62 PSR_UPDATE_ERROR_INT | PSR_WAKE_ERROR_INT)
63
64 #define DP_INTERRUPT_MASK4 \
65 (PSR_UPDATE_MASK | PSR_CAPTURE_MASK | PSR_EXIT_MASK | \
66 PSR_UPDATE_ERROR_MASK | PSR_WAKE_ERROR_MASK)
67
68 #define DP_CTRL_INTR_READY_FOR_VIDEO BIT(0)
69 #define DP_CTRL_INTR_IDLE_PATTERN_SENT BIT(3)
70
71 #define MR_LINK_TRAINING1 0x8
72 #define MR_LINK_SYMBOL_ERM 0x80
73 #define MR_LINK_PRBS7 0x100
74 #define MR_LINK_CUSTOM80 0x200
75 #define MR_LINK_TRAINING4 0x40
76
77 enum {
78 DP_TRAINING_NONE,
79 DP_TRAINING_1,
80 DP_TRAINING_2,
81 };
82
83 struct msm_dp_tu_calc_input {
84 u64 lclk; /* 162, 270, 540 and 810 */
85 u64 pclk_khz; /* in KHz */
86 u64 hactive; /* active h-width */
87 u64 hporch; /* bp + fp + pulse */
88 int nlanes; /* no.of.lanes */
89 int bpp; /* bits */
90 int pixel_enc; /* 444, 420, 422 */
91 int dsc_en; /* dsc on/off */
92 int async_en; /* async mode */
93 int fec_en; /* fec */
94 int compress_ratio; /* 2:1 = 200, 3:1 = 300, 3.75:1 = 375 */
95 int num_of_dsc_slices; /* number of slices per line */
96 };
97
98 struct msm_dp_vc_tu_mapping_table {
99 u32 vic;
100 u8 lanes;
101 u8 lrate; /* DP_LINK_RATE -> 162(6), 270(10), 540(20), 810 (30) */
102 u8 bpp;
103 u8 valid_boundary_link;
104 u16 delay_start_link;
105 bool boundary_moderation_en;
106 u8 valid_lower_boundary_link;
107 u8 upper_boundary_count;
108 u8 lower_boundary_count;
109 u8 tu_size_minus1;
110 };
111
112 struct msm_dp_ctrl_private {
113 struct msm_dp_ctrl msm_dp_ctrl;
114 struct drm_device *drm_dev;
115 struct device *dev;
116 struct drm_dp_aux *aux;
117 struct msm_dp_link *link;
118 void __iomem *ahb_base;
119 void __iomem *link_base;
120
121 struct phy *phy;
122
123 unsigned int num_core_clks;
124 struct clk_bulk_data *core_clks;
125
126 unsigned int num_link_clks;
127 struct clk_bulk_data *link_clks;
128
129 struct clk *pixel_clk;
130
131 union phy_configure_opts phy_opts;
132
133 struct completion idle_comp;
134 struct completion psr_op_comp;
135 struct completion video_comp;
136
137 u32 hw_revision;
138
139 bool core_clks_on;
140 bool link_clks_on;
141 bool stream_clks_on;
142 };
143
msm_dp_read_ahb(const struct msm_dp_ctrl_private * ctrl,u32 offset)144 static inline u32 msm_dp_read_ahb(const struct msm_dp_ctrl_private *ctrl, u32 offset)
145 {
146 return readl_relaxed(ctrl->ahb_base + offset);
147 }
148
msm_dp_write_ahb(struct msm_dp_ctrl_private * ctrl,u32 offset,u32 data)149 static inline void msm_dp_write_ahb(struct msm_dp_ctrl_private *ctrl,
150 u32 offset, u32 data)
151 {
152 /*
153 * To make sure phy reg writes happens before any other operation,
154 * this function uses writel() instread of writel_relaxed()
155 */
156 writel(data, ctrl->ahb_base + offset);
157 }
158
msm_dp_read_link(struct msm_dp_ctrl_private * ctrl,u32 offset)159 static inline u32 msm_dp_read_link(struct msm_dp_ctrl_private *ctrl, u32 offset)
160 {
161 return readl_relaxed(ctrl->link_base + offset);
162 }
163
msm_dp_write_link(struct msm_dp_ctrl_private * ctrl,u32 offset,u32 data)164 static inline void msm_dp_write_link(struct msm_dp_ctrl_private *ctrl,
165 u32 offset, u32 data)
166 {
167 /*
168 * To make sure link reg writes happens before any other operation,
169 * this function uses writel() instread of writel_relaxed()
170 */
171 writel(data, ctrl->link_base + offset);
172 }
173
msm_dp_aux_link_configure(struct drm_dp_aux * aux,struct msm_dp_link_info * link)174 static int msm_dp_aux_link_configure(struct drm_dp_aux *aux,
175 struct msm_dp_link_info *link)
176 {
177 u8 lane_count, bw_code;
178 int err;
179
180 lane_count = link->num_lanes;
181
182 if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
183 lane_count |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
184
185 err = drm_dp_dpcd_writeb(aux, DP_LANE_COUNT_SET, lane_count);
186 if (err < 0)
187 return err;
188
189 if (link->use_rate_set) {
190 DRM_DEBUG_DP("using LINK_RATE_SET: 0x%02x", link->rate_set);
191 err = drm_dp_dpcd_writeb(aux, DP_LINK_RATE_SET, link->rate_set);
192 } else {
193 bw_code = drm_dp_link_rate_to_bw_code(link->rate);
194 DRM_DEBUG_DP("using LINK_BW_SET: 0x%02x", bw_code);
195 err = drm_dp_dpcd_writeb(aux, DP_LINK_BW_SET, bw_code);
196 }
197
198 return err;
199 }
200
201 /*
202 * NOTE: resetting DP controller will also clear any pending HPD related interrupts
203 */
msm_dp_ctrl_reset(struct msm_dp_ctrl * msm_dp_ctrl,struct msm_dp_panel * panel)204 void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl,
205 struct msm_dp_panel *panel)
206 {
207 struct msm_dp_ctrl_private *ctrl =
208 container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
209 u32 sw_reset;
210
211 sw_reset = msm_dp_read_ahb(ctrl, REG_DP_SW_RESET);
212
213 sw_reset |= DP_SW_RESET;
214 msm_dp_write_ahb(ctrl, REG_DP_SW_RESET, sw_reset);
215 usleep_range(1000, 1100); /* h/w recommended delay */
216
217 sw_reset &= ~DP_SW_RESET;
218 msm_dp_write_ahb(ctrl, REG_DP_SW_RESET, sw_reset);
219
220 if (!ctrl->hw_revision)
221 ctrl->hw_revision = msm_dp_read_ahb(ctrl, REG_DP_HW_VERSION);
222 panel->hw_revision = ctrl->hw_revision;
223 }
224
msm_dp_ctrl_get_aux_interrupt(struct msm_dp_ctrl_private * ctrl)225 static u32 msm_dp_ctrl_get_aux_interrupt(struct msm_dp_ctrl_private *ctrl)
226 {
227 u32 intr, intr_ack;
228
229 intr = msm_dp_read_ahb(ctrl, REG_DP_INTR_STATUS);
230 intr &= ~DP_INTERRUPT_STATUS1_MASK;
231 intr_ack = (intr & DP_INTERRUPT_STATUS1)
232 << DP_INTERRUPT_STATUS_ACK_SHIFT;
233 msm_dp_write_ahb(ctrl, REG_DP_INTR_STATUS,
234 intr_ack | DP_INTERRUPT_STATUS1_MASK);
235
236 return intr;
237
238 }
239
msm_dp_ctrl_get_interrupt(struct msm_dp_ctrl_private * ctrl)240 static u32 msm_dp_ctrl_get_interrupt(struct msm_dp_ctrl_private *ctrl)
241 {
242 u32 intr, intr_ack;
243
244 intr = msm_dp_read_ahb(ctrl, REG_DP_INTR_STATUS2);
245 intr &= ~DP_INTERRUPT_STATUS2_MASK;
246 intr_ack = (intr & DP_INTERRUPT_STATUS2)
247 << DP_INTERRUPT_STATUS_ACK_SHIFT;
248 msm_dp_write_ahb(ctrl, REG_DP_INTR_STATUS2,
249 intr_ack | DP_INTERRUPT_STATUS2_MASK);
250
251 return intr;
252 }
253
msm_dp_ctrl_enable_irq(struct msm_dp_ctrl * msm_dp_ctrl)254 void msm_dp_ctrl_enable_irq(struct msm_dp_ctrl *msm_dp_ctrl)
255 {
256 struct msm_dp_ctrl_private *ctrl =
257 container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
258
259 msm_dp_write_ahb(ctrl, REG_DP_INTR_STATUS,
260 DP_INTERRUPT_STATUS1_MASK);
261 msm_dp_write_ahb(ctrl, REG_DP_INTR_STATUS2,
262 DP_INTERRUPT_STATUS2_MASK);
263 }
264
msm_dp_ctrl_disable_irq(struct msm_dp_ctrl * msm_dp_ctrl)265 void msm_dp_ctrl_disable_irq(struct msm_dp_ctrl *msm_dp_ctrl)
266 {
267 struct msm_dp_ctrl_private *ctrl =
268 container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
269
270 msm_dp_write_ahb(ctrl, REG_DP_INTR_STATUS, 0x00);
271 msm_dp_write_ahb(ctrl, REG_DP_INTR_STATUS2, 0x00);
272 }
273
msm_dp_ctrl_get_psr_interrupt(struct msm_dp_ctrl_private * ctrl)274 static u32 msm_dp_ctrl_get_psr_interrupt(struct msm_dp_ctrl_private *ctrl)
275 {
276 u32 intr, intr_ack;
277
278 intr = msm_dp_read_ahb(ctrl, REG_DP_INTR_STATUS4);
279 intr_ack = (intr & DP_INTERRUPT_STATUS4)
280 << DP_INTERRUPT_STATUS_ACK_SHIFT;
281 msm_dp_write_ahb(ctrl, REG_DP_INTR_STATUS4, intr_ack);
282
283 return intr;
284 }
285
msm_dp_ctrl_config_psr_interrupt(struct msm_dp_ctrl_private * ctrl)286 static void msm_dp_ctrl_config_psr_interrupt(struct msm_dp_ctrl_private *ctrl)
287 {
288 msm_dp_write_ahb(ctrl, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
289 }
290
msm_dp_ctrl_psr_mainlink_enable(struct msm_dp_ctrl_private * ctrl)291 static void msm_dp_ctrl_psr_mainlink_enable(struct msm_dp_ctrl_private *ctrl)
292 {
293 u32 val;
294
295 val = msm_dp_read_link(ctrl, REG_DP_MAINLINK_CTRL);
296 val |= DP_MAINLINK_CTRL_ENABLE;
297 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, val);
298 }
299
msm_dp_ctrl_psr_mainlink_disable(struct msm_dp_ctrl_private * ctrl)300 static void msm_dp_ctrl_psr_mainlink_disable(struct msm_dp_ctrl_private *ctrl)
301 {
302 u32 val;
303
304 val = msm_dp_read_link(ctrl, REG_DP_MAINLINK_CTRL);
305 val &= ~DP_MAINLINK_CTRL_ENABLE;
306 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, val);
307 }
308
msm_dp_ctrl_mainlink_enable(struct msm_dp_ctrl_private * ctrl)309 static void msm_dp_ctrl_mainlink_enable(struct msm_dp_ctrl_private *ctrl)
310 {
311 u32 mainlink_ctrl;
312
313 drm_dbg_dp(ctrl->drm_dev, "enable\n");
314
315 mainlink_ctrl = msm_dp_read_link(ctrl, REG_DP_MAINLINK_CTRL);
316
317 mainlink_ctrl &= ~(DP_MAINLINK_CTRL_RESET |
318 DP_MAINLINK_CTRL_ENABLE);
319 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
320
321 mainlink_ctrl |= DP_MAINLINK_CTRL_RESET;
322 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
323
324 mainlink_ctrl &= ~DP_MAINLINK_CTRL_RESET;
325 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
326
327 mainlink_ctrl |= (DP_MAINLINK_CTRL_ENABLE |
328 DP_MAINLINK_FB_BOUNDARY_SEL);
329 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
330 }
331
msm_dp_ctrl_mainlink_disable(struct msm_dp_ctrl_private * ctrl)332 static void msm_dp_ctrl_mainlink_disable(struct msm_dp_ctrl_private *ctrl)
333 {
334 u32 mainlink_ctrl;
335
336 drm_dbg_dp(ctrl->drm_dev, "disable\n");
337
338 mainlink_ctrl = msm_dp_read_link(ctrl, REG_DP_MAINLINK_CTRL);
339 mainlink_ctrl &= ~DP_MAINLINK_CTRL_ENABLE;
340 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
341 }
342
msm_dp_setup_peripheral_flush(struct msm_dp_ctrl_private * ctrl)343 static void msm_dp_setup_peripheral_flush(struct msm_dp_ctrl_private *ctrl)
344 {
345 u32 mainlink_ctrl;
346
347 mainlink_ctrl = msm_dp_read_link(ctrl, REG_DP_MAINLINK_CTRL);
348
349 if (ctrl->hw_revision >= DP_HW_VERSION_1_2)
350 mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_SDE_PERIPH_UPDATE;
351 else
352 mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_UPDATE_SDP;
353
354 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
355 }
356
msm_dp_ctrl_mainlink_ready(struct msm_dp_ctrl_private * ctrl)357 static bool msm_dp_ctrl_mainlink_ready(struct msm_dp_ctrl_private *ctrl)
358 {
359 u32 data;
360 int ret;
361
362 /* Poll for mainlink ready status */
363 ret = readl_poll_timeout(ctrl->link_base + REG_DP_MAINLINK_READY,
364 data, data & DP_MAINLINK_READY_FOR_VIDEO,
365 POLLING_SLEEP_US, POLLING_TIMEOUT_US);
366 if (ret < 0) {
367 DRM_ERROR("mainlink not ready\n");
368 return false;
369 }
370
371 return true;
372 }
373
msm_dp_ctrl_push_idle(struct msm_dp_ctrl * msm_dp_ctrl)374 void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl)
375 {
376 struct msm_dp_ctrl_private *ctrl;
377
378 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
379
380 reinit_completion(&ctrl->idle_comp);
381 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_PUSH_IDLE);
382
383 if (!wait_for_completion_timeout(&ctrl->idle_comp,
384 IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES))
385 pr_warn("PUSH_IDLE pattern timedout\n");
386
387 drm_dbg_dp(ctrl->drm_dev, "mainlink off\n");
388 }
389
msm_dp_ctrl_config_ctrl_streams(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * msm_dp_panel)390 static void msm_dp_ctrl_config_ctrl_streams(struct msm_dp_ctrl_private *ctrl,
391 struct msm_dp_panel *msm_dp_panel)
392 {
393 u32 config = 0, tbd;
394
395 /*
396 * RMW: called from atomic_enable(), serialized by the DRM atomic framework.
397 * Clear stream-specific fields before OR-ing to avoid bit accumulation.
398 */
399 config = msm_dp_read_link(ctrl, REG_DP_CONFIGURATION_CTRL);
400 config &= ~(DP_CONFIGURATION_CTRL_RGB_YUV_MASK |
401 DP_CONFIGURATION_CTRL_BPC_MASK |
402 DP_CONFIGURATION_CTRL_SEND_VSC);
403
404 if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
405 config |= DP_CONFIGURATION_CTRL_RGB_YUV; /* YUV420 */
406
407 tbd = msm_dp_link_get_test_bits_depth(ctrl->link,
408 msm_dp_panel->msm_dp_mode.bpp);
409
410 config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT;
411
412 if (msm_dp_panel->psr_cap.version)
413 config |= DP_CONFIGURATION_CTRL_SEND_VSC;
414
415 drm_dbg_dp(ctrl->drm_dev, "stream DP_CONFIGURATION_CTRL=0x%x\n", config);
416
417 msm_dp_write_link(ctrl, REG_DP_CONFIGURATION_CTRL, config);
418 }
419
msm_dp_ctrl_config_ctrl_link(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel)420 static void msm_dp_ctrl_config_ctrl_link(struct msm_dp_ctrl_private *ctrl,
421 struct msm_dp_panel *panel)
422 {
423 u32 config = 0;
424 const u8 *dpcd = panel->dpcd;
425
426 /* Default-> LSCLK DIV: 1/4 LCLK */
427 config |= (2 << DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT);
428
429 /* Scrambler reset enable */
430 if (drm_dp_alternate_scrambler_reset_cap(dpcd))
431 config |= DP_CONFIGURATION_CTRL_ASSR;
432
433 /* Num of Lanes */
434 config |= ((ctrl->link->link_params.num_lanes - 1)
435 << DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT);
436
437 if (drm_dp_enhanced_frame_cap(dpcd))
438 config |= DP_CONFIGURATION_CTRL_ENHANCED_FRAMING;
439
440 config |= DP_CONFIGURATION_CTRL_P_INTERLACED; /* progressive video */
441
442 /* sync clock & static Mvid */
443 config |= DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN;
444 config |= DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK;
445
446 drm_dbg_dp(ctrl->drm_dev, "link DP_CONFIGURATION_CTRL=0x%x\n", config);
447
448 msm_dp_write_link(ctrl, REG_DP_CONFIGURATION_CTRL, config);
449 }
450
msm_dp_ctrl_lane_mapping(struct msm_dp_ctrl_private * ctrl)451 static void msm_dp_ctrl_lane_mapping(struct msm_dp_ctrl_private *ctrl)
452 {
453 u32 *lane_map = ctrl->link->lane_map;
454 u32 ln_mapping;
455
456 ln_mapping = lane_map[0] << LANE0_MAPPING_SHIFT;
457 ln_mapping |= lane_map[1] << LANE1_MAPPING_SHIFT;
458 ln_mapping |= lane_map[2] << LANE2_MAPPING_SHIFT;
459 ln_mapping |= lane_map[3] << LANE3_MAPPING_SHIFT;
460
461 msm_dp_write_link(ctrl, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
462 ln_mapping);
463 }
464
msm_dp_ctrl_config_misc1_misc0(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * msm_dp_panel)465 static void msm_dp_ctrl_config_misc1_misc0(struct msm_dp_ctrl_private *ctrl,
466 struct msm_dp_panel *msm_dp_panel)
467 {
468 u32 colorimetry_cfg, test_bits_depth, misc_val;
469
470 test_bits_depth = msm_dp_link_get_test_bits_depth(ctrl->link,
471 msm_dp_panel->msm_dp_mode.bpp);
472 colorimetry_cfg = msm_dp_link_get_colorimetry_config(ctrl->link);
473
474 misc_val = msm_dp_read_link(ctrl, REG_DP_MISC1_MISC0);
475
476 /* clear bpp bits */
477 misc_val &= ~(0x07 << DP_MISC0_TEST_BITS_DEPTH_SHIFT);
478 misc_val |= colorimetry_cfg << DP_MISC0_COLORIMETRY_CFG_SHIFT;
479 misc_val |= test_bits_depth << DP_MISC0_TEST_BITS_DEPTH_SHIFT;
480 /* Configure clock to synchronous mode */
481 misc_val |= DP_MISC0_SYNCHRONOUS_CLK;
482
483 drm_dbg_dp(ctrl->drm_dev, "misc settings = 0x%x\n", misc_val);
484 msm_dp_write_link(ctrl, REG_DP_MISC1_MISC0, misc_val);
485 }
486
msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel)487 static void msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private *ctrl,
488 struct msm_dp_panel *panel)
489 {
490 msm_dp_ctrl_config_ctrl_streams(ctrl, panel);
491
492 msm_dp_ctrl_config_misc1_misc0(ctrl, panel);
493
494 msm_dp_panel_timing_cfg(panel, ctrl->msm_dp_ctrl.wide_bus_en);
495 }
496
497 /*
498 * The structure and few functions present below are IP/Hardware
499 * specific implementation. Most of the implementation will not
500 * have coding comments
501 */
502 struct tu_algo_data {
503 s64 lclk_fp;
504 s64 pclk_fp;
505 s64 lwidth;
506 s64 lwidth_fp;
507 s64 hbp_relative_to_pclk;
508 s64 hbp_relative_to_pclk_fp;
509 int nlanes;
510 int bpp;
511 int pixelEnc;
512 int dsc_en;
513 int async_en;
514 int bpc;
515
516 uint delay_start_link_extra_pixclk;
517 int extra_buffer_margin;
518 s64 ratio_fp;
519 s64 original_ratio_fp;
520
521 s64 err_fp;
522 s64 n_err_fp;
523 s64 n_n_err_fp;
524 int tu_size;
525 int tu_size_desired;
526 int tu_size_minus1;
527
528 int valid_boundary_link;
529 s64 resulting_valid_fp;
530 s64 total_valid_fp;
531 s64 effective_valid_fp;
532 s64 effective_valid_recorded_fp;
533 int n_tus;
534 int n_tus_per_lane;
535 int paired_tus;
536 int remainder_tus;
537 int remainder_tus_upper;
538 int remainder_tus_lower;
539 int extra_bytes;
540 int filler_size;
541 int delay_start_link;
542
543 int extra_pclk_cycles;
544 int extra_pclk_cycles_in_link_clk;
545 s64 ratio_by_tu_fp;
546 s64 average_valid2_fp;
547 int new_valid_boundary_link;
548 int remainder_symbols_exist;
549 int n_symbols;
550 s64 n_remainder_symbols_per_lane_fp;
551 s64 last_partial_tu_fp;
552 s64 TU_ratio_err_fp;
553
554 int n_tus_incl_last_incomplete_tu;
555 int extra_pclk_cycles_tmp;
556 int extra_pclk_cycles_in_link_clk_tmp;
557 int extra_required_bytes_new_tmp;
558 int filler_size_tmp;
559 int lower_filler_size_tmp;
560 int delay_start_link_tmp;
561
562 bool boundary_moderation_en;
563 int boundary_mod_lower_err;
564 int upper_boundary_count;
565 int lower_boundary_count;
566 int i_upper_boundary_count;
567 int i_lower_boundary_count;
568 int valid_lower_boundary_link;
569 int even_distribution_BF;
570 int even_distribution_legacy;
571 int even_distribution;
572 int min_hblank_violated;
573 s64 delay_start_time_fp;
574 s64 hbp_time_fp;
575 s64 hactive_time_fp;
576 s64 diff_abs_fp;
577
578 s64 ratio;
579 };
580
_tu_param_compare(s64 a,s64 b)581 static int _tu_param_compare(s64 a, s64 b)
582 {
583 u32 a_sign;
584 u32 b_sign;
585 s64 a_temp, b_temp, minus_1;
586
587 if (a == b)
588 return 0;
589
590 minus_1 = drm_fixp_from_fraction(-1, 1);
591
592 a_sign = (a >> 32) & 0x80000000 ? 1 : 0;
593
594 b_sign = (b >> 32) & 0x80000000 ? 1 : 0;
595
596 if (a_sign > b_sign)
597 return 2;
598 else if (b_sign > a_sign)
599 return 1;
600
601 if (!a_sign && !b_sign) { /* positive */
602 if (a > b)
603 return 1;
604 else
605 return 2;
606 } else { /* negative */
607 a_temp = drm_fixp_mul(a, minus_1);
608 b_temp = drm_fixp_mul(b, minus_1);
609
610 if (a_temp > b_temp)
611 return 2;
612 else
613 return 1;
614 }
615 }
616
msm_dp_panel_update_tu_timings(struct msm_dp_tu_calc_input * in,struct tu_algo_data * tu)617 static void msm_dp_panel_update_tu_timings(struct msm_dp_tu_calc_input *in,
618 struct tu_algo_data *tu)
619 {
620 int nlanes = in->nlanes;
621 int dsc_num_slices = in->num_of_dsc_slices;
622 int dsc_num_bytes = 0;
623 int numerator;
624 s64 pclk_dsc_fp;
625 s64 dwidth_dsc_fp;
626 s64 hbp_dsc_fp;
627
628 int tot_num_eoc_symbols = 0;
629 int tot_num_hor_bytes = 0;
630 int tot_num_dummy_bytes = 0;
631 int dwidth_dsc_bytes = 0;
632 int eoc_bytes = 0;
633
634 s64 temp1_fp, temp2_fp, temp3_fp;
635
636 tu->lclk_fp = drm_fixp_from_fraction(in->lclk, 1);
637 tu->pclk_fp = drm_fixp_from_fraction(in->pclk_khz, 1000);
638 tu->lwidth = in->hactive;
639 tu->hbp_relative_to_pclk = in->hporch;
640 tu->nlanes = in->nlanes;
641 tu->bpp = in->bpp;
642 tu->pixelEnc = in->pixel_enc;
643 tu->dsc_en = in->dsc_en;
644 tu->async_en = in->async_en;
645 tu->lwidth_fp = drm_fixp_from_fraction(in->hactive, 1);
646 tu->hbp_relative_to_pclk_fp = drm_fixp_from_fraction(in->hporch, 1);
647
648 if (tu->pixelEnc == 420) {
649 temp1_fp = drm_fixp_from_fraction(2, 1);
650 tu->pclk_fp = drm_fixp_div(tu->pclk_fp, temp1_fp);
651 tu->lwidth_fp = drm_fixp_div(tu->lwidth_fp, temp1_fp);
652 tu->hbp_relative_to_pclk_fp =
653 drm_fixp_div(tu->hbp_relative_to_pclk_fp, 2);
654 }
655
656 if (tu->pixelEnc == 422) {
657 switch (tu->bpp) {
658 case 24:
659 tu->bpp = 16;
660 tu->bpc = 8;
661 break;
662 case 30:
663 tu->bpp = 20;
664 tu->bpc = 10;
665 break;
666 default:
667 tu->bpp = 16;
668 tu->bpc = 8;
669 break;
670 }
671 } else {
672 tu->bpc = tu->bpp/3;
673 }
674
675 if (!in->dsc_en)
676 goto fec_check;
677
678 temp1_fp = drm_fixp_from_fraction(in->compress_ratio, 100);
679 temp2_fp = drm_fixp_from_fraction(in->bpp, 1);
680 temp3_fp = drm_fixp_div(temp2_fp, temp1_fp);
681 temp2_fp = drm_fixp_mul(tu->lwidth_fp, temp3_fp);
682
683 temp1_fp = drm_fixp_from_fraction(8, 1);
684 temp3_fp = drm_fixp_div(temp2_fp, temp1_fp);
685
686 numerator = drm_fixp2int(temp3_fp);
687
688 dsc_num_bytes = numerator / dsc_num_slices;
689 eoc_bytes = dsc_num_bytes % nlanes;
690 tot_num_eoc_symbols = nlanes * dsc_num_slices;
691 tot_num_hor_bytes = dsc_num_bytes * dsc_num_slices;
692 tot_num_dummy_bytes = (nlanes - eoc_bytes) * dsc_num_slices;
693
694 if (dsc_num_bytes == 0)
695 pr_info("incorrect no of bytes per slice=%d\n", dsc_num_bytes);
696
697 dwidth_dsc_bytes = (tot_num_hor_bytes +
698 tot_num_eoc_symbols +
699 (eoc_bytes == 0 ? 0 : tot_num_dummy_bytes));
700
701 dwidth_dsc_fp = drm_fixp_from_fraction(dwidth_dsc_bytes, 3);
702
703 temp2_fp = drm_fixp_mul(tu->pclk_fp, dwidth_dsc_fp);
704 temp1_fp = drm_fixp_div(temp2_fp, tu->lwidth_fp);
705 pclk_dsc_fp = temp1_fp;
706
707 temp1_fp = drm_fixp_div(pclk_dsc_fp, tu->pclk_fp);
708 temp2_fp = drm_fixp_mul(tu->hbp_relative_to_pclk_fp, temp1_fp);
709 hbp_dsc_fp = temp2_fp;
710
711 /* output */
712 tu->pclk_fp = pclk_dsc_fp;
713 tu->lwidth_fp = dwidth_dsc_fp;
714 tu->hbp_relative_to_pclk_fp = hbp_dsc_fp;
715
716 fec_check:
717 if (in->fec_en) {
718 temp1_fp = drm_fixp_from_fraction(976, 1000); /* 0.976 */
719 tu->lclk_fp = drm_fixp_mul(tu->lclk_fp, temp1_fp);
720 }
721 }
722
_tu_valid_boundary_calc(struct tu_algo_data * tu)723 static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
724 {
725 s64 temp1_fp, temp2_fp, temp, temp1, temp2;
726 int compare_result_1, compare_result_2, compare_result_3;
727
728 temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
729 temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
730
731 tu->new_valid_boundary_link = drm_fixp2int_ceil(temp2_fp);
732
733 temp = (tu->i_upper_boundary_count *
734 tu->new_valid_boundary_link +
735 tu->i_lower_boundary_count *
736 (tu->new_valid_boundary_link-1));
737 tu->average_valid2_fp = drm_fixp_from_fraction(temp,
738 (tu->i_upper_boundary_count +
739 tu->i_lower_boundary_count));
740
741 temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
742 temp2_fp = tu->lwidth_fp;
743 temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
744 temp2_fp = drm_fixp_div(temp1_fp, tu->average_valid2_fp);
745 tu->n_tus = drm_fixp2int(temp2_fp);
746 if ((temp2_fp & 0xFFFFFFFF) > 0xFFFFF000)
747 tu->n_tus += 1;
748
749 temp1_fp = drm_fixp_from_fraction(tu->n_tus, 1);
750 temp2_fp = drm_fixp_mul(temp1_fp, tu->average_valid2_fp);
751 temp1_fp = drm_fixp_from_fraction(tu->n_symbols, 1);
752 temp2_fp = temp1_fp - temp2_fp;
753 temp1_fp = drm_fixp_from_fraction(tu->nlanes, 1);
754 temp2_fp = drm_fixp_div(temp2_fp, temp1_fp);
755 tu->n_remainder_symbols_per_lane_fp = temp2_fp;
756
757 temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
758 tu->last_partial_tu_fp =
759 drm_fixp_div(tu->n_remainder_symbols_per_lane_fp,
760 temp1_fp);
761
762 if (tu->n_remainder_symbols_per_lane_fp != 0)
763 tu->remainder_symbols_exist = 1;
764 else
765 tu->remainder_symbols_exist = 0;
766
767 temp1_fp = drm_fixp_from_fraction(tu->n_tus, tu->nlanes);
768 tu->n_tus_per_lane = drm_fixp2int(temp1_fp);
769
770 tu->paired_tus = (int)((tu->n_tus_per_lane) /
771 (tu->i_upper_boundary_count +
772 tu->i_lower_boundary_count));
773
774 tu->remainder_tus = tu->n_tus_per_lane - tu->paired_tus *
775 (tu->i_upper_boundary_count +
776 tu->i_lower_boundary_count);
777
778 if ((tu->remainder_tus - tu->i_upper_boundary_count) > 0) {
779 tu->remainder_tus_upper = tu->i_upper_boundary_count;
780 tu->remainder_tus_lower = tu->remainder_tus -
781 tu->i_upper_boundary_count;
782 } else {
783 tu->remainder_tus_upper = tu->remainder_tus;
784 tu->remainder_tus_lower = 0;
785 }
786
787 temp = tu->paired_tus * (tu->i_upper_boundary_count *
788 tu->new_valid_boundary_link +
789 tu->i_lower_boundary_count *
790 (tu->new_valid_boundary_link - 1)) +
791 (tu->remainder_tus_upper *
792 tu->new_valid_boundary_link) +
793 (tu->remainder_tus_lower *
794 (tu->new_valid_boundary_link - 1));
795 tu->total_valid_fp = drm_fixp_from_fraction(temp, 1);
796
797 if (tu->remainder_symbols_exist) {
798 temp1_fp = tu->total_valid_fp +
799 tu->n_remainder_symbols_per_lane_fp;
800 temp2_fp = drm_fixp_from_fraction(tu->n_tus_per_lane, 1);
801 temp2_fp = temp2_fp + tu->last_partial_tu_fp;
802 temp1_fp = drm_fixp_div(temp1_fp, temp2_fp);
803 } else {
804 temp2_fp = drm_fixp_from_fraction(tu->n_tus_per_lane, 1);
805 temp1_fp = drm_fixp_div(tu->total_valid_fp, temp2_fp);
806 }
807 tu->effective_valid_fp = temp1_fp;
808
809 temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
810 temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
811 tu->n_n_err_fp = tu->effective_valid_fp - temp2_fp;
812
813 temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
814 temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
815 tu->n_err_fp = tu->average_valid2_fp - temp2_fp;
816
817 tu->even_distribution = tu->n_tus % tu->nlanes == 0 ? 1 : 0;
818
819 temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
820 temp2_fp = tu->lwidth_fp;
821 temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
822 temp2_fp = drm_fixp_div(temp1_fp, tu->average_valid2_fp);
823
824 if (temp2_fp)
825 tu->n_tus_incl_last_incomplete_tu = drm_fixp2int_ceil(temp2_fp);
826 else
827 tu->n_tus_incl_last_incomplete_tu = 0;
828
829 temp1 = 0;
830 temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
831 temp2_fp = drm_fixp_mul(tu->original_ratio_fp, temp1_fp);
832 temp1_fp = tu->average_valid2_fp - temp2_fp;
833 temp2_fp = drm_fixp_from_fraction(tu->n_tus_incl_last_incomplete_tu, 1);
834 temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
835
836 if (temp1_fp)
837 temp1 = drm_fixp2int_ceil(temp1_fp);
838
839 temp = tu->i_upper_boundary_count * tu->nlanes;
840 temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
841 temp2_fp = drm_fixp_mul(tu->original_ratio_fp, temp1_fp);
842 temp1_fp = drm_fixp_from_fraction(tu->new_valid_boundary_link, 1);
843 temp2_fp = temp1_fp - temp2_fp;
844 temp1_fp = drm_fixp_from_fraction(temp, 1);
845 temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp);
846
847 if (temp2_fp)
848 temp2 = drm_fixp2int_ceil(temp2_fp);
849 else
850 temp2 = 0;
851 tu->extra_required_bytes_new_tmp = (int)(temp1 + temp2);
852
853 temp1_fp = drm_fixp_from_fraction(8, tu->bpp);
854 temp2_fp = drm_fixp_from_fraction(
855 tu->extra_required_bytes_new_tmp, 1);
856 temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
857
858 if (temp1_fp)
859 tu->extra_pclk_cycles_tmp = drm_fixp2int_ceil(temp1_fp);
860 else
861 tu->extra_pclk_cycles_tmp = 0;
862
863 temp1_fp = drm_fixp_from_fraction(tu->extra_pclk_cycles_tmp, 1);
864 temp2_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp);
865 temp1_fp = drm_fixp_mul(temp1_fp, temp2_fp);
866
867 if (temp1_fp)
868 tu->extra_pclk_cycles_in_link_clk_tmp =
869 drm_fixp2int_ceil(temp1_fp);
870 else
871 tu->extra_pclk_cycles_in_link_clk_tmp = 0;
872
873 tu->filler_size_tmp = tu->tu_size - tu->new_valid_boundary_link;
874
875 tu->lower_filler_size_tmp = tu->filler_size_tmp + 1;
876
877 tu->delay_start_link_tmp = tu->extra_pclk_cycles_in_link_clk_tmp +
878 tu->lower_filler_size_tmp +
879 tu->extra_buffer_margin;
880
881 temp1_fp = drm_fixp_from_fraction(tu->delay_start_link_tmp, 1);
882 tu->delay_start_time_fp = drm_fixp_div(temp1_fp, tu->lclk_fp);
883
884 compare_result_1 = _tu_param_compare(tu->n_n_err_fp, tu->diff_abs_fp);
885 if (compare_result_1 == 2)
886 compare_result_1 = 1;
887 else
888 compare_result_1 = 0;
889
890 compare_result_2 = _tu_param_compare(tu->n_n_err_fp, tu->err_fp);
891 if (compare_result_2 == 2)
892 compare_result_2 = 1;
893 else
894 compare_result_2 = 0;
895
896 compare_result_3 = _tu_param_compare(tu->hbp_time_fp,
897 tu->delay_start_time_fp);
898 if (compare_result_3 == 2)
899 compare_result_3 = 0;
900 else
901 compare_result_3 = 1;
902
903 if (((tu->even_distribution == 1) ||
904 ((tu->even_distribution_BF == 0) &&
905 (tu->even_distribution_legacy == 0))) &&
906 tu->n_err_fp >= 0 && tu->n_n_err_fp >= 0 &&
907 compare_result_2 &&
908 (compare_result_1 || (tu->min_hblank_violated == 1)) &&
909 (tu->new_valid_boundary_link - 1) > 0 &&
910 compare_result_3 &&
911 (tu->delay_start_link_tmp <= 1023)) {
912 tu->upper_boundary_count = tu->i_upper_boundary_count;
913 tu->lower_boundary_count = tu->i_lower_boundary_count;
914 tu->err_fp = tu->n_n_err_fp;
915 tu->boundary_moderation_en = true;
916 tu->tu_size_desired = tu->tu_size;
917 tu->valid_boundary_link = tu->new_valid_boundary_link;
918 tu->effective_valid_recorded_fp = tu->effective_valid_fp;
919 tu->even_distribution_BF = 1;
920 tu->delay_start_link = tu->delay_start_link_tmp;
921 } else if (tu->boundary_mod_lower_err == 0) {
922 compare_result_1 = _tu_param_compare(tu->n_n_err_fp,
923 tu->diff_abs_fp);
924 if (compare_result_1 == 2)
925 tu->boundary_mod_lower_err = 1;
926 }
927 }
928
_dp_ctrl_calc_tu(struct msm_dp_ctrl_private * ctrl,struct msm_dp_tu_calc_input * in,struct msm_dp_vc_tu_mapping_table * tu_table)929 static void _dp_ctrl_calc_tu(struct msm_dp_ctrl_private *ctrl,
930 struct msm_dp_tu_calc_input *in,
931 struct msm_dp_vc_tu_mapping_table *tu_table)
932 {
933 struct tu_algo_data *tu;
934 int compare_result_1, compare_result_2;
935 u64 temp = 0;
936 s64 temp_fp = 0, temp1_fp = 0, temp2_fp = 0;
937
938 s64 LCLK_FAST_SKEW_fp = drm_fixp_from_fraction(6, 10000); /* 0.0006 */
939 s64 const_p49_fp = drm_fixp_from_fraction(49, 100); /* 0.49 */
940 s64 const_p56_fp = drm_fixp_from_fraction(56, 100); /* 0.56 */
941 s64 RATIO_SCALE_fp = drm_fixp_from_fraction(1001, 1000);
942
943 u8 DP_BRUTE_FORCE = 1;
944 s64 BRUTE_FORCE_THRESHOLD_fp = drm_fixp_from_fraction(1, 10); /* 0.1 */
945 uint EXTRA_PIXCLK_CYCLE_DELAY = 4;
946 uint HBLANK_MARGIN = 4;
947
948 tu = kzalloc_obj(*tu);
949 if (!tu)
950 return;
951
952 msm_dp_panel_update_tu_timings(in, tu);
953
954 tu->err_fp = drm_fixp_from_fraction(1000, 1); /* 1000 */
955
956 temp1_fp = drm_fixp_from_fraction(4, 1);
957 temp2_fp = drm_fixp_mul(temp1_fp, tu->lclk_fp);
958 temp_fp = drm_fixp_div(temp2_fp, tu->pclk_fp);
959 tu->extra_buffer_margin = drm_fixp2int_ceil(temp_fp);
960
961 temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
962 temp2_fp = drm_fixp_mul(tu->pclk_fp, temp1_fp);
963 temp1_fp = drm_fixp_from_fraction(tu->nlanes, 1);
964 temp2_fp = drm_fixp_div(temp2_fp, temp1_fp);
965 tu->ratio_fp = drm_fixp_div(temp2_fp, tu->lclk_fp);
966
967 tu->original_ratio_fp = tu->ratio_fp;
968 tu->boundary_moderation_en = false;
969 tu->upper_boundary_count = 0;
970 tu->lower_boundary_count = 0;
971 tu->i_upper_boundary_count = 0;
972 tu->i_lower_boundary_count = 0;
973 tu->valid_lower_boundary_link = 0;
974 tu->even_distribution_BF = 0;
975 tu->even_distribution_legacy = 0;
976 tu->even_distribution = 0;
977 tu->delay_start_time_fp = 0;
978
979 tu->err_fp = drm_fixp_from_fraction(1000, 1);
980 tu->n_err_fp = 0;
981 tu->n_n_err_fp = 0;
982
983 tu->ratio = drm_fixp2int(tu->ratio_fp);
984 temp1_fp = drm_fixp_from_fraction(tu->nlanes, 1);
985 div64_u64_rem(tu->lwidth_fp, temp1_fp, &temp2_fp);
986 if (temp2_fp != 0 &&
987 !tu->ratio && tu->dsc_en == 0) {
988 tu->ratio_fp = drm_fixp_mul(tu->ratio_fp, RATIO_SCALE_fp);
989 tu->ratio = drm_fixp2int(tu->ratio_fp);
990 if (tu->ratio)
991 tu->ratio_fp = drm_fixp_from_fraction(1, 1);
992 }
993
994 if (tu->ratio > 1)
995 tu->ratio = 1;
996
997 if (tu->ratio == 1)
998 goto tu_size_calc;
999
1000 compare_result_1 = _tu_param_compare(tu->ratio_fp, const_p49_fp);
1001 if (!compare_result_1 || compare_result_1 == 1)
1002 compare_result_1 = 1;
1003 else
1004 compare_result_1 = 0;
1005
1006 compare_result_2 = _tu_param_compare(tu->ratio_fp, const_p56_fp);
1007 if (!compare_result_2 || compare_result_2 == 2)
1008 compare_result_2 = 1;
1009 else
1010 compare_result_2 = 0;
1011
1012 if (tu->dsc_en && compare_result_1 && compare_result_2) {
1013 HBLANK_MARGIN += 4;
1014 drm_dbg_dp(ctrl->drm_dev,
1015 "increase HBLANK_MARGIN to %d\n", HBLANK_MARGIN);
1016 }
1017
1018 tu_size_calc:
1019 for (tu->tu_size = 32; tu->tu_size <= 64; tu->tu_size++) {
1020 temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
1021 temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
1022 temp = drm_fixp2int_ceil(temp2_fp);
1023 temp1_fp = drm_fixp_from_fraction(temp, 1);
1024 tu->n_err_fp = temp1_fp - temp2_fp;
1025
1026 if (tu->n_err_fp < tu->err_fp) {
1027 tu->err_fp = tu->n_err_fp;
1028 tu->tu_size_desired = tu->tu_size;
1029 }
1030 }
1031
1032 tu->tu_size_minus1 = tu->tu_size_desired - 1;
1033
1034 temp1_fp = drm_fixp_from_fraction(tu->tu_size_desired, 1);
1035 temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
1036 tu->valid_boundary_link = drm_fixp2int_ceil(temp2_fp);
1037
1038 temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
1039 temp2_fp = tu->lwidth_fp;
1040 temp2_fp = drm_fixp_mul(temp2_fp, temp1_fp);
1041
1042 temp1_fp = drm_fixp_from_fraction(tu->valid_boundary_link, 1);
1043 temp2_fp = drm_fixp_div(temp2_fp, temp1_fp);
1044 tu->n_tus = drm_fixp2int(temp2_fp);
1045 if ((temp2_fp & 0xFFFFFFFF) > 0xFFFFF000)
1046 tu->n_tus += 1;
1047
1048 tu->even_distribution_legacy = tu->n_tus % tu->nlanes == 0 ? 1 : 0;
1049
1050 drm_dbg_dp(ctrl->drm_dev,
1051 "n_sym = %d, num_of_tus = %d\n",
1052 tu->valid_boundary_link, tu->n_tus);
1053
1054 temp1_fp = drm_fixp_from_fraction(tu->tu_size_desired, 1);
1055 temp2_fp = drm_fixp_mul(tu->original_ratio_fp, temp1_fp);
1056 temp1_fp = drm_fixp_from_fraction(tu->valid_boundary_link, 1);
1057 temp2_fp = temp1_fp - temp2_fp;
1058 temp1_fp = drm_fixp_from_fraction(tu->n_tus + 1, 1);
1059 temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp);
1060
1061 temp = drm_fixp2int(temp2_fp);
1062 if (temp && temp2_fp)
1063 tu->extra_bytes = drm_fixp2int_ceil(temp2_fp);
1064 else
1065 tu->extra_bytes = 0;
1066
1067 temp1_fp = drm_fixp_from_fraction(tu->extra_bytes, 1);
1068 temp2_fp = drm_fixp_from_fraction(8, tu->bpp);
1069 temp1_fp = drm_fixp_mul(temp1_fp, temp2_fp);
1070
1071 if (temp && temp1_fp)
1072 tu->extra_pclk_cycles = drm_fixp2int_ceil(temp1_fp);
1073 else
1074 tu->extra_pclk_cycles = drm_fixp2int(temp1_fp);
1075
1076 temp1_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp);
1077 temp2_fp = drm_fixp_from_fraction(tu->extra_pclk_cycles, 1);
1078 temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
1079
1080 if (temp1_fp)
1081 tu->extra_pclk_cycles_in_link_clk = drm_fixp2int_ceil(temp1_fp);
1082 else
1083 tu->extra_pclk_cycles_in_link_clk = drm_fixp2int(temp1_fp);
1084
1085 tu->filler_size = tu->tu_size_desired - tu->valid_boundary_link;
1086
1087 temp1_fp = drm_fixp_from_fraction(tu->tu_size_desired, 1);
1088 tu->ratio_by_tu_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
1089
1090 tu->delay_start_link = tu->extra_pclk_cycles_in_link_clk +
1091 tu->filler_size + tu->extra_buffer_margin;
1092
1093 tu->resulting_valid_fp =
1094 drm_fixp_from_fraction(tu->valid_boundary_link, 1);
1095
1096 temp1_fp = drm_fixp_from_fraction(tu->tu_size_desired, 1);
1097 temp2_fp = drm_fixp_div(tu->resulting_valid_fp, temp1_fp);
1098 tu->TU_ratio_err_fp = temp2_fp - tu->original_ratio_fp;
1099
1100 temp1_fp = drm_fixp_from_fraction(HBLANK_MARGIN, 1);
1101 temp1_fp = tu->hbp_relative_to_pclk_fp - temp1_fp;
1102 tu->hbp_time_fp = drm_fixp_div(temp1_fp, tu->pclk_fp);
1103
1104 temp1_fp = drm_fixp_from_fraction(tu->delay_start_link, 1);
1105 tu->delay_start_time_fp = drm_fixp_div(temp1_fp, tu->lclk_fp);
1106
1107 compare_result_1 = _tu_param_compare(tu->hbp_time_fp,
1108 tu->delay_start_time_fp);
1109 if (compare_result_1 == 2) /* if (hbp_time_fp < delay_start_time_fp) */
1110 tu->min_hblank_violated = 1;
1111
1112 tu->hactive_time_fp = drm_fixp_div(tu->lwidth_fp, tu->pclk_fp);
1113
1114 compare_result_2 = _tu_param_compare(tu->hactive_time_fp,
1115 tu->delay_start_time_fp);
1116 if (compare_result_2 == 2)
1117 tu->min_hblank_violated = 1;
1118
1119 tu->delay_start_time_fp = 0;
1120
1121 /* brute force */
1122
1123 tu->delay_start_link_extra_pixclk = EXTRA_PIXCLK_CYCLE_DELAY;
1124 tu->diff_abs_fp = tu->resulting_valid_fp - tu->ratio_by_tu_fp;
1125
1126 temp = drm_fixp2int(tu->diff_abs_fp);
1127 if (!temp && tu->diff_abs_fp <= 0xffff)
1128 tu->diff_abs_fp = 0;
1129
1130 /* if(diff_abs < 0) diff_abs *= -1 */
1131 if (tu->diff_abs_fp < 0)
1132 tu->diff_abs_fp = drm_fixp_mul(tu->diff_abs_fp, -1);
1133
1134 tu->boundary_mod_lower_err = 0;
1135 if ((tu->diff_abs_fp != 0 &&
1136 ((tu->diff_abs_fp > BRUTE_FORCE_THRESHOLD_fp) ||
1137 (tu->even_distribution_legacy == 0) ||
1138 (DP_BRUTE_FORCE == 1))) ||
1139 (tu->min_hblank_violated == 1)) {
1140 do {
1141 tu->err_fp = drm_fixp_from_fraction(1000, 1);
1142
1143 temp1_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp);
1144 temp2_fp = drm_fixp_from_fraction(
1145 tu->delay_start_link_extra_pixclk, 1);
1146 temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
1147
1148 if (temp1_fp)
1149 tu->extra_buffer_margin =
1150 drm_fixp2int_ceil(temp1_fp);
1151 else
1152 tu->extra_buffer_margin = 0;
1153
1154 temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
1155 temp1_fp = drm_fixp_mul(tu->lwidth_fp, temp1_fp);
1156
1157 if (temp1_fp)
1158 tu->n_symbols = drm_fixp2int_ceil(temp1_fp);
1159 else
1160 tu->n_symbols = 0;
1161
1162 for (tu->tu_size = 32; tu->tu_size <= 64; tu->tu_size++) {
1163 for (tu->i_upper_boundary_count = 1;
1164 tu->i_upper_boundary_count <= 15;
1165 tu->i_upper_boundary_count++) {
1166 for (tu->i_lower_boundary_count = 1;
1167 tu->i_lower_boundary_count <= 15;
1168 tu->i_lower_boundary_count++) {
1169 _tu_valid_boundary_calc(tu);
1170 }
1171 }
1172 }
1173 tu->delay_start_link_extra_pixclk--;
1174 } while (tu->boundary_moderation_en != true &&
1175 tu->boundary_mod_lower_err == 1 &&
1176 tu->delay_start_link_extra_pixclk != 0);
1177
1178 if (tu->boundary_moderation_en == true) {
1179 temp1_fp = drm_fixp_from_fraction(
1180 (tu->upper_boundary_count *
1181 tu->valid_boundary_link +
1182 tu->lower_boundary_count *
1183 (tu->valid_boundary_link - 1)), 1);
1184 temp2_fp = drm_fixp_from_fraction(
1185 (tu->upper_boundary_count +
1186 tu->lower_boundary_count), 1);
1187 tu->resulting_valid_fp =
1188 drm_fixp_div(temp1_fp, temp2_fp);
1189
1190 temp1_fp = drm_fixp_from_fraction(
1191 tu->tu_size_desired, 1);
1192 tu->ratio_by_tu_fp =
1193 drm_fixp_mul(tu->original_ratio_fp, temp1_fp);
1194
1195 tu->valid_lower_boundary_link =
1196 tu->valid_boundary_link - 1;
1197
1198 temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
1199 temp1_fp = drm_fixp_mul(tu->lwidth_fp, temp1_fp);
1200 temp2_fp = drm_fixp_div(temp1_fp,
1201 tu->resulting_valid_fp);
1202 tu->n_tus = drm_fixp2int(temp2_fp);
1203
1204 tu->tu_size_minus1 = tu->tu_size_desired - 1;
1205 tu->even_distribution_BF = 1;
1206
1207 temp1_fp =
1208 drm_fixp_from_fraction(tu->tu_size_desired, 1);
1209 temp2_fp =
1210 drm_fixp_div(tu->resulting_valid_fp, temp1_fp);
1211 tu->TU_ratio_err_fp = temp2_fp - tu->original_ratio_fp;
1212 }
1213 }
1214
1215 temp2_fp = drm_fixp_mul(LCLK_FAST_SKEW_fp, tu->lwidth_fp);
1216
1217 if (temp2_fp)
1218 temp = drm_fixp2int_ceil(temp2_fp);
1219 else
1220 temp = 0;
1221
1222 temp1_fp = drm_fixp_from_fraction(tu->nlanes, 1);
1223 temp2_fp = drm_fixp_mul(tu->original_ratio_fp, temp1_fp);
1224 temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
1225 temp2_fp = drm_fixp_div(temp1_fp, temp2_fp);
1226 temp1_fp = drm_fixp_from_fraction(temp, 1);
1227 temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp);
1228 temp = drm_fixp2int(temp2_fp);
1229
1230 if (tu->async_en)
1231 tu->delay_start_link += (int)temp;
1232
1233 temp1_fp = drm_fixp_from_fraction(tu->delay_start_link, 1);
1234 tu->delay_start_time_fp = drm_fixp_div(temp1_fp, tu->lclk_fp);
1235
1236 /* OUTPUTS */
1237 tu_table->valid_boundary_link = tu->valid_boundary_link;
1238 tu_table->delay_start_link = tu->delay_start_link;
1239 tu_table->boundary_moderation_en = tu->boundary_moderation_en;
1240 tu_table->valid_lower_boundary_link = tu->valid_lower_boundary_link;
1241 tu_table->upper_boundary_count = tu->upper_boundary_count;
1242 tu_table->lower_boundary_count = tu->lower_boundary_count;
1243 tu_table->tu_size_minus1 = tu->tu_size_minus1;
1244
1245 drm_dbg_dp(ctrl->drm_dev, "TU: valid_boundary_link: %d\n",
1246 tu_table->valid_boundary_link);
1247 drm_dbg_dp(ctrl->drm_dev, "TU: delay_start_link: %d\n",
1248 tu_table->delay_start_link);
1249 drm_dbg_dp(ctrl->drm_dev, "TU: boundary_moderation_en: %d\n",
1250 tu_table->boundary_moderation_en);
1251 drm_dbg_dp(ctrl->drm_dev, "TU: valid_lower_boundary_link: %d\n",
1252 tu_table->valid_lower_boundary_link);
1253 drm_dbg_dp(ctrl->drm_dev, "TU: upper_boundary_count: %d\n",
1254 tu_table->upper_boundary_count);
1255 drm_dbg_dp(ctrl->drm_dev, "TU: lower_boundary_count: %d\n",
1256 tu_table->lower_boundary_count);
1257 drm_dbg_dp(ctrl->drm_dev, "TU: tu_size_minus1: %d\n",
1258 tu_table->tu_size_minus1);
1259
1260 kfree(tu);
1261 }
1262
msm_dp_ctrl_calc_tu_parameters(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel,struct msm_dp_vc_tu_mapping_table * tu_table)1263 static void msm_dp_ctrl_calc_tu_parameters(struct msm_dp_ctrl_private *ctrl,
1264 struct msm_dp_panel *panel,
1265 struct msm_dp_vc_tu_mapping_table *tu_table)
1266 {
1267 struct msm_dp_tu_calc_input in;
1268 const struct drm_display_mode *drm_mode;
1269
1270 drm_mode = &panel->msm_dp_mode.drm_mode;
1271
1272 in.lclk = ctrl->link->link_params.rate / 1000;
1273 in.pclk_khz = drm_mode->clock;
1274 in.hactive = drm_mode->hdisplay;
1275 in.hporch = drm_mode->htotal - drm_mode->hdisplay;
1276 in.nlanes = ctrl->link->link_params.num_lanes;
1277 in.bpp = panel->msm_dp_mode.bpp;
1278 in.pixel_enc = panel->msm_dp_mode.out_fmt_is_yuv_420 ? 420 : 444;
1279 in.dsc_en = 0;
1280 in.async_en = 0;
1281 in.fec_en = 0;
1282 in.num_of_dsc_slices = 0;
1283 in.compress_ratio = 100;
1284
1285 _dp_ctrl_calc_tu(ctrl, &in, tu_table);
1286 }
1287
msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel)1288 static void msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private *ctrl,
1289 struct msm_dp_panel *panel)
1290 {
1291 u32 msm_dp_tu = 0x0;
1292 u32 valid_boundary = 0x0;
1293 u32 valid_boundary2 = 0x0;
1294 struct msm_dp_vc_tu_mapping_table tu_calc_table;
1295
1296 msm_dp_ctrl_calc_tu_parameters(ctrl, panel, &tu_calc_table);
1297
1298 msm_dp_tu |= tu_calc_table.tu_size_minus1;
1299 valid_boundary |= tu_calc_table.valid_boundary_link;
1300 valid_boundary |= (tu_calc_table.delay_start_link << 16);
1301
1302 valid_boundary2 |= (tu_calc_table.valid_lower_boundary_link << 1);
1303 valid_boundary2 |= (tu_calc_table.upper_boundary_count << 16);
1304 valid_boundary2 |= (tu_calc_table.lower_boundary_count << 20);
1305
1306 if (tu_calc_table.boundary_moderation_en)
1307 valid_boundary2 |= BIT(0);
1308
1309 pr_debug("dp_tu=0x%x, valid_boundary=0x%x, valid_boundary2=0x%x\n",
1310 msm_dp_tu, valid_boundary, valid_boundary2);
1311
1312 msm_dp_write_link(ctrl, REG_DP_VALID_BOUNDARY, valid_boundary);
1313 msm_dp_write_link(ctrl, REG_DP_TU, msm_dp_tu);
1314 msm_dp_write_link(ctrl, REG_DP_VALID_BOUNDARY_2, valid_boundary2);
1315 }
1316
msm_dp_ctrl_wait4video_ready(struct msm_dp_ctrl_private * ctrl)1317 static int msm_dp_ctrl_wait4video_ready(struct msm_dp_ctrl_private *ctrl)
1318 {
1319 int ret = 0;
1320
1321 if (!wait_for_completion_timeout(&ctrl->video_comp,
1322 WAIT_FOR_VIDEO_READY_TIMEOUT_JIFFIES)) {
1323 DRM_ERROR("wait4video timedout\n");
1324 ret = -ETIMEDOUT;
1325 }
1326 return ret;
1327 }
1328
msm_dp_ctrl_set_vx_px(struct msm_dp_ctrl_private * ctrl,u8 v_level,u8 p_level)1329 static int msm_dp_ctrl_set_vx_px(struct msm_dp_ctrl_private *ctrl,
1330 u8 v_level, u8 p_level)
1331 {
1332 union phy_configure_opts *phy_opts = &ctrl->phy_opts;
1333
1334 /* TODO: Update for all lanes instead of just first one */
1335 phy_opts->dp.voltage[0] = v_level;
1336 phy_opts->dp.pre[0] = p_level;
1337 phy_opts->dp.set_voltages = 1;
1338 phy_configure(ctrl->phy, phy_opts);
1339 phy_opts->dp.set_voltages = 0;
1340
1341 return 0;
1342 }
1343
msm_dp_ctrl_update_phy_vx_px(struct msm_dp_ctrl_private * ctrl,enum drm_dp_phy dp_phy)1344 static int msm_dp_ctrl_update_phy_vx_px(struct msm_dp_ctrl_private *ctrl,
1345 enum drm_dp_phy dp_phy)
1346 {
1347 struct msm_dp_link *link = ctrl->link;
1348 int lane, lane_cnt, reg;
1349 int ret = 0;
1350 u8 buf[4];
1351 u32 max_level_reached = 0;
1352 u32 voltage_swing_level = link->phy_params.v_level;
1353 u32 pre_emphasis_level = link->phy_params.p_level;
1354
1355 drm_dbg_dp(ctrl->drm_dev,
1356 "voltage level: %d emphasis level: %d\n",
1357 voltage_swing_level, pre_emphasis_level);
1358 ret = msm_dp_ctrl_set_vx_px(ctrl,
1359 voltage_swing_level, pre_emphasis_level);
1360
1361 if (ret)
1362 return ret;
1363
1364 if (voltage_swing_level >= DP_TRAIN_LEVEL_MAX) {
1365 drm_dbg_dp(ctrl->drm_dev,
1366 "max. voltage swing level reached %d\n",
1367 voltage_swing_level);
1368 max_level_reached |= DP_TRAIN_MAX_SWING_REACHED;
1369 }
1370
1371 if (pre_emphasis_level >= DP_TRAIN_LEVEL_MAX) {
1372 drm_dbg_dp(ctrl->drm_dev,
1373 "max. pre-emphasis level reached %d\n",
1374 pre_emphasis_level);
1375 max_level_reached |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
1376 }
1377
1378 pre_emphasis_level <<= DP_TRAIN_PRE_EMPHASIS_SHIFT;
1379
1380 lane_cnt = ctrl->link->link_params.num_lanes;
1381 for (lane = 0; lane < lane_cnt; lane++)
1382 buf[lane] = voltage_swing_level | pre_emphasis_level
1383 | max_level_reached;
1384
1385 drm_dbg_dp(ctrl->drm_dev, "sink: p|v=0x%x\n",
1386 voltage_swing_level | pre_emphasis_level);
1387
1388 if (dp_phy == DP_PHY_DPRX)
1389 reg = DP_TRAINING_LANE0_SET;
1390 else
1391 reg = DP_TRAINING_LANE0_SET_PHY_REPEATER(dp_phy);
1392
1393 ret = drm_dp_dpcd_write(ctrl->aux, reg, buf, lane_cnt);
1394 if (ret == lane_cnt)
1395 ret = 0;
1396
1397 return ret;
1398 }
1399
msm_dp_ctrl_train_pattern_set(struct msm_dp_ctrl_private * ctrl,u8 pattern,enum drm_dp_phy dp_phy)1400 static bool msm_dp_ctrl_train_pattern_set(struct msm_dp_ctrl_private *ctrl,
1401 u8 pattern, enum drm_dp_phy dp_phy)
1402 {
1403 u8 buf;
1404 int reg;
1405 int ret = 0;
1406
1407 drm_dbg_dp(ctrl->drm_dev, "sink: pattern=%x\n", pattern);
1408
1409 buf = pattern;
1410
1411 if (pattern && pattern != DP_TRAINING_PATTERN_4)
1412 buf |= DP_LINK_SCRAMBLING_DISABLE;
1413
1414 if (dp_phy == DP_PHY_DPRX)
1415 reg = DP_TRAINING_PATTERN_SET;
1416 else
1417 reg = DP_TRAINING_PATTERN_SET_PHY_REPEATER(dp_phy);
1418
1419 ret = drm_dp_dpcd_writeb(ctrl->aux, reg, buf);
1420 return ret == 1;
1421 }
1422
msm_dp_ctrl_set_pattern_state_bit(struct msm_dp_ctrl_private * ctrl,u32 state_bit)1423 static int msm_dp_ctrl_set_pattern_state_bit(struct msm_dp_ctrl_private *ctrl,
1424 u32 state_bit)
1425 {
1426 int bit, ret;
1427 u32 data;
1428
1429 bit = BIT(state_bit - 1);
1430 drm_dbg_dp(ctrl->drm_dev, "hw: bit=%d train=%d\n", bit, state_bit);
1431 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, bit);
1432
1433 bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT;
1434
1435 /* Poll for mainlink ready status */
1436 ret = readx_poll_timeout(readl, ctrl->link_base + REG_DP_MAINLINK_READY,
1437 data, data & bit,
1438 POLLING_SLEEP_US, POLLING_TIMEOUT_US);
1439 if (ret < 0) {
1440 DRM_ERROR("set state_bit for link_train=%d failed\n", state_bit);
1441 return ret;
1442 }
1443
1444 return 0;
1445 }
1446
msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel,int * training_step,enum drm_dp_phy dp_phy)1447 static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
1448 struct msm_dp_panel *panel,
1449 int *training_step, enum drm_dp_phy dp_phy)
1450 {
1451 int delay_us;
1452 int tries, old_v_level, ret = 0;
1453 u8 link_status[DP_LINK_STATUS_SIZE];
1454 int const maximum_retries = 4;
1455
1456 delay_us = drm_dp_read_clock_recovery_delay(ctrl->aux,
1457 panel->dpcd, dp_phy, false);
1458
1459 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
1460
1461 *training_step = DP_TRAINING_1;
1462
1463 ret = msm_dp_ctrl_set_pattern_state_bit(ctrl, 1);
1464 if (ret)
1465 return ret;
1466 msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 |
1467 DP_LINK_SCRAMBLING_DISABLE, dp_phy);
1468
1469 msm_dp_link_reset_phy_params_vx_px(ctrl->link);
1470 ret = msm_dp_ctrl_update_phy_vx_px(ctrl, dp_phy);
1471 if (ret)
1472 return ret;
1473
1474 tries = 0;
1475 old_v_level = ctrl->link->phy_params.v_level;
1476 for (tries = 0; tries < maximum_retries; tries++) {
1477 fsleep(delay_us);
1478
1479 ret = drm_dp_dpcd_read_phy_link_status(ctrl->aux, dp_phy, link_status);
1480 if (ret)
1481 return ret;
1482
1483 if (drm_dp_clock_recovery_ok(link_status,
1484 ctrl->link->link_params.num_lanes)) {
1485 return 0;
1486 }
1487
1488 if (ctrl->link->phy_params.v_level >=
1489 DP_TRAIN_LEVEL_MAX) {
1490 DRM_ERROR_RATELIMITED("max v_level reached\n");
1491 return -EAGAIN;
1492 }
1493
1494 if (old_v_level != ctrl->link->phy_params.v_level) {
1495 tries = 0;
1496 old_v_level = ctrl->link->phy_params.v_level;
1497 }
1498
1499 msm_dp_link_adjust_levels(ctrl->link, link_status);
1500 ret = msm_dp_ctrl_update_phy_vx_px(ctrl, dp_phy);
1501 if (ret)
1502 return ret;
1503 }
1504
1505 DRM_ERROR("max tries reached\n");
1506 return -ETIMEDOUT;
1507 }
1508
msm_dp_ctrl_link_rate_down_shift(struct msm_dp_ctrl_private * ctrl)1509 static int msm_dp_ctrl_link_rate_down_shift(struct msm_dp_ctrl_private *ctrl)
1510 {
1511 int ret = 0;
1512 struct msm_dp_link_info *link_params = &ctrl->link->link_params;
1513
1514 if (link_params->rate_set) {
1515 --link_params->rate_set;
1516 link_params->rate = link_params->supported_rates[link_params->rate_set];
1517 } else {
1518 switch (link_params->rate) {
1519 case 810000:
1520 link_params->rate = 540000;
1521 break;
1522 case 540000:
1523 link_params->rate = 270000;
1524 break;
1525 case 270000:
1526 link_params->rate = 162000;
1527 break;
1528 case 162000:
1529 default:
1530 ret = -EINVAL;
1531 break;
1532 }
1533 }
1534
1535 if (!ret) {
1536 drm_dbg_dp(ctrl->drm_dev, "new rate=0x%x\n",
1537 link_params->rate);
1538 }
1539
1540 return ret;
1541 }
1542
msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel)1543 static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl,
1544 struct msm_dp_panel *panel)
1545 {
1546
1547 if (ctrl->link->link_params.num_lanes == 1)
1548 return -1;
1549
1550 ctrl->link->link_params.num_lanes /= 2;
1551 ctrl->link->link_params.rate = panel->link_info.rate;
1552
1553 ctrl->link->phy_params.p_level = 0;
1554 ctrl->link->phy_params.v_level = 0;
1555
1556 return 0;
1557 }
1558
msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel,enum drm_dp_phy dp_phy)1559 static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl,
1560 struct msm_dp_panel *panel,
1561 enum drm_dp_phy dp_phy)
1562 {
1563 int delay_us;
1564
1565 msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE, dp_phy);
1566
1567 delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,
1568 panel->dpcd, dp_phy, false);
1569 fsleep(delay_us);
1570 }
1571
msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel,int * training_step,enum drm_dp_phy dp_phy)1572 static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
1573 struct msm_dp_panel *panel,
1574 int *training_step, enum drm_dp_phy dp_phy)
1575 {
1576 int delay_us;
1577 int tries = 0, ret = 0;
1578 u8 pattern;
1579 u32 state_ctrl_bit;
1580 int const maximum_retries = 5;
1581 u8 link_status[DP_LINK_STATUS_SIZE];
1582
1583 delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,
1584 panel->dpcd, dp_phy, false);
1585
1586 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
1587
1588 *training_step = DP_TRAINING_2;
1589
1590 if (drm_dp_tps4_supported(panel->dpcd)) {
1591 pattern = DP_TRAINING_PATTERN_4;
1592 state_ctrl_bit = 4;
1593 } else if (drm_dp_tps3_supported(panel->dpcd)) {
1594 pattern = DP_TRAINING_PATTERN_3;
1595 state_ctrl_bit = 3;
1596 } else {
1597 pattern = DP_TRAINING_PATTERN_2;
1598 state_ctrl_bit = 2;
1599 }
1600
1601 ret = msm_dp_ctrl_set_pattern_state_bit(ctrl, state_ctrl_bit);
1602 if (ret)
1603 return ret;
1604
1605 msm_dp_ctrl_train_pattern_set(ctrl, pattern, dp_phy);
1606
1607 for (tries = 0; tries <= maximum_retries; tries++) {
1608 fsleep(delay_us);
1609
1610 ret = drm_dp_dpcd_read_phy_link_status(ctrl->aux, dp_phy, link_status);
1611 if (ret)
1612 return ret;
1613
1614 if (drm_dp_channel_eq_ok(link_status,
1615 ctrl->link->link_params.num_lanes)) {
1616 return 0;
1617 }
1618
1619 msm_dp_link_adjust_levels(ctrl->link, link_status);
1620 ret = msm_dp_ctrl_update_phy_vx_px(ctrl, dp_phy);
1621 if (ret)
1622 return ret;
1623
1624 }
1625
1626 return -ETIMEDOUT;
1627 }
1628
msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel,int * training_step,enum drm_dp_phy dp_phy)1629 static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl,
1630 struct msm_dp_panel *panel,
1631 int *training_step, enum drm_dp_phy dp_phy)
1632 {
1633 int ret;
1634
1635 ret = msm_dp_ctrl_link_train_1(ctrl, panel, training_step, dp_phy);
1636 if (ret) {
1637 DRM_ERROR("link training #1 on phy %d failed. ret=%d\n", dp_phy, ret);
1638 return ret;
1639 }
1640 drm_dbg_dp(ctrl->drm_dev, "link training #1 on phy %d successful\n", dp_phy);
1641
1642 ret = msm_dp_ctrl_link_train_2(ctrl, panel, training_step, dp_phy);
1643 if (ret) {
1644 DRM_ERROR("link training #2 on phy %d failed. ret=%d\n", dp_phy, ret);
1645 return ret;
1646 }
1647 drm_dbg_dp(ctrl->drm_dev, "link training #2 on phy %d successful\n", dp_phy);
1648
1649 return 0;
1650 }
1651
msm_dp_ctrl_link_train(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel,int * training_step)1652 static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
1653 struct msm_dp_panel *panel,
1654 int *training_step)
1655 {
1656 int i;
1657 int ret = 0;
1658 const u8 *dpcd = panel->dpcd;
1659 u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
1660 u8 assr;
1661 struct msm_dp_link_info link_info = {0};
1662
1663 msm_dp_ctrl_config_ctrl_link(ctrl, panel);
1664 msm_dp_ctrl_config_ctrl_streams(ctrl, panel);
1665
1666 link_info.num_lanes = ctrl->link->link_params.num_lanes;
1667 link_info.rate = ctrl->link->link_params.rate;
1668 link_info.capabilities = DP_LINK_CAP_ENHANCED_FRAMING;
1669
1670 msm_dp_aux_link_configure(ctrl->aux, &link_info);
1671
1672 if (drm_dp_max_downspread(dpcd))
1673 encoding[0] |= DP_SPREAD_AMP_0_5;
1674
1675 /* config DOWNSPREAD_CTRL and MAIN_LINK_CHANNEL_CODING_SET */
1676 drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, encoding, 2);
1677
1678 if (drm_dp_alternate_scrambler_reset_cap(dpcd)) {
1679 assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE;
1680 drm_dp_dpcd_write(ctrl->aux, DP_EDP_CONFIGURATION_SET,
1681 &assr, 1);
1682 }
1683
1684 for (i = ctrl->link->lttpr_count - 1; i >= 0; i--) {
1685 enum drm_dp_phy dp_phy = DP_PHY_LTTPR(i);
1686
1687 ret = msm_dp_ctrl_link_train_1_2(ctrl, panel, training_step, dp_phy);
1688 msm_dp_ctrl_clear_training_pattern(ctrl, panel, dp_phy);
1689
1690 if (ret)
1691 break;
1692 }
1693
1694 if (ret) {
1695 DRM_ERROR("link training of LTTPR(s) failed. ret=%d\n", ret);
1696 goto end;
1697 }
1698
1699 ret = msm_dp_ctrl_link_train_1_2(ctrl, panel, training_step, DP_PHY_DPRX);
1700 if (ret) {
1701 DRM_ERROR("link training on sink failed. ret=%d\n", ret);
1702 goto end;
1703 }
1704
1705 end:
1706 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
1707
1708 return ret;
1709 }
1710
msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel,int * training_step)1711 static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl,
1712 struct msm_dp_panel *panel,
1713 int *training_step)
1714 {
1715 int ret = 0;
1716
1717 msm_dp_ctrl_mainlink_enable(ctrl);
1718
1719 if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)
1720 return ret;
1721
1722 /*
1723 * As part of previous calls, DP controller state might have
1724 * transitioned to PUSH_IDLE. In order to start transmitting
1725 * a link training pattern, we have to first do soft reset.
1726 */
1727
1728 ret = msm_dp_ctrl_link_train(ctrl, panel, training_step);
1729
1730 return ret;
1731 }
1732
msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl * msm_dp_ctrl)1733 int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl)
1734 {
1735 struct msm_dp_ctrl_private *ctrl;
1736 int ret = 0;
1737
1738 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
1739
1740 if (ctrl->core_clks_on) {
1741 drm_dbg_dp(ctrl->drm_dev, "core clks already enabled\n");
1742 return 0;
1743 }
1744
1745 ret = clk_bulk_prepare_enable(ctrl->num_core_clks, ctrl->core_clks);
1746 if (ret)
1747 return ret;
1748
1749 ctrl->core_clks_on = true;
1750
1751 drm_dbg_dp(ctrl->drm_dev, "enable core clocks \n");
1752 drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
1753 str_on_off(ctrl->stream_clks_on),
1754 str_on_off(ctrl->link_clks_on),
1755 str_on_off(ctrl->core_clks_on));
1756
1757 return 0;
1758 }
1759
msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl * msm_dp_ctrl)1760 void msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl)
1761 {
1762 struct msm_dp_ctrl_private *ctrl;
1763
1764 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
1765
1766 clk_bulk_disable_unprepare(ctrl->num_core_clks, ctrl->core_clks);
1767
1768 ctrl->core_clks_on = false;
1769
1770 drm_dbg_dp(ctrl->drm_dev, "disable core clocks \n");
1771 drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
1772 str_on_off(ctrl->stream_clks_on),
1773 str_on_off(ctrl->link_clks_on),
1774 str_on_off(ctrl->core_clks_on));
1775 }
1776
msm_dp_ctrl_link_clk_enable(struct msm_dp_ctrl * msm_dp_ctrl)1777 static int msm_dp_ctrl_link_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl)
1778 {
1779 struct msm_dp_ctrl_private *ctrl;
1780 int ret = 0;
1781
1782 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
1783
1784 if (ctrl->link_clks_on) {
1785 drm_dbg_dp(ctrl->drm_dev, "links clks already enabled\n");
1786 return 0;
1787 }
1788
1789 if (!ctrl->core_clks_on) {
1790 drm_dbg_dp(ctrl->drm_dev, "Enable core clks before link clks\n");
1791
1792 msm_dp_ctrl_core_clk_enable(msm_dp_ctrl);
1793 }
1794
1795 ret = clk_bulk_prepare_enable(ctrl->num_link_clks, ctrl->link_clks);
1796 if (ret)
1797 return ret;
1798
1799 ctrl->link_clks_on = true;
1800
1801 drm_dbg_dp(ctrl->drm_dev, "enable link clocks\n");
1802 drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
1803 str_on_off(ctrl->stream_clks_on),
1804 str_on_off(ctrl->link_clks_on),
1805 str_on_off(ctrl->core_clks_on));
1806
1807 return 0;
1808 }
1809
msm_dp_ctrl_link_clk_disable(struct msm_dp_ctrl * msm_dp_ctrl)1810 static void msm_dp_ctrl_link_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl)
1811 {
1812 struct msm_dp_ctrl_private *ctrl;
1813
1814 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
1815
1816 clk_bulk_disable_unprepare(ctrl->num_link_clks, ctrl->link_clks);
1817
1818 ctrl->link_clks_on = false;
1819
1820 drm_dbg_dp(ctrl->drm_dev, "disabled link clocks\n");
1821 drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
1822 str_on_off(ctrl->stream_clks_on),
1823 str_on_off(ctrl->link_clks_on),
1824 str_on_off(ctrl->core_clks_on));
1825 }
1826
msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel)1827 static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl,
1828 struct msm_dp_panel *panel)
1829 {
1830 int ret = 0;
1831 struct phy *phy = ctrl->phy;
1832 const u8 *dpcd = panel->dpcd;
1833
1834 ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
1835 ctrl->phy_opts.dp.link_rate = ctrl->link->link_params.rate / 100;
1836 ctrl->phy_opts.dp.ssc = drm_dp_max_downspread(dpcd);
1837
1838 phy_configure(phy, &ctrl->phy_opts);
1839 phy_power_on(phy);
1840
1841 dev_pm_opp_set_rate(ctrl->dev, ctrl->link->link_params.rate * 1000);
1842 ret = msm_dp_ctrl_link_clk_enable(&ctrl->msm_dp_ctrl);
1843 if (ret)
1844 DRM_ERROR("Unable to start link clocks. ret=%d\n", ret);
1845
1846 drm_dbg_dp(ctrl->drm_dev, "link rate=%d\n", ctrl->link->link_params.rate);
1847
1848 return ret;
1849 }
1850
msm_dp_ctrl_enable_sdp(struct msm_dp_ctrl_private * ctrl)1851 static void msm_dp_ctrl_enable_sdp(struct msm_dp_ctrl_private *ctrl)
1852 {
1853 /* trigger sdp */
1854 msm_dp_write_link(ctrl, MMSS_DP_SDP_CFG3, UPDATE_SDP);
1855 msm_dp_write_link(ctrl, MMSS_DP_SDP_CFG3, 0x0);
1856 }
1857
msm_dp_ctrl_psr_enter(struct msm_dp_ctrl_private * ctrl)1858 static void msm_dp_ctrl_psr_enter(struct msm_dp_ctrl_private *ctrl)
1859 {
1860 u32 cmd;
1861
1862 cmd = msm_dp_read_link(ctrl, REG_PSR_CMD);
1863
1864 cmd &= ~(PSR_ENTER | PSR_EXIT);
1865 cmd |= PSR_ENTER;
1866
1867 msm_dp_ctrl_enable_sdp(ctrl);
1868 msm_dp_write_link(ctrl, REG_PSR_CMD, cmd);
1869 }
1870
msm_dp_ctrl_psr_exit(struct msm_dp_ctrl_private * ctrl)1871 static void msm_dp_ctrl_psr_exit(struct msm_dp_ctrl_private *ctrl)
1872 {
1873 u32 cmd;
1874
1875 cmd = msm_dp_read_link(ctrl, REG_PSR_CMD);
1876
1877 cmd &= ~(PSR_ENTER | PSR_EXIT);
1878 cmd |= PSR_EXIT;
1879
1880 msm_dp_ctrl_enable_sdp(ctrl);
1881 msm_dp_write_link(ctrl, REG_PSR_CMD, cmd);
1882 }
1883
msm_dp_ctrl_config_psr(struct msm_dp_ctrl * msm_dp_ctrl,struct msm_dp_panel * panel)1884 void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl,
1885 struct msm_dp_panel *panel)
1886 {
1887 struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
1888 struct msm_dp_ctrl_private, msm_dp_ctrl);
1889 u32 cfg;
1890
1891 if (!panel->psr_cap.version)
1892 return;
1893
1894 /* enable PSR1 function */
1895 cfg = msm_dp_read_link(ctrl, REG_PSR_CONFIG);
1896 cfg |= PSR1_SUPPORTED;
1897 msm_dp_write_link(ctrl, REG_PSR_CONFIG, cfg);
1898
1899 msm_dp_ctrl_config_psr_interrupt(ctrl);
1900 msm_dp_ctrl_enable_sdp(ctrl);
1901
1902 cfg = DP_PSR_ENABLE;
1903 drm_dp_dpcd_write(ctrl->aux, DP_PSR_EN_CFG, &cfg, 1);
1904 }
1905
msm_dp_ctrl_set_psr(struct msm_dp_ctrl * msm_dp_ctrl,struct msm_dp_panel * panel,bool enter)1906 void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl,
1907 struct msm_dp_panel *panel, bool enter)
1908 {
1909 struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
1910 struct msm_dp_ctrl_private, msm_dp_ctrl);
1911
1912 if (!panel->psr_cap.version)
1913 return;
1914
1915 /*
1916 * When entering PSR,
1917 * 1. Send PSR enter SDP and wait for the PSR_UPDATE_INT
1918 * 2. Turn off video
1919 * 3. Disable the mainlink
1920 *
1921 * When exiting PSR,
1922 * 1. Enable the mainlink
1923 * 2. Send the PSR exit SDP
1924 */
1925 if (enter) {
1926 reinit_completion(&ctrl->psr_op_comp);
1927 msm_dp_ctrl_psr_enter(ctrl);
1928
1929 if (!wait_for_completion_timeout(&ctrl->psr_op_comp,
1930 PSR_OPERATION_COMPLETION_TIMEOUT_JIFFIES)) {
1931 DRM_ERROR("PSR_ENTRY timedout\n");
1932 msm_dp_ctrl_psr_exit(ctrl);
1933 return;
1934 }
1935
1936 msm_dp_ctrl_push_idle(msm_dp_ctrl);
1937 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
1938
1939 msm_dp_ctrl_psr_mainlink_disable(ctrl);
1940 } else {
1941 msm_dp_ctrl_psr_mainlink_enable(ctrl);
1942
1943 msm_dp_ctrl_psr_exit(ctrl);
1944 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
1945 msm_dp_ctrl_wait4video_ready(ctrl);
1946 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
1947 }
1948 }
1949
msm_dp_ctrl_phy_reset(struct msm_dp_ctrl_private * ctrl)1950 static void msm_dp_ctrl_phy_reset(struct msm_dp_ctrl_private *ctrl)
1951 {
1952 msm_dp_write_ahb(ctrl, REG_DP_PHY_CTRL,
1953 DP_PHY_CTRL_SW_RESET | DP_PHY_CTRL_SW_RESET_PLL);
1954 usleep_range(1000, 1100); /* h/w recommended delay */
1955 msm_dp_write_ahb(ctrl, REG_DP_PHY_CTRL, 0x0);
1956 }
1957
msm_dp_ctrl_phy_init(struct msm_dp_ctrl * msm_dp_ctrl)1958 void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl)
1959 {
1960 struct msm_dp_ctrl_private *ctrl;
1961 struct phy *phy;
1962
1963 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
1964 phy = ctrl->phy;
1965
1966 msm_dp_ctrl_phy_reset(ctrl);
1967 phy_init(phy);
1968 }
1969
msm_dp_ctrl_phy_exit(struct msm_dp_ctrl * msm_dp_ctrl)1970 void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl)
1971 {
1972 struct msm_dp_ctrl_private *ctrl;
1973 struct phy *phy;
1974
1975 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
1976 phy = ctrl->phy;
1977
1978 msm_dp_ctrl_phy_reset(ctrl);
1979 phy_exit(phy);
1980 }
1981
msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel)1982 static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl,
1983 struct msm_dp_panel *panel)
1984 {
1985 struct phy *phy = ctrl->phy;
1986 int ret = 0;
1987
1988 msm_dp_ctrl_mainlink_disable(ctrl);
1989 ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
1990 phy_configure(phy, &ctrl->phy_opts);
1991
1992 /*
1993 * Disable and re-enable the mainlink clock since the
1994 * link clock might have been adjusted as part of the
1995 * link maintenance.
1996 */
1997 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
1998
1999 phy_power_off(phy);
2000 /* hw recommended delay before re-enabling clocks */
2001 msleep(20);
2002
2003 ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
2004 if (ret) {
2005 DRM_ERROR("Failed to enable mainlink clks. ret=%d\n", ret);
2006 return ret;
2007 }
2008
2009 return ret;
2010 }
2011
msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel)2012 static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl,
2013 struct msm_dp_panel *panel)
2014 {
2015 struct phy *phy;
2016
2017 phy = ctrl->phy;
2018
2019 msm_dp_ctrl_mainlink_disable(ctrl);
2020
2021 msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl, panel);
2022
2023 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
2024
2025 phy_power_off(phy);
2026
2027 /* aux channel down, reinit phy */
2028 phy_exit(phy);
2029 phy_init(phy);
2030
2031 return 0;
2032 }
2033
msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel)2034 static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl,
2035 struct msm_dp_panel *panel)
2036 {
2037 int ret = 0;
2038 int training_step = DP_TRAINING_NONE;
2039
2040 msm_dp_ctrl_push_idle(&ctrl->msm_dp_ctrl);
2041
2042 ctrl->link->phy_params.p_level = 0;
2043 ctrl->link->phy_params.v_level = 0;
2044
2045 ret = msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
2046 if (ret)
2047 goto end;
2048
2049 msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
2050
2051 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
2052
2053 ret = msm_dp_ctrl_wait4video_ready(ctrl);
2054 end:
2055 return ret;
2056 }
2057
2058 #define SCRAMBLER_RESET_COUNT_VALUE 0xFC
2059
msm_dp_ctrl_send_phy_pattern(struct msm_dp_ctrl_private * ctrl,u32 pattern)2060 static void msm_dp_ctrl_send_phy_pattern(struct msm_dp_ctrl_private *ctrl,
2061 u32 pattern)
2062 {
2063 u32 value = 0x0;
2064
2065 /* Make sure to clear the current pattern before starting a new one */
2066 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0x0);
2067
2068 drm_dbg_dp(ctrl->drm_dev, "pattern: %#x\n", pattern);
2069 switch (pattern) {
2070 case DP_PHY_TEST_PATTERN_D10_2:
2071 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL,
2072 DP_STATE_CTRL_LINK_TRAINING_PATTERN1);
2073 break;
2074
2075 case DP_PHY_TEST_PATTERN_ERROR_COUNT:
2076 value &= ~(1 << 16);
2077 msm_dp_write_link(ctrl, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
2078 value);
2079 value |= SCRAMBLER_RESET_COUNT_VALUE;
2080 msm_dp_write_link(ctrl, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
2081 value);
2082 msm_dp_write_link(ctrl, REG_DP_MAINLINK_LEVELS,
2083 DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
2084 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL,
2085 DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
2086 break;
2087
2088 case DP_PHY_TEST_PATTERN_PRBS7:
2089 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL,
2090 DP_STATE_CTRL_LINK_PRBS7);
2091 break;
2092
2093 case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
2094 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL,
2095 DP_STATE_CTRL_LINK_TEST_CUSTOM_PATTERN);
2096 /* 00111110000011111000001111100000 */
2097 msm_dp_write_link(ctrl, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0,
2098 0x3E0F83E0);
2099 /* 00001111100000111110000011111000 */
2100 msm_dp_write_link(ctrl, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1,
2101 0x0F83E0F8);
2102 /* 1111100000111110 */
2103 msm_dp_write_link(ctrl, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2,
2104 0x0000F83E);
2105 break;
2106
2107 case DP_PHY_TEST_PATTERN_CP2520:
2108 value = msm_dp_read_link(ctrl, REG_DP_MAINLINK_CTRL);
2109 value &= ~DP_MAINLINK_CTRL_SW_BYPASS_SCRAMBLER;
2110 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, value);
2111
2112 value = DP_HBR2_ERM_PATTERN;
2113 msm_dp_write_link(ctrl, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
2114 value);
2115 value |= SCRAMBLER_RESET_COUNT_VALUE;
2116 msm_dp_write_link(ctrl, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
2117 value);
2118 msm_dp_write_link(ctrl, REG_DP_MAINLINK_LEVELS,
2119 DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
2120 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL,
2121 DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
2122 value = msm_dp_read_link(ctrl, REG_DP_MAINLINK_CTRL);
2123 value |= DP_MAINLINK_CTRL_ENABLE;
2124 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, value);
2125 break;
2126
2127 case DP_PHY_TEST_PATTERN_SEL_MASK:
2128 msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL,
2129 DP_MAINLINK_CTRL_ENABLE);
2130 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL,
2131 DP_STATE_CTRL_LINK_TRAINING_PATTERN4);
2132 break;
2133
2134 default:
2135 drm_dbg_dp(ctrl->drm_dev,
2136 "No valid test pattern requested: %#x\n", pattern);
2137 break;
2138 }
2139 }
2140
msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private * ctrl)2141 static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl)
2142 {
2143 bool success = false;
2144 u32 pattern_sent = 0x0;
2145 u32 pattern_requested = ctrl->link->phy_params.phy_test_pattern_sel;
2146
2147 drm_dbg_dp(ctrl->drm_dev, "request: 0x%x\n", pattern_requested);
2148
2149 if (msm_dp_ctrl_set_vx_px(ctrl,
2150 ctrl->link->phy_params.v_level,
2151 ctrl->link->phy_params.p_level)) {
2152 DRM_ERROR("Failed to set v/p levels\n");
2153 return false;
2154 }
2155 msm_dp_ctrl_send_phy_pattern(ctrl, pattern_requested);
2156 msm_dp_ctrl_update_phy_vx_px(ctrl, DP_PHY_DPRX);
2157 msm_dp_link_send_test_response(ctrl->link);
2158
2159 pattern_sent = msm_dp_read_link(ctrl, REG_DP_MAINLINK_READY);
2160
2161 switch (pattern_sent) {
2162 case MR_LINK_TRAINING1:
2163 success = (pattern_requested ==
2164 DP_PHY_TEST_PATTERN_D10_2);
2165 break;
2166 case MR_LINK_SYMBOL_ERM:
2167 success = ((pattern_requested ==
2168 DP_PHY_TEST_PATTERN_ERROR_COUNT) ||
2169 (pattern_requested ==
2170 DP_PHY_TEST_PATTERN_CP2520));
2171 break;
2172 case MR_LINK_PRBS7:
2173 success = (pattern_requested ==
2174 DP_PHY_TEST_PATTERN_PRBS7);
2175 break;
2176 case MR_LINK_CUSTOM80:
2177 success = (pattern_requested ==
2178 DP_PHY_TEST_PATTERN_80BIT_CUSTOM);
2179 break;
2180 case MR_LINK_TRAINING4:
2181 success = (pattern_requested ==
2182 DP_PHY_TEST_PATTERN_SEL_MASK);
2183 break;
2184 default:
2185 success = false;
2186 }
2187
2188 drm_dbg_dp(ctrl->drm_dev, "%s: test->0x%x\n",
2189 success ? "success" : "failed", pattern_requested);
2190 return success;
2191 }
2192
msm_dp_ctrl_on_pixel_clk(struct msm_dp_ctrl_private * ctrl,unsigned long pixel_rate)2193 static int msm_dp_ctrl_on_pixel_clk(struct msm_dp_ctrl_private *ctrl, unsigned long pixel_rate)
2194 {
2195 int ret;
2196
2197 ret = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);
2198 if (ret) {
2199 DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
2200 return ret;
2201 }
2202
2203 if (WARN_ON_ONCE(ctrl->stream_clks_on))
2204 return 0;
2205
2206 ret = clk_prepare_enable(ctrl->pixel_clk);
2207 if (ret) {
2208 DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
2209 return ret;
2210 }
2211 ctrl->stream_clks_on = true;
2212
2213 return ret;
2214 }
2215
msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl * msm_dp_ctrl)2216 void msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl *msm_dp_ctrl)
2217 {
2218 struct msm_dp_ctrl_private *ctrl;
2219
2220 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2221
2222 if (ctrl->stream_clks_on) {
2223 clk_disable_unprepare(ctrl->pixel_clk);
2224 ctrl->stream_clks_on = false;
2225 }
2226 }
2227
msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel)2228 static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl,
2229 struct msm_dp_panel *panel)
2230 {
2231 int ret;
2232 unsigned long pixel_rate;
2233
2234 if (!ctrl->link->phy_params.phy_test_pattern_sel) {
2235 drm_dbg_dp(ctrl->drm_dev,
2236 "no test pattern selected by sink\n");
2237 return 0;
2238 }
2239
2240 /*
2241 * The global reset will need DP link related clocks to be
2242 * running. Add the global reset just before disabling the
2243 * link clocks and core clocks.
2244 */
2245 msm_dp_ctrl_off_pixel_clk(&ctrl->msm_dp_ctrl);
2246 msm_dp_ctrl_off_link(&ctrl->msm_dp_ctrl, panel);
2247
2248 ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl, panel);
2249 if (ret) {
2250 DRM_ERROR("failed to enable DP link controller\n");
2251 return ret;
2252 }
2253
2254 pixel_rate = panel->msm_dp_mode.drm_mode.clock;
2255 ret = msm_dp_ctrl_on_pixel_clk(ctrl, pixel_rate);
2256 if (ret)
2257 return ret;
2258
2259 msm_dp_ctrl_send_phy_test_pattern(ctrl);
2260
2261 return 0;
2262 }
2263
msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl * msm_dp_ctrl,struct msm_dp_panel * panel)2264 void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl,
2265 struct msm_dp_panel *panel)
2266 {
2267 struct msm_dp_ctrl_private *ctrl;
2268 u32 sink_request = 0x0;
2269
2270 if (!msm_dp_ctrl) {
2271 DRM_ERROR("invalid input\n");
2272 return;
2273 }
2274
2275 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2276 sink_request = ctrl->link->sink_request;
2277
2278 if (sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
2279 drm_dbg_dp(ctrl->drm_dev, "PHY_TEST_PATTERN request\n");
2280 if (msm_dp_ctrl_process_phy_test_request(ctrl, panel)) {
2281 DRM_ERROR("process phy_test_req failed\n");
2282 return;
2283 }
2284 }
2285
2286 if (sink_request & DP_LINK_STATUS_UPDATED) {
2287 if (msm_dp_ctrl_link_maintenance(ctrl, panel)) {
2288 DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
2289 return;
2290 }
2291 }
2292
2293 if (sink_request & DP_TEST_LINK_TRAINING) {
2294 msm_dp_link_send_test_response(ctrl->link);
2295 if (msm_dp_ctrl_link_maintenance(ctrl, panel)) {
2296 DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
2297 return;
2298 }
2299 }
2300 }
2301
msm_dp_ctrl_clock_recovery_any_ok(const u8 link_status[DP_LINK_STATUS_SIZE],int lane_count)2302 static bool msm_dp_ctrl_clock_recovery_any_ok(
2303 const u8 link_status[DP_LINK_STATUS_SIZE],
2304 int lane_count)
2305 {
2306 int reduced_cnt;
2307
2308 if (lane_count <= 1)
2309 return false;
2310
2311 /*
2312 * only interested in the lane number after reduced
2313 * lane_count = 4, then only interested in 2 lanes
2314 * lane_count = 2, then only interested in 1 lane
2315 */
2316 reduced_cnt = lane_count >> 1;
2317
2318 return drm_dp_clock_recovery_ok(link_status, reduced_cnt);
2319 }
2320
msm_dp_ctrl_channel_eq_ok(struct msm_dp_ctrl_private * ctrl)2321 static bool msm_dp_ctrl_channel_eq_ok(struct msm_dp_ctrl_private *ctrl)
2322 {
2323 u8 link_status[DP_LINK_STATUS_SIZE];
2324 int num_lanes = ctrl->link->link_params.num_lanes;
2325
2326 drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
2327
2328 return drm_dp_channel_eq_ok(link_status, num_lanes);
2329 }
2330
msm_dp_ctrl_on_link(struct msm_dp_ctrl * msm_dp_ctrl,struct msm_dp_panel * panel)2331 int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
2332 struct msm_dp_panel *panel)
2333 {
2334 int rc = 0;
2335 struct msm_dp_ctrl_private *ctrl;
2336 u32 rate;
2337 int link_train_max_retries = 5;
2338 u32 const phy_cts_pixel_clk_khz = 148500;
2339 u8 link_status[DP_LINK_STATUS_SIZE];
2340 unsigned int training_step;
2341 unsigned long pixel_rate;
2342
2343 if (!msm_dp_ctrl)
2344 return -EINVAL;
2345
2346 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2347
2348 rate = panel->link_info.rate;
2349 pixel_rate = panel->msm_dp_mode.drm_mode.clock;
2350
2351 msm_dp_ctrl_core_clk_enable(&ctrl->msm_dp_ctrl);
2352
2353 if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
2354 drm_dbg_dp(ctrl->drm_dev,
2355 "using phy test link parameters\n");
2356 if (!pixel_rate)
2357 pixel_rate = phy_cts_pixel_clk_khz;
2358 } else {
2359 ctrl->link->link_params.rate = rate;
2360 ctrl->link->link_params.num_lanes =
2361 panel->link_info.num_lanes;
2362 if (panel->msm_dp_mode.out_fmt_is_yuv_420)
2363 pixel_rate >>= 1;
2364 }
2365
2366 drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d, pixel_rate=%lu\n",
2367 ctrl->link->link_params.rate, ctrl->link->link_params.num_lanes,
2368 pixel_rate);
2369
2370 rc = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
2371 if (rc)
2372 return rc;
2373
2374 while (--link_train_max_retries) {
2375 training_step = DP_TRAINING_NONE;
2376 rc = msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
2377 if (rc == 0) {
2378 /* training completed successfully */
2379 break;
2380 } else if (training_step == DP_TRAINING_1) {
2381 /* link train_1 failed */
2382 if (!msm_dp_aux_is_link_connected(ctrl->aux))
2383 break;
2384
2385 drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
2386
2387 rc = msm_dp_ctrl_link_rate_down_shift(ctrl);
2388 if (rc < 0) { /* already in RBR = 1.6G */
2389 if (msm_dp_ctrl_clock_recovery_any_ok(link_status,
2390 ctrl->link->link_params.num_lanes)) {
2391 /*
2392 * some lanes are ready,
2393 * reduce lane number
2394 */
2395 rc = msm_dp_ctrl_link_lane_down_shift(ctrl, panel);
2396 if (rc < 0) { /* lane == 1 already */
2397 /* end with failure */
2398 break;
2399 }
2400 } else {
2401 /* end with failure */
2402 break; /* lane == 1 already */
2403 }
2404 }
2405 } else if (training_step == DP_TRAINING_2) {
2406 /* link train_2 failed */
2407 if (!msm_dp_aux_is_link_connected(ctrl->aux))
2408 break;
2409
2410 drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
2411
2412 if (!drm_dp_clock_recovery_ok(link_status,
2413 ctrl->link->link_params.num_lanes))
2414 rc = msm_dp_ctrl_link_rate_down_shift(ctrl);
2415 else
2416 rc = msm_dp_ctrl_link_lane_down_shift(ctrl, panel);
2417
2418 if (rc < 0) {
2419 /* end with failure */
2420 break; /* lane == 1 already */
2421 }
2422
2423 /* stop link training before start re training */
2424 msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
2425 }
2426
2427 rc = msm_dp_ctrl_reinitialize_mainlink(ctrl, panel);
2428 if (rc) {
2429 DRM_ERROR("Failed to reinitialize mainlink. rc=%d\n", rc);
2430 break;
2431 }
2432 }
2433
2434 if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)
2435 return rc;
2436
2437 if (rc == 0) { /* link train successfully */
2438 /*
2439 * do not stop train pattern here
2440 * stop link training at on_stream
2441 * to pass compliance test
2442 */
2443 } else {
2444 /*
2445 * link training failed
2446 * end txing train pattern here
2447 */
2448 msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
2449
2450 msm_dp_ctrl_deinitialize_mainlink(ctrl, panel);
2451 rc = -ECONNRESET;
2452 }
2453
2454 return rc;
2455 }
2456
msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private * ctrl,struct msm_dp_panel * panel)2457 static int msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private *ctrl,
2458 struct msm_dp_panel *panel)
2459 {
2460 int training_step = DP_TRAINING_NONE;
2461
2462 return msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
2463 }
2464
msm_dp_ctrl_config_msa(struct msm_dp_ctrl_private * ctrl,u32 rate,u32 stream_rate_khz,bool is_ycbcr_420)2465 static void msm_dp_ctrl_config_msa(struct msm_dp_ctrl_private *ctrl,
2466 u32 rate, u32 stream_rate_khz,
2467 bool is_ycbcr_420)
2468 {
2469 u32 pixel_m, pixel_n;
2470 u32 mvid, nvid, pixel_div, dispcc_input_rate;
2471 u32 const nvid_fixed = DP_LINK_CONSTANT_N_VALUE;
2472 u32 const link_rate_hbr2 = 540000;
2473 u32 const link_rate_hbr3 = 810000;
2474 unsigned long den, num;
2475
2476 switch (rate) {
2477 case link_rate_hbr3:
2478 pixel_div = 6;
2479 break;
2480 case link_rate_hbr2:
2481 pixel_div = 4;
2482 break;
2483 case 162000:
2484 case 270000:
2485 pixel_div = 2;
2486 break;
2487 default:
2488 /*
2489 * This cannot be reached but the compiler is not able to know
2490 * that statically so return early to avoid a possibly invalid
2491 * division.
2492 */
2493 DRM_ERROR("Invalid pixel mux divider\n");
2494 return;
2495 }
2496
2497 dispcc_input_rate = (rate * 10) / pixel_div;
2498
2499 rational_best_approximation(dispcc_input_rate, stream_rate_khz,
2500 (unsigned long)(1 << 16) - 1,
2501 (unsigned long)(1 << 16) - 1, &den, &num);
2502
2503 den = ~(den - num);
2504 den = den & 0xFFFF;
2505 pixel_m = num;
2506 pixel_n = den;
2507
2508 mvid = (pixel_m & 0xFFFF) * 5;
2509 nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
2510
2511 if (nvid < nvid_fixed) {
2512 u32 temp;
2513
2514 temp = (nvid_fixed / nvid) * nvid;
2515 mvid = (nvid_fixed / nvid) * mvid;
2516 nvid = temp;
2517 }
2518
2519 if (is_ycbcr_420)
2520 mvid /= 2;
2521
2522 if (link_rate_hbr2 == rate)
2523 nvid *= 2;
2524
2525 if (link_rate_hbr3 == rate)
2526 nvid *= 3;
2527
2528 drm_dbg_dp(ctrl->drm_dev, "mvid=0x%x, nvid=0x%x\n", mvid, nvid);
2529 msm_dp_write_link(ctrl, REG_DP_SOFTWARE_MVID, mvid);
2530 msm_dp_write_link(ctrl, REG_DP_SOFTWARE_NVID, nvid);
2531 }
2532
msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl * msm_dp_ctrl,struct msm_dp_panel * panel,bool force_link_train)2533 int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl,
2534 struct msm_dp_panel *panel,
2535 bool force_link_train)
2536 {
2537 int ret = 0;
2538 struct msm_dp_ctrl_private *ctrl;
2539
2540 if (!msm_dp_ctrl)
2541 return -EINVAL;
2542
2543 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2544
2545 drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d\n",
2546 ctrl->link->link_params.rate,
2547 ctrl->link->link_params.num_lanes);
2548
2549 drm_dbg_dp(ctrl->drm_dev,
2550 "core_clk_on=%d link_clk_on=%d stream_clk_on=%d\n",
2551 ctrl->core_clks_on, ctrl->link_clks_on, ctrl->stream_clks_on);
2552
2553 if (!ctrl->link_clks_on) { /* link clk is off */
2554 ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
2555 if (ret) {
2556 DRM_ERROR("Failed to start link clocks. ret=%d\n", ret);
2557 return ret;
2558 }
2559 }
2560
2561 if (force_link_train || !msm_dp_ctrl_channel_eq_ok(ctrl))
2562 msm_dp_ctrl_link_retrain(ctrl, panel);
2563
2564 /* stop txing train pattern to end link training */
2565 msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
2566
2567 return ret;
2568 }
2569
msm_dp_ctrl_on_stream(struct msm_dp_ctrl * msm_dp_ctrl,struct msm_dp_panel * panel)2570 int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel)
2571 {
2572 int ret = 0;
2573 bool mainlink_ready = false;
2574 struct msm_dp_ctrl_private *ctrl;
2575 unsigned long pixel_rate;
2576 unsigned long pixel_rate_orig;
2577
2578 if (!msm_dp_ctrl)
2579 return -EINVAL;
2580
2581 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2582
2583 pixel_rate_orig = panel->msm_dp_mode.drm_mode.clock;
2584 pixel_rate = pixel_rate_orig;
2585
2586 if (msm_dp_ctrl->wide_bus_en || panel->msm_dp_mode.out_fmt_is_yuv_420)
2587 pixel_rate >>= 1;
2588
2589 drm_dbg_dp(ctrl->drm_dev, "pixel_rate=%lu\n", pixel_rate);
2590
2591 ret = msm_dp_ctrl_on_pixel_clk(ctrl, pixel_rate);
2592 if (ret)
2593 return ret;
2594
2595 /*
2596 * Set up transfer unit values and set controller state to send
2597 * video.
2598 */
2599 reinit_completion(&ctrl->video_comp);
2600
2601 msm_dp_ctrl_lane_mapping(ctrl);
2602 msm_dp_setup_peripheral_flush(ctrl);
2603 msm_dp_ctrl_config_ctrl_link(ctrl, panel);
2604
2605 msm_dp_ctrl_configure_source_params(ctrl, panel);
2606
2607 msm_dp_ctrl_config_msa(ctrl,
2608 ctrl->link->link_params.rate,
2609 pixel_rate_orig,
2610 panel->msm_dp_mode.out_fmt_is_yuv_420);
2611
2612 msm_dp_panel_clear_dsc_dto(panel);
2613
2614 msm_dp_ctrl_setup_tr_unit(ctrl, panel);
2615
2616 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
2617
2618 ret = msm_dp_ctrl_wait4video_ready(ctrl);
2619 if (ret)
2620 return ret;
2621
2622 mainlink_ready = msm_dp_ctrl_mainlink_ready(ctrl);
2623 drm_dbg_dp(ctrl->drm_dev,
2624 "mainlink %s\n", mainlink_ready ? "READY" : "NOT READY");
2625
2626 return ret;
2627 }
2628
msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl * msm_dp_ctrl)2629 void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl)
2630 {
2631 struct msm_dp_ctrl_private *ctrl;
2632 struct phy *phy;
2633
2634 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2635 phy = ctrl->phy;
2636
2637 /* aux channel down, reinit phy */
2638 phy_exit(phy);
2639 phy_init(phy);
2640 }
2641
msm_dp_ctrl_off_link(struct msm_dp_ctrl * msm_dp_ctrl,struct msm_dp_panel * panel)2642 void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl,
2643 struct msm_dp_panel *panel)
2644 {
2645 struct msm_dp_ctrl_private *ctrl;
2646 struct phy *phy;
2647
2648 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2649 phy = ctrl->phy;
2650
2651 msm_dp_panel_disable_vsc_sdp(panel);
2652
2653 msm_dp_ctrl_mainlink_disable(ctrl);
2654
2655 msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl, panel);
2656
2657 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
2658
2659 phy_power_off(phy);
2660 }
2661
msm_dp_ctrl_isr(struct msm_dp_ctrl * msm_dp_ctrl,struct msm_dp_panel * panel)2662 irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl,
2663 struct msm_dp_panel *panel)
2664 {
2665 struct msm_dp_ctrl_private *ctrl;
2666 u32 isr;
2667 irqreturn_t ret = IRQ_NONE;
2668
2669 if (!msm_dp_ctrl)
2670 return IRQ_NONE;
2671
2672 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2673
2674 if (panel->psr_cap.version) {
2675 isr = msm_dp_ctrl_get_psr_interrupt(ctrl);
2676
2677 if (isr)
2678 complete(&ctrl->psr_op_comp);
2679
2680 if (isr & PSR_EXIT_INT)
2681 drm_dbg_dp(ctrl->drm_dev, "PSR exit done\n");
2682
2683 if (isr & PSR_UPDATE_INT)
2684 drm_dbg_dp(ctrl->drm_dev, "PSR frame update done\n");
2685
2686 if (isr & PSR_CAPTURE_INT)
2687 drm_dbg_dp(ctrl->drm_dev, "PSR frame capture done\n");
2688 }
2689
2690 isr = msm_dp_ctrl_get_interrupt(ctrl);
2691
2692 if (isr & DP_CTRL_INTR_READY_FOR_VIDEO) {
2693 drm_dbg_dp(ctrl->drm_dev, "dp_video_ready\n");
2694 complete(&ctrl->video_comp);
2695 ret = IRQ_HANDLED;
2696 }
2697
2698 if (isr & DP_CTRL_INTR_IDLE_PATTERN_SENT) {
2699 drm_dbg_dp(ctrl->drm_dev, "idle_patterns_sent\n");
2700 complete(&ctrl->idle_comp);
2701 ret = IRQ_HANDLED;
2702 }
2703
2704 /* DP aux isr */
2705 isr = msm_dp_ctrl_get_aux_interrupt(ctrl);
2706 if (isr)
2707 ret |= msm_dp_aux_isr(ctrl->aux, isr);
2708
2709 return ret;
2710 }
2711
2712 static const char *core_clks[] = {
2713 "core_iface",
2714 "core_aux",
2715 };
2716
2717 static const char *ctrl_clks[] = {
2718 "ctrl_link",
2719 "ctrl_link_iface",
2720 };
2721
msm_dp_ctrl_clk_init(struct msm_dp_ctrl * msm_dp_ctrl)2722 static int msm_dp_ctrl_clk_init(struct msm_dp_ctrl *msm_dp_ctrl)
2723 {
2724 struct msm_dp_ctrl_private *ctrl;
2725 struct device *dev;
2726 int i, rc;
2727
2728 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2729 dev = ctrl->dev;
2730
2731 ctrl->num_core_clks = ARRAY_SIZE(core_clks);
2732 ctrl->core_clks = devm_kcalloc(dev, ctrl->num_core_clks, sizeof(*ctrl->core_clks), GFP_KERNEL);
2733 if (!ctrl->core_clks)
2734 return -ENOMEM;
2735
2736 for (i = 0; i < ctrl->num_core_clks; i++)
2737 ctrl->core_clks[i].id = core_clks[i];
2738
2739 rc = devm_clk_bulk_get(dev, ctrl->num_core_clks, ctrl->core_clks);
2740 if (rc)
2741 return rc;
2742
2743 ctrl->num_link_clks = ARRAY_SIZE(ctrl_clks);
2744 ctrl->link_clks = devm_kcalloc(dev, ctrl->num_link_clks, sizeof(*ctrl->link_clks), GFP_KERNEL);
2745 if (!ctrl->link_clks)
2746 return -ENOMEM;
2747
2748 for (i = 0; i < ctrl->num_link_clks; i++)
2749 ctrl->link_clks[i].id = ctrl_clks[i];
2750
2751 rc = devm_clk_bulk_get(dev, ctrl->num_link_clks, ctrl->link_clks);
2752 if (rc)
2753 return rc;
2754
2755 ctrl->pixel_clk = devm_clk_get(dev, "stream_pixel");
2756 if (IS_ERR(ctrl->pixel_clk))
2757 return PTR_ERR(ctrl->pixel_clk);
2758
2759 return 0;
2760 }
2761
msm_dp_ctrl_get(struct device * dev,struct msm_dp_link * link,struct drm_dp_aux * aux,struct phy * phy,void __iomem * ahb_base,void __iomem * link_base)2762 struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link,
2763 struct drm_dp_aux *aux,
2764 struct phy *phy,
2765 void __iomem *ahb_base,
2766 void __iomem *link_base)
2767 {
2768 struct msm_dp_ctrl_private *ctrl;
2769 int ret;
2770
2771 if (!dev || !aux || !link) {
2772 DRM_ERROR("invalid input\n");
2773 return ERR_PTR(-EINVAL);
2774 }
2775
2776 ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
2777 if (!ctrl) {
2778 DRM_ERROR("Mem allocation failure\n");
2779 return ERR_PTR(-ENOMEM);
2780 }
2781
2782 ret = devm_pm_opp_set_clkname(dev, "ctrl_link");
2783 if (ret) {
2784 dev_err(dev, "invalid DP OPP table in device tree\n");
2785 /* caller do PTR_ERR(opp_table) */
2786 return (struct msm_dp_ctrl *)ERR_PTR(ret);
2787 }
2788
2789 /* OPP table is optional */
2790 ret = devm_pm_opp_of_add_table(dev);
2791 if (ret)
2792 dev_err(dev, "failed to add DP OPP table\n");
2793
2794 init_completion(&ctrl->idle_comp);
2795 init_completion(&ctrl->psr_op_comp);
2796 init_completion(&ctrl->video_comp);
2797
2798 /* in parameters */
2799 ctrl->aux = aux;
2800 ctrl->link = link;
2801 ctrl->dev = dev;
2802 ctrl->phy = phy;
2803 ctrl->ahb_base = ahb_base;
2804 ctrl->link_base = link_base;
2805
2806 ret = msm_dp_ctrl_clk_init(&ctrl->msm_dp_ctrl);
2807 if (ret) {
2808 dev_err(dev, "failed to init clocks\n");
2809 return ERR_PTR(ret);
2810 }
2811
2812 return &ctrl->msm_dp_ctrl;
2813 }
2814