From c98f50628722e2e287656bc7e7492e3d3a0726b8 Mon Sep 17 00:00:00 2001 From: Akash Goel Date: Mon, 24 Mar 2014 23:00:07 +0530 Subject: drm/i915/vlv: Modifying WA 'WaDisableL3Bank2xClockGate for vlv For disabling L3 clock gating we need to set bit 25 of MMIO register 940c. Earlier this was being done by just writing 1 into bit 25 and resetting all other bits. This patch modifies the routine to read-modify-write of the register, so that the values of other bits are not destroyed. v2: Modifying the comments and the patch commit message (Chris) Signed-off-by: Akash Goel Signed-off-by: Sourab Gupta Reviewed-by: Damien Lespiau [danvet: Apply checkpatch fixup.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b86b58c44228..7a4798f52fa1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5348,8 +5348,11 @@ static void valleyview_init_clock_gating(struct drm_device *dev) I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); - /* WaDisableL3Bank2xClockGate:vlv */ - I915_WRITE(GEN7_UCGCTL4, GEN7_L3BANK2X_CLOCK_GATE_DISABLE); + /* WaDisableL3Bank2xClockGate:vlv + * Disabling L3 clock gating- MMIO 940c[25] = 1 + * Set bit 25, to disable L3_BANK_2x_CLK_GATING */ + I915_WRITE(GEN7_UCGCTL4, + I915_READ(GEN7_UCGCTL4) | GEN7_L3BANK2X_CLOCK_GATE_DISABLE); I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE); -- cgit v1.2.2 From 570210598444f2b9c20db8b0e7a877633a3cb1ea Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 23 May 2014 13:16:40 -0700 Subject: drm/i915/vlv: assert and de-assert sideband reset at boot and resume v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a bit like the CMN reset de-assert we do in DPIO_CTL, except that it resets the whole common lane section of the PHY. This is required on machines where the BIOS doesn't do this for us on boot or resume to properly re-calibrate and get the PHY ready to transmit data. Without this patch, such machines won't resume correctly much of the time, with the symptom being a 'port ready' timeout and/or a link training failure. Note that simply asserting reset at suspend and de-asserting at resume is not sufficient, nor is simply de-asserting at boot. Both of these cases have been tested and have still been found to have failures on some configurations. v2: extract simpler set_power_well function for use in reset_dpio (Imre) move to reset_dpio (Daniel & Ville) v3: don't reset if DPIO reset is already de-asserted (Imre) Signed-off-by: Jesse Barnes Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7a4798f52fa1..25caf8fb6656 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5708,10 +5708,9 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv, return true; } -static void vlv_set_power_well(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well, bool enable) +void __vlv_set_power_well(struct drm_i915_private *dev_priv, + enum punit_power_well power_well_id, bool enable) { - enum punit_power_well power_well_id = power_well->data; u32 mask; u32 state; u32 ctrl; @@ -5744,6 +5743,14 @@ out: mutex_unlock(&dev_priv->rps.hw_lock); } +static void vlv_set_power_well(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well, bool enable) +{ + enum punit_power_well power_well_id = power_well->data; + + __vlv_set_power_well(dev_priv, power_well_id, enable); +} + static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { -- cgit v1.2.2 From b00f025cf8242a4c91402abeaac6c2b589fcb263 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 23 May 2014 13:16:42 -0700 Subject: drm/i915/vlv: move CRI refclk enable into __vlv_set_power_well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This needs to be done before we power back on the CMN_BC well so the PHY can calibrate properly. Signed-off-by: Jesse Barnes Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 25caf8fb6656..813afac04ddf 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5715,6 +5715,17 @@ void __vlv_set_power_well(struct drm_i915_private *dev_priv, u32 state; u32 ctrl; + if (power_well_id == PUNIT_POWER_WELL_DPIO_CMN_BC && enable) { + /* + * Enable the CRI clock source so we can get at the display + * and the reference clock for VGA hotplug / manual detection. + */ + I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | + DPLL_REFA_CLK_ENABLE_VLV | + DPLL_INTEGRATED_CRI_CLK_VLV); + udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ + } + mask = PUNIT_PWRGT_MASK(power_well_id); state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) : PUNIT_PWRGT_PWR_GATE(power_well_id); -- cgit v1.2.2 From f099a3c605724b2f848ed4edd318e20528761904 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 23 May 2014 13:16:43 -0700 Subject: drm/i915/vlv: re-order power wells so DPIO common comes after TX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There may be a dependency here. Signed-off-by: Jesse Barnes Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 813afac04ddf..c2cf9063dd7a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6094,12 +6094,6 @@ static struct i915_power_well vlv_power_wells[] = { .data = PUNIT_POWER_WELL_DISP2D, .ops = &vlv_display_power_well_ops, }, - { - .name = "dpio-common", - .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS, - .data = PUNIT_POWER_WELL_DPIO_CMN_BC, - .ops = &vlv_dpio_power_well_ops, - }, { .name = "dpio-tx-b-01", .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | @@ -6136,6 +6130,12 @@ static struct i915_power_well vlv_power_wells[] = { .ops = &vlv_dpio_power_well_ops, .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, }, + { + .name = "dpio-common", + .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS, + .data = PUNIT_POWER_WELL_DPIO_CMN_BC, + .ops = &vlv_dpio_power_well_ops, + }, }; #define set_power_wells(power_domains, __power_wells) ({ \ -- cgit v1.2.2 From f618e38dedb17e86278cc7eb9a6cef184893885d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 23 May 2014 13:16:44 -0700 Subject: drm/i915/vlv: move DPIO common reset de-assert into __vlv_set_power_well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to do this anytime we power gate the DPIO common well. Signed-off-by: Jesse Barnes Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c2cf9063dd7a..cca93d06894c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5715,15 +5715,22 @@ void __vlv_set_power_well(struct drm_i915_private *dev_priv, u32 state; u32 ctrl; - if (power_well_id == PUNIT_POWER_WELL_DPIO_CMN_BC && enable) { - /* - * Enable the CRI clock source so we can get at the display - * and the reference clock for VGA hotplug / manual detection. - */ - I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | - DPLL_REFA_CLK_ENABLE_VLV | - DPLL_INTEGRATED_CRI_CLK_VLV); - udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ + if (power_well_id == PUNIT_POWER_WELL_DPIO_CMN_BC) { + if (enable) { + /* + * Enable the CRI clock source so we can get at the + * display and the reference clock for VGA + * hotplug / manual detection. + */ + I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | + DPLL_REFA_CLK_ENABLE_VLV | + DPLL_INTEGRATED_CRI_CLK_VLV); + udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ + } else { + /* Assert common reset */ + I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) & + ~DPIO_CMNRST); + } } mask = PUNIT_PWRGT_MASK(power_well_id); @@ -5752,6 +5759,20 @@ void __vlv_set_power_well(struct drm_i915_private *dev_priv, out: mutex_unlock(&dev_priv->rps.hw_lock); + + /* + * From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx - + * 6. De-assert cmn_reset/side_reset. Same as VLV X0. + * a. GUnit 0x2110 bit[0] set to 1 (def 0) + * b. The other bits such as sfr settings / modesel may all + * be set to 0. + * + * This should only be done on init and resume from S3 with + * both PLLs disabled, or we risk losing DPIO and PLL + * synchronization. + */ + if (power_well_id == PUNIT_POWER_WELL_DPIO_CMN_BC && enable) + I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) | DPIO_CMNRST); } static void vlv_set_power_well(struct drm_i915_private *dev_priv, -- cgit v1.2.2 From 4dfbd12c33a7f76cdf38b9edcc21b06223b33268 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 23 May 2014 13:16:45 -0700 Subject: drm/i915/vlv: add pll assertion when disabling DPIO common well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When doing this, all PLLs should be disabled. Signed-off-by: Jesse Barnes Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index cca93d06894c..b86edac51be2 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5711,9 +5711,11 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv, void __vlv_set_power_well(struct drm_i915_private *dev_priv, enum punit_power_well power_well_id, bool enable) { + struct drm_device *dev = dev_priv->dev; u32 mask; u32 state; u32 ctrl; + enum pipe pipe; if (power_well_id == PUNIT_POWER_WELL_DPIO_CMN_BC) { if (enable) { @@ -5727,6 +5729,8 @@ void __vlv_set_power_well(struct drm_i915_private *dev_priv, DPLL_INTEGRATED_CRI_CLK_VLV); udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ } else { + for_each_pipe(pipe) + assert_pll_disabled(dev_priv, pipe); /* Assert common reset */ I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) & ~DPIO_CMNRST); -- cgit v1.2.2 From 12fabbcb9f0935c283230217c7de6b26d3d5caac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 25 Feb 2014 15:13:38 +0200 Subject: drm/i915: Set AGPBUSY# bit in init_clock_gating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I don't see why we wouldn't want interrupts to wake up the CPU from C3 always, so just set the AGPBUSY# bit in gen3_init_clock_gating(). Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b86edac51be2..71de9eec3381 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5504,6 +5504,9 @@ static void gen3_init_clock_gating(struct drm_device *dev) /* IIR "flip pending" means done if this bit is set */ I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); + + /* interrupts should cause a wake up from C3 */ + I915_WRITE(INSTPM, _MASKED_BIT_DISABLE(INSTPM_AGPBUSY_DIS)); } static void i85x_init_clock_gating(struct drm_device *dev) -- cgit v1.2.2 From 3299254ffc42082a0ae36ecb841ade1a98a2af92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 25 Feb 2014 15:13:39 +0200 Subject: drm/i915: Flip the sense of AGPBUSY_DIS bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit My Gen3 Bspec lists the AGPBUSY# bit in INSTPM as an enable bit rather than a disable bit. Our code has the opposite idea. Make the code match the spec. Might fix some gen3 C3 related interrupt delivery problems. Untested due to lack of hardware. v2: call it AGPBUSY_INT_EN to make it clearer it has to do with interrupts Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 71de9eec3381..ab98dac3da73 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5506,7 +5506,7 @@ static void gen3_init_clock_gating(struct drm_device *dev) I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); /* interrupts should cause a wake up from C3 */ - I915_WRITE(INSTPM, _MASKED_BIT_DISABLE(INSTPM_AGPBUSY_DIS)); + I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN)); } static void i85x_init_clock_gating(struct drm_device *dev) -- cgit v1.2.2 From 54e472ae9632992bfbd0c6fd8c8fc5c88d2bdd1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 25 Feb 2014 15:13:40 +0200 Subject: drm/i915: Enable interrupt-based AGPBUSY# enable on 85x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 85x also has a similar AGPBUSY# bit as gen3. Enable it to make sure vblank interrupts don't get dealyed during C3 state. There's also another bit which controls whether AGPBUSY# is asserted based on pending cacheable cycles and interrupts, or just based on pending commands in the ring and interrupts. Select the cacheable cycles mode since that seems to be the new way of doing things in 85x, and it does give slightly better C3 residency numbers with glxgears running. Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ab98dac3da73..b124ba4ca7e5 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5514,6 +5514,10 @@ static void i85x_init_clock_gating(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); + + /* interrupts should cause a wake up from C3 */ + I915_WRITE(MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) | + _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE)); } static void i830_init_clock_gating(struct drm_device *dev) -- cgit v1.2.2 From dbb42748ac4929987c1449ecb296b39ef8956b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 25 Feb 2014 15:13:41 +0200 Subject: drm/i915: Move the C3 LP write bit setup to gen3_init_clock_gating() for KMS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the MI_ARB_STATE MI_ARB_C3_LP_WRITE_ENABLE setup to gen3_init_clock_gating() from i915_gem_load() when KMS is enabled. Leave it in i915_gem_load() for the UMS case, but add an explcit check, just to make it easier to spot it when we eventually rip out UMS support. Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b124ba4ca7e5..f6fd86a17174 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5507,6 +5507,9 @@ static void gen3_init_clock_gating(struct drm_device *dev) /* interrupts should cause a wake up from C3 */ I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN)); + + /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ + I915_WRITE(MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); } static void i85x_init_clock_gating(struct drm_device *dev) -- cgit v1.2.2 From b8c000d9bf23e7c1155ef421f595d1cbc25262da Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 2 Jun 2014 14:21:10 +0300 Subject: drm/i915: fix display power sw state reporting Atm, we refcount both power domains and power wells and intel_display_power_enabled_sw() returns the power domain refcount. What the callers are really interested in though is the sw state of the underlying power wells. Due to this we will report incorrectly that a given power domain is off if its power wells were enabled via another power domain, for example POWER_DOMAIN_INIT which enables all power wells. As a fix return instead the state based on the refcount of all power wells included in the passed in power domain. References: https://bugs.freedesktop.org/show_bug.cgi?id=79505 References: https://bugs.freedesktop.org/show_bug.cgi?id=79038 Reported-by: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_pm.c') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f6fd86a17174..8bbd4f910663 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5572,10 +5572,25 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain) { struct i915_power_domains *power_domains; + struct i915_power_well *power_well; + bool is_enabled; + int i; + + if (dev_priv->pm.suspended) + return false; power_domains = &dev_priv->power_domains; + is_enabled = true; + for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { + if (power_well->always_on) + continue; - return power_domains->domain_use_count[domain]; + if (!power_well->count) { + is_enabled = false; + break; + } + } + return is_enabled; } bool intel_display_power_enabled(struct drm_i915_private *dev_priv, -- cgit v1.2.2