diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display.c | 135 |
1 files changed, 63 insertions, 72 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3031e64ee518..346846609f45 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -41,7 +41,6 @@ #include <drm/drm_plane_helper.h> #include <drm/drm_probe_helper.h> #include <drm/drm_rect.h> -#include <drm/i915_drm.h> #include "display/intel_crt.h" #include "display/intel_ddi.h" @@ -2720,9 +2719,10 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv, /* * We assume the primary plane for pipe A has - * the highest stride limits of them all. + * the highest stride limits of them all, + * if in case pipe A is disabled, use the first pipe from pipe_mask. */ - crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A); + crtc = intel_get_first_crtc(dev_priv); if (!crtc) return 0; @@ -9542,7 +9542,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) } /* Check if any DPLLs are using the SSC source */ - for (i = 0; i < dev_priv->num_shared_dpll; i++) { + for (i = 0; i < dev_priv->dpll.num_shared_dpll; i++) { u32 temp = intel_de_read(dev_priv, PCH_DPLL(i)); if (!(temp & DPLL_VCO_ENABLE)) @@ -10129,6 +10129,9 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state) BIT(PLANE_CURSOR))) == 0) val |= PIPEMISC_HDR_MODE_PRECISION; + if (INTEL_GEN(dev_priv) >= 12) + val |= PIPEMISC_PIXEL_ROUNDING_TRUNC; + intel_de_write(dev_priv, PIPEMISC(crtc->pipe), val); } @@ -14299,11 +14302,11 @@ verify_single_dpll_state(struct drm_i915_private *dev_priv, if (new_crtc_state->hw.active) I915_STATE_WARN(!(pll->active_mask & crtc_mask), "pll active mismatch (expected pipe %c in active mask 0x%02x)\n", - pipe_name(drm_crtc_index(&crtc->base)), pll->active_mask); + pipe_name(crtc->pipe), pll->active_mask); else I915_STATE_WARN(pll->active_mask & crtc_mask, "pll active mismatch (didn't expect pipe %c in active mask 0x%02x)\n", - pipe_name(drm_crtc_index(&crtc->base)), pll->active_mask); + pipe_name(crtc->pipe), pll->active_mask); I915_STATE_WARN(!(pll->state.crtc_mask & crtc_mask), "pll enabled crtcs mismatch (expected 0x%x in 0x%02x)\n", @@ -14332,10 +14335,10 @@ verify_shared_dpll_state(struct intel_crtc *crtc, I915_STATE_WARN(pll->active_mask & crtc_mask, "pll active mismatch (didn't expect pipe %c in active mask)\n", - pipe_name(drm_crtc_index(&crtc->base))); + pipe_name(crtc->pipe)); I915_STATE_WARN(pll->state.crtc_mask & crtc_mask, "pll enabled crtcs mismatch (found %x in enabled mask)\n", - pipe_name(drm_crtc_index(&crtc->base))); + pipe_name(crtc->pipe)); } } @@ -14359,8 +14362,10 @@ verify_disabled_dpll_state(struct drm_i915_private *dev_priv) { int i; - for (i = 0; i < dev_priv->num_shared_dpll; i++) - verify_single_dpll_state(dev_priv, &dev_priv->shared_dplls[i], NULL, NULL); + for (i = 0; i < dev_priv->dpll.num_shared_dpll; i++) + verify_single_dpll_state(dev_priv, + &dev_priv->dpll.shared_dplls[i], + NULL, NULL); } static void @@ -14743,8 +14748,8 @@ static int intel_atomic_check(struct drm_device *dev, /* Catch I915_MODE_FLAG_INHERITED */ for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { - if (new_crtc_state->hw.mode.private_flags != - old_crtc_state->hw.mode.private_flags) + if (new_crtc_state->uapi.mode.private_flags != + old_crtc_state->uapi.mode.private_flags) new_crtc_state->uapi.mode_changed = true; } @@ -15318,7 +15323,6 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) struct intel_crtc *crtc; struct intel_crtc_state *old_crtc_state, *new_crtc_state; struct skl_ddb_entry entries[I915_MAX_PIPES] = {}; - const u8 num_pipes = INTEL_NUM_PIPES(dev_priv); u8 update_pipes = 0, modeset_pipes = 0; int i; @@ -15355,7 +15359,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) continue; if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb, - entries, num_pipes, pipe)) + entries, I915_MAX_PIPES, pipe)) continue; entries[pipe] = new_crtc_state->wm.skl.ddb; @@ -15393,7 +15397,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) continue; drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb, - entries, num_pipes, pipe)); + entries, I915_MAX_PIPES, pipe)); entries[pipe] = new_crtc_state->wm.skl.ddb; modeset_pipes &= ~BIT(pipe); @@ -15428,7 +15432,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) continue; drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb, - entries, num_pipes, pipe)); + entries, I915_MAX_PIPES, pipe)); entries[pipe] = new_crtc_state->wm.skl.ddb; modeset_pipes &= ~BIT(pipe); @@ -16320,7 +16324,6 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) struct intel_plane *plane; const struct drm_plane_funcs *plane_funcs; unsigned int supported_rotations; - unsigned int possible_crtcs; const u32 *formats; int num_formats; int ret, zpos; @@ -16401,18 +16404,16 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) plane->get_hw_state = i9xx_plane_get_hw_state; plane->check_plane = i9xx_plane_check; - possible_crtcs = BIT(pipe); - if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, - possible_crtcs, plane_funcs, + 0, plane_funcs, formats, num_formats, i9xx_format_modifiers, DRM_PLANE_TYPE_PRIMARY, "primary %c", pipe_name(pipe)); else ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, - possible_crtcs, plane_funcs, + 0, plane_funcs, formats, num_formats, i9xx_format_modifiers, DRM_PLANE_TYPE_PRIMARY, @@ -16454,7 +16455,6 @@ static struct intel_plane * intel_cursor_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) { - unsigned int possible_crtcs; struct intel_plane *cursor; int ret, zpos; @@ -16487,10 +16487,8 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, if (IS_I845G(dev_priv) || IS_I865G(dev_priv) || HAS_CUR_FBC(dev_priv)) cursor->cursor.size = ~0; - possible_crtcs = BIT(pipe); - ret = drm_universal_plane_init(&dev_priv->drm, &cursor->base, - possible_crtcs, &intel_cursor_plane_funcs, + 0, &intel_cursor_plane_funcs, intel_cursor_formats, ARRAY_SIZE(intel_cursor_formats), cursor_format_modifiers, @@ -16619,6 +16617,18 @@ static void intel_crtc_free(struct intel_crtc *crtc) kfree(crtc); } +static void intel_plane_possible_crtcs_init(struct drm_i915_private *dev_priv) +{ + struct intel_plane *plane; + + for_each_intel_plane(&dev_priv->drm, plane) { + struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, + plane->pipe); + + plane->base.possible_crtcs = drm_crtc_mask(&crtc->base); + } +} + static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) { struct intel_plane *primary, *cursor; @@ -16697,6 +16707,8 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) intel_color_init(crtc); + intel_crtc_crc_init(crtc); + drm_WARN_ON(&dev_priv->drm, drm_crtc_index(&crtc->base) != crtc->pipe); return 0; @@ -17785,11 +17797,9 @@ static void plane_config_fini(struct intel_initial_plane_config *plane_config) i915_vma_put(plane_config->vma); } -int intel_modeset_init(struct drm_i915_private *i915) +/* part #1: call before irq install */ +int intel_modeset_init_noirq(struct drm_i915_private *i915) { - struct drm_device *dev = &i915->drm; - enum pipe pipe; - struct intel_crtc *crtc; int ret; i915->modeset_wq = alloc_ordered_workqueue("i915_modeset", 0); @@ -17814,6 +17824,17 @@ int intel_modeset_init(struct drm_i915_private *i915) intel_fbc_init(i915); + return 0; +} + +/* part #2: call after irq install */ +int intel_modeset_init(struct drm_i915_private *i915) +{ + struct drm_device *dev = &i915->drm; + enum pipe pipe; + struct intel_crtc *crtc; + int ret; + intel_init_pm(i915); intel_panel_sanitize_ssc(i915); @@ -17834,6 +17855,7 @@ int intel_modeset_init(struct drm_i915_private *i915) } } + intel_plane_possible_crtcs_init(i915); intel_shared_dpll_init(dev); intel_update_fdi_pll_freq(i915); @@ -18311,7 +18333,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) struct intel_connector *connector; struct drm_connector_list_iter conn_iter; u8 active_pipes = 0; - int i; for_each_intel_crtc(dev, crtc) { struct intel_crtc_state *crtc_state = @@ -18340,33 +18361,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) readout_plane_state(dev_priv); - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; - - pll->on = pll->info->funcs->get_hw_state(dev_priv, pll, - &pll->state.hw_state); - - if (IS_ELKHARTLAKE(dev_priv) && pll->on && - pll->info->id == DPLL_ID_EHL_DPLL4) { - pll->wakeref = intel_display_power_get(dev_priv, - POWER_DOMAIN_DPLL_DC_OFF); - } - - pll->state.crtc_mask = 0; - for_each_intel_crtc(dev, crtc) { - struct intel_crtc_state *crtc_state = - to_intel_crtc_state(crtc->base.state); - - if (crtc_state->hw.active && - crtc_state->shared_dpll == pll) - pll->state.crtc_mask |= 1 << crtc->pipe; - } - pll->active_mask = pll->state.crtc_mask; - - drm_dbg_kms(&dev_priv->drm, - "%s hw state readout: crtc_mask 0x%08x, on %i\n", - pll->info->name, pll->state.crtc_mask, pll->on); - } + intel_dpll_readout_hw_state(dev_priv); for_each_intel_encoder(dev, encoder) { pipe = 0; @@ -18623,7 +18618,6 @@ intel_modeset_setup_hw_state(struct drm_device *dev, struct intel_encoder *encoder; struct intel_crtc *crtc; intel_wakeref_t wakeref; - int i; wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); @@ -18676,19 +18670,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev, intel_modeset_update_connector_atomic_state(dev); - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; - - if (!pll->on || pll->active_mask) - continue; - - drm_dbg_kms(&dev_priv->drm, - "%s enabled but not in use, disabling\n", - pll->info->name); - - pll->info->funcs->disable(dev_priv, pll); - pll->on = false; - } + intel_dpll_sanitize_state(dev_priv); if (IS_G4X(dev_priv)) { g4x_wm_get_hw_state(dev_priv); @@ -18820,6 +18802,15 @@ void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915) #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) +static bool +has_transcoder(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder) +{ + if (cpu_transcoder == TRANSCODER_EDP) + return HAS_TRANSCODER_EDP(dev_priv); + else + return INTEL_INFO(dev_priv)->pipe_mask & BIT(cpu_transcoder); +} + struct intel_display_error_state { u32 power_well_driver; @@ -18928,7 +18919,7 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv) for (i = 0; i < ARRAY_SIZE(error->transcoder); i++) { enum transcoder cpu_transcoder = transcoders[i]; - if (!INTEL_INFO(dev_priv)->trans_offsets[cpu_transcoder]) + if (!has_transcoder(dev_priv, cpu_transcoder)) continue; error->transcoder[i].available = true; |