summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c1134
1 files changed, 154 insertions, 980 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 3c29792137a5..09320e14d75c 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -31,8 +31,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string_helpers.h>
-#include <linux/vga_switcheroo.h>
-#include <acpi/video.h>
#include <drm/display/drm_dp_helper.h>
#include <drm/drm_atomic.h>
@@ -41,7 +39,6 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_fourcc.h>
-#include <drm/drm_privacy_screen_consumer.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_rect.h>
@@ -57,7 +54,6 @@
#include "i9xx_plane.h"
#include "i9xx_wm.h"
#include "icl_dsi.h"
-#include "intel_acpi.h"
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
#include "intel_audio.h"
@@ -70,7 +66,7 @@
#include "intel_crtc_state_dump.h"
#include "intel_ddi.h"
#include "intel_de.h"
-#include "intel_display_debugfs.h"
+#include "intel_display_driver.h"
#include "intel_display_power.h"
#include "intel_display_types.h"
#include "intel_dmc.h"
@@ -90,11 +86,8 @@
#include "intel_fdi.h"
#include "intel_fifo_underrun.h"
#include "intel_frontbuffer.h"
-#include "intel_gmbus.h"
-#include "intel_hdcp.h"
#include "intel_hdmi.h"
#include "intel_hotplug.h"
-#include "intel_hti.h"
#include "intel_lvds.h"
#include "intel_lvds_regs.h"
#include "intel_modeset_setup.h"
@@ -108,7 +101,6 @@
#include "intel_plane_initial.h"
#include "intel_pps.h"
#include "intel_psr.h"
-#include "intel_quirks.h"
#include "intel_sdvo.h"
#include "intel_snps_phy.h"
#include "intel_tc.h"
@@ -131,7 +123,6 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state);
static void hsw_set_transconf(const struct intel_crtc_state *crtc_state);
static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state);
-static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state);
/* returns HPLL frequency in kHz */
int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
@@ -178,7 +169,7 @@ int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
return hpll;
}
-static void intel_update_czclk(struct drm_i915_private *dev_priv)
+void intel_update_czclk(struct drm_i915_private *dev_priv)
{
if (!(IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)))
return;
@@ -234,7 +225,7 @@ is_trans_port_sync_slave(const struct intel_crtc_state *crtc_state)
return crtc_state->master_transcoder != INVALID_TRANSCODER;
}
-static bool
+bool
is_trans_port_sync_master(const struct intel_crtc_state *crtc_state)
{
return crtc_state->sync_mode_slaves_mask != 0;
@@ -331,20 +322,21 @@ void assert_transcoder(struct drm_i915_private *dev_priv,
cur_state = false;
}
- I915_STATE_WARN(cur_state != state,
+ I915_STATE_WARN(dev_priv, cur_state != state,
"transcoder %s assertion failure (expected %s, current %s)\n",
- transcoder_name(cpu_transcoder),
- str_on_off(state), str_on_off(cur_state));
+ transcoder_name(cpu_transcoder), str_on_off(state),
+ str_on_off(cur_state));
}
static void assert_plane(struct intel_plane *plane, bool state)
{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum pipe pipe;
bool cur_state;
cur_state = plane->get_hw_state(plane, &pipe);
- I915_STATE_WARN(cur_state != state,
+ I915_STATE_WARN(i915, cur_state != state,
"%s assertion failure (expected %s, current %s)\n",
plane->base.name, str_on_off(state),
str_on_off(cur_state));
@@ -701,175 +693,6 @@ intel_plane_fence_y_offset(const struct intel_plane_state *plane_state)
return y;
}
-static int
-intel_display_commit_duplicated_state(struct intel_atomic_state *state,
- struct drm_modeset_acquire_ctx *ctx)
-{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
- int ret;
-
- ret = drm_atomic_helper_commit_duplicated_state(&state->base, ctx);
-
- drm_WARN_ON(&i915->drm, ret == -EDEADLK);
-
- return ret;
-}
-
-static int
-__intel_display_resume(struct drm_i915_private *i915,
- struct drm_atomic_state *state,
- struct drm_modeset_acquire_ctx *ctx)
-{
- struct drm_crtc_state *crtc_state;
- struct drm_crtc *crtc;
- int i;
-
- intel_modeset_setup_hw_state(i915, ctx);
- intel_vga_redisable(i915);
-
- if (!state)
- return 0;
-
- /*
- * We've duplicated the state, pointers to the old state are invalid.
- *
- * Don't attempt to use the old state until we commit the duplicated state.
- */
- for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
- /*
- * Force recalculation even if we restore
- * current state. With fast modeset this may not result
- * in a modeset when the state is compatible.
- */
- crtc_state->mode_changed = true;
- }
-
- /* ignore any reset values/BIOS leftovers in the WM registers */
- if (!HAS_GMCH(i915))
- to_intel_atomic_state(state)->skip_intermediate_wm = true;
-
- return intel_display_commit_duplicated_state(to_intel_atomic_state(state), ctx);
-}
-
-static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv)
-{
- return (INTEL_INFO(dev_priv)->gpu_reset_clobbers_display &&
- intel_has_gpu_reset(to_gt(dev_priv)));
-}
-
-void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
-{
- struct drm_modeset_acquire_ctx *ctx = &dev_priv->display.restore.reset_ctx;
- struct drm_atomic_state *state;
- int ret;
-
- if (!HAS_DISPLAY(dev_priv))
- return;
-
- /* reset doesn't touch the display */
- if (!dev_priv->params.force_reset_modeset_test &&
- !gpu_reset_clobbers_display(dev_priv))
- return;
-
- /* We have a modeset vs reset deadlock, defensively unbreak it. */
- set_bit(I915_RESET_MODESET, &to_gt(dev_priv)->reset.flags);
- smp_mb__after_atomic();
- wake_up_bit(&to_gt(dev_priv)->reset.flags, I915_RESET_MODESET);
-
- if (atomic_read(&dev_priv->gpu_error.pending_fb_pin)) {
- drm_dbg_kms(&dev_priv->drm,
- "Modeset potentially stuck, unbreaking through wedging\n");
- intel_gt_set_wedged(to_gt(dev_priv));
- }
-
- /*
- * Need mode_config.mutex so that we don't
- * trample ongoing ->detect() and whatnot.
- */
- mutex_lock(&dev_priv->drm.mode_config.mutex);
- drm_modeset_acquire_init(ctx, 0);
- while (1) {
- ret = drm_modeset_lock_all_ctx(&dev_priv->drm, ctx);
- if (ret != -EDEADLK)
- break;
-
- drm_modeset_backoff(ctx);
- }
- /*
- * Disabling the crtcs gracefully seems nicer. Also the
- * g33 docs say we should at least disable all the planes.
- */
- state = drm_atomic_helper_duplicate_state(&dev_priv->drm, ctx);
- if (IS_ERR(state)) {
- ret = PTR_ERR(state);
- drm_err(&dev_priv->drm, "Duplicating state failed with %i\n",
- ret);
- return;
- }
-
- ret = drm_atomic_helper_disable_all(&dev_priv->drm, ctx);
- if (ret) {
- drm_err(&dev_priv->drm, "Suspending crtc's failed with %i\n",
- ret);
- drm_atomic_state_put(state);
- return;
- }
-
- dev_priv->display.restore.modeset_state = state;
- state->acquire_ctx = ctx;
-}
-
-void intel_display_finish_reset(struct drm_i915_private *i915)
-{
- struct drm_modeset_acquire_ctx *ctx = &i915->display.restore.reset_ctx;
- struct drm_atomic_state *state;
- int ret;
-
- if (!HAS_DISPLAY(i915))
- return;
-
- /* reset doesn't touch the display */
- if (!test_bit(I915_RESET_MODESET, &to_gt(i915)->reset.flags))
- return;
-
- state = fetch_and_zero(&i915->display.restore.modeset_state);
- if (!state)
- goto unlock;
-
- /* reset doesn't touch the display */
- if (!gpu_reset_clobbers_display(i915)) {
- /* for testing only restore the display */
- ret = intel_display_commit_duplicated_state(to_intel_atomic_state(state), ctx);
- if (ret)
- drm_err(&i915->drm,
- "Restoring old state failed with %i\n", ret);
- } else {
- /*
- * The display has been reset as well,
- * so need a full re-initialization.
- */
- intel_pps_unlock_regs_wa(i915);
- intel_modeset_init_hw(i915);
- intel_clock_gating_init(i915);
- intel_hpd_init(i915);
-
- ret = __intel_display_resume(i915, state, ctx);
- if (ret)
- drm_err(&i915->drm,
- "Restoring old state failed with %i\n", ret);
-
- intel_hpd_poll_disable(i915);
- }
-
- drm_atomic_state_put(state);
-unlock:
- drm_modeset_drop_locks(ctx);
- drm_modeset_acquire_fini(ctx);
- mutex_unlock(&i915->drm.mode_config.mutex);
-
- clear_bit_unlock(I915_RESET_MODESET, &to_gt(i915)->reset.flags);
-}
-
static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -990,8 +813,10 @@ static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state)
else
intel_de_write_fw(dev_priv, PF_CTL(pipe), PF_ENABLE |
PF_FILTER_MED_3x3);
- intel_de_write_fw(dev_priv, PF_WIN_POS(pipe), x << 16 | y);
- intel_de_write_fw(dev_priv, PF_WIN_SZ(pipe), width << 16 | height);
+ intel_de_write_fw(dev_priv, PF_WIN_POS(pipe),
+ PF_WIN_XPOS(x) | PF_WIN_YPOS(y));
+ intel_de_write_fw(dev_priv, PF_WIN_SZ(pipe),
+ PF_WIN_XSIZE(width) | PF_WIN_YSIZE(height));
}
static void intel_crtc_dpms_overlay_disable(struct intel_crtc *crtc)
@@ -1069,20 +894,40 @@ static bool needs_async_flip_vtd_wa(const struct intel_crtc_state *crtc_state)
(DISPLAY_VER(i915) == 9 || IS_BROADWELL(i915) || IS_HASWELL(i915));
}
+#define is_enabling(feature, old_crtc_state, new_crtc_state) \
+ ((!(old_crtc_state)->feature || intel_crtc_needs_modeset(new_crtc_state)) && \
+ (new_crtc_state)->feature)
+#define is_disabling(feature, old_crtc_state, new_crtc_state) \
+ ((old_crtc_state)->feature && \
+ (!(new_crtc_state)->feature || intel_crtc_needs_modeset(new_crtc_state)))
+
static bool planes_enabling(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state)
{
- return (!old_crtc_state->active_planes || intel_crtc_needs_modeset(new_crtc_state)) &&
- new_crtc_state->active_planes;
+ return is_enabling(active_planes, old_crtc_state, new_crtc_state);
}
static bool planes_disabling(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state)
{
- return old_crtc_state->active_planes &&
- (!new_crtc_state->active_planes || intel_crtc_needs_modeset(new_crtc_state));
+ return is_disabling(active_planes, old_crtc_state, new_crtc_state);
+}
+
+static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,
+ const struct intel_crtc_state *new_crtc_state)
+{
+ return is_enabling(vrr.enable, old_crtc_state, new_crtc_state);
+}
+
+static bool vrr_disabling(const struct intel_crtc_state *old_crtc_state,
+ const struct intel_crtc_state *new_crtc_state)
+{
+ return is_disabling(vrr.enable, old_crtc_state, new_crtc_state);
}
+#undef is_disabling
+#undef is_enabling
+
static void intel_post_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@@ -1196,6 +1041,11 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
intel_atomic_get_new_crtc_state(state, crtc);
enum pipe pipe = crtc->pipe;
+ if (vrr_disabling(old_crtc_state, new_crtc_state)) {
+ intel_vrr_disable(old_crtc_state);
+ intel_crtc_update_active_timings(old_crtc_state, false);
+ }
+
intel_drrs_deactivate(old_crtc_state);
intel_psr_pre_plane_update(state, crtc);
@@ -1676,6 +1526,8 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta
}
intel_set_transcoder_timings(crtc_state);
+ if (HAS_VRR(dev_priv))
+ intel_vrr_set_transcoder_timings(crtc_state);
if (cpu_transcoder != TRANSCODER_EDP)
intel_de_write(dev_priv, TRANS_MULT(cpu_transcoder),
@@ -1851,9 +1703,17 @@ static void hsw_crtc_disable(struct intel_atomic_state *state,
intel_disable_shared_dpll(old_crtc_state);
- intel_encoders_post_pll_disable(state, crtc);
+ if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
+ struct intel_crtc *slave_crtc;
+
+ intel_encoders_post_pll_disable(state, crtc);
- intel_dmc_disable_pipe(i915, crtc->pipe);
+ intel_dmc_disable_pipe(i915, crtc->pipe);
+
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
+ intel_crtc_bigjoiner_slave_pipes(old_crtc_state))
+ intel_dmc_disable_pipe(i915, slave_crtc->pipe);
+ }
}
static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
@@ -1907,7 +1767,7 @@ bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy)
if (IS_DG2(dev_priv))
/* DG2's "TC1" output uses a SNPS PHY */
return false;
- else if (IS_ALDERLAKE_P(dev_priv))
+ else if (IS_ALDERLAKE_P(dev_priv) || IS_METEORLAKE(dev_priv))
return phy >= PHY_F && phy <= PHY_I;
else if (IS_TIGERLAKE(dev_priv))
return phy >= PHY_D && phy <= PHY_I;
@@ -2214,30 +2074,6 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state,
i830_enable_pipe(dev_priv, pipe);
}
-
-/*
- * turn all crtc's off, but do not adjust state
- * This has to be paired with a call to intel_modeset_setup_hw_state.
- */
-int intel_display_suspend(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_atomic_state *state;
- int ret;
-
- if (!HAS_DISPLAY(dev_priv))
- return 0;
-
- state = drm_atomic_helper_suspend(dev);
- ret = PTR_ERR_OR_ZERO(state);
- if (ret)
- drm_err(&dev_priv->drm, "Suspending crtc's failed with %i\n",
- ret);
- else
- dev_priv->display.restore.modeset_state = state;
- return ret;
-}
-
void intel_encoder_destroy(struct drm_encoder *encoder)
{
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
@@ -2567,7 +2403,7 @@ intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
0x80000);
}
-static void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv)
+void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv)
{
/*
* There may be no VBT; and if the BIOS enabled SSC we can
@@ -2923,6 +2759,7 @@ static void i9xx_get_pfit_config(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum pipe pipe;
u32 tmp;
if (!i9xx_has_pfit(dev_priv))
@@ -2933,13 +2770,13 @@ static void i9xx_get_pfit_config(struct intel_crtc_state *crtc_state)
return;
/* Check whether the pfit is attached to our pipe. */
- if (DISPLAY_VER(dev_priv) < 4) {
- if (crtc->pipe != PIPE_B)
- return;
- } else {
- if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT))
- return;
- }
+ if (DISPLAY_VER(dev_priv) >= 4)
+ pipe = REG_FIELD_GET(PFIT_PIPE_MASK, tmp);
+ else
+ pipe = PIPE_B;
+
+ if (pipe != crtc->pipe)
+ return;
crtc_state->gmch_pfit.control = tmp;
crtc_state->gmch_pfit.pgm_ratios =
@@ -3061,6 +2898,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
return false;
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
+ pipe_config->sink_format = pipe_config->output_format;
pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
pipe_config->shared_dpll = NULL;
@@ -3398,73 +3236,39 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc,
PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder));
}
-static void ilk_get_pfit_pos_size(struct intel_crtc_state *crtc_state,
- u32 pos, u32 size)
-{
- drm_rect_init(&crtc_state->pch_pfit.dst,
- pos >> 16, pos & 0xffff,
- size >> 16, size & 0xffff);
-}
-
-static void skl_get_pfit_config(struct intel_crtc_state *crtc_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
- int id = -1;
- int i;
-
- /* find scaler attached to this pipe */
- for (i = 0; i < crtc->num_scalers; i++) {
- u32 ctl, pos, size;
-
- ctl = intel_de_read(dev_priv, SKL_PS_CTRL(crtc->pipe, i));
- if ((ctl & (PS_SCALER_EN | PS_PLANE_SEL_MASK)) != PS_SCALER_EN)
- continue;
-
- id = i;
- crtc_state->pch_pfit.enabled = true;
-
- pos = intel_de_read(dev_priv, SKL_PS_WIN_POS(crtc->pipe, i));
- size = intel_de_read(dev_priv, SKL_PS_WIN_SZ(crtc->pipe, i));
-
- ilk_get_pfit_pos_size(crtc_state, pos, size);
-
- scaler_state->scalers[i].in_use = true;
- break;
- }
-
- scaler_state->scaler_id = id;
- if (id >= 0)
- scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX);
- else
- scaler_state->scaler_users &= ~(1 << SKL_CRTC_INDEX);
-}
-
static void ilk_get_pfit_config(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 ctl, pos, size;
+ enum pipe pipe;
ctl = intel_de_read(dev_priv, PF_CTL(crtc->pipe));
if ((ctl & PF_ENABLE) == 0)
return;
+ if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv))
+ pipe = REG_FIELD_GET(PF_PIPE_SEL_MASK_IVB, ctl);
+ else
+ pipe = crtc->pipe;
+
crtc_state->pch_pfit.enabled = true;
pos = intel_de_read(dev_priv, PF_WIN_POS(crtc->pipe));
size = intel_de_read(dev_priv, PF_WIN_SZ(crtc->pipe));
- ilk_get_pfit_pos_size(crtc_state, pos, size);
+ drm_rect_init(&crtc_state->pch_pfit.dst,
+ REG_FIELD_GET(PF_WIN_XPOS_MASK, pos),
+ REG_FIELD_GET(PF_WIN_YPOS_MASK, pos),
+ REG_FIELD_GET(PF_WIN_XSIZE_MASK, size),
+ REG_FIELD_GET(PF_WIN_YSIZE_MASK, size));
/*
* We currently do not free assignements of panel fitters on
* ivb/hsw (since we don't use the higher upscaling modes which
* differentiates them) so just WARN about this case for now.
*/
- drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) == 7 &&
- (ctl & PF_PIPE_SEL_MASK_IVB) != PF_PIPE_SEL_IVB(crtc->pipe));
+ drm_WARN_ON(&dev_priv->drm, pipe != crtc->pipe);
}
static bool ilk_get_pipe_config(struct intel_crtc *crtc,
@@ -3520,6 +3324,8 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
break;
}
+ pipe_config->sink_format = pipe_config->output_format;
+
pipe_config->gamma_mode = REG_FIELD_GET(TRANSCONF_GAMMA_MODE_MASK_ILK, tmp);
pipe_config->framestart_delay = REG_FIELD_GET(TRANSCONF_FRAME_START_DELAY_MASK, tmp) + 1;
@@ -3901,7 +3707,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
intel_get_transcoder_timings(crtc, pipe_config);
if (HAS_VRR(dev_priv) && !transcoder_is_dsi(pipe_config->cpu_transcoder))
- intel_vrr_get_config(crtc, pipe_config);
+ intel_vrr_get_config(pipe_config);
intel_get_pipe_src_size(crtc, pipe_config);
@@ -3918,6 +3724,8 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
bdw_get_pipe_misc_output_format(crtc);
}
+ pipe_config->sink_format = pipe_config->output_format;
+
pipe_config->gamma_mode = intel_de_read(dev_priv,
GAMMA_MODE(crtc->pipe));
@@ -3947,7 +3755,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
if (intel_display_power_get_in_set_if_enabled(dev_priv, &crtc->hw_readout_power_domains,
POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe))) {
if (DISPLAY_VER(dev_priv) >= 9)
- skl_get_pfit_config(pipe_config);
+ skl_scaler_get_config(pipe_config);
else
ilk_get_pfit_config(pipe_config);
}
@@ -3995,218 +3803,6 @@ bool intel_crtc_get_pipe_config(struct intel_crtc_state *crtc_state)
return true;
}
-/* VESA 640x480x72Hz mode to set on the pipe */
-static const struct drm_display_mode load_detect_mode = {
- DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664,
- 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
-};
-
-static int intel_modeset_disable_planes(struct drm_atomic_state *state,
- struct drm_crtc *crtc)
-{
- struct drm_plane *plane;
- struct drm_plane_state *plane_state;
- int ret, i;
-
- ret = drm_atomic_add_affected_planes(state, crtc);
- if (ret)
- return ret;
-
- for_each_new_plane_in_state(state, plane, plane_state, i) {
- if (plane_state->crtc != crtc)
- continue;
-
- ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
- if (ret)
- return ret;
-
- drm_atomic_set_fb_for_plane(plane_state, NULL);
- }
-
- return 0;
-}
-
-int intel_get_load_detect_pipe(struct drm_connector *connector,
- struct intel_load_detect_pipe *old,
- struct drm_modeset_acquire_ctx *ctx)
-{
- struct intel_encoder *encoder =
- intel_attached_encoder(to_intel_connector(connector));
- struct intel_crtc *possible_crtc;
- struct intel_crtc *crtc = NULL;
- struct drm_device *dev = encoder->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_mode_config *config = &dev->mode_config;
- struct drm_atomic_state *state = NULL, *restore_state = NULL;
- struct drm_connector_state *connector_state;
- struct intel_crtc_state *crtc_state;
- int ret;
-
- drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
- connector->base.id, connector->name,
- encoder->base.base.id, encoder->base.name);
-
- old->restore_state = NULL;
-
- drm_WARN_ON(dev, !drm_modeset_is_locked(&config->connection_mutex));
-
- /*
- * Algorithm gets a little messy:
- *
- * - if the connector already has an assigned crtc, use it (but make
- * sure it's on first)
- *
- * - try to find the first unused crtc that can drive this connector,
- * and use that if we find one
- */
-
- /* See if we already have a CRTC for this connector */
- if (connector->state->crtc) {
- crtc = to_intel_crtc(connector->state->crtc);
-
- ret = drm_modeset_lock(&crtc->base.mutex, ctx);
- if (ret)
- goto fail;
-
- /* Make sure the crtc and connector are running */
- goto found;
- }
-
- /* Find an unused one (if possible) */
- for_each_intel_crtc(dev, possible_crtc) {
- if (!(encoder->base.possible_crtcs &
- drm_crtc_mask(&possible_crtc->base)))
- continue;
-
- ret = drm_modeset_lock(&possible_crtc->base.mutex, ctx);
- if (ret)
- goto fail;
-
- if (possible_crtc->base.state->enable) {
- drm_modeset_unlock(&possible_crtc->base.mutex);
- continue;
- }
-
- crtc = possible_crtc;
- break;
- }
-
- /*
- * If we didn't find an unused CRTC, don't use any.
- */
- if (!crtc) {
- drm_dbg_kms(&dev_priv->drm,
- "no pipe available for load-detect\n");
- ret = -ENODEV;
- goto fail;
- }
-
-found:
- state = drm_atomic_state_alloc(dev);
- restore_state = drm_atomic_state_alloc(dev);
- if (!state || !restore_state) {
- ret = -ENOMEM;
- goto fail;
- }
-
- state->acquire_ctx = ctx;
- restore_state->acquire_ctx = ctx;
-
- connector_state = drm_atomic_get_connector_state(state, connector);
- if (IS_ERR(connector_state)) {
- ret = PTR_ERR(connector_state);
- goto fail;
- }
-
- ret = drm_atomic_set_crtc_for_connector(connector_state, &crtc->base);
- if (ret)
- goto fail;
-
- crtc_state = intel_atomic_get_crtc_state(state, crtc);
- if (IS_ERR(crtc_state)) {
- ret = PTR_ERR(crtc_state);
- goto fail;
- }
-
- crtc_state->uapi.active = true;
-
- ret = drm_atomic_set_mode_for_crtc(&crtc_state->uapi,
- &load_detect_mode);
- if (ret)
- goto fail;
-
- ret = intel_modeset_disable_planes(state, &crtc->base);
- if (ret)
- goto fail;
-
- ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector));
- if (!ret)
- ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, &crtc->base));
- if (!ret)
- ret = drm_atomic_add_affected_planes(restore_state, &crtc->base);
- if (ret) {
- drm_dbg_kms(&dev_priv->drm,
- "Failed to create a copy of old state to restore: %i\n",
- ret);
- goto fail;
- }
-
- ret = drm_atomic_commit(state);
- if (ret) {
- drm_dbg_kms(&dev_priv->drm,
- "failed to set mode on load-detect pipe\n");
- goto fail;
- }
-
- old->restore_state = restore_state;
- drm_atomic_state_put(state);
-
- /* let the connector get through one full cycle before testing */
- intel_crtc_wait_for_next_vblank(crtc);
-
- return true;
-
-fail:
- if (state) {
- drm_atomic_state_put(state);
- state = NULL;
- }
- if (restore_state) {
- drm_atomic_state_put(restore_state);
- restore_state = NULL;
- }
-
- if (ret == -EDEADLK)
- return ret;
-
- return false;
-}
-
-void intel_release_load_detect_pipe(struct drm_connector *connector,
- struct intel_load_detect_pipe *old,
- struct drm_modeset_acquire_ctx *ctx)
-{
- struct intel_encoder *intel_encoder =
- intel_attached_encoder(to_intel_connector(connector));
- struct drm_i915_private *i915 = to_i915(intel_encoder->base.dev);
- struct drm_encoder *encoder = &intel_encoder->base;
- struct drm_atomic_state *state = old->restore_state;
- int ret;
-
- drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
- connector->base.id, connector->name,
- encoder->base.id, encoder->name);
-
- if (!state)
- return;
-
- ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
- if (ret)
- drm_dbg_kms(&i915->drm,
- "Couldn't release load detect pipe: %i\n", ret);
- drm_atomic_state_put(state);
-}
-
static int i9xx_pll_refclk(struct drm_device *dev,
const struct intel_crtc_state *pipe_config)
{
@@ -5269,7 +4865,7 @@ pipe_config_infoframe_mismatch(struct drm_i915_private *dev_priv,
return;
drm_dbg_kms(&dev_priv->drm,
- "fastset mismatch in %s infoframe\n", name);
+ "fastset requirement not met in %s infoframe\n", name);
drm_dbg_kms(&dev_priv->drm, "expected:\n");
hdmi_infoframe_log(KERN_DEBUG, dev_priv->drm.dev, a);
drm_dbg_kms(&dev_priv->drm, "found:\n");
@@ -5294,7 +4890,7 @@ pipe_config_dp_vsc_sdp_mismatch(struct drm_i915_private *dev_priv,
return;
drm_dbg_kms(&dev_priv->drm,
- "fastset mismatch in %s dp sdp\n", name);
+ "fastset requirement not met in %s dp sdp\n", name);
drm_dbg_kms(&dev_priv->drm, "expected:\n");
drm_dp_vsc_sdp_log(KERN_DEBUG, dev_priv->drm.dev, a);
drm_dbg_kms(&dev_priv->drm, "found:\n");
@@ -5335,7 +4931,7 @@ pipe_config_buffer_mismatch(struct drm_i915_private *dev_priv,
len = memcmp_diff_len(a, b, len);
drm_dbg_kms(&dev_priv->drm,
- "fastset mismatch in %s buffer\n", name);
+ "fastset requirement not met in %s buffer\n", name);
print_hex_dump(KERN_DEBUG, "expected: ", DUMP_PREFIX_NONE,
16, 0, a, len, false);
print_hex_dump(KERN_DEBUG, "found: ", DUMP_PREFIX_NONE,
@@ -5366,7 +4962,7 @@ pipe_config_mismatch(bool fastset, const struct intel_crtc *crtc,
if (fastset)
drm_dbg_kms(&i915->drm,
- "[CRTC:%d:%s] fastset mismatch in %s %pV\n",
+ "[CRTC:%d:%s] fastset requirement not met in %s %pV\n",
crtc->base.base.id, crtc->base.name, name, &vaf);
else
drm_err(&i915->drm, "[CRTC:%d:%s] mismatch in %s %pV\n",
@@ -5573,6 +5169,24 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
} \
} while (0)
+#define PIPE_CONF_CHECK_CSC(name) do { \
+ PIPE_CONF_CHECK_X(name.preoff[0]); \
+ PIPE_CONF_CHECK_X(name.preoff[1]); \
+ PIPE_CONF_CHECK_X(name.preoff[2]); \
+ PIPE_CONF_CHECK_X(name.coeff[0]); \
+ PIPE_CONF_CHECK_X(name.coeff[1]); \
+ PIPE_CONF_CHECK_X(name.coeff[2]); \
+ PIPE_CONF_CHECK_X(name.coeff[3]); \
+ PIPE_CONF_CHECK_X(name.coeff[4]); \
+ PIPE_CONF_CHECK_X(name.coeff[5]); \
+ PIPE_CONF_CHECK_X(name.coeff[6]); \
+ PIPE_CONF_CHECK_X(name.coeff[7]); \
+ PIPE_CONF_CHECK_X(name.coeff[8]); \
+ PIPE_CONF_CHECK_X(name.postoff[0]); \
+ PIPE_CONF_CHECK_X(name.postoff[1]); \
+ PIPE_CONF_CHECK_X(name.postoff[2]); \
+} while (0)
+
#define PIPE_CONF_QUIRK(quirk) \
((current_config->quirks | pipe_config->quirks) & (quirk))
@@ -5670,6 +5284,9 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_COLOR_LUT(pre_csc_lut, true);
PIPE_CONF_CHECK_COLOR_LUT(post_csc_lut, false);
+ PIPE_CONF_CHECK_CSC(csc);
+ PIPE_CONF_CHECK_CSC(output_csc);
+
if (current_config->active_planes) {
PIPE_CONF_CHECK_BOOL(has_psr);
PIPE_CONF_CHECK_BOOL(has_psr2);
@@ -5756,7 +5373,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_I(splitter.link_count);
PIPE_CONF_CHECK_I(splitter.pixel_overlap);
- PIPE_CONF_CHECK_BOOL(vrr.enable);
+ if (!fastset)
+ PIPE_CONF_CHECK_BOOL(vrr.enable);
PIPE_CONF_CHECK_I(vrr.vmin);
PIPE_CONF_CHECK_I(vrr.vmax);
PIPE_CONF_CHECK_I(vrr.flipline);
@@ -5932,8 +5550,13 @@ static int intel_modeset_checks(struct intel_atomic_state *state)
static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *new_crtc_state)
{
- if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true))
+ struct drm_i915_private *i915 = to_i915(old_crtc_state->uapi.crtc->dev);
+
+ if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true)) {
+ drm_dbg_kms(&i915->drm, "fastset requirement not met, forcing full modeset\n");
+
return;
+ }
new_crtc_state->uapi.mode_changed = false;
if (!intel_crtc_needs_modeset(new_crtc_state))
@@ -6536,6 +6159,13 @@ int intel_atomic_check(struct drm_device *dev,
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
+ /*
+ * crtc's state no longer considered to be inherited
+ * after the first userspace/client initiated commit.
+ */
+ if (!state->internal)
+ new_crtc_state->inherited = false;
+
if (new_crtc_state->inherited != old_crtc_state->inherited)
new_crtc_state->uapi.mode_changed = true;
@@ -6881,7 +6511,8 @@ static void intel_enable_crtc(struct intel_atomic_state *state,
if (!intel_crtc_needs_modeset(new_crtc_state))
return;
- intel_crtc_update_active_timings(new_crtc_state);
+ /* VRR will be enable later, if required */
+ intel_crtc_update_active_timings(new_crtc_state, false);
dev_priv->display.funcs.display->crtc_enable(state, crtc);
@@ -6908,6 +6539,12 @@ static void intel_update_crtc(struct intel_atomic_state *state,
intel_dpt_configure(crtc);
}
+ if (vrr_enabling(old_crtc_state, new_crtc_state)) {
+ intel_vrr_enable(new_crtc_state);
+ intel_crtc_update_active_timings(new_crtc_state,
+ new_crtc_state->vrr.enable);
+ }
+
if (!modeset) {
if (new_crtc_state->preload_luts &&
intel_crtc_needs_color_update(new_crtc_state))
@@ -7181,7 +6818,7 @@ static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv)
drm_atomic_state_put(&state->base);
}
-static void intel_atomic_helper_free_state_worker(struct work_struct *work)
+void intel_atomic_helper_free_state_worker(struct work_struct *work)
{
struct drm_i915_private *dev_priv =
container_of(work, typeof(*dev_priv), display.atomic_helper.free_work);
@@ -7313,6 +6950,12 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
* 7. New _arm() registers are finally written
* 8. Hardware finally latches a complete set of new
* register values, and subsequent frames will be OK again
+ *
+ * Also note that due to the pipe CSC hardware issues on
+ * SKL/GLK DC states must remain off until the pipe CSC
+ * state readout has happened. Otherwise we risk corrupting
+ * the CSC latched register values with the readout (see
+ * skl_read_csc() and skl_color_commit_noarm()).
*/
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DC_OFF);
@@ -7523,9 +7166,8 @@ static void intel_atomic_track_fbs(struct intel_atomic_state *state)
plane->frontbuffer_bit);
}
-static int intel_atomic_commit(struct drm_device *dev,
- struct drm_atomic_state *_state,
- bool nonblock)
+int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state,
+ bool nonblock)
{
struct intel_atomic_state *state = to_intel_atomic_state(_state);
struct drm_i915_private *dev_priv = to_i915(dev);
@@ -7627,19 +7269,6 @@ void intel_plane_destroy(struct drm_plane *plane)
kfree(to_intel_plane(plane));
}
-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_crtc_for_pipe(dev_priv,
- plane->pipe);
-
- plane->base.possible_crtcs = drm_crtc_mask(&crtc->base);
- }
-}
-
-
int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
{
@@ -7719,7 +7348,7 @@ static bool intel_ddi_crt_present(struct drm_i915_private *dev_priv)
return true;
}
-static void intel_setup_outputs(struct drm_i915_private *dev_priv)
+void intel_setup_outputs(struct drm_i915_private *dev_priv)
{
struct intel_encoder *encoder;
bool dpd_is_edp = false;
@@ -7729,7 +7358,14 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
if (!HAS_DISPLAY(dev_priv))
return;
- if (IS_DG2(dev_priv)) {
+ if (IS_METEORLAKE(dev_priv)) {
+ intel_ddi_init(dev_priv, PORT_A);
+ intel_ddi_init(dev_priv, PORT_B);
+ intel_ddi_init(dev_priv, PORT_TC1);
+ intel_ddi_init(dev_priv, PORT_TC2);
+ intel_ddi_init(dev_priv, PORT_TC3);
+ intel_ddi_init(dev_priv, PORT_TC4);
+ } else if (IS_DG2(dev_priv)) {
intel_ddi_init(dev_priv, PORT_A);
intel_ddi_init(dev_priv, PORT_B);
intel_ddi_init(dev_priv, PORT_C);
@@ -7971,9 +7607,8 @@ static int max_dotclock(struct drm_i915_private *i915)
return max_dotclock;
}
-static enum drm_mode_status
-intel_mode_valid(struct drm_device *dev,
- const struct drm_display_mode *mode)
+enum drm_mode_status intel_mode_valid(struct drm_device *dev,
+ const struct drm_display_mode *mode)
{
struct drm_i915_private *dev_priv = to_i915(dev);
int hdisplay_max, htotal_max;
@@ -8113,18 +7748,6 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
return MODE_OK;
}
-static const struct drm_mode_config_funcs intel_mode_funcs = {
- .fb_create = intel_user_framebuffer_create,
- .get_format_info = intel_fb_get_format_info,
- .output_poll_changed = intel_fbdev_output_poll_changed,
- .mode_valid = intel_mode_valid,
- .atomic_check = intel_atomic_check,
- .atomic_commit = intel_atomic_commit,
- .atomic_state_alloc = intel_atomic_state_alloc,
- .atomic_state_clear = intel_atomic_state_clear,
- .atomic_state_free = intel_atomic_state_free,
-};
-
static const struct intel_display_funcs skl_display_funcs = {
.get_pipe_config = hsw_get_pipe_config,
.crtc_enable = hsw_crtc_enable,
@@ -8171,15 +7794,6 @@ static const struct intel_display_funcs i9xx_display_funcs = {
*/
void intel_init_display_hooks(struct drm_i915_private *dev_priv)
{
- if (!HAS_DISPLAY(dev_priv))
- return;
-
- intel_color_init_hooks(dev_priv);
- intel_init_cdclk_hooks(dev_priv);
- intel_audio_hooks_init(dev_priv);
-
- intel_dpll_init_clock_hook(dev_priv);
-
if (DISPLAY_VER(dev_priv) >= 9) {
dev_priv->display.funcs.display = &skl_display_funcs;
} else if (HAS_DDI(dev_priv)) {
@@ -8192,25 +7806,9 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
} else {
dev_priv->display.funcs.display = &i9xx_display_funcs;
}
-
- intel_fdi_init_hook(dev_priv);
-}
-
-void intel_modeset_init_hw(struct drm_i915_private *i915)
-{
- struct intel_cdclk_state *cdclk_state;
-
- if (!HAS_DISPLAY(i915))
- return;
-
- cdclk_state = to_intel_cdclk_state(i915->display.cdclk.obj.state);
-
- intel_update_cdclk(i915);
- intel_cdclk_dump_config(i915, &i915->display.cdclk.hw, "Current CDCLK");
- cdclk_state->logical = cdclk_state->actual = i915->display.cdclk.hw;
}
-static int intel_initial_commit(struct drm_device *dev)
+int intel_initial_commit(struct drm_device *dev)
{
struct drm_atomic_state *state = NULL;
struct drm_modeset_acquire_ctx ctx;
@@ -8223,9 +7821,10 @@ static int intel_initial_commit(struct drm_device *dev)
drm_modeset_acquire_init(&ctx, 0);
-retry:
state->acquire_ctx = &ctx;
+ to_intel_atomic_state(state)->internal = true;
+retry:
for_each_intel_crtc(dev, crtc) {
struct intel_crtc_state *crtc_state =
intel_atomic_get_crtc_state(state, crtc);
@@ -8238,15 +7837,6 @@ retry:
if (crtc_state->hw.active) {
struct intel_encoder *encoder;
- /*
- * We've not yet detected sink capabilities
- * (audio,infoframes,etc.) and thus we don't want to
- * force a full state recomputation yet. We want that to
- * happen only for the first real commit from userspace.
- * So preserve the inherited flag for the time being.
- */
- crtc_state->inherited = true;
-
ret = drm_atomic_add_affected_planes(state, &crtc->base);
if (ret)
goto out;
@@ -8289,246 +7879,6 @@ out:
return ret;
}
-static const struct drm_mode_config_helper_funcs intel_mode_config_funcs = {
- .atomic_commit_setup = drm_dp_mst_atomic_setup_commit,
-};
-
-static void intel_mode_config_init(struct drm_i915_private *i915)
-{
- struct drm_mode_config *mode_config = &i915->drm.mode_config;
-
- drm_mode_config_init(&i915->drm);
- INIT_LIST_HEAD(&i915->display.global.obj_list);
-
- mode_config->min_width = 0;
- mode_config->min_height = 0;
-
- mode_config->preferred_depth = 24;
- mode_config->prefer_shadow = 1;
-
- mode_config->funcs = &intel_mode_funcs;
- mode_config->helper_private = &intel_mode_config_funcs;
-
- mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915);
-
- /*
- * Maximum framebuffer dimensions, chosen to match
- * the maximum render engine surface size on gen4+.
- */
- if (DISPLAY_VER(i915) >= 7) {
- mode_config->max_width = 16384;
- mode_config->max_height = 16384;
- } else if (DISPLAY_VER(i915) >= 4) {
- mode_config->max_width = 8192;
- mode_config->max_height = 8192;
- } else if (DISPLAY_VER(i915) == 3) {
- mode_config->max_width = 4096;
- mode_config->max_height = 4096;
- } else {
- mode_config->max_width = 2048;
- mode_config->max_height = 2048;
- }
-
- if (IS_I845G(i915) || IS_I865G(i915)) {
- mode_config->cursor_width = IS_I845G(i915) ? 64 : 512;
- mode_config->cursor_height = 1023;
- } else if (IS_I830(i915) || IS_I85X(i915) ||
- IS_I915G(i915) || IS_I915GM(i915)) {
- mode_config->cursor_width = 64;
- mode_config->cursor_height = 64;
- } else {
- mode_config->cursor_width = 256;
- mode_config->cursor_height = 256;
- }
-}
-
-static void intel_mode_config_cleanup(struct drm_i915_private *i915)
-{
- intel_atomic_global_obj_cleanup(i915);
- drm_mode_config_cleanup(&i915->drm);
-}
-
-/* part #1: call before irq install */
-int intel_modeset_init_noirq(struct drm_i915_private *i915)
-{
- int ret;
-
- if (i915_inject_probe_failure(i915))
- return -ENODEV;
-
- if (HAS_DISPLAY(i915)) {
- ret = drm_vblank_init(&i915->drm,
- INTEL_NUM_PIPES(i915));
- if (ret)
- return ret;
- }
-
- intel_bios_init(i915);
-
- ret = intel_vga_register(i915);
- if (ret)
- goto cleanup_bios;
-
- /* FIXME: completely on the wrong abstraction layer */
- ret = intel_power_domains_init(i915);
- if (ret < 0)
- goto cleanup_vga;
-
- intel_power_domains_init_hw(i915, false);
-
- if (!HAS_DISPLAY(i915))
- return 0;
-
- intel_dmc_init(i915);
-
- i915->display.wq.modeset = alloc_ordered_workqueue("i915_modeset", 0);
- i915->display.wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI |
- WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE);
-
- intel_mode_config_init(i915);
-
- ret = intel_cdclk_init(i915);
- if (ret)
- goto cleanup_vga_client_pw_domain_dmc;
-
- ret = intel_color_init(i915);
- if (ret)
- goto cleanup_vga_client_pw_domain_dmc;
-
- ret = intel_dbuf_init(i915);
- if (ret)
- goto cleanup_vga_client_pw_domain_dmc;
-
- ret = intel_bw_init(i915);
- if (ret)
- goto cleanup_vga_client_pw_domain_dmc;
-
- init_llist_head(&i915->display.atomic_helper.free_list);
- INIT_WORK(&i915->display.atomic_helper.free_work,
- intel_atomic_helper_free_state_worker);
-
- intel_init_quirks(i915);
-
- intel_fbc_init(i915);
-
- return 0;
-
-cleanup_vga_client_pw_domain_dmc:
- intel_dmc_fini(i915);
- intel_power_domains_driver_remove(i915);
-cleanup_vga:
- intel_vga_unregister(i915);
-cleanup_bios:
- intel_bios_driver_remove(i915);
-
- return ret;
-}
-
-/* part #2: call after irq install, but before gem init */
-int intel_modeset_init_nogem(struct drm_i915_private *i915)
-{
- struct drm_device *dev = &i915->drm;
- enum pipe pipe;
- struct intel_crtc *crtc;
- int ret;
-
- if (!HAS_DISPLAY(i915))
- return 0;
-
- intel_wm_init(i915);
-
- intel_panel_sanitize_ssc(i915);
-
- intel_pps_setup(i915);
-
- intel_gmbus_setup(i915);
-
- drm_dbg_kms(&i915->drm, "%d display pipe%s available.\n",
- INTEL_NUM_PIPES(i915),
- INTEL_NUM_PIPES(i915) > 1 ? "s" : "");
-
- for_each_pipe(i915, pipe) {
- ret = intel_crtc_init(i915, pipe);
- if (ret) {
- intel_mode_config_cleanup(i915);
- return ret;
- }
- }
-
- intel_plane_possible_crtcs_init(i915);
- intel_shared_dpll_init(i915);
- intel_fdi_pll_freq_update(i915);
-
- intel_update_czclk(i915);
- intel_modeset_init_hw(i915);
- intel_dpll_update_ref_clks(i915);
-
- intel_hdcp_component_init(i915);
-
- if (i915->display.cdclk.max_cdclk_freq == 0)
- intel_update_max_cdclk(i915);
-
- intel_hti_init(i915);
-
- /* Just disable it once at startup */
- intel_vga_disable(i915);
- intel_setup_outputs(i915);
-
- drm_modeset_lock_all(dev);
- intel_modeset_setup_hw_state(i915, dev->mode_config.acquire_ctx);
- intel_acpi_assign_connector_fwnodes(i915);
- drm_modeset_unlock_all(dev);
-
- for_each_intel_crtc(dev, crtc) {
- if (!to_intel_crtc_state(crtc->base.state)->uapi.active)
- continue;
- intel_crtc_initial_plane_config(crtc);
- }
-
- /*
- * Make sure hardware watermarks really match the state we read out.
- * Note that we need to do this after reconstructing the BIOS fb's
- * since the watermark calculation done here will use pstate->fb.
- */
- if (!HAS_GMCH(i915))
- ilk_wm_sanitize(i915);
-
- return 0;
-}
-
-/* part #3: call after gem init */
-int intel_modeset_init(struct drm_i915_private *i915)
-{
- int ret;
-
- if (!HAS_DISPLAY(i915))
- return 0;
-
- /*
- * Force all active planes to recompute their states. So that on
- * mode_setcrtc after probe, all the intel_plane_state variables
- * are already calculated and there is no assert_plane warnings
- * during bootup.
- */
- ret = intel_initial_commit(&i915->drm);
- if (ret)
- drm_dbg_kms(&i915->drm, "Initial modeset failed, %d\n", ret);
-
- intel_overlay_setup(i915);
-
- ret = intel_fbdev_init(&i915->drm);
- if (ret)
- return ret;
-
- /* Only enable hotplug handling once the fbdev is fully set up. */
- intel_hpd_init(i915);
- intel_hpd_poll_disable(i915);
-
- skl_watermark_ipc_init(i915);
-
- return 0;
-}
-
void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
{
struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
@@ -8636,45 +7986,7 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
intel_de_posting_read(dev_priv, DPLL(pipe));
}
-void intel_display_resume(struct drm_device *dev)
-{
- struct drm_i915_private *i915 = to_i915(dev);
- struct drm_atomic_state *state = i915->display.restore.modeset_state;
- struct drm_modeset_acquire_ctx ctx;
- int ret;
-
- if (!HAS_DISPLAY(i915))
- return;
-
- i915->display.restore.modeset_state = NULL;
- if (state)
- state->acquire_ctx = &ctx;
-
- drm_modeset_acquire_init(&ctx, 0);
-
- while (1) {
- ret = drm_modeset_lock_all_ctx(dev, &ctx);
- if (ret != -EDEADLK)
- break;
-
- drm_modeset_backoff(&ctx);
- }
-
- if (!ret)
- ret = __intel_display_resume(i915, state, &ctx);
-
- skl_watermark_ipc_update(i915);
- drm_modeset_drop_locks(&ctx);
- drm_modeset_acquire_fini(&ctx);
-
- if (ret)
- drm_err(&i915->drm,
- "Restoring old state failed with %i\n", ret);
- if (state)
- drm_atomic_state_put(state);
-}
-
-static void intel_hpd_poll_fini(struct drm_i915_private *i915)
+void intel_hpd_poll_fini(struct drm_i915_private *i915)
{
struct intel_connector *connector;
struct drm_connector_list_iter conn_iter;
@@ -8692,144 +8004,6 @@ static void intel_hpd_poll_fini(struct drm_i915_private *i915)
drm_connector_list_iter_end(&conn_iter);
}
-/* part #1: call before irq uninstall */
-void intel_modeset_driver_remove(struct drm_i915_private *i915)
-{
- if (!HAS_DISPLAY(i915))
- return;
-
- flush_workqueue(i915->display.wq.flip);
- flush_workqueue(i915->display.wq.modeset);
-
- flush_work(&i915->display.atomic_helper.free_work);
- drm_WARN_ON(&i915->drm, !llist_empty(&i915->display.atomic_helper.free_list));
-
- /*
- * MST topology needs to be suspended so we don't have any calls to
- * fbdev after it's finalized. MST will be destroyed later as part of
- * drm_mode_config_cleanup()
- */
- intel_dp_mst_suspend(i915);
-}
-
-/* part #2: call after irq uninstall */
-void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915)
-{
- if (!HAS_DISPLAY(i915))
- return;
-
- /*
- * Due to the hpd irq storm handling the hotplug work can re-arm the
- * poll handlers. Hence disable polling after hpd handling is shut down.
- */
- intel_hpd_poll_fini(i915);
-
- /* poll work can call into fbdev, hence clean that up afterwards */
- intel_fbdev_fini(i915);
-
- intel_unregister_dsm_handler();
-
- /* flush any delayed tasks or pending work */
- flush_scheduled_work();
-
- intel_hdcp_component_fini(i915);
-
- intel_mode_config_cleanup(i915);
-
- intel_overlay_cleanup(i915);
-
- intel_gmbus_teardown(i915);
-
- destroy_workqueue(i915->display.wq.flip);
- destroy_workqueue(i915->display.wq.modeset);
-
- intel_fbc_cleanup(i915);
-}
-
-/* part #3: call after gem init */
-void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915)
-{
- intel_dmc_fini(i915);
-
- intel_power_domains_driver_remove(i915);
-
- intel_vga_unregister(i915);
-
- intel_bios_driver_remove(i915);
-}
-
-bool intel_modeset_probe_defer(struct pci_dev *pdev)
-{
- struct drm_privacy_screen *privacy_screen;
-
- /*
- * apple-gmux is needed on dual GPU MacBook Pro
- * to probe the panel if we're the inactive GPU.
- */
- if (vga_switcheroo_client_probe_defer(pdev))
- return true;
-
- /* If the LCD panel has a privacy-screen, wait for it */
- privacy_screen = drm_privacy_screen_get(&pdev->dev, NULL);
- if (IS_ERR(privacy_screen) && PTR_ERR(privacy_screen) == -EPROBE_DEFER)
- return true;
-
- drm_privacy_screen_put(privacy_screen);
-
- return false;
-}
-
-void intel_display_driver_register(struct drm_i915_private *i915)
-{
- if (!HAS_DISPLAY(i915))
- return;
-
- /* Must be done after probing outputs */
- intel_opregion_register(i915);
- intel_acpi_video_register(i915);
-
- intel_audio_init(i915);
-
- intel_display_debugfs_register(i915);
-
- /*
- * Some ports require correctly set-up hpd registers for
- * detection to work properly (leading to ghost connected
- * connector status), e.g. VGA on gm45. Hence we can only set
- * up the initial fbdev config after hpd irqs are fully
- * enabled. We do it last so that the async config cannot run
- * before the connectors are registered.
- */
- intel_fbdev_initial_config_async(i915);
-
- /*
- * We need to coordinate the hotplugs with the asynchronous
- * fbdev configuration, for which we use the
- * fbdev->async_cookie.
- */
- drm_kms_helper_poll_init(&i915->drm);
-}
-
-void intel_display_driver_unregister(struct drm_i915_private *i915)
-{
- if (!HAS_DISPLAY(i915))
- return;
-
- intel_fbdev_unregister(i915);
- intel_audio_deinit(i915);
-
- /*
- * After flushing the fbdev (incl. a late async config which
- * will have delayed queuing of a hotplug event), then flush
- * the hotplug events.
- */
- drm_kms_helper_poll_fini(&i915->drm);
- drm_atomic_helper_shutdown(&i915->drm);
-
- acpi_video_unregister();
- intel_opregion_unregister(i915);
-}
-
bool intel_scanout_needs_vtd_wa(struct drm_i915_private *i915)
{
return DISPLAY_VER(i915) >= 6 && i915_vtd_active(i915);