summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c177
1 files changed, 100 insertions, 77 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ed662937ec3c..0201816a4229 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -125,6 +125,7 @@ static void bxt_init_clock_gating(struct drm_i915_private *dev_priv)
static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
{
+ u32 val;
gen9_init_clock_gating(dev_priv);
/*
@@ -144,6 +145,11 @@ static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
I915_WRITE(CHICKEN_MISC_2, val);
}
+ /* Display WA #1133: WaFbcSkipSegments:glk */
+ val = I915_READ(ILK_DPFC_CHICKEN);
+ val &= ~GLK_SKIP_SEG_COUNT_MASK;
+ val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
+ I915_WRITE(ILK_DPFC_CHICKEN, val);
}
static void i915_pineview_get_mem_freq(struct drm_i915_private *dev_priv)
@@ -1322,21 +1328,21 @@ static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state)
int num_active_planes = hweight32(crtc_state->active_planes &
~BIT(PLANE_CURSOR));
const struct g4x_pipe_wm *raw;
- struct intel_plane_state *plane_state;
+ const struct intel_plane_state *old_plane_state;
+ const struct intel_plane_state *new_plane_state;
struct intel_plane *plane;
enum plane_id plane_id;
int i, level;
unsigned int dirty = 0;
- for_each_intel_plane_in_state(state, plane, plane_state, i) {
- const struct intel_plane_state *old_plane_state =
- to_intel_plane_state(plane->base.state);
-
- if (plane_state->base.crtc != &crtc->base &&
+ for_each_oldnew_intel_plane_in_state(state, plane,
+ old_plane_state,
+ new_plane_state, i) {
+ if (new_plane_state->base.crtc != &crtc->base &&
old_plane_state->base.crtc != &crtc->base)
continue;
- if (g4x_raw_plane_wm_compute(crtc_state, plane_state))
+ if (g4x_raw_plane_wm_compute(crtc_state, new_plane_state))
dirty |= BIT(plane->id);
}
@@ -1831,21 +1837,21 @@ static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state)
int num_active_planes = hweight32(crtc_state->active_planes &
~BIT(PLANE_CURSOR));
bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->base);
- struct intel_plane_state *plane_state;
+ const struct intel_plane_state *old_plane_state;
+ const struct intel_plane_state *new_plane_state;
struct intel_plane *plane;
enum plane_id plane_id;
int level, ret, i;
unsigned int dirty = 0;
- for_each_intel_plane_in_state(state, plane, plane_state, i) {
- const struct intel_plane_state *old_plane_state =
- to_intel_plane_state(plane->base.state);
-
- if (plane_state->base.crtc != &crtc->base &&
+ for_each_oldnew_intel_plane_in_state(state, plane,
+ old_plane_state,
+ new_plane_state, i) {
+ if (new_plane_state->base.crtc != &crtc->base &&
old_plane_state->base.crtc != &crtc->base)
continue;
- if (vlv_raw_plane_wm_compute(crtc_state, plane_state))
+ if (vlv_raw_plane_wm_compute(crtc_state, new_plane_state))
dirty |= BIT(plane->id);
}
@@ -1864,7 +1870,7 @@ static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state)
/* cursor changes don't warrant a FIFO recompute */
if (dirty & ~BIT(PLANE_CURSOR)) {
const struct intel_crtc_state *old_crtc_state =
- to_intel_crtc_state(crtc->base.state);
+ intel_atomic_get_old_crtc_state(state, crtc);
const struct vlv_fifo_state *old_fifo_state =
&old_crtc_state->wm.vlv.fifo_state;
@@ -6169,6 +6175,7 @@ void gen6_rps_boost(struct drm_i915_gem_request *rq,
struct intel_rps_client *rps)
{
struct drm_i915_private *i915 = rq->i915;
+ unsigned long flags;
bool boost;
/* This is intentionally racy! We peek at the state here, then
@@ -6178,13 +6185,13 @@ void gen6_rps_boost(struct drm_i915_gem_request *rq,
return;
boost = false;
- spin_lock_irq(&rq->lock);
+ spin_lock_irqsave(&rq->lock, flags);
if (!rq->waitboost && !i915_gem_request_completed(rq)) {
atomic_inc(&i915->rps.num_waiters);
rq->waitboost = true;
boost = true;
}
- spin_unlock_irq(&rq->lock);
+ spin_unlock_irqrestore(&rq->lock, flags);
if (!boost)
return;
@@ -7980,7 +7987,7 @@ static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv)
*/
}
-static void ironlake_init_clock_gating(struct drm_i915_private *dev_priv)
+static void ilk_init_clock_gating(struct drm_i915_private *dev_priv)
{
uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE;
@@ -8263,7 +8270,56 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
I915_WRITE(GEN7_MISCCPCTL, misccpctl);
}
-static void kabylake_init_clock_gating(struct drm_i915_private *dev_priv)
+static void cnp_init_clock_gating(struct drm_i915_private *dev_priv)
+{
+ if (!HAS_PCH_CNP(dev_priv))
+ return;
+
+ /* Wa #1181 */
+ I915_WRITE(SOUTH_DSPCLK_GATE_D, CNP_PWM_CGE_GATING_DISABLE);
+}
+
+static void cnl_init_clock_gating(struct drm_i915_private *dev_priv)
+{
+ u32 val;
+ cnp_init_clock_gating(dev_priv);
+
+ /* This is not an Wa. Enable for better image quality */
+ I915_WRITE(_3D_CHICKEN3,
+ _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE));
+
+ /* WaEnableChickenDCPR:cnl */
+ I915_WRITE(GEN8_CHICKEN_DCPR_1,
+ I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM);
+
+ /* WaFbcWakeMemOn:cnl */
+ I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
+ DISP_FBC_MEMORY_WAKE);
+
+ /* WaSarbUnitClockGatingDisable:cnl (pre-prod) */
+ if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0))
+ I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE,
+ I915_READ(SLICE_UNIT_LEVEL_CLKGATE) |
+ SARBUNIT_CLKGATE_DIS);
+
+ /* Display WA #1133: WaFbcSkipSegments:cnl */
+ val = I915_READ(ILK_DPFC_CHICKEN);
+ val &= ~GLK_SKIP_SEG_COUNT_MASK;
+ val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1);
+ I915_WRITE(ILK_DPFC_CHICKEN, val);
+}
+
+static void cfl_init_clock_gating(struct drm_i915_private *dev_priv)
+{
+ cnp_init_clock_gating(dev_priv);
+ gen9_init_clock_gating(dev_priv);
+
+ /* WaFbcNukeOnHostModify:cfl */
+ I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
+ ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
+}
+
+static void kbl_init_clock_gating(struct drm_i915_private *dev_priv)
{
gen9_init_clock_gating(dev_priv);
@@ -8277,12 +8333,12 @@ static void kabylake_init_clock_gating(struct drm_i915_private *dev_priv)
I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) |
GEN6_GAMUNIT_CLOCK_GATE_DISABLE);
- /* WaFbcNukeOnHostModify:kbl,cfl */
+ /* WaFbcNukeOnHostModify:kbl */
I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
}
-static void skylake_init_clock_gating(struct drm_i915_private *dev_priv)
+static void skl_init_clock_gating(struct drm_i915_private *dev_priv)
{
gen9_init_clock_gating(dev_priv);
@@ -8295,7 +8351,7 @@ static void skylake_init_clock_gating(struct drm_i915_private *dev_priv)
ILK_DPFC_NUKE_ON_ANY_MODIFICATION);
}
-static void broadwell_init_clock_gating(struct drm_i915_private *dev_priv)
+static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
{
enum pipe pipe;
@@ -8353,7 +8409,7 @@ static void broadwell_init_clock_gating(struct drm_i915_private *dev_priv)
I915_READ(GEN6_UCGCTL1) | GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE);
}
-static void haswell_init_clock_gating(struct drm_i915_private *dev_priv)
+static void hsw_init_clock_gating(struct drm_i915_private *dev_priv)
{
ilk_init_lp_watermarks(dev_priv);
@@ -8407,7 +8463,7 @@ static void haswell_init_clock_gating(struct drm_i915_private *dev_priv)
lpt_init_clock_gating(dev_priv);
}
-static void ivybridge_init_clock_gating(struct drm_i915_private *dev_priv)
+static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
{
uint32_t snpcr;
@@ -8504,7 +8560,7 @@ static void ivybridge_init_clock_gating(struct drm_i915_private *dev_priv)
gen6_check_mch_setup(dev_priv);
}
-static void valleyview_init_clock_gating(struct drm_i915_private *dev_priv)
+static void vlv_init_clock_gating(struct drm_i915_private *dev_priv)
{
/* WaDisableEarlyCull:vlv */
I915_WRITE(_3D_CHICKEN3,
@@ -8584,7 +8640,7 @@ static void valleyview_init_clock_gating(struct drm_i915_private *dev_priv)
I915_WRITE(VLV_GUNIT_CLOCK_GATE, GCFG_DIS);
}
-static void cherryview_init_clock_gating(struct drm_i915_private *dev_priv)
+static void chv_init_clock_gating(struct drm_i915_private *dev_priv)
{
/* WaVSRefCountFullforceMissDisable:chv */
/* WaDSRefCountFullforceMissDisable:chv */
@@ -8644,7 +8700,7 @@ static void g4x_init_clock_gating(struct drm_i915_private *dev_priv)
g4x_disable_trickle_feed(dev_priv);
}
-static void crestline_init_clock_gating(struct drm_i915_private *dev_priv)
+static void i965gm_init_clock_gating(struct drm_i915_private *dev_priv)
{
I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
I915_WRITE(RENCLK_GATE_D2, 0);
@@ -8658,7 +8714,7 @@ static void crestline_init_clock_gating(struct drm_i915_private *dev_priv)
I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
}
-static void broadwater_init_clock_gating(struct drm_i915_private *dev_priv)
+static void i965g_init_clock_gating(struct drm_i915_private *dev_priv)
{
I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
I965_RCC_CLOCK_GATE_DISABLE |
@@ -8743,34 +8799,38 @@ static void nop_init_clock_gating(struct drm_i915_private *dev_priv)
*/
void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv)
{
- if (IS_SKYLAKE(dev_priv))
- dev_priv->display.init_clock_gating = skylake_init_clock_gating;
- else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv))
- dev_priv->display.init_clock_gating = kabylake_init_clock_gating;
+ if (IS_CANNONLAKE(dev_priv))
+ dev_priv->display.init_clock_gating = cnl_init_clock_gating;
+ else if (IS_COFFEELAKE(dev_priv))
+ dev_priv->display.init_clock_gating = cfl_init_clock_gating;
+ else if (IS_SKYLAKE(dev_priv))
+ dev_priv->display.init_clock_gating = skl_init_clock_gating;
+ else if (IS_KABYLAKE(dev_priv))
+ dev_priv->display.init_clock_gating = kbl_init_clock_gating;
else if (IS_BROXTON(dev_priv))
dev_priv->display.init_clock_gating = bxt_init_clock_gating;
else if (IS_GEMINILAKE(dev_priv))
dev_priv->display.init_clock_gating = glk_init_clock_gating;
else if (IS_BROADWELL(dev_priv))
- dev_priv->display.init_clock_gating = broadwell_init_clock_gating;
+ dev_priv->display.init_clock_gating = bdw_init_clock_gating;
else if (IS_CHERRYVIEW(dev_priv))
- dev_priv->display.init_clock_gating = cherryview_init_clock_gating;
+ dev_priv->display.init_clock_gating = chv_init_clock_gating;
else if (IS_HASWELL(dev_priv))
- dev_priv->display.init_clock_gating = haswell_init_clock_gating;
+ dev_priv->display.init_clock_gating = hsw_init_clock_gating;
else if (IS_IVYBRIDGE(dev_priv))
- dev_priv->display.init_clock_gating = ivybridge_init_clock_gating;
+ dev_priv->display.init_clock_gating = ivb_init_clock_gating;
else if (IS_VALLEYVIEW(dev_priv))
- dev_priv->display.init_clock_gating = valleyview_init_clock_gating;
+ dev_priv->display.init_clock_gating = vlv_init_clock_gating;
else if (IS_GEN6(dev_priv))
dev_priv->display.init_clock_gating = gen6_init_clock_gating;
else if (IS_GEN5(dev_priv))
- dev_priv->display.init_clock_gating = ironlake_init_clock_gating;
+ dev_priv->display.init_clock_gating = ilk_init_clock_gating;
else if (IS_G4X(dev_priv))
dev_priv->display.init_clock_gating = g4x_init_clock_gating;
else if (IS_I965GM(dev_priv))
- dev_priv->display.init_clock_gating = crestline_init_clock_gating;
+ dev_priv->display.init_clock_gating = i965gm_init_clock_gating;
else if (IS_I965G(dev_priv))
- dev_priv->display.init_clock_gating = broadwater_init_clock_gating;
+ dev_priv->display.init_clock_gating = i965g_init_clock_gating;
else if (IS_GEN3(dev_priv))
dev_priv->display.init_clock_gating = gen3_init_clock_gating;
else if (IS_I85X(dev_priv) || IS_I865G(dev_priv))
@@ -9132,43 +9192,6 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
return DIV_ROUND_CLOSEST(val, GT_FREQUENCY_MULTIPLIER);
}
-struct request_boost {
- struct work_struct work;
- struct drm_i915_gem_request *req;
-};
-
-static void __intel_rps_boost_work(struct work_struct *work)
-{
- struct request_boost *boost = container_of(work, struct request_boost, work);
- struct drm_i915_gem_request *req = boost->req;
-
- if (!i915_gem_request_completed(req))
- gen6_rps_boost(req, NULL);
-
- i915_gem_request_put(req);
- kfree(boost);
-}
-
-void intel_queue_rps_boost_for_request(struct drm_i915_gem_request *req)
-{
- struct request_boost *boost;
-
- if (req == NULL || INTEL_GEN(req->i915) < 6)
- return;
-
- if (i915_gem_request_completed(req))
- return;
-
- boost = kmalloc(sizeof(*boost), GFP_ATOMIC);
- if (boost == NULL)
- return;
-
- boost->req = i915_gem_request_get(req);
-
- INIT_WORK(&boost->work, __intel_rps_boost_work);
- queue_work(req->i915->wq, &boost->work);
-}
-
void intel_pm_setup(struct drm_i915_private *dev_priv)
{
mutex_init(&dev_priv->rps.hw_lock);