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