Rev 5354 | Rev 6660 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5354 | Rev 6084 | ||
---|---|---|---|
Line 24... | Line 24... | ||
24 | */ |
24 | */ |
Line 25... | Line 25... | ||
25 | 25 | ||
26 | #include |
26 | #include |
27 | #include "i915_drv.h" |
27 | #include "i915_drv.h" |
- | 28 | #include "intel_drv.h" |
|
28 | #include "intel_drv.h" |
29 | #include |
29 | #include |
30 | #include |
Line 30... | Line 31... | ||
30 | #include |
31 | #include |
31 | 32 | ||
32 | static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, |
33 | static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, |
- | 34 | struct intel_crtc_state *pipe_config) |
|
33 | struct intel_crtc_config *pipe_config) |
35 | { |
34 | { |
36 | struct drm_device *dev = encoder->base.dev; |
35 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); |
37 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); |
36 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
38 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
37 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
39 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
38 | struct drm_device *dev = encoder->base.dev; |
40 | struct drm_atomic_state *state; |
39 | int bpp; |
41 | int bpp, i; |
- | 42 | int lane_count, slots; |
|
40 | int lane_count, slots; |
43 | const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
- | 44 | struct drm_connector *drm_connector; |
|
41 | struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; |
45 | struct intel_connector *connector, *found = NULL; |
Line 42... | Line 46... | ||
42 | struct intel_connector *found = NULL, *intel_connector; |
46 | struct drm_connector_state *connector_state; |
43 | int mst_pbn; |
47 | int mst_pbn; |
44 | 48 | ||
Line 49... | Line 53... | ||
49 | /* |
53 | /* |
50 | * for MST we always configure max link bw - the spec doesn't |
54 | * for MST we always configure max link bw - the spec doesn't |
51 | * seem to suggest we should do otherwise. |
55 | * seem to suggest we should do otherwise. |
52 | */ |
56 | */ |
53 | lane_count = drm_dp_max_lane_count(intel_dp->dpcd); |
57 | lane_count = drm_dp_max_lane_count(intel_dp->dpcd); |
54 | intel_dp->link_bw = intel_dp_max_link_bw(intel_dp); |
- | |
- | 58 | ||
- | 59 | ||
55 | intel_dp->lane_count = lane_count; |
60 | pipe_config->lane_count = lane_count; |
Line 56... | Line 61... | ||
56 | 61 | ||
57 | pipe_config->pipe_bpp = 24; |
62 | pipe_config->pipe_bpp = 24; |
- | 63 | pipe_config->port_clock = intel_dp_max_link_rate(intel_dp); |
|
- | 64 | ||
Line 58... | Line 65... | ||
58 | pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw); |
65 | state = pipe_config->base.state; |
- | 66 | ||
- | 67 | for_each_connector_in_state(state, drm_connector, connector_state, i) { |
|
59 | 68 | connector = to_intel_connector(drm_connector); |
|
60 | list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) { |
69 | |
61 | if (intel_connector->new_encoder == encoder) { |
70 | if (connector_state->best_encoder == &encoder->base) { |
62 | found = intel_connector; |
71 | found = connector; |
63 | break; |
72 | break; |
Line 64... | Line 73... | ||
64 | } |
73 | } |
65 | } |
74 | } |
66 | 75 | ||
67 | if (!found) { |
76 | if (!found) { |
Line 68... | Line 77... | ||
68 | DRM_ERROR("can't find connector\n"); |
77 | DRM_ERROR("can't find connector\n"); |
Line 69... | Line 78... | ||
69 | return false; |
78 | return false; |
70 | } |
79 | } |
Line 71... | Line 80... | ||
71 | 80 | ||
72 | mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->clock, bpp); |
81 | mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp); |
73 | 82 | ||
74 | pipe_config->pbn = mst_pbn; |
83 | pipe_config->pbn = mst_pbn; |
Line 75... | Line 84... | ||
75 | slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn); |
84 | slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn); |
- | 85 | ||
- | 86 | intel_link_compute_m_n(bpp, lane_count, |
|
- | 87 | adjusted_mode->crtc_clock, |
|
- | 88 | pipe_config->port_clock, |
|
76 | 89 | &pipe_config->dp_m_n); |
|
Line 77... | Line 90... | ||
77 | intel_link_compute_m_n(bpp, lane_count, |
90 | |
Line 78... | Line 91... | ||
78 | adjusted_mode->crtc_clock, |
91 | pipe_config->dp_m_n.tu = slots; |
Line 132... | Line 145... | ||
132 | struct drm_device *dev = encoder->base.dev; |
145 | struct drm_device *dev = encoder->base.dev; |
133 | struct drm_i915_private *dev_priv = dev->dev_private; |
146 | struct drm_i915_private *dev_priv = dev->dev_private; |
134 | enum port port = intel_dig_port->port; |
147 | enum port port = intel_dig_port->port; |
135 | int ret; |
148 | int ret; |
136 | uint32_t temp; |
149 | uint32_t temp; |
137 | struct intel_connector *found = NULL, *intel_connector; |
150 | struct intel_connector *found = NULL, *connector; |
138 | int slots; |
151 | int slots; |
139 | struct drm_crtc *crtc = encoder->base.crtc; |
152 | struct drm_crtc *crtc = encoder->base.crtc; |
140 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
153 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
Line 141... | Line 154... | ||
141 | 154 | ||
142 | list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) { |
155 | for_each_intel_connector(dev, connector) { |
143 | if (intel_connector->new_encoder == encoder) { |
156 | if (connector->base.state->best_encoder == &encoder->base) { |
144 | found = intel_connector; |
157 | found = connector; |
145 | break; |
158 | break; |
146 | } |
159 | } |
Line 147... | Line 160... | ||
147 | } |
160 | } |
148 | 161 | ||
149 | if (!found) { |
162 | if (!found) { |
150 | DRM_ERROR("can't find connector\n"); |
163 | DRM_ERROR("can't find connector\n"); |
Line -... | Line 164... | ||
- | 164 | return; |
|
- | 165 | } |
|
- | 166 | ||
- | 167 | /* MST encoders are bound to a crtc, not to a connector, |
|
- | 168 | * force the mapping here for get_hw_state. |
|
151 | return; |
169 | */ |
152 | } |
170 | found->encoder = encoder; |
Line 153... | Line 171... | ||
153 | 171 | ||
154 | DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); |
172 | DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); |
Line -... | Line 173... | ||
- | 173 | intel_mst->port = found->port; |
|
- | 174 | ||
- | 175 | if (intel_dp->active_mst_links == 0) { |
|
- | 176 | enum port port = intel_ddi_get_encoder_port(encoder); |
|
- | 177 | ||
155 | intel_mst->port = found->port; |
178 | intel_dp_set_link_params(intel_dp, intel_crtc->config); |
Line 156... | Line 179... | ||
156 | 179 | ||
Line 157... | Line 180... | ||
157 | if (intel_dp->active_mst_links == 0) { |
180 | /* FIXME: add support for SKL */ |
Line 158... | Line 181... | ||
158 | enum port port = intel_ddi_get_encoder_port(encoder); |
181 | if (INTEL_INFO(dev)->gen < 9) |
159 | - | ||
160 | I915_WRITE(PORT_CLK_SEL(port), intel_crtc->config.ddi_pll_sel); |
182 | I915_WRITE(PORT_CLK_SEL(port), |
161 | 183 | intel_crtc->config->ddi_pll_sel); |
|
Line 162... | Line 184... | ||
162 | intel_ddi_init_dp_buf_reg(&intel_dig_port->base); |
184 | |
- | 185 | intel_ddi_init_dp_buf_reg(&intel_dig_port->base); |
|
163 | 186 | ||
164 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
187 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
165 | 188 | ||
166 | 189 | ||
167 | intel_dp_start_link_train(intel_dp); |
190 | intel_dp_start_link_train(intel_dp); |
Line 214... | Line 237... | ||
214 | return true; |
237 | return true; |
215 | return false; |
238 | return false; |
216 | } |
239 | } |
Line 217... | Line 240... | ||
217 | 240 | ||
218 | static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, |
241 | static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, |
219 | struct intel_crtc_config *pipe_config) |
242 | struct intel_crtc_state *pipe_config) |
220 | { |
243 | { |
221 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); |
244 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); |
222 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
245 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
223 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
246 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
224 | struct drm_device *dev = encoder->base.dev; |
247 | struct drm_device *dev = encoder->base.dev; |
225 | struct drm_i915_private *dev_priv = dev->dev_private; |
248 | struct drm_i915_private *dev_priv = dev->dev_private; |
226 | enum transcoder cpu_transcoder = crtc->config.cpu_transcoder; |
249 | enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; |
Line 227... | Line 250... | ||
227 | u32 temp, flags = 0; |
250 | u32 temp, flags = 0; |
Line 228... | Line 251... | ||
228 | 251 | ||
Line 252... | Line 275... | ||
252 | pipe_config->pipe_bpp = 36; |
275 | pipe_config->pipe_bpp = 36; |
253 | break; |
276 | break; |
254 | default: |
277 | default: |
255 | break; |
278 | break; |
256 | } |
279 | } |
257 | pipe_config->adjusted_mode.flags |= flags; |
280 | pipe_config->base.adjusted_mode.flags |= flags; |
- | 281 | ||
- | 282 | pipe_config->lane_count = |
|
- | 283 | ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; |
|
- | 284 | ||
258 | intel_dp_get_m_n(crtc, pipe_config); |
285 | intel_dp_get_m_n(crtc, pipe_config); |
Line 259... | Line 286... | ||
259 | 286 | ||
260 | intel_ddi_clock_get(&intel_dig_port->base, pipe_config); |
287 | intel_ddi_clock_get(&intel_dig_port->base, pipe_config); |
Line 305... | Line 332... | ||
305 | drm_connector_cleanup(connector); |
332 | drm_connector_cleanup(connector); |
306 | kfree(connector); |
333 | kfree(connector); |
307 | } |
334 | } |
Line 308... | Line 335... | ||
308 | 335 | ||
309 | static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { |
336 | static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { |
310 | .dpms = intel_connector_dpms, |
337 | .dpms = drm_atomic_helper_connector_dpms, |
311 | .detect = intel_dp_mst_detect, |
338 | .detect = intel_dp_mst_detect, |
312 | .fill_modes = drm_helper_probe_single_connector_modes, |
339 | .fill_modes = drm_helper_probe_single_connector_modes, |
- | 340 | .set_property = intel_dp_mst_set_property, |
|
313 | .set_property = intel_dp_mst_set_property, |
341 | .atomic_get_property = intel_connector_atomic_get_property, |
- | 342 | .destroy = intel_dp_mst_connector_destroy, |
|
- | 343 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
|
314 | .destroy = intel_dp_mst_connector_destroy, |
344 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
Line 315... | Line 345... | ||
315 | }; |
345 | }; |
316 | 346 | ||
317 | static int intel_dp_mst_get_modes(struct drm_connector *connector) |
347 | static int intel_dp_mst_get_modes(struct drm_connector *connector) |
Line 331... | Line 361... | ||
331 | return MODE_H_ILLEGAL; |
361 | return MODE_H_ILLEGAL; |
Line 332... | Line 362... | ||
332 | 362 | ||
333 | return MODE_OK; |
363 | return MODE_OK; |
Line -... | Line 364... | ||
- | 364 | } |
|
- | 365 | ||
- | 366 | static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *connector, |
|
- | 367 | struct drm_connector_state *state) |
|
- | 368 | { |
|
- | 369 | struct intel_connector *intel_connector = to_intel_connector(connector); |
|
- | 370 | struct intel_dp *intel_dp = intel_connector->mst_port; |
|
- | 371 | struct intel_crtc *crtc = to_intel_crtc(state->crtc); |
|
- | 372 | ||
- | 373 | return &intel_dp->mst_encoders[crtc->pipe]->base.base; |
|
334 | } |
374 | } |
335 | 375 | ||
336 | static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector) |
376 | static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector) |
337 | { |
377 | { |
338 | struct intel_connector *intel_connector = to_intel_connector(connector); |
378 | struct intel_connector *intel_connector = to_intel_connector(connector); |
339 | struct intel_dp *intel_dp = intel_connector->mst_port; |
379 | struct intel_dp *intel_dp = intel_connector->mst_port; |
Line 340... | Line 380... | ||
340 | return &intel_dp->mst_encoders[0]->base.base; |
380 | return &intel_dp->mst_encoders[0]->base.base; |
341 | } |
381 | } |
342 | 382 | ||
- | 383 | static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { |
|
343 | static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { |
384 | .get_modes = intel_dp_mst_get_modes, |
344 | .get_modes = intel_dp_mst_get_modes, |
385 | .mode_valid = intel_dp_mst_mode_valid, |
Line 345... | Line 386... | ||
345 | .mode_valid = intel_dp_mst_mode_valid, |
386 | .atomic_best_encoder = intel_mst_atomic_best_encoder, |
346 | .best_encoder = intel_mst_best_encoder, |
387 | .best_encoder = intel_mst_best_encoder, |
Line 358... | Line 399... | ||
358 | .destroy = intel_dp_mst_encoder_destroy, |
399 | .destroy = intel_dp_mst_encoder_destroy, |
359 | }; |
400 | }; |
Line 360... | Line 401... | ||
360 | 401 | ||
361 | static bool intel_dp_mst_get_hw_state(struct intel_connector *connector) |
402 | static bool intel_dp_mst_get_hw_state(struct intel_connector *connector) |
362 | { |
403 | { |
363 | if (connector->encoder) { |
404 | if (connector->encoder && connector->base.state->crtc) { |
364 | enum pipe pipe; |
405 | enum pipe pipe; |
365 | if (!connector->encoder->get_hw_state(connector->encoder, &pipe)) |
406 | if (!connector->encoder->get_hw_state(connector->encoder, &pipe)) |
366 | return false; |
407 | return false; |
367 | return true; |
408 | return true; |
368 | } |
409 | } |
369 | return false; |
410 | return false; |
Line 370... | Line 411... | ||
370 | } |
411 | } |
371 | 412 | ||
372 | static void intel_connector_add_to_fbdev(struct intel_connector *connector) |
413 | static void intel_connector_add_to_fbdev(struct intel_connector *connector) |
373 | { |
414 | { |
374 | #ifdef CONFIG_DRM_I915_FBDEV |
415 | #ifdef CONFIG_DRM_FBDEV_EMULATION |
375 | struct drm_i915_private *dev_priv = to_i915(connector->base.dev); |
416 | struct drm_i915_private *dev_priv = to_i915(connector->base.dev); |
376 | drm_fb_helper_add_one_connector(&dev_priv->fbdev->helper, &connector->base); |
417 | drm_fb_helper_add_one_connector(&dev_priv->fbdev->helper, &connector->base); |
Line 377... | Line 418... | ||
377 | #endif |
418 | #endif |
378 | } |
419 | } |
379 | 420 | ||
380 | static void intel_connector_remove_from_fbdev(struct intel_connector *connector) |
421 | static void intel_connector_remove_from_fbdev(struct intel_connector *connector) |
381 | { |
422 | { |
382 | #ifdef CONFIG_DRM_I915_FBDEV |
423 | #ifdef CONFIG_DRM_FBDEV_EMULATION |
383 | struct drm_i915_private *dev_priv = to_i915(connector->base.dev); |
424 | struct drm_i915_private *dev_priv = to_i915(connector->base.dev); |
Line 392... | Line 433... | ||
392 | struct drm_device *dev = intel_dig_port->base.base.dev; |
433 | struct drm_device *dev = intel_dig_port->base.base.dev; |
393 | struct intel_connector *intel_connector; |
434 | struct intel_connector *intel_connector; |
394 | struct drm_connector *connector; |
435 | struct drm_connector *connector; |
395 | int i; |
436 | int i; |
Line 396... | Line 437... | ||
396 | 437 | ||
397 | intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL); |
438 | intel_connector = intel_connector_alloc(); |
398 | if (!intel_connector) |
439 | if (!intel_connector) |
Line 399... | Line 440... | ||
399 | return NULL; |
440 | return NULL; |
400 | 441 | ||
Line 415... | Line 456... | ||
415 | 456 | ||
416 | drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0); |
457 | drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0); |
Line 417... | Line 458... | ||
417 | drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0); |
458 | drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0); |
- | 459 | ||
- | 460 | drm_mode_connector_set_path_property(connector, pathprop); |
|
- | 461 | return connector; |
|
- | 462 | } |
|
- | 463 | ||
- | 464 | static void intel_dp_register_mst_connector(struct drm_connector *connector) |
|
418 | 465 | { |
|
419 | drm_mode_connector_set_path_property(connector, pathprop); |
466 | struct intel_connector *intel_connector = to_intel_connector(connector); |
420 | drm_reinit_primary_mode_group(dev); |
467 | struct drm_device *dev = connector->dev; |
421 | mutex_lock(&dev->mode_config.mutex); |
468 | drm_modeset_lock_all(dev); |
422 | intel_connector_add_to_fbdev(intel_connector); |
469 | intel_connector_add_to_fbdev(intel_connector); |
423 | mutex_unlock(&dev->mode_config.mutex); |
- | |
424 | drm_connector_register(&intel_connector->base); |
470 | drm_modeset_unlock_all(dev); |
Line 425... | Line 471... | ||
425 | return connector; |
471 | drm_connector_register(&intel_connector->base); |
426 | } |
472 | } |
427 | 473 | ||
428 | static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, |
474 | static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, |
429 | struct drm_connector *connector) |
475 | struct drm_connector *connector) |
- | 476 | { |
|
430 | { |
477 | struct intel_connector *intel_connector = to_intel_connector(connector); |
- | 478 | struct drm_device *dev = connector->dev; |
|
- | 479 | ||
431 | struct intel_connector *intel_connector = to_intel_connector(connector); |
480 | /* need to nuke the connector */ |
- | 481 | drm_modeset_lock_all(dev); |
|
- | 482 | if (connector->state->crtc) { |
|
- | 483 | struct drm_mode_set set; |
|
432 | struct drm_device *dev = connector->dev; |
484 | int ret; |
- | 485 | ||
433 | /* need to nuke the connector */ |
486 | memset(&set, 0, sizeof(set)); |
- | 487 | set.crtc = connector->state->crtc, |
|
- | 488 | ||
- | 489 | ret = drm_atomic_helper_set_config(&set); |
|
- | 490 | ||
Line 434... | Line 491... | ||
434 | mutex_lock(&dev->mode_config.mutex); |
491 | WARN(ret, "Disabling mst crtc failed with %i\n", ret); |
Line 435... | Line 492... | ||
435 | intel_connector_dpms(connector, DRM_MODE_DPMS_OFF); |
492 | } |
436 | mutex_unlock(&dev->mode_config.mutex); |
493 | drm_modeset_unlock_all(dev); |
437 | 494 | ||
438 | intel_connector->unregister(intel_connector); |
- | |
439 | - | ||
440 | mutex_lock(&dev->mode_config.mutex); |
495 | intel_connector->unregister(intel_connector); |
Line 441... | Line 496... | ||
441 | intel_connector_remove_from_fbdev(intel_connector); |
496 | |
442 | drm_connector_cleanup(connector); |
497 | drm_modeset_lock_all(dev); |
443 | mutex_unlock(&dev->mode_config.mutex); |
498 | intel_connector_remove_from_fbdev(intel_connector); |
Line 457... | Line 512... | ||
457 | drm_kms_helper_hotplug_event(dev); |
512 | drm_kms_helper_hotplug_event(dev); |
458 | } |
513 | } |
Line 459... | Line 514... | ||
459 | 514 | ||
460 | static struct drm_dp_mst_topology_cbs mst_cbs = { |
515 | static struct drm_dp_mst_topology_cbs mst_cbs = { |
- | 516 | .add_connector = intel_dp_add_mst_connector, |
|
461 | .add_connector = intel_dp_add_mst_connector, |
517 | .register_connector = intel_dp_register_mst_connector, |
462 | .destroy_connector = intel_dp_destroy_mst_connector, |
518 | .destroy_connector = intel_dp_destroy_mst_connector, |
463 | .hotplug = intel_dp_mst_hotplug, |
519 | .hotplug = intel_dp_mst_hotplug, |
Line 464... | Line 520... | ||
464 | }; |
520 | }; |