diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 70 |
1 files changed, 52 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 694a4703042f..8f3199b06d1f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -5632,6 +5632,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, | |||
5632 | struct intel_atomic_state *old_intel_state = | 5632 | struct intel_atomic_state *old_intel_state = |
5633 | to_intel_atomic_state(old_state); | 5633 | to_intel_atomic_state(old_state); |
5634 | bool psl_clkgate_wa; | 5634 | bool psl_clkgate_wa; |
5635 | u32 pipe_chicken; | ||
5635 | 5636 | ||
5636 | if (WARN_ON(intel_crtc->active)) | 5637 | if (WARN_ON(intel_crtc->active)) |
5637 | return; | 5638 | return; |
@@ -5691,6 +5692,17 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, | |||
5691 | */ | 5692 | */ |
5692 | intel_color_load_luts(&pipe_config->base); | 5693 | intel_color_load_luts(&pipe_config->base); |
5693 | 5694 | ||
5695 | /* | ||
5696 | * Display WA #1153: enable hardware to bypass the alpha math | ||
5697 | * and rounding for per-pixel values 00 and 0xff | ||
5698 | */ | ||
5699 | if (INTEL_GEN(dev_priv) >= 11) { | ||
5700 | pipe_chicken = I915_READ(PIPE_CHICKEN(pipe)); | ||
5701 | if (!(pipe_chicken & PER_PIXEL_ALPHA_BYPASS_EN)) | ||
5702 | I915_WRITE_FW(PIPE_CHICKEN(pipe), | ||
5703 | pipe_chicken | PER_PIXEL_ALPHA_BYPASS_EN); | ||
5704 | } | ||
5705 | |||
5694 | intel_ddi_set_pipe_settings(pipe_config); | 5706 | intel_ddi_set_pipe_settings(pipe_config); |
5695 | if (!transcoder_is_dsi(cpu_transcoder)) | 5707 | if (!transcoder_is_dsi(cpu_transcoder)) |
5696 | intel_ddi_enable_transcoder_func(pipe_config); | 5708 | intel_ddi_enable_transcoder_func(pipe_config); |
@@ -9347,6 +9359,7 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, | |||
9347 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { | 9359 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { |
9348 | default: | 9360 | default: |
9349 | WARN(1, "unknown pipe linked to edp transcoder\n"); | 9361 | WARN(1, "unknown pipe linked to edp transcoder\n"); |
9362 | /* fall through */ | ||
9350 | case TRANS_DDI_EDP_INPUT_A_ONOFF: | 9363 | case TRANS_DDI_EDP_INPUT_A_ONOFF: |
9351 | case TRANS_DDI_EDP_INPUT_A_ON: | 9364 | case TRANS_DDI_EDP_INPUT_A_ON: |
9352 | trans_edp_pipe = PIPE_A; | 9365 | trans_edp_pipe = PIPE_A; |
@@ -9402,7 +9415,7 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, | |||
9402 | * registers/MIPI[BXT]. We can break out here early, since we | 9415 | * registers/MIPI[BXT]. We can break out here early, since we |
9403 | * need the same DSI PLL to be enabled for both DSI ports. | 9416 | * need the same DSI PLL to be enabled for both DSI ports. |
9404 | */ | 9417 | */ |
9405 | if (!intel_dsi_pll_is_enabled(dev_priv)) | 9418 | if (!bxt_dsi_pll_is_enabled(dev_priv)) |
9406 | break; | 9419 | break; |
9407 | 9420 | ||
9408 | /* XXX: this works for video mode only */ | 9421 | /* XXX: this works for video mode only */ |
@@ -10724,7 +10737,7 @@ static void intel_modeset_update_connector_atomic_state(struct drm_device *dev) | |||
10724 | drm_connector_list_iter_begin(dev, &conn_iter); | 10737 | drm_connector_list_iter_begin(dev, &conn_iter); |
10725 | for_each_intel_connector_iter(connector, &conn_iter) { | 10738 | for_each_intel_connector_iter(connector, &conn_iter) { |
10726 | if (connector->base.state->crtc) | 10739 | if (connector->base.state->crtc) |
10727 | drm_connector_unreference(&connector->base); | 10740 | drm_connector_put(&connector->base); |
10728 | 10741 | ||
10729 | if (connector->base.encoder) { | 10742 | if (connector->base.encoder) { |
10730 | connector->base.state->best_encoder = | 10743 | connector->base.state->best_encoder = |
@@ -10732,7 +10745,7 @@ static void intel_modeset_update_connector_atomic_state(struct drm_device *dev) | |||
10732 | connector->base.state->crtc = | 10745 | connector->base.state->crtc = |
10733 | connector->base.encoder->crtc; | 10746 | connector->base.encoder->crtc; |
10734 | 10747 | ||
10735 | drm_connector_reference(&connector->base); | 10748 | drm_connector_get(&connector->base); |
10736 | } else { | 10749 | } else { |
10737 | connector->base.state->best_encoder = NULL; | 10750 | connector->base.state->best_encoder = NULL; |
10738 | connector->base.state->crtc = NULL; | 10751 | connector->base.state->crtc = NULL; |
@@ -11011,6 +11024,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state) | |||
11011 | case INTEL_OUTPUT_DDI: | 11024 | case INTEL_OUTPUT_DDI: |
11012 | if (WARN_ON(!HAS_DDI(to_i915(dev)))) | 11025 | if (WARN_ON(!HAS_DDI(to_i915(dev)))) |
11013 | break; | 11026 | break; |
11027 | /* else: fall through */ | ||
11014 | case INTEL_OUTPUT_DP: | 11028 | case INTEL_OUTPUT_DP: |
11015 | case INTEL_OUTPUT_HDMI: | 11029 | case INTEL_OUTPUT_HDMI: |
11016 | case INTEL_OUTPUT_EDP: | 11030 | case INTEL_OUTPUT_EDP: |
@@ -12542,6 +12556,19 @@ static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_stat | |||
12542 | finish_wait(&dev_priv->gpu_error.wait_queue, &wait_reset); | 12556 | finish_wait(&dev_priv->gpu_error.wait_queue, &wait_reset); |
12543 | } | 12557 | } |
12544 | 12558 | ||
12559 | static void intel_atomic_cleanup_work(struct work_struct *work) | ||
12560 | { | ||
12561 | struct drm_atomic_state *state = | ||
12562 | container_of(work, struct drm_atomic_state, commit_work); | ||
12563 | struct drm_i915_private *i915 = to_i915(state->dev); | ||
12564 | |||
12565 | drm_atomic_helper_cleanup_planes(&i915->drm, state); | ||
12566 | drm_atomic_helper_commit_cleanup_done(state); | ||
12567 | drm_atomic_state_put(state); | ||
12568 | |||
12569 | intel_atomic_helper_free_state(i915); | ||
12570 | } | ||
12571 | |||
12545 | static void intel_atomic_commit_tail(struct drm_atomic_state *state) | 12572 | static void intel_atomic_commit_tail(struct drm_atomic_state *state) |
12546 | { | 12573 | { |
12547 | struct drm_device *dev = state->dev; | 12574 | struct drm_device *dev = state->dev; |
@@ -12702,13 +12729,16 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
12702 | intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET); | 12729 | intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET); |
12703 | } | 12730 | } |
12704 | 12731 | ||
12705 | drm_atomic_helper_cleanup_planes(dev, state); | 12732 | /* |
12706 | 12733 | * Defer the cleanup of the old state to a separate worker to not | |
12707 | drm_atomic_helper_commit_cleanup_done(state); | 12734 | * impede the current task (userspace for blocking modesets) that |
12708 | 12735 | * are executed inline. For out-of-line asynchronous modesets/flips, | |
12709 | drm_atomic_state_put(state); | 12736 | * deferring to a new worker seems overkill, but we would place a |
12710 | 12737 | * schedule point (cond_resched()) here anyway to keep latencies | |
12711 | intel_atomic_helper_free_state(dev_priv); | 12738 | * down. |
12739 | */ | ||
12740 | INIT_WORK(&state->commit_work, intel_atomic_cleanup_work); | ||
12741 | schedule_work(&state->commit_work); | ||
12712 | } | 12742 | } |
12713 | 12743 | ||
12714 | static void intel_atomic_commit_work(struct work_struct *work) | 12744 | static void intel_atomic_commit_work(struct work_struct *work) |
@@ -14105,7 +14135,7 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) | |||
14105 | intel_ddi_init(dev_priv, PORT_B); | 14135 | intel_ddi_init(dev_priv, PORT_B); |
14106 | intel_ddi_init(dev_priv, PORT_C); | 14136 | intel_ddi_init(dev_priv, PORT_C); |
14107 | 14137 | ||
14108 | intel_dsi_init(dev_priv); | 14138 | vlv_dsi_init(dev_priv); |
14109 | } else if (HAS_DDI(dev_priv)) { | 14139 | } else if (HAS_DDI(dev_priv)) { |
14110 | int found; | 14140 | int found; |
14111 | 14141 | ||
@@ -14211,7 +14241,7 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) | |||
14211 | intel_hdmi_init(dev_priv, CHV_HDMID, PORT_D); | 14241 | intel_hdmi_init(dev_priv, CHV_HDMID, PORT_D); |
14212 | } | 14242 | } |
14213 | 14243 | ||
14214 | intel_dsi_init(dev_priv); | 14244 | vlv_dsi_init(dev_priv); |
14215 | } else if (!IS_GEN2(dev_priv) && !IS_PINEVIEW(dev_priv)) { | 14245 | } else if (!IS_GEN2(dev_priv) && !IS_PINEVIEW(dev_priv)) { |
14216 | bool found = false; | 14246 | bool found = false; |
14217 | 14247 | ||
@@ -14493,11 +14523,6 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, | |||
14493 | } | 14523 | } |
14494 | break; | 14524 | break; |
14495 | case DRM_FORMAT_NV12: | 14525 | case DRM_FORMAT_NV12: |
14496 | if (mode_cmd->modifier[0] == I915_FORMAT_MOD_Y_TILED_CCS || | ||
14497 | mode_cmd->modifier[0] == I915_FORMAT_MOD_Yf_TILED_CCS) { | ||
14498 | DRM_DEBUG_KMS("RC not to be enabled with NV12\n"); | ||
14499 | goto err; | ||
14500 | } | ||
14501 | if (INTEL_GEN(dev_priv) < 9 || IS_SKYLAKE(dev_priv) || | 14526 | if (INTEL_GEN(dev_priv) < 9 || IS_SKYLAKE(dev_priv) || |
14502 | IS_BROXTON(dev_priv)) { | 14527 | IS_BROXTON(dev_priv)) { |
14503 | DRM_DEBUG_KMS("unsupported pixel format: %s\n", | 14528 | DRM_DEBUG_KMS("unsupported pixel format: %s\n", |
@@ -15676,11 +15701,20 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv) | |||
15676 | for_each_intel_encoder(&dev_priv->drm, encoder) { | 15701 | for_each_intel_encoder(&dev_priv->drm, encoder) { |
15677 | u64 get_domains; | 15702 | u64 get_domains; |
15678 | enum intel_display_power_domain domain; | 15703 | enum intel_display_power_domain domain; |
15704 | struct intel_crtc_state *crtc_state; | ||
15679 | 15705 | ||
15680 | if (!encoder->get_power_domains) | 15706 | if (!encoder->get_power_domains) |
15681 | continue; | 15707 | continue; |
15682 | 15708 | ||
15683 | get_domains = encoder->get_power_domains(encoder); | 15709 | /* |
15710 | * MST-primary and inactive encoders don't have a crtc state | ||
15711 | * and neither of these require any power domain references. | ||
15712 | */ | ||
15713 | if (!encoder->base.crtc) | ||
15714 | continue; | ||
15715 | |||
15716 | crtc_state = to_intel_crtc_state(encoder->base.crtc->state); | ||
15717 | get_domains = encoder->get_power_domains(encoder, crtc_state); | ||
15684 | for_each_power_domain(domain, get_domains) | 15718 | for_each_power_domain(domain, get_domains) |
15685 | intel_display_power_get(dev_priv, domain); | 15719 | intel_display_power_get(dev_priv, domain); |
15686 | } | 15720 | } |