From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 11/18] drm/i915: skip modeset if compatible, and enable fastboot for everyone
Date: Thu, 2 Jul 2015 16:36:55 +0200 [thread overview]
Message-ID: <1435847822-5318-12-git-send-email-maarten.lankhorst@linux.intel.com> (raw)
In-Reply-To: <1435847822-5318-1-git-send-email-maarten.lankhorst@linux.intel.com>
Now that we read out the full atomic state we can force fastboot without
hacks. The only thing that we have to worry about is preventing unneeded
modesets. This can be easily done by calculating if the new state matches
the old state, with exception for pfit and pipe size. Because the original
fastboot code only touched pipe size and panel fitter we can keep that as
base options in pipe_config_compare, and patch it up inside
intel_update_pipe_config.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/i915_params.c | 5 --
drivers/gpu/drm/i915/intel_atomic.c | 2 +-
drivers/gpu/drm/i915/intel_display.c | 144 ++++++++++++++++++++++-------------
drivers/gpu/drm/i915/intel_drv.h | 2 +
drivers/gpu/drm/i915/intel_fbdev.c | 3 -
5 files changed, 92 insertions(+), 64 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 7983fe48a654..d6f9d9a117b6 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -40,7 +40,6 @@ struct i915_params i915 __read_mostly = {
.preliminary_hw_support = IS_ENABLED(CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT),
.disable_power_well = 1,
.enable_ips = 1,
- .fastboot = 0,
.prefault_disable = 0,
.load_detect_test = 0,
.reset = true,
@@ -131,10 +130,6 @@ MODULE_PARM_DESC(disable_power_well,
module_param_named(enable_ips, i915.enable_ips, int, 0600);
MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)");
-module_param_named(fastboot, i915.fastboot, bool, 0600);
-MODULE_PARM_DESC(fastboot,
- "Try to skip unnecessary mode sets at boot time (default: false)");
-
module_param_named_unsafe(prefault_disable, i915.prefault_disable, bool, 0600);
MODULE_PARM_DESC(prefault_disable,
"Disable page prefaulting for pread/pwrite/reloc (default:false). "
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index b593612a917d..0bbdc2fc5298 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -221,8 +221,8 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
return NULL;
__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
-
crtc_state->base.crtc = crtc;
+ crtc_state->update_pipe = false;
return &crtc_state->base;
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 52f7f75dd519..ae694720e263 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -110,6 +110,9 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
int num_connectors);
static void intel_pre_disable_primary(struct drm_crtc *crtc);
+static void skylake_pfit_enable(struct intel_crtc *crtc);
+static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
+static void ironlake_pfit_enable(struct intel_crtc *crtc);
static void intel_modeset_setup_hw_state(struct drm_device *dev);
static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
@@ -3299,14 +3302,17 @@ static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
return pending;
}
-static void intel_update_pipe_size(struct intel_crtc *crtc)
+static void intel_update_pipe_config(struct intel_crtc *crtc,
+ struct intel_crtc_state *old_crtc_state)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- const struct drm_display_mode *adjusted_mode;
+ struct intel_crtc_state *pipe_config =
+ to_intel_crtc_state(crtc->base.state);
- if (!i915.fastboot)
- return;
+ DRM_DEBUG_KMS("Updating pipe size %ix%i -> %ix%i\n",
+ old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h,
+ pipe_config->pipe_src_w, pipe_config->pipe_src_h);
/*
* Update pipe size and adjust fitter if needed: the reason for this is
@@ -3315,27 +3321,26 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
* fastboot case, we'll flip, but if we don't update the pipesrc and
* pfit state, we'll end up with a big fb scanned out into the wrong
* sized surface.
- *
- * To fix this properly, we need to hoist the checks up into
- * compute_mode_changes (or above), check the actual pfit state and
- * whether the platform allows pfit disable with pipe active, and only
- * then update the pipesrc and pfit state, even on the flip path.
*/
- adjusted_mode = &crtc->config->base.adjusted_mode;
-
I915_WRITE(PIPESRC(crtc->pipe),
- ((adjusted_mode->crtc_hdisplay - 1) << 16) |
- (adjusted_mode->crtc_vdisplay - 1));
- if (!crtc->config->pch_pfit.enabled &&
- (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
- intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
- I915_WRITE(PF_CTL(crtc->pipe), 0);
- I915_WRITE(PF_WIN_POS(crtc->pipe), 0);
- I915_WRITE(PF_WIN_SZ(crtc->pipe), 0);
+ ((pipe_config->pipe_src_w - 1) << 16) |
+ (pipe_config->pipe_src_h - 1));
+
+ /* on skylake this is done by detaching scalers */
+ if (INTEL_INFO(dev)->gen == 9) {
+ skl_detach_scalers(crtc);
+
+ if (pipe_config->pch_pfit.enabled)
+ skylake_pfit_enable(crtc);
+ }
+ else if (INTEL_INFO(dev)->gen < 9 &&
+ HAS_PCH_SPLIT(dev)) {
+ if (pipe_config->pch_pfit.enabled)
+ ironlake_pfit_enable(crtc);
+ else if (old_crtc_state->pch_pfit.enabled)
+ ironlake_pfit_disable(crtc, true);
}
- crtc->config->pipe_src_w = adjusted_mode->crtc_hdisplay;
- crtc->config->pipe_src_h = adjusted_mode->crtc_vdisplay;
}
static void intel_fdi_normal_train(struct drm_crtc *crtc)
@@ -5001,7 +5006,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
}
}
-static void ironlake_pfit_disable(struct intel_crtc *crtc)
+static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5009,7 +5014,7 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc)
/* To avoid upsetting the power well on haswell only disable the pfit if
* it's in use. The hw state code will make sure we get this right. */
- if (crtc->config->pch_pfit.enabled) {
+ if (force || crtc->config->pch_pfit.enabled) {
I915_WRITE(PF_CTL(pipe), 0);
I915_WRITE(PF_WIN_POS(pipe), 0);
I915_WRITE(PF_WIN_SZ(pipe), 0);
@@ -5036,7 +5041,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
intel_disable_pipe(intel_crtc);
- ironlake_pfit_disable(intel_crtc);
+ ironlake_pfit_disable(intel_crtc, false);
if (intel_crtc->config->has_pch_encoder)
ironlake_fdi_disable(crtc);
@@ -5096,7 +5101,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
if (INTEL_INFO(dev)->gen == 9)
skylake_scaler_disable(intel_crtc);
else if (INTEL_INFO(dev)->gen < 9)
- ironlake_pfit_disable(intel_crtc);
+ ironlake_pfit_disable(intel_crtc, false);
else
MISSING_CASE(INTEL_INFO(dev)->gen);
@@ -5247,7 +5252,8 @@ static void modeset_update_crtc_power_domains(struct drm_atomic_state *state)
int i;
for_each_crtc_in_state(state, crtc, crtc_state, i) {
- if (needs_modeset(crtc->state))
+ if (needs_modeset(crtc->state) ||
+ to_intel_crtc_state(crtc->state)->update_pipe)
put_domains[to_intel_crtc(crtc)->pipe] =
modeset_get_crtc_power_domains(crtc);
}
@@ -12339,7 +12345,6 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
base.head) \
if (mask & (1 <<(intel_crtc)->pipe))
-
static bool
intel_compare_m_n(unsigned int m, unsigned int n,
unsigned int m2, unsigned int n2)
@@ -12561,18 +12566,21 @@ intel_pipe_config_compare(struct drm_device *dev,
* Proper atomic modesets with recomputed global state will fix this.
* Until then just don't check gmch state for inherited modes.
*/
- if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_INHERITED_MODE)) {
- PIPE_CONF_CHECK_I(gmch_pfit.control);
- /* pfit ratios are autocomputed by the hw on gen4+ */
- if (INTEL_INFO(dev)->gen < 4)
- PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
- PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
- }
+ if (!adjust) {
+ PIPE_CONF_CHECK_I(pipe_src_w);
+ PIPE_CONF_CHECK_I(pipe_src_h);
- PIPE_CONF_CHECK_I(pch_pfit.enabled);
- if (current_config->pch_pfit.enabled) {
- PIPE_CONF_CHECK_I(pch_pfit.pos);
- PIPE_CONF_CHECK_I(pch_pfit.size);
+ PIPE_CONF_CHECK_I(pch_pfit.enabled);
+ if (current_config->pch_pfit.enabled) {
+ PIPE_CONF_CHECK_I(pch_pfit.pos);
+ PIPE_CONF_CHECK_I(pch_pfit.size);
+
+ PIPE_CONF_CHECK_I(gmch_pfit.control);
+ /* pfit ratios are autocomputed by the hw on gen4+ */
+ if (INTEL_INFO(dev)->gen < 4)
+ PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
+ PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
+ }
}
PIPE_CONF_CHECK_I(scaler_state.scaler_id);
@@ -13039,6 +13047,7 @@ static int intel_modeset_all_pipes(struct drm_atomic_state *state)
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
+ to_intel_crtc_state(crtc_state)->update_pipe = false;
if (!crtc_state->active || needs_modeset(crtc_state))
continue;
@@ -13056,6 +13065,29 @@ static int intel_modeset_all_pipes(struct drm_atomic_state *state)
return ret;
}
+static bool intel_modeset_calc_update_pipe(struct drm_crtc *crtc,
+ struct drm_crtc_state *crtc_state)
+{
+ struct drm_device *dev = crtc->dev;
+ struct intel_crtc_state *pipe_config =
+ to_intel_crtc_state(crtc_state);
+ struct intel_crtc_state *old_state =
+ to_intel_crtc_state(crtc->state);
+
+ if (crtc_state->active_changed || crtc_state->connectors_changed)
+ return false;
+
+ pipe_config->quirks = 0;
+ if (!intel_pipe_config_compare(dev, pipe_config, old_state, true)) {
+ DRM_DEBUG_ATOMIC("[CRTC:%i] new state incompatible, forcing modeset\n",
+ crtc->base.id);
+ return false;
+ }
+ pipe_config->quirks = old_state->quirks & PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS;
+ DRM_DEBUG_ATOMIC("[CRTC:%i] new state compatible, skipping modeset\n",
+ crtc->base.id);
+ return true;
+}
/* Code that should eventually be part of atomic_check() */
static int intel_modeset_checks(struct drm_atomic_state *state)
@@ -13114,6 +13146,9 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc_state);
+ if (!needs_modeset(crtc_state))
+ continue;
+
if (!crtc_state->enable) {
if (needs_modeset(crtc_state))
any_ms = true;
@@ -13133,17 +13168,13 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
if (ret)
return ret;
- if (!intel_pipe_config_compare(state->dev,
- to_intel_crtc_state(crtc->state),
- pipe_config, true))
- crtc_state->mode_changed = true;
- else if (!needs_modeset(crtc_state))
- continue;
-
any_ms = true;
+ pipe_config->update_pipe =
+ intel_modeset_calc_update_pipe(crtc, crtc_state);
+ pipe_config->base.mode_changed = !pipe_config->update_pipe;
+
intel_dump_pipe_config(to_intel_crtc(crtc),
- pipe_config,
- "[modeset]");
+ pipe_config, "[modeset]");
}
if (any_ms) {
@@ -13177,6 +13208,7 @@ static int __intel_set_mode(struct drm_atomic_state *state)
for_each_crtc_in_state(state, crtc, crtc_state, i) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ any_ms |= to_intel_crtc_state(crtc->state)->update_pipe;
if (!needs_modeset(crtc->state))
continue;
@@ -13488,8 +13520,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
if (ret)
goto out;
- intel_update_pipe_size(to_intel_crtc(set->crtc));
-
ret = intel_set_mode_checked(state);
if (ret) {
DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n",
@@ -13762,10 +13792,6 @@ intel_commit_primary_plane(struct drm_plane *plane,
if (!crtc->state->active)
return;
- if (state->visible)
- /* FIXME: kill this fastboot hack */
- intel_update_pipe_size(intel_crtc);
-
dev_priv->display.update_primary_plane(crtc, fb, crtc->x, crtc->y);
}
@@ -13785,8 +13811,11 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc_state *old_intel_state =
+ to_intel_crtc_state(old_crtc_state);
+ bool modeset = needs_modeset(crtc->state);
- if (!needs_modeset(crtc->state))
+ if (!modeset)
intel_pre_plane_update(intel_crtc);
if (intel_crtc->atomic.update_wm_pre)
@@ -13800,7 +13829,12 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
intel_pipe_update_start(intel_crtc,
&intel_crtc->atomic.start_vbl_count);
- if (!needs_modeset(crtc->state) && INTEL_INFO(dev)->gen >= 9)
+ if (modeset)
+ return;
+
+ if (to_intel_crtc_state(crtc->state)->update_pipe)
+ intel_update_pipe_config(intel_crtc, old_intel_state);
+ else if (INTEL_INFO(dev)->gen >= 9)
skl_detach_scalers(intel_crtc);
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 549fc4333d89..f7e729232f03 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -332,6 +332,8 @@ struct intel_crtc_state {
#define PIPE_CONFIG_QUIRK_INHERITED_MODE (1<<1) /* mode inherited from firmware */
unsigned long quirks;
+ bool update_pipe;
+
/* Pipe source size (ie. panel fitter input size)
* All planes will be positioned inside this space,
* and get clipped at the edges. */
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 52d20cea182c..220370161aac 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -579,9 +579,6 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
struct intel_crtc *intel_crtc;
unsigned int max_size = 0;
- if (!i915.fastboot)
- return false;
-
/* Find the largest fb */
for_each_crtc(dev, crtc) {
struct drm_i915_gem_object *obj =
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2015-07-02 14:37 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-02 14:36 [PATCH 00/18] Convert to atomic, part 4 Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 01/18] drm/atomic: add connectors_changed to separate it from mode_changed Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 02/18] drm/i915: Fix noatomic crtc disabling Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 03/18] drm/i915: Do not update pfit state when toggling crtc enabled Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 04/18] drm/i915: Do not use plane_config in intel_fbdev.c Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 05/18] drm/i915: Allow fuzzy matching in pipe_config_compare Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 06/18] drm/i915: Fill in more crtc state Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 07/18] drm/i915: fill in more mode members Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 08/18] drm/i915: Rework primary plane stuff slightly Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 09/18] drm/i915: Convert suspend/resume to atomic Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 10/18] drm/i915: Update power domains on readout Maarten Lankhorst
2015-07-02 14:36 ` Maarten Lankhorst [this message]
2015-07-02 14:36 ` [PATCH 12/18] drm/i915: Always reset in intel_crtc_restore_mode Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 13/18] drm/i915: Make intel_display_suspend atomic, try 2 Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 14/18] drm/i915: Use full atomic modeset Maarten Lankhorst
2015-07-02 14:36 ` [PATCH 15/18] drm/i915: Call plane update functions directly from intel_atomic_commit Maarten Lankhorst
2015-07-02 14:37 ` [PATCH 16/18] drm/i915: always disable irqs in intel_pipe_update_start Maarten Lankhorst
2015-07-02 14:37 ` [PATCH 17/18] drm/i915: Only commit planes on crtc's that have changed planes Maarten Lankhorst
2015-07-02 14:37 ` [PATCH 18/18] drm/i915: Remove use of runtime pm in atomic commit functions Maarten Lankhorst
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1435847822-5318-12-git-send-email-maarten.lankhorst@linux.intel.com \
--to=maarten.lankhorst@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox