]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - drivers/gpu/drm/i915/icl_dsi.c
drm/i915/icl: Define DSI transcoder timing registers
[thirdparty/kernel/stable.git] / drivers / gpu / drm / i915 / icl_dsi.c
CommitLineData
fcfe0bdc
MC
1/*
2 * Copyright © 2018 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Madhav Chauhan <madhav.chauhan@intel.com>
25 * Jani Nikula <jani.nikula@intel.com>
26 */
27
28#include "intel_dsi.h"
29
d364dc66 30static enum transcoder dsi_port_to_transcoder(enum port port)
ca8fc99f
MC
31{
32 if (port == PORT_A)
33 return TRANSCODER_DSI_0;
34 else
35 return TRANSCODER_DSI_1;
36}
37
3f4b9d9d
MC
38static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
39{
40 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
41 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
42 enum port port;
43 u32 tmp;
44 int lane;
45
46 for_each_dsi_port(port, intel_dsi->ports) {
47
48 /*
49 * Program voltage swing and pre-emphasis level values as per
50 * table in BSPEC under DDI buffer programing
51 */
52 tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port));
53 tmp &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK);
54 tmp |= SCALING_MODE_SEL(0x2);
55 tmp |= TAP2_DISABLE | TAP3_DISABLE;
56 tmp |= RTERM_SELECT(0x6);
57 I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp);
58
59 tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port));
60 tmp &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK);
61 tmp |= SCALING_MODE_SEL(0x2);
62 tmp |= TAP2_DISABLE | TAP3_DISABLE;
63 tmp |= RTERM_SELECT(0x6);
64 I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp);
65
66 tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port));
67 tmp &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
68 RCOMP_SCALAR_MASK);
69 tmp |= SWING_SEL_UPPER(0x2);
70 tmp |= SWING_SEL_LOWER(0x2);
71 tmp |= RCOMP_SCALAR(0x98);
72 I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp);
73
74 tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port));
75 tmp &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
76 RCOMP_SCALAR_MASK);
77 tmp |= SWING_SEL_UPPER(0x2);
78 tmp |= SWING_SEL_LOWER(0x2);
79 tmp |= RCOMP_SCALAR(0x98);
80 I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp);
81
82 tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port));
83 tmp &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
84 CURSOR_COEFF_MASK);
85 tmp |= POST_CURSOR_1(0x0);
86 tmp |= POST_CURSOR_2(0x0);
87 tmp |= CURSOR_COEFF(0x3f);
88 I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp);
89
90 for (lane = 0; lane <= 3; lane++) {
91 /* Bspec: must not use GRP register for write */
92 tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane));
93 tmp &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
94 CURSOR_COEFF_MASK);
95 tmp |= POST_CURSOR_1(0x0);
96 tmp |= POST_CURSOR_2(0x0);
97 tmp |= CURSOR_COEFF(0x3f);
98 I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp);
99 }
100 }
101}
102
fcfe0bdc
MC
103static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder)
104{
105 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
106 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
107 enum port port;
108 u32 bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
109 u32 afe_clk_khz; /* 8X Clock */
110 u32 esc_clk_div_m;
111
112 afe_clk_khz = DIV_ROUND_CLOSEST(intel_dsi->pclk * bpp,
113 intel_dsi->lane_count);
114
115 esc_clk_div_m = DIV_ROUND_UP(afe_clk_khz, DSI_MAX_ESC_CLK);
116
117 for_each_dsi_port(port, intel_dsi->ports) {
118 I915_WRITE(ICL_DSI_ESC_CLK_DIV(port),
119 esc_clk_div_m & ICL_ESC_CLK_DIV_MASK);
120 POSTING_READ(ICL_DSI_ESC_CLK_DIV(port));
121 }
122
123 for_each_dsi_port(port, intel_dsi->ports) {
124 I915_WRITE(ICL_DPHY_ESC_CLK_DIV(port),
125 esc_clk_div_m & ICL_ESC_CLK_DIV_MASK);
126 POSTING_READ(ICL_DPHY_ESC_CLK_DIV(port));
127 }
128}
129
b1cb21a5
MC
130static void gen11_dsi_enable_io_power(struct intel_encoder *encoder)
131{
132 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
133 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
134 enum port port;
135 u32 tmp;
136
137 for_each_dsi_port(port, intel_dsi->ports) {
138 tmp = I915_READ(ICL_DSI_IO_MODECTL(port));
139 tmp |= COMBO_PHY_MODE_DSI;
140 I915_WRITE(ICL_DSI_IO_MODECTL(port), tmp);
141 }
142
143 for_each_dsi_port(port, intel_dsi->ports) {
144 intel_display_power_get(dev_priv, port == PORT_A ?
145 POWER_DOMAIN_PORT_DDI_A_IO :
146 POWER_DOMAIN_PORT_DDI_B_IO);
147 }
148}
149
45f09f7a
MC
150static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder)
151{
152 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
153 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
154 enum port port;
155 u32 tmp;
156 u32 lane_mask;
157
158 switch (intel_dsi->lane_count) {
159 case 1:
160 lane_mask = PWR_DOWN_LN_3_1_0;
161 break;
162 case 2:
163 lane_mask = PWR_DOWN_LN_3_1;
164 break;
165 case 3:
166 lane_mask = PWR_DOWN_LN_3;
167 break;
168 case 4:
169 default:
170 lane_mask = PWR_UP_ALL_LANES;
171 break;
172 }
173
174 for_each_dsi_port(port, intel_dsi->ports) {
175 tmp = I915_READ(ICL_PORT_CL_DW10(port));
176 tmp &= ~PWR_DOWN_LN_MASK;
177 I915_WRITE(ICL_PORT_CL_DW10(port), tmp | lane_mask);
178 }
179}
180
fc41001d
MC
181static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
182{
183 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
184 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
185 enum port port;
186 u32 tmp;
187 int lane;
188
189 /* Step 4b(i) set loadgen select for transmit and aux lanes */
190 for_each_dsi_port(port, intel_dsi->ports) {
191 tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port));
192 tmp &= ~LOADGEN_SELECT;
193 I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp);
194 for (lane = 0; lane <= 3; lane++) {
195 tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane));
196 tmp &= ~LOADGEN_SELECT;
197 if (lane != 2)
198 tmp |= LOADGEN_SELECT;
199 I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp);
200 }
201 }
202
203 /* Step 4b(ii) set latency optimization for transmit and aux lanes */
204 for_each_dsi_port(port, intel_dsi->ports) {
205 tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port));
206 tmp &= ~FRC_LATENCY_OPTIM_MASK;
207 tmp |= FRC_LATENCY_OPTIM_VAL(0x5);
208 I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp);
209 tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port));
210 tmp &= ~FRC_LATENCY_OPTIM_MASK;
211 tmp |= FRC_LATENCY_OPTIM_VAL(0x5);
212 I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp);
213 }
214
215}
216
3f4b9d9d
MC
217static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder)
218{
219 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
220 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
221 u32 tmp;
222 enum port port;
223
224 /* clear common keeper enable bit */
225 for_each_dsi_port(port, intel_dsi->ports) {
226 tmp = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
227 tmp &= ~COMMON_KEEPER_EN;
228 I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), tmp);
229 tmp = I915_READ(ICL_PORT_PCS_DW1_AUX(port));
230 tmp &= ~COMMON_KEEPER_EN;
231 I915_WRITE(ICL_PORT_PCS_DW1_AUX(port), tmp);
232 }
233
234 /*
235 * Set SUS Clock Config bitfield to 11b
236 * Note: loadgen select program is done
237 * as part of lane phy sequence configuration
238 */
239 for_each_dsi_port(port, intel_dsi->ports) {
240 tmp = I915_READ(ICL_PORT_CL_DW5(port));
241 tmp |= SUS_CLOCK_CONFIG;
242 I915_WRITE(ICL_PORT_CL_DW5(port), tmp);
243 }
244
245 /* Clear training enable to change swing values */
246 for_each_dsi_port(port, intel_dsi->ports) {
247 tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port));
248 tmp &= ~TX_TRAINING_EN;
249 I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp);
250 tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port));
251 tmp &= ~TX_TRAINING_EN;
252 I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp);
253 }
254
255 /* Program swing and de-emphasis */
256 dsi_program_swing_and_deemphasis(encoder);
257
258 /* Set training enable to trigger update */
259 for_each_dsi_port(port, intel_dsi->ports) {
260 tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port));
261 tmp |= TX_TRAINING_EN;
262 I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp);
263 tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port));
264 tmp |= TX_TRAINING_EN;
265 I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp);
266 }
267}
268
ba3df888
MC
269static void gen11_dsi_enable_ddi_buffer(struct intel_encoder *encoder)
270{
271 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
272 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
273 u32 tmp;
274 enum port port;
275
276 for_each_dsi_port(port, intel_dsi->ports) {
277 tmp = I915_READ(DDI_BUF_CTL(port));
278 tmp |= DDI_BUF_CTL_ENABLE;
279 I915_WRITE(DDI_BUF_CTL(port), tmp);
280
281 if (wait_for_us(!(I915_READ(DDI_BUF_CTL(port)) &
282 DDI_BUF_IS_IDLE),
283 500))
284 DRM_ERROR("DDI port:%c buffer idle\n", port_name(port));
285 }
286}
287
70a7b836
MC
288static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder)
289{
290 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
291 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
292 u32 tmp;
293 enum port port;
294
295 /* Program T-INIT master registers */
296 for_each_dsi_port(port, intel_dsi->ports) {
297 tmp = I915_READ(ICL_DSI_T_INIT_MASTER(port));
298 tmp &= ~MASTER_INIT_TIMER_MASK;
299 tmp |= intel_dsi->init_count;
300 I915_WRITE(ICL_DSI_T_INIT_MASTER(port), tmp);
301 }
e72cce53
MC
302
303 /* Program DPHY clock lanes timings */
304 for_each_dsi_port(port, intel_dsi->ports) {
305 I915_WRITE(DPHY_CLK_TIMING_PARAM(port), intel_dsi->dphy_reg);
306
307 /* shadow register inside display core */
308 I915_WRITE(DSI_CLK_TIMING_PARAM(port), intel_dsi->dphy_reg);
309 }
310
311 /* Program DPHY data lanes timings */
312 for_each_dsi_port(port, intel_dsi->ports) {
313 I915_WRITE(DPHY_DATA_TIMING_PARAM(port),
314 intel_dsi->dphy_data_lane_reg);
315
316 /* shadow register inside display core */
317 I915_WRITE(DSI_DATA_TIMING_PARAM(port),
318 intel_dsi->dphy_data_lane_reg);
319 }
5fea8645
MC
320
321 /*
322 * If DSI link operating at or below an 800 MHz,
323 * TA_SURE should be override and programmed to
324 * a value '0' inside TA_PARAM_REGISTERS otherwise
325 * leave all fields at HW default values.
326 */
327 if (intel_dsi_bitrate(intel_dsi) <= 800000) {
328 for_each_dsi_port(port, intel_dsi->ports) {
329 tmp = I915_READ(DPHY_TA_TIMING_PARAM(port));
330 tmp &= ~TA_SURE_MASK;
331 tmp |= TA_SURE_OVERRIDE | TA_SURE(0);
332 I915_WRITE(DPHY_TA_TIMING_PARAM(port), tmp);
333
334 /* shadow register inside display core */
335 tmp = I915_READ(DSI_TA_TIMING_PARAM(port));
336 tmp &= ~TA_SURE_MASK;
337 tmp |= TA_SURE_OVERRIDE | TA_SURE(0);
338 I915_WRITE(DSI_TA_TIMING_PARAM(port), tmp);
339 }
340 }
70a7b836
MC
341}
342
70f4f502
MC
343static void
344gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
345 const struct intel_crtc_state *pipe_config)
d364dc66
MC
346{
347 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
348 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
70f4f502
MC
349 struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
350 enum pipe pipe = intel_crtc->pipe;
d364dc66
MC
351 u32 tmp;
352 enum port port;
353 enum transcoder dsi_trans;
354
355 for_each_dsi_port(port, intel_dsi->ports) {
356 dsi_trans = dsi_port_to_transcoder(port);
357 tmp = I915_READ(DSI_TRANS_FUNC_CONF(dsi_trans));
358
359 if (intel_dsi->eotp_pkt)
360 tmp &= ~EOTP_DISABLED;
361 else
362 tmp |= EOTP_DISABLED;
363
364 /* enable link calibration if freq > 1.5Gbps */
365 if (intel_dsi_bitrate(intel_dsi) >= 1500 * 1000) {
366 tmp &= ~LINK_CALIBRATION_MASK;
367 tmp |= CALIBRATION_ENABLED_INITIAL_ONLY;
368 }
369
370 /* configure continuous clock */
371 tmp &= ~CONTINUOUS_CLK_MASK;
372 if (intel_dsi->clock_stop)
373 tmp |= CLK_ENTER_LP_AFTER_DATA;
374 else
375 tmp |= CLK_HS_CONTINUOUS;
376
377 /* configure buffer threshold limit to minimum */
378 tmp &= ~PIX_BUF_THRESHOLD_MASK;
379 tmp |= PIX_BUF_THRESHOLD_1_4;
380
381 /* set virtual channel to '0' */
382 tmp &= ~PIX_VIRT_CHAN_MASK;
383 tmp |= PIX_VIRT_CHAN(0);
384
385 /* program BGR transmission */
386 if (intel_dsi->bgr_enabled)
387 tmp |= BGR_TRANSMISSION;
388
389 /* select pixel format */
390 tmp &= ~PIX_FMT_MASK;
391 switch (intel_dsi->pixel_format) {
392 default:
393 MISSING_CASE(intel_dsi->pixel_format);
394 /* fallthrough */
395 case MIPI_DSI_FMT_RGB565:
396 tmp |= PIX_FMT_RGB565;
397 break;
398 case MIPI_DSI_FMT_RGB666_PACKED:
399 tmp |= PIX_FMT_RGB666_PACKED;
400 break;
401 case MIPI_DSI_FMT_RGB666:
402 tmp |= PIX_FMT_RGB666_LOOSE;
403 break;
404 case MIPI_DSI_FMT_RGB888:
405 tmp |= PIX_FMT_RGB888;
406 break;
407 }
408
409 /* program DSI operation mode */
410 if (is_vid_mode(intel_dsi)) {
411 tmp &= ~OP_MODE_MASK;
412 switch (intel_dsi->video_mode_format) {
413 default:
414 MISSING_CASE(intel_dsi->video_mode_format);
415 /* fallthrough */
416 case VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS:
417 tmp |= VIDEO_MODE_SYNC_EVENT;
418 break;
419 case VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE:
420 tmp |= VIDEO_MODE_SYNC_PULSE;
421 break;
422 }
423 }
424
425 I915_WRITE(DSI_TRANS_FUNC_CONF(dsi_trans), tmp);
426 }
70f4f502
MC
427
428 /* enable port sync mode if dual link */
429 if (intel_dsi->dual_link) {
430 for_each_dsi_port(port, intel_dsi->ports) {
431 dsi_trans = dsi_port_to_transcoder(port);
432 tmp = I915_READ(TRANS_DDI_FUNC_CTL2(dsi_trans));
433 tmp |= PORT_SYNC_MODE_ENABLE;
434 I915_WRITE(TRANS_DDI_FUNC_CTL2(dsi_trans), tmp);
435 }
436
437 //TODO: configure DSS_CTL1
438 }
439
440 for_each_dsi_port(port, intel_dsi->ports) {
441 dsi_trans = dsi_port_to_transcoder(port);
442
443 /* select data lane width */
444 tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans));
445 tmp &= ~DDI_PORT_WIDTH_MASK;
446 tmp |= DDI_PORT_WIDTH(intel_dsi->lane_count);
447
448 /* select input pipe */
449 tmp &= ~TRANS_DDI_EDP_INPUT_MASK;
450 switch (pipe) {
451 default:
452 MISSING_CASE(pipe);
453 /* fallthrough */
454 case PIPE_A:
455 tmp |= TRANS_DDI_EDP_INPUT_A_ON;
456 break;
457 case PIPE_B:
458 tmp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
459 break;
460 case PIPE_C:
461 tmp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
462 break;
463 }
464
465 /* enable DDI buffer */
466 tmp |= TRANS_DDI_FUNC_ENABLE;
467 I915_WRITE(TRANS_DDI_FUNC_CTL(dsi_trans), tmp);
468 }
469
470 /* wait for link ready */
471 for_each_dsi_port(port, intel_dsi->ports) {
472 dsi_trans = dsi_port_to_transcoder(port);
473 if (wait_for_us((I915_READ(DSI_TRANS_FUNC_CONF(dsi_trans)) &
474 LINK_READY), 2500))
475 DRM_ERROR("DSI link not ready\n");
476 }
d364dc66
MC
477}
478
70f4f502
MC
479static void
480gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
481 const struct intel_crtc_state *pipe_config)
45f09f7a
MC
482{
483 /* step 4a: power up all lanes of the DDI used by DSI */
484 gen11_dsi_power_up_lanes(encoder);
fc41001d
MC
485
486 /* step 4b: configure lane sequencing of the Combo-PHY transmitters */
487 gen11_dsi_config_phy_lanes_sequence(encoder);
3f4b9d9d
MC
488
489 /* step 4c: configure voltage swing and skew */
490 gen11_dsi_voltage_swing_program_seq(encoder);
ba3df888
MC
491
492 /* enable DDI buffer */
493 gen11_dsi_enable_ddi_buffer(encoder);
70a7b836
MC
494
495 /* setup D-PHY timings */
496 gen11_dsi_setup_dphy_timings(encoder);
d364dc66
MC
497
498 /* Step (4h, 4i, 4j, 4k): Configure transcoder */
70f4f502 499 gen11_dsi_configure_transcoder(encoder, pipe_config);
45f09f7a
MC
500}
501
fcfe0bdc
MC
502static void __attribute__((unused))
503gen11_dsi_pre_enable(struct intel_encoder *encoder,
504 const struct intel_crtc_state *pipe_config,
505 const struct drm_connector_state *conn_state)
506{
b1cb21a5
MC
507 /* step2: enable IO power */
508 gen11_dsi_enable_io_power(encoder);
509
fcfe0bdc
MC
510 /* step3: enable DSI PLL */
511 gen11_dsi_program_esc_clk_div(encoder);
45f09f7a
MC
512
513 /* step4: enable DSI port and DPHY */
70f4f502 514 gen11_dsi_enable_port_and_phy(encoder, pipe_config);
fcfe0bdc 515}