Commit 3cf43cdc authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Introduce proper dbuf state

Add a global state to track the dbuf slices. Gets rid of all the nasty
coupling between state->modeset and dbuf recomputation. Also we can now
totally nuke state->active_pipe_changes.

dev_priv->wm.distrust_bios_wm still remains, but that too will get
nuked soon.

Cc: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200225171125.28885-9-ville.syrjala@linux.intel.comReviewed-by: default avatarStanislav Lisovskiy <stanislav.lisovskiy@intel.com>
parent 56f48c1d
...@@ -7579,6 +7579,8 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, ...@@ -7579,6 +7579,8 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
to_intel_bw_state(dev_priv->bw_obj.state); to_intel_bw_state(dev_priv->bw_obj.state);
struct intel_cdclk_state *cdclk_state = struct intel_cdclk_state *cdclk_state =
to_intel_cdclk_state(dev_priv->cdclk.obj.state); to_intel_cdclk_state(dev_priv->cdclk.obj.state);
struct intel_dbuf_state *dbuf_state =
to_intel_dbuf_state(dev_priv->dbuf.obj.state);
struct intel_crtc_state *crtc_state = struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state); to_intel_crtc_state(crtc->base.state);
enum intel_display_power_domain domain; enum intel_display_power_domain domain;
...@@ -7652,6 +7654,8 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, ...@@ -7652,6 +7654,8 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
cdclk_state->min_voltage_level[pipe] = 0; cdclk_state->min_voltage_level[pipe] = 0;
cdclk_state->active_pipes &= ~BIT(pipe); cdclk_state->active_pipes &= ~BIT(pipe);
dbuf_state->active_pipes &= ~BIT(pipe);
bw_state->data_rate[pipe] = 0; bw_state->data_rate[pipe] = 0;
bw_state->num_active_planes[pipe] = 0; bw_state->num_active_planes[pipe] = 0;
} }
...@@ -14009,10 +14013,10 @@ static void verify_wm_state(struct intel_crtc *crtc, ...@@ -14009,10 +14013,10 @@ static void verify_wm_state(struct intel_crtc *crtc,
hw_enabled_slices = intel_enabled_dbuf_slices_mask(dev_priv); hw_enabled_slices = intel_enabled_dbuf_slices_mask(dev_priv);
if (INTEL_GEN(dev_priv) >= 11 && if (INTEL_GEN(dev_priv) >= 11 &&
hw_enabled_slices != dev_priv->enabled_dbuf_slices_mask) hw_enabled_slices != dev_priv->dbuf.enabled_slices)
drm_err(&dev_priv->drm, drm_err(&dev_priv->drm,
"mismatch in DBUF Slices (expected 0x%x, got 0x%x)\n", "mismatch in DBUF Slices (expected 0x%x, got 0x%x)\n",
dev_priv->enabled_dbuf_slices_mask, dev_priv->dbuf.enabled_slices,
hw_enabled_slices); hw_enabled_slices);
/* planes */ /* planes */
...@@ -14553,9 +14557,7 @@ static int intel_modeset_checks(struct intel_atomic_state *state) ...@@ -14553,9 +14557,7 @@ static int intel_modeset_checks(struct intel_atomic_state *state)
state->modeset = true; state->modeset = true;
state->active_pipes = intel_calc_active_pipes(state, dev_priv->active_pipes); state->active_pipes = intel_calc_active_pipes(state, dev_priv->active_pipes);
state->active_pipe_changes = state->active_pipes ^ dev_priv->active_pipes; if (state->active_pipes != dev_priv->active_pipes) {
if (state->active_pipe_changes) {
ret = _intel_atomic_lock_global_state(state); ret = _intel_atomic_lock_global_state(state);
if (ret) if (ret)
return ret; return ret;
...@@ -15209,22 +15211,38 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state) ...@@ -15209,22 +15211,38 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
static void icl_dbuf_slice_pre_update(struct intel_atomic_state *state) static void icl_dbuf_slice_pre_update(struct intel_atomic_state *state)
{ {
struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct drm_i915_private *dev_priv = to_i915(state->base.dev);
u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_mask; const struct intel_dbuf_state *new_dbuf_state =
u8 required_slices = state->enabled_dbuf_slices_mask; intel_atomic_get_new_dbuf_state(state);
u8 slices_union = hw_enabled_slices | required_slices; const struct intel_dbuf_state *old_dbuf_state =
intel_atomic_get_old_dbuf_state(state);
if (!new_dbuf_state ||
new_dbuf_state->enabled_slices == old_dbuf_state->enabled_slices)
return;
if (INTEL_GEN(dev_priv) >= 11 && slices_union != hw_enabled_slices) WARN_ON(!new_dbuf_state->base.changed);
gen9_dbuf_slices_update(dev_priv, slices_union);
gen9_dbuf_slices_update(dev_priv,
old_dbuf_state->enabled_slices |
new_dbuf_state->enabled_slices);
} }
static void icl_dbuf_slice_post_update(struct intel_atomic_state *state) static void icl_dbuf_slice_post_update(struct intel_atomic_state *state)
{ {
struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct drm_i915_private *dev_priv = to_i915(state->base.dev);
u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_mask; const struct intel_dbuf_state *new_dbuf_state =
u8 required_slices = state->enabled_dbuf_slices_mask; intel_atomic_get_new_dbuf_state(state);
const struct intel_dbuf_state *old_dbuf_state =
intel_atomic_get_old_dbuf_state(state);
if (!new_dbuf_state ||
new_dbuf_state->enabled_slices == old_dbuf_state->enabled_slices)
return;
if (INTEL_GEN(dev_priv) >= 11 && required_slices != hw_enabled_slices) WARN_ON(!new_dbuf_state->base.changed);
gen9_dbuf_slices_update(dev_priv, required_slices);
gen9_dbuf_slices_update(dev_priv,
new_dbuf_state->enabled_slices);
} }
static void skl_commit_modeset_enables(struct intel_atomic_state *state) static void skl_commit_modeset_enables(struct intel_atomic_state *state)
...@@ -15467,9 +15485,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) ...@@ -15467,9 +15485,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
if (state->modeset) if (state->modeset)
intel_encoders_update_prepare(state); intel_encoders_update_prepare(state);
/* Enable all new slices, we might need */ icl_dbuf_slice_pre_update(state);
if (state->modeset)
icl_dbuf_slice_pre_update(state);
/* Now enable the clocks, plane, pipe, and connectors that we set up. */ /* Now enable the clocks, plane, pipe, and connectors that we set up. */
dev_priv->display.commit_modeset_enables(state); dev_priv->display.commit_modeset_enables(state);
...@@ -15524,9 +15540,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) ...@@ -15524,9 +15540,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
dev_priv->display.optimize_watermarks(state, crtc); dev_priv->display.optimize_watermarks(state, crtc);
} }
/* Disable all slices, we don't need */ icl_dbuf_slice_post_update(state);
if (state->modeset)
icl_dbuf_slice_post_update(state);
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
intel_post_plane_update(state, crtc); intel_post_plane_update(state, crtc);
...@@ -17420,10 +17434,14 @@ void intel_modeset_init_hw(struct drm_i915_private *i915) ...@@ -17420,10 +17434,14 @@ void intel_modeset_init_hw(struct drm_i915_private *i915)
{ {
struct intel_cdclk_state *cdclk_state = struct intel_cdclk_state *cdclk_state =
to_intel_cdclk_state(i915->cdclk.obj.state); to_intel_cdclk_state(i915->cdclk.obj.state);
struct intel_dbuf_state *dbuf_state =
to_intel_dbuf_state(i915->dbuf.obj.state);
intel_update_cdclk(i915); intel_update_cdclk(i915);
intel_dump_cdclk_config(&i915->cdclk.hw, "Current CDCLK"); intel_dump_cdclk_config(&i915->cdclk.hw, "Current CDCLK");
cdclk_state->logical = cdclk_state->actual = i915->cdclk.hw; cdclk_state->logical = cdclk_state->actual = i915->cdclk.hw;
dbuf_state->enabled_slices = i915->dbuf.enabled_slices;
} }
static int sanitize_watermarks_add_affected(struct drm_atomic_state *state) static int sanitize_watermarks_add_affected(struct drm_atomic_state *state)
...@@ -17712,6 +17730,10 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915) ...@@ -17712,6 +17730,10 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
if (ret) if (ret)
return ret; return ret;
ret = intel_dbuf_init(i915);
if (ret)
return ret;
ret = intel_bw_init(i915); ret = intel_bw_init(i915);
if (ret) if (ret)
return ret; return ret;
...@@ -18228,6 +18250,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) ...@@ -18228,6 +18250,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_cdclk_state *cdclk_state = struct intel_cdclk_state *cdclk_state =
to_intel_cdclk_state(dev_priv->cdclk.obj.state); to_intel_cdclk_state(dev_priv->cdclk.obj.state);
struct intel_dbuf_state *dbuf_state =
to_intel_dbuf_state(dev_priv->dbuf.obj.state);
enum pipe pipe; enum pipe pipe;
struct intel_crtc *crtc; struct intel_crtc *crtc;
struct intel_encoder *encoder; struct intel_encoder *encoder;
...@@ -18258,7 +18282,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) ...@@ -18258,7 +18282,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
enableddisabled(crtc_state->hw.active)); enableddisabled(crtc_state->hw.active));
} }
dev_priv->active_pipes = cdclk_state->active_pipes = active_pipes; dev_priv->active_pipes = cdclk_state->active_pipes =
dbuf_state->active_pipes = active_pipes;
readout_plane_state(dev_priv); readout_plane_state(dev_priv);
......
...@@ -1161,7 +1161,7 @@ static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv, ...@@ -1161,7 +1161,7 @@ static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv,
static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv) static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv)
{ {
u8 hw_enabled_dbuf_slices = intel_enabled_dbuf_slices_mask(dev_priv); u8 hw_enabled_dbuf_slices = intel_enabled_dbuf_slices_mask(dev_priv);
u8 enabled_dbuf_slices = dev_priv->enabled_dbuf_slices_mask; u8 enabled_dbuf_slices = dev_priv->dbuf.enabled_slices;
drm_WARN(&dev_priv->drm, drm_WARN(&dev_priv->drm,
hw_enabled_dbuf_slices != enabled_dbuf_slices, hw_enabled_dbuf_slices != enabled_dbuf_slices,
...@@ -4539,14 +4539,14 @@ void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv, ...@@ -4539,14 +4539,14 @@ void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv,
for (slice = DBUF_S1; slice < num_slices; slice++) for (slice = DBUF_S1; slice < num_slices; slice++)
gen9_dbuf_slice_set(dev_priv, slice, req_slices & BIT(slice)); gen9_dbuf_slice_set(dev_priv, slice, req_slices & BIT(slice));
dev_priv->enabled_dbuf_slices_mask = req_slices; dev_priv->dbuf.enabled_slices = req_slices;
mutex_unlock(&power_domains->lock); mutex_unlock(&power_domains->lock);
} }
static void gen9_dbuf_enable(struct drm_i915_private *dev_priv) static void gen9_dbuf_enable(struct drm_i915_private *dev_priv)
{ {
dev_priv->enabled_dbuf_slices_mask = dev_priv->dbuf.enabled_slices =
intel_enabled_dbuf_slices_mask(dev_priv); intel_enabled_dbuf_slices_mask(dev_priv);
/* /*
...@@ -4554,7 +4554,7 @@ static void gen9_dbuf_enable(struct drm_i915_private *dev_priv) ...@@ -4554,7 +4554,7 @@ static void gen9_dbuf_enable(struct drm_i915_private *dev_priv)
* figure out later which slices we have and what we need. * figure out later which slices we have and what we need.
*/ */
gen9_dbuf_slices_update(dev_priv, BIT(DBUF_S1) | gen9_dbuf_slices_update(dev_priv, BIT(DBUF_S1) |
dev_priv->enabled_dbuf_slices_mask); dev_priv->dbuf.enabled_slices);
} }
static void gen9_dbuf_disable(struct drm_i915_private *dev_priv) static void gen9_dbuf_disable(struct drm_i915_private *dev_priv)
......
...@@ -479,16 +479,6 @@ struct intel_atomic_state { ...@@ -479,16 +479,6 @@ struct intel_atomic_state {
bool dpll_set, modeset; bool dpll_set, modeset;
/*
* Does this transaction change the pipes that are active? This mask
* tracks which CRTC's have changed their active state at the end of
* the transaction (not counting the temporary disable during modesets).
* This mask should only be non-zero when intel_state->modeset is true,
* but the converse is not necessarily true; simply changing a mode may
* not flip the final active status of any CRTC's
*/
u8 active_pipe_changes;
u8 active_pipes; u8 active_pipes;
struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS]; struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
...@@ -506,9 +496,6 @@ struct intel_atomic_state { ...@@ -506,9 +496,6 @@ struct intel_atomic_state {
*/ */
bool global_state_changed; bool global_state_changed;
/* Number of enabled DBuf slices */
u8 enabled_dbuf_slices_mask;
struct i915_sw_fence commit_ready; struct i915_sw_fence commit_ready;
struct llist_node freed; struct llist_node freed;
......
...@@ -947,6 +947,13 @@ struct drm_i915_private { ...@@ -947,6 +947,13 @@ struct drm_i915_private {
struct intel_global_obj obj; struct intel_global_obj obj;
} cdclk; } cdclk;
struct {
/* The current hardware dbuf configuration */
u8 enabled_slices;
struct intel_global_obj obj;
} dbuf;
/** /**
* wq - Driver workqueue for GEM. * wq - Driver workqueue for GEM.
* *
...@@ -1123,12 +1130,12 @@ struct drm_i915_private { ...@@ -1123,12 +1130,12 @@ struct drm_i915_private {
* Set during HW readout of watermarks/DDB. Some platforms * Set during HW readout of watermarks/DDB. Some platforms
* need to know when we're still using BIOS-provided values * need to know when we're still using BIOS-provided values
* (which we don't fully trust). * (which we don't fully trust).
*
* FIXME get rid of this.
*/ */
bool distrust_bios_wm; bool distrust_bios_wm;
} wm; } wm;
u8 enabled_dbuf_slices_mask; /* GEN11 has configurable 2 slices */
struct dram_info { struct dram_info {
bool valid; bool valid;
bool is_16gb_dimm; bool is_16gb_dimm;
......
This diff is collapsed.
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <linux/types.h> #include <linux/types.h>
#include "display/intel_global_state.h"
#include "i915_reg.h" #include "i915_reg.h"
#include "display/intel_bw.h" #include "display/intel_bw.h"
...@@ -63,4 +65,24 @@ void intel_enable_ipc(struct drm_i915_private *dev_priv); ...@@ -63,4 +65,24 @@ void intel_enable_ipc(struct drm_i915_private *dev_priv);
bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable); bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable);
struct intel_dbuf_state {
struct intel_global_state base;
u8 enabled_slices;
u8 active_pipes;
};
int intel_dbuf_init(struct drm_i915_private *dev_priv);
struct intel_dbuf_state *
intel_atomic_get_dbuf_state(struct intel_atomic_state *state);
#define to_intel_dbuf_state(x) container_of((x), struct intel_dbuf_state, base)
#define intel_atomic_get_old_dbuf_state(state) \
to_intel_dbuf_state(intel_atomic_get_old_global_obj_state(state, &to_i915(state->base.dev)->dbuf.obj))
#define intel_atomic_get_new_dbuf_state(state) \
to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, &to_i915(state->base.dev)->dbuf.obj))
int intel_dbuf_init(struct drm_i915_private *dev_priv);
#endif /* __INTEL_PM_H__ */ #endif /* __INTEL_PM_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment