diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp_mst.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp_mst.c | 79 |
1 files changed, 31 insertions, 48 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 772521440a9f..c3de0918ee13 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c | |||
@@ -34,6 +34,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, | |||
34 | struct intel_crtc_state *pipe_config, | 34 | struct intel_crtc_state *pipe_config, |
35 | struct drm_connector_state *conn_state) | 35 | struct drm_connector_state *conn_state) |
36 | { | 36 | { |
37 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | ||
37 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); | 38 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); |
38 | struct intel_digital_port *intel_dig_port = intel_mst->primary; | 39 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
39 | struct intel_dp *intel_dp = &intel_dig_port->dp; | 40 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
@@ -87,6 +88,12 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, | |||
87 | 88 | ||
88 | pipe_config->dp_m_n.tu = slots; | 89 | pipe_config->dp_m_n.tu = slots; |
89 | 90 | ||
91 | if (IS_GEN9_LP(dev_priv)) | ||
92 | pipe_config->lane_lat_optim_mask = | ||
93 | bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); | ||
94 | |||
95 | intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); | ||
96 | |||
90 | return true; | 97 | return true; |
91 | } | 98 | } |
92 | 99 | ||
@@ -142,7 +149,8 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder, | |||
142 | DRM_ERROR("failed to update payload %d\n", ret); | 149 | DRM_ERROR("failed to update payload %d\n", ret); |
143 | } | 150 | } |
144 | if (old_crtc_state->has_audio) | 151 | if (old_crtc_state->has_audio) |
145 | intel_audio_codec_disable(encoder); | 152 | intel_audio_codec_disable(encoder, |
153 | old_crtc_state, old_conn_state); | ||
146 | } | 154 | } |
147 | 155 | ||
148 | static void intel_mst_post_disable_dp(struct intel_encoder *encoder, | 156 | static void intel_mst_post_disable_dp(struct intel_encoder *encoder, |
@@ -172,13 +180,27 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder, | |||
172 | intel_dp->active_mst_links--; | 180 | intel_dp->active_mst_links--; |
173 | 181 | ||
174 | intel_mst->connector = NULL; | 182 | intel_mst->connector = NULL; |
175 | if (intel_dp->active_mst_links == 0) { | 183 | if (intel_dp->active_mst_links == 0) |
176 | intel_dig_port->base.post_disable(&intel_dig_port->base, | 184 | intel_dig_port->base.post_disable(&intel_dig_port->base, |
177 | NULL, NULL); | 185 | old_crtc_state, NULL); |
178 | } | 186 | |
179 | DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); | 187 | DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); |
180 | } | 188 | } |
181 | 189 | ||
190 | static void intel_mst_pre_pll_enable_dp(struct intel_encoder *encoder, | ||
191 | const struct intel_crtc_state *pipe_config, | ||
192 | const struct drm_connector_state *conn_state) | ||
193 | { | ||
194 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); | ||
195 | struct intel_digital_port *intel_dig_port = intel_mst->primary; | ||
196 | struct intel_dp *intel_dp = &intel_dig_port->dp; | ||
197 | |||
198 | if (intel_dp->active_mst_links == 0 && | ||
199 | intel_dig_port->base.pre_pll_enable) | ||
200 | intel_dig_port->base.pre_pll_enable(&intel_dig_port->base, | ||
201 | pipe_config, NULL); | ||
202 | } | ||
203 | |||
182 | static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, | 204 | static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, |
183 | const struct intel_crtc_state *pipe_config, | 205 | const struct intel_crtc_state *pipe_config, |
184 | const struct drm_connector_state *conn_state) | 206 | const struct drm_connector_state *conn_state) |
@@ -187,7 +209,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, | |||
187 | struct intel_digital_port *intel_dig_port = intel_mst->primary; | 209 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
188 | struct intel_dp *intel_dp = &intel_dig_port->dp; | 210 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
189 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 211 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
190 | enum port port = intel_dig_port->port; | 212 | enum port port = intel_dig_port->base.port; |
191 | struct intel_connector *connector = | 213 | struct intel_connector *connector = |
192 | to_intel_connector(conn_state->connector); | 214 | to_intel_connector(conn_state->connector); |
193 | int ret; | 215 | int ret; |
@@ -231,7 +253,7 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder, | |||
231 | struct intel_digital_port *intel_dig_port = intel_mst->primary; | 253 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
232 | struct intel_dp *intel_dp = &intel_dig_port->dp; | 254 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
233 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 255 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
234 | enum port port = intel_dig_port->port; | 256 | enum port port = intel_dig_port->base.port; |
235 | int ret; | 257 | int ret; |
236 | 258 | ||
237 | DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); | 259 | DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); |
@@ -265,48 +287,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, | |||
265 | { | 287 | { |
266 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); | 288 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); |
267 | struct intel_digital_port *intel_dig_port = intel_mst->primary; | 289 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
268 | struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc); | ||
269 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | ||
270 | enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; | ||
271 | u32 temp, flags = 0; | ||
272 | |||
273 | pipe_config->has_audio = | ||
274 | intel_ddi_is_audio_enabled(dev_priv, crtc); | ||
275 | |||
276 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); | ||
277 | if (temp & TRANS_DDI_PHSYNC) | ||
278 | flags |= DRM_MODE_FLAG_PHSYNC; | ||
279 | else | ||
280 | flags |= DRM_MODE_FLAG_NHSYNC; | ||
281 | if (temp & TRANS_DDI_PVSYNC) | ||
282 | flags |= DRM_MODE_FLAG_PVSYNC; | ||
283 | else | ||
284 | flags |= DRM_MODE_FLAG_NVSYNC; | ||
285 | |||
286 | switch (temp & TRANS_DDI_BPC_MASK) { | ||
287 | case TRANS_DDI_BPC_6: | ||
288 | pipe_config->pipe_bpp = 18; | ||
289 | break; | ||
290 | case TRANS_DDI_BPC_8: | ||
291 | pipe_config->pipe_bpp = 24; | ||
292 | break; | ||
293 | case TRANS_DDI_BPC_10: | ||
294 | pipe_config->pipe_bpp = 30; | ||
295 | break; | ||
296 | case TRANS_DDI_BPC_12: | ||
297 | pipe_config->pipe_bpp = 36; | ||
298 | break; | ||
299 | default: | ||
300 | break; | ||
301 | } | ||
302 | pipe_config->base.adjusted_mode.flags |= flags; | ||
303 | |||
304 | pipe_config->lane_count = | ||
305 | ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; | ||
306 | |||
307 | intel_dp_get_m_n(crtc, pipe_config); | ||
308 | 290 | ||
309 | intel_ddi_clock_get(&intel_dig_port->base, pipe_config); | 291 | intel_ddi_get_config(&intel_dig_port->base, pipe_config); |
310 | } | 292 | } |
311 | 293 | ||
312 | static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector) | 294 | static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector) |
@@ -570,13 +552,14 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum | |||
570 | 552 | ||
571 | intel_encoder->type = INTEL_OUTPUT_DP_MST; | 553 | intel_encoder->type = INTEL_OUTPUT_DP_MST; |
572 | intel_encoder->power_domain = intel_dig_port->base.power_domain; | 554 | intel_encoder->power_domain = intel_dig_port->base.power_domain; |
573 | intel_encoder->port = intel_dig_port->port; | 555 | intel_encoder->port = intel_dig_port->base.port; |
574 | intel_encoder->crtc_mask = 0x7; | 556 | intel_encoder->crtc_mask = 0x7; |
575 | intel_encoder->cloneable = 0; | 557 | intel_encoder->cloneable = 0; |
576 | 558 | ||
577 | intel_encoder->compute_config = intel_dp_mst_compute_config; | 559 | intel_encoder->compute_config = intel_dp_mst_compute_config; |
578 | intel_encoder->disable = intel_mst_disable_dp; | 560 | intel_encoder->disable = intel_mst_disable_dp; |
579 | intel_encoder->post_disable = intel_mst_post_disable_dp; | 561 | intel_encoder->post_disable = intel_mst_post_disable_dp; |
562 | intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp; | ||
580 | intel_encoder->pre_enable = intel_mst_pre_enable_dp; | 563 | intel_encoder->pre_enable = intel_mst_pre_enable_dp; |
581 | intel_encoder->enable = intel_mst_enable_dp; | 564 | intel_encoder->enable = intel_mst_enable_dp; |
582 | intel_encoder->get_hw_state = intel_dp_mst_enc_get_hw_state; | 565 | intel_encoder->get_hw_state = intel_dp_mst_enc_get_hw_state; |