All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/7] DC3CO Support for TGL
@ 2019-09-03 17:59 Anshuman Gupta
  2019-09-03 17:59 ` [PATCH v6 1/7] drm/i915/tgl: Add DC3CO required register and bits Anshuman Gupta
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Anshuman Gupta @ 2019-09-03 17:59 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

This is a new design proposal for DC3CO feature after disscussing
it with Ville and Imre.

This design uses a API tgl_set_target_dc_state() API
to switch between DC3CO and DC5 by using "DC off"
power well. Another major change in this design using page flip
frontbuffer flush call to allow DC3CO.

As part of DC3CO feature, it needs to configure and enable
TRANS_EXITLINE register which only needs to change when
transcoder/port is not enabled. It requires to configure and
enable it in full modeset sequence. Which requires to force
the modeset only at system bootup, with only eDP panel.

Tested this series on real H/W, DC3CO counter is validated
without any other issue observed.

Anshuman Gupta (7):
  drm/i915/tgl: Add DC3CO required register and bits
  drm/i915/tgl: Add DC3CO mask to allowed_dc_mask and gen9_dc_mask
  drm/i915/tgl: Enable DC3CO state in "DC Off" power well
  drm/i915/tgl: Add helper function for DC3CO exitline.
  drm/i915/tgl: DC3CO PSR2 helper
  drm/i915/tgl: switch between dc3co and dc5 based on display idleness
  drm/i915/tgl: Add DC3CO counter in i915_dmc_info

 drivers/gpu/drm/i915/display/intel_display.c  |   7 +
 .../drm/i915/display/intel_display_power.c    | 305 ++++++++++++++++--
 .../drm/i915/display/intel_display_power.h    |  15 +
 .../gpu/drm/i915/display/intel_frontbuffer.c  |   1 +
 drivers/gpu/drm/i915/display/intel_psr.c      |  44 +++
 drivers/gpu/drm/i915/display/intel_psr.h      |   2 +
 drivers/gpu/drm/i915/i915_debugfs.c           |   6 +
 drivers/gpu/drm/i915/i915_drv.h               |   5 +
 drivers/gpu/drm/i915/i915_params.c            |   3 +-
 drivers/gpu/drm/i915/i915_reg.h               |  10 +
 drivers/gpu/drm/i915/intel_pm.c               |   2 +-
 drivers/gpu/drm/i915/intel_pm.h               |   2 +
 12 files changed, 372 insertions(+), 30 deletions(-)

-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v6 1/7] drm/i915/tgl: Add DC3CO required register and bits
  2019-09-03 17:59 [PATCH v6 0/7] DC3CO Support for TGL Anshuman Gupta
@ 2019-09-03 17:59 ` Anshuman Gupta
  2019-09-03 17:59 ` [PATCH v6 2/7] drm/i915/tgl: Add DC3CO mask to allowed_dc_mask and gen9_dc_mask Anshuman Gupta
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anshuman Gupta @ 2019-09-03 17:59 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Adding following definition to i915_reg.h
1. DC_STATE_EN register DC3CO bit fields and masks.
2. Transcoder EXITLINE register and its bit fields and mask.

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 6c43b8c583bb..e1bdd54b1816 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4135,6 +4135,7 @@ enum {
 #define _VTOTAL_A	0x6000c
 #define _VBLANK_A	0x60010
 #define _VSYNC_A	0x60014
+#define _EXITLINE_A	0x60018
 #define _PIPEASRC	0x6001c
 #define _BCLRPAT_A	0x60020
 #define _VSYNCSHIFT_A	0x60028
@@ -4181,11 +4182,16 @@ enum {
 #define VTOTAL(trans)		_MMIO_TRANS2(trans, _VTOTAL_A)
 #define VBLANK(trans)		_MMIO_TRANS2(trans, _VBLANK_A)
 #define VSYNC(trans)		_MMIO_TRANS2(trans, _VSYNC_A)
+#define EXITLINE(trans)		_MMIO_TRANS2(trans, _EXITLINE_A)
 #define BCLRPAT(trans)		_MMIO_TRANS2(trans, _BCLRPAT_A)
 #define VSYNCSHIFT(trans)	_MMIO_TRANS2(trans, _VSYNCSHIFT_A)
 #define PIPESRC(trans)		_MMIO_TRANS2(trans, _PIPEASRC)
 #define PIPE_MULT(trans)	_MMIO_TRANS2(trans, _PIPE_MULT_A)
 
+#define  EXITLINE_ENABLE	(1 << 31)
+#define  EXITLINE_MASK		(0x1fff)
+#define  EXITLINE_SHIFT		0
+
 /*
  * HSW+ eDP PSR registers
  *
@@ -10097,6 +10103,8 @@ enum skl_power_gate {
 /* GEN9 DC */
 #define DC_STATE_EN			_MMIO(0x45504)
 #define  DC_STATE_DISABLE		0
+#define  DC_STATE_EN_DC3CO		(1 << 30)
+#define  DC_STATE_DC3CO_STATUS		(1 << 29)
 #define  DC_STATE_EN_UPTO_DC5		(1 << 0)
 #define  DC_STATE_EN_DC9		(1 << 3)
 #define  DC_STATE_EN_UPTO_DC6		(2 << 0)
-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 2/7] drm/i915/tgl: Add DC3CO mask to allowed_dc_mask and gen9_dc_mask
  2019-09-03 17:59 [PATCH v6 0/7] DC3CO Support for TGL Anshuman Gupta
  2019-09-03 17:59 ` [PATCH v6 1/7] drm/i915/tgl: Add DC3CO required register and bits Anshuman Gupta
@ 2019-09-03 17:59 ` Anshuman Gupta
  2019-09-03 17:59 ` [PATCH v6 3/7] drm/i915/tgl: Enable DC3CO state in "DC Off" power well Anshuman Gupta
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anshuman Gupta @ 2019-09-03 17:59 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Enable dc3co state in enable_dc module param and add dc3co
enable mask to allowed_dc_mask and gen9_dc_mask.

v1: Adding enable_dc=3,4 options to enable DC3CO with DC5 and DC6
    independently.

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
---
 .../drm/i915/display/intel_display_power.c    | 29 ++++++++++++++-----
 drivers/gpu/drm/i915/i915_params.c            |  3 +-
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index ce88a27229ef..496fa1b53ffb 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -698,7 +698,11 @@ static u32 gen9_dc_mask(struct drm_i915_private *dev_priv)
 	u32 mask;
 
 	mask = DC_STATE_EN_UPTO_DC5;
-	if (INTEL_GEN(dev_priv) >= 11)
+
+	if (INTEL_GEN(dev_priv) >= 12)
+		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6
+					  | DC_STATE_EN_DC9;
+	else if (IS_GEN(dev_priv, 11))
 		mask |= DC_STATE_EN_UPTO_DC6 | DC_STATE_EN_DC9;
 	else if (IS_GEN9_LP(dev_priv))
 		mask |= DC_STATE_EN_DC9;
@@ -3927,14 +3931,17 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
 	int requested_dc;
 	int max_dc;
 
-	if (INTEL_GEN(dev_priv) >= 11) {
-		max_dc = 2;
+	if (INTEL_GEN(dev_priv) >= 12) {
+		max_dc = 4;
 		/*
 		 * DC9 has a separate HW flow from the rest of the DC states,
 		 * not depending on the DMC firmware. It's needed by system
 		 * suspend/resume, so allow it unconditionally.
 		 */
 		mask = DC_STATE_EN_DC9;
+	} else if (IS_GEN(dev_priv, 11)) {
+		max_dc = 2;
+		mask = DC_STATE_EN_DC9;
 	} else if (IS_GEN(dev_priv, 10) || IS_GEN9_BC(dev_priv)) {
 		max_dc = 2;
 		mask = 0;
@@ -3953,7 +3960,7 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
 		requested_dc = enable_dc;
 	} else if (enable_dc == -1) {
 		requested_dc = max_dc;
-	} else if (enable_dc > max_dc && enable_dc <= 2) {
+	} else if (enable_dc > max_dc && enable_dc <= 4) {
 		DRM_DEBUG_KMS("Adjusting requested max DC state (%d->%d)\n",
 			      enable_dc, max_dc);
 		requested_dc = max_dc;
@@ -3962,10 +3969,16 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
 		requested_dc = max_dc;
 	}
 
-	if (requested_dc > 1)
-		mask |= DC_STATE_EN_UPTO_DC6;
-	if (requested_dc > 0)
-		mask |= DC_STATE_EN_UPTO_DC5;
+	if (requested_dc == 4) {
+		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6;
+	} else if (requested_dc == 3) {
+		mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC5;
+	} else {
+		if (requested_dc > 1)
+			mask |= DC_STATE_EN_UPTO_DC6;
+		if (requested_dc > 0)
+			mask |= DC_STATE_EN_UPTO_DC5;
+	}
 
 	DRM_DEBUG_KMS("Allowed DC state mask %02x\n", mask);
 
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 296452f9efe4..4f1806f65040 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -46,7 +46,8 @@ i915_param_named(modeset, int, 0400,
 
 i915_param_named_unsafe(enable_dc, int, 0400,
 	"Enable power-saving display C-states. "
-	"(-1=auto [default]; 0=disable; 1=up to DC5; 2=up to DC6)");
+	"(-1=auto [default]; 0=disable; 1=up to DC5; 2=up to DC6; "
+	"3=up to DC5 with DC3CO; 4=up to DC6 with DC3CO)");
 
 i915_param_named_unsafe(enable_fbc, int, 0600,
 	"Enable frame buffer compression for power savings "
-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 3/7] drm/i915/tgl: Enable DC3CO state in "DC Off" power well
  2019-09-03 17:59 [PATCH v6 0/7] DC3CO Support for TGL Anshuman Gupta
  2019-09-03 17:59 ` [PATCH v6 1/7] drm/i915/tgl: Add DC3CO required register and bits Anshuman Gupta
  2019-09-03 17:59 ` [PATCH v6 2/7] drm/i915/tgl: Add DC3CO mask to allowed_dc_mask and gen9_dc_mask Anshuman Gupta
@ 2019-09-03 17:59 ` Anshuman Gupta
  2019-09-03 17:59 ` [PATCH v6 4/7] drm/i915/tgl: Add helper function for DC3CO exitline Anshuman Gupta
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anshuman Gupta @ 2019-09-03 17:59 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Add max_dc_state and tgl_set_target_dc_state() API
in order to enable DC3CO state with existing DC states.
max_dc_state will enable/disable the desired DC state in
DC_STATE_EN reg when "DC Off" power well gets disable/enable.

v2: commit log improvement.
v3: Used intel_wait_for_register to wait for DC3CO exit. [Imre]
    Used gen9_set_dc_state() to allow/disallow DC3CO. [Imre]
    Moved transcoder psr2 exit line enablement from tgl_allow_dc3co()
    to a appropriate place haswell_crtc_enable(). [Imre]
    Changed the DC3CO power well enabled call back logic as
    recommended in review comments. [Imre]
v4: Used wait_for_us() instead of intel_wait_for_reg(). [Imre (IRC)]
v5: using udelay() instead of waiting for DC3CO exit status.
v6: Fixed minor unwanted change.
v7: Removed DC3CO powerwell and POWER_DOMAIN_VIDEO.

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
---
 .../drm/i915/display/intel_display_power.c    | 106 ++++++++++++++----
 .../drm/i915/display/intel_display_power.h    |   2 +
 drivers/gpu/drm/i915/i915_drv.h               |   1 +
 3 files changed, 89 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 496fa1b53ffb..868197bb4860 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -772,6 +772,29 @@ static void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state)
 	dev_priv->csr.dc_state = val & mask;
 }
 
+static void tgl_allow_dc3co(struct drm_i915_private *dev_priv)
+{
+	if (!dev_priv->psr.sink_psr2_support)
+		return;
+
+	if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_DC3CO)
+		gen9_set_dc_state(dev_priv, DC_STATE_EN_DC3CO);
+}
+
+static void tgl_disallow_dc3co(struct drm_i915_private *dev_priv)
+{
+	u32 val;
+
+	val = I915_READ(DC_STATE_EN);
+	val &= ~DC_STATE_DC3CO_STATUS;
+	I915_WRITE(DC_STATE_EN, val);
+	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+	/*
+	 * Delay of 200us DC3CO Exit time B.Spec 49196
+	 */
+	udelay(200);
+}
+
 static void bxt_enable_dc9(struct drm_i915_private *dev_priv)
 {
 	assert_can_enable_dc9(dev_priv);
@@ -939,7 +962,8 @@ static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv)
 static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv,
 					   struct i915_power_well *power_well)
 {
-	return (I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0;
+	return ((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC3CO) == 0 &&
+		(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0);
 }
 
 static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv)
@@ -955,24 +979,32 @@ static void gen9_disable_dc_states(struct drm_i915_private *dev_priv)
 {
 	struct intel_cdclk_state cdclk_state = {};
 
-	gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+	if (dev_priv->csr.max_dc_state & DC_STATE_EN_DC3CO) {
+		tgl_disallow_dc3co(dev_priv);
+	} else {
+		gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
 
-	dev_priv->display.get_cdclk(dev_priv, &cdclk_state);
-	/* Can't read out voltage_level so can't use intel_cdclk_changed() */
-	WARN_ON(intel_cdclk_needs_modeset(&dev_priv->cdclk.hw, &cdclk_state));
+		dev_priv->display.get_cdclk(dev_priv, &cdclk_state);
+		/*
+		 * Can't read out voltage_level so can't use
+		 * intel_cdclk_changed()
+		 */
+		WARN_ON(intel_cdclk_needs_modeset(&dev_priv->cdclk.hw,
+						  &cdclk_state));
 
-	gen9_assert_dbuf_enabled(dev_priv);
+		gen9_assert_dbuf_enabled(dev_priv);
 
-	if (IS_GEN9_LP(dev_priv))
-		bxt_verify_ddi_phy_power_wells(dev_priv);
+		if (IS_GEN9_LP(dev_priv))
+			bxt_verify_ddi_phy_power_wells(dev_priv);
 
-	if (INTEL_GEN(dev_priv) >= 11)
-		/*
-		 * DMC retains HW context only for port A, the other combo
-		 * PHY's HW context for port B is lost after DC transitions,
-		 * so we need to restore it manually.
-		 */
-		intel_combo_phy_init(dev_priv);
+		if (INTEL_GEN(dev_priv) >= 11)
+			/*
+			 * DMC retains HW context only for port A, the other
+			 * combo PHY's HW context for port B is lost after
+			 * DC transitions, so we need to restore it manually.
+			 */
+			intel_combo_phy_init(dev_priv);
+	}
 }
 
 static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
@@ -987,10 +1019,43 @@ static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
 	if (!dev_priv->csr.dmc_payload)
 		return;
 
-	if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC6)
-		skl_enable_dc6(dev_priv);
-	else if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5)
-		gen9_enable_dc5(dev_priv);
+	if (dev_priv->csr.max_dc_state & DC_STATE_EN_DC3CO) {
+		tgl_allow_dc3co(dev_priv);
+	} else if (dev_priv->csr.max_dc_state & DC_STATE_EN_UPTO_DC5_DC6_MASK) {
+		if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC6)
+			skl_enable_dc6(dev_priv);
+		else if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5)
+			gen9_enable_dc5(dev_priv);
+	}
+}
+
+void tgl_set_target_dc_state(struct drm_i915_private *dev_priv, u32 state)
+{
+	struct i915_power_well *power_well;
+	bool dc_off_enabled;
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+
+	mutex_lock(&power_domains->lock);
+	power_well = lookup_power_well(dev_priv, TGL_DISP_DC_OFF);
+	dc_off_enabled = power_well->desc->ops->is_enabled(dev_priv,
+							   power_well);
+	if (state == dev_priv->csr.max_dc_state)
+		goto unlock;
+
+	if (!dc_off_enabled) {
+		/*
+		 * Need to disable the DC off power well to
+		 * effect target DC state.
+		 */
+		power_well->desc->ops->enable(dev_priv, power_well);
+		dev_priv->csr.max_dc_state = state;
+		power_well->desc->ops->disable(dev_priv, power_well);
+		goto unlock;
+	}
+		dev_priv->csr.max_dc_state = state;
+
+unlock:
+	mutex_unlock(&power_domains->lock);
 }
 
 static void i9xx_power_well_sync_hw_noop(struct drm_i915_private *dev_priv,
@@ -3610,7 +3675,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
 		.name = "DC off",
 		.domains = TGL_DISPLAY_DC_OFF_POWER_DOMAINS,
 		.ops = &gen9_dc_off_power_well_ops,
-		.id = DISP_PW_ID_NONE,
+		.id = TGL_DISP_DC_OFF,
 	},
 	{
 		.name = "power well 2",
@@ -4039,6 +4104,7 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
 	dev_priv->csr.allowed_dc_mask =
 		get_allowed_dc_mask(dev_priv, i915_modparams.enable_dc);
 
+	dev_priv->csr.max_dc_state = DC_STATE_EN_UPTO_DC5_DC6_MASK;
 	BUILD_BUG_ON(POWER_DOMAIN_NUM > 64);
 
 	mutex_init(&power_domains->lock);
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index 737b5def7fc6..1add626da458 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -100,6 +100,7 @@ enum i915_power_well_id {
 	SKL_DISP_PW_MISC_IO,
 	SKL_DISP_PW_1,
 	SKL_DISP_PW_2,
+	TGL_DISP_DC_OFF,
 };
 
 #define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
@@ -256,6 +257,7 @@ void intel_display_power_suspend_late(struct drm_i915_private *i915);
 void intel_display_power_resume_early(struct drm_i915_private *i915);
 void intel_display_power_suspend(struct drm_i915_private *i915);
 void intel_display_power_resume(struct drm_i915_private *i915);
+void tgl_set_target_dc_state(struct drm_i915_private *dev_priv, u32 state);
 
 const char *
 intel_display_power_domain_str(enum intel_display_power_domain domain);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index db7480831e52..999da5d2da0b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -336,6 +336,7 @@ struct intel_csr {
 	i915_reg_t mmioaddr[20];
 	u32 mmiodata[20];
 	u32 dc_state;
+	u32 max_dc_state;
 	u32 allowed_dc_mask;
 	intel_wakeref_t wakeref;
 };
-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 4/7] drm/i915/tgl: Add helper function for DC3CO exitline.
  2019-09-03 17:59 [PATCH v6 0/7] DC3CO Support for TGL Anshuman Gupta
                   ` (2 preceding siblings ...)
  2019-09-03 17:59 ` [PATCH v6 3/7] drm/i915/tgl: Enable DC3CO state in "DC Off" power well Anshuman Gupta
@ 2019-09-03 17:59 ` Anshuman Gupta
  2019-09-03 17:59 ` [PATCH v6 5/7] drm/i915/tgl: DC3CO PSR2 helper Anshuman Gupta
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anshuman Gupta @ 2019-09-03 17:59 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

DC3CO enabling B.Specs sequence requires to enable end configure
exit scanlines to TRANS_EXITLINE register, programming this register
has to be part of modeset sequence as this can't be change when
transcoder or port is enabled.
When system boots with only eDP panel there may not be real
modeset as BIOS has already programmed the necessary registers,
therefore it needs to force a modeset at bootup to enable and configure
DC3CO exitline.

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  |  5 +
 .../drm/i915/display/intel_display_power.c    | 95 +++++++++++++++++++
 .../drm/i915/display/intel_display_power.h    |  6 ++
 drivers/gpu/drm/i915/i915_drv.h               |  3 +
 drivers/gpu/drm/i915/intel_pm.c               |  2 +-
 drivers/gpu/drm/i915/intel_pm.h               |  2 +
 6 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 12a94c6e3d51..01b23443c96b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7409,6 +7409,8 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 	int clock_limit = dev_priv->max_dotclk_freq;
 
+	tgl_compute_dc3co_crtc(pipe_config);
+
 	if (INTEL_GEN(dev_priv) < 4) {
 		clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
 
@@ -13567,6 +13569,9 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
 	if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true))
 		return;
 
+	if (!tgl_dc3co_can_enable_fastset(new_crtc_state))
+		return;
+
 	new_crtc_state->base.mode_changed = false;
 	new_crtc_state->update_pipe = true;
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 868197bb4860..95f352bf0173 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -19,6 +19,7 @@
 #include "intel_hotplug.h"
 #include "intel_sideband.h"
 #include "intel_tc.h"
+#include "intel_pm.h"
 
 bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
 					 enum i915_power_well_id power_well_id);
@@ -772,6 +773,100 @@ static void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state)
 	dev_priv->csr.dc_state = val & mask;
 }
 
+void tgl_enable_psr2_transcoder_exitline(const struct intel_crtc_state *cstate)
+{
+	u32 linetime_us, val, exit_scanlines;
+	u32 crtc_vdisplay = cstate->base.adjusted_mode.crtc_vdisplay;
+	struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev);
+
+	linetime_us = fixed16_to_u32_round_up(intel_get_linetime_us(cstate));
+	if (WARN_ON(!linetime_us))
+		return;
+	/*
+	 * DC3CO Exit time 200us B.Spec 49196
+	 * PSR2 transcoder Early Exit scanlines = ROUNDUP(200 / line time) + 1
+	 * Exit line event need to program above calculated scan lines before
+	 * next VBLANK.
+	 */
+	exit_scanlines = DIV_ROUND_UP(200, linetime_us) + 1;
+	if (WARN_ON(exit_scanlines > crtc_vdisplay))
+		return;
+
+	exit_scanlines = crtc_vdisplay - exit_scanlines;
+	exit_scanlines <<= EXITLINE_SHIFT;
+	val = I915_READ(EXITLINE(cstate->cpu_transcoder));
+	val &= ~(EXITLINE_MASK | EXITLINE_ENABLE);
+	val |= exit_scanlines;
+	val |= EXITLINE_ENABLE;
+	I915_WRITE(EXITLINE(cstate->cpu_transcoder), val);
+}
+
+static bool tgl_dc3co_is_edp_connected(struct intel_crtc_state  *crtc_state)
+{
+	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	int i;
+
+	for_each_new_connector_in_state(state, connector, connector_state, i) {
+		if (connector->status == connector_status_connected &&
+		    connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/*
+ * DC3CO requires to enable exitline and program DC3CO requires
+ * exit scanlines to TRANS_EXITLINE register, which should only
+ * change before transcoder or port is enabled.
+ * This requires to disable the fastset at boot for eDP output.
+ */
+bool tgl_dc3co_can_enable_fastset(struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	bool fastset = true;
+
+	if (!IS_TIGERLAKE(dev_priv))
+		return fastset;
+
+	if (!(dev_priv->csr.allowed_dc_mask & DC_STATE_EN_DC3CO))
+		return fastset;
+
+	if (crtc_state->has_psr2 && crtc_state->base.active) {
+		if (tgl_dc3co_is_edp_connected(crtc_state)) {
+			if (!dev_priv->csr.dc3co_boot_modeset) {
+				fastset = false;
+				dev_priv->csr.dc3co_boot_modeset = true;
+			}
+		}
+	}
+
+	return fastset;
+}
+
+void tgl_compute_dc3co_crtc(struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+
+	dev_priv->csr.dc3co_crtc = NULL;
+
+	if (!IS_TIGERLAKE(dev_priv))
+		return;
+
+	if (!(dev_priv->csr.allowed_dc_mask & DC_STATE_EN_DC3CO))
+		return;
+
+	if (crtc_state->has_psr2 && crtc_state->base.active) {
+		if (tgl_dc3co_is_edp_connected(crtc_state)) {
+			dev_priv->csr.dc3co_crtc =
+				to_intel_crtc(crtc_state->base.crtc);
+		}
+	}
+}
+
 static void tgl_allow_dc3co(struct drm_i915_private *dev_priv)
 {
 	if (!dev_priv->psr.sink_psr2_support)
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index 1add626da458..c37c4ce24a5f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -12,6 +12,8 @@
 
 struct drm_i915_private;
 struct intel_encoder;
+struct intel_crtc_state;
+struct intel_atomic_state;
 
 enum intel_display_power_domain {
 	POWER_DOMAIN_DISPLAY_CORE,
@@ -258,6 +260,10 @@ void intel_display_power_resume_early(struct drm_i915_private *i915);
 void intel_display_power_suspend(struct drm_i915_private *i915);
 void intel_display_power_resume(struct drm_i915_private *i915);
 void tgl_set_target_dc_state(struct drm_i915_private *dev_priv, u32 state);
+bool tgl_dc3co_can_enable_fastset(struct intel_crtc_state *crtc_state);
+void tgl_compute_dc3co_crtc(struct intel_crtc_state *crtc_state);
+void tgl_dc5_idle_thread(struct work_struct *work);
+void tgl_enable_psr2_transcoder_exitline(const struct intel_crtc_state *cstate);
 
 const char *
 intel_display_power_domain_str(enum intel_display_power_domain domain);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 999da5d2da0b..d593980e3d51 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -339,6 +339,9 @@ struct intel_csr {
 	u32 max_dc_state;
 	u32 allowed_dc_mask;
 	intel_wakeref_t wakeref;
+	bool dc3co_boot_modeset;
+	/* cache the crtc on which DC3CO will be allowed */
+	struct intel_crtc *dc3co_crtc;
 };
 
 enum i915_cache_level {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 4fa9bc83c8b4..3ee104ae3e2d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4584,7 +4584,7 @@ skl_wm_method2(u32 pixel_rate, u32 pipe_htotal, u32 latency,
 	return ret;
 }
 
-static uint_fixed_16_16_t
+uint_fixed_16_16_t
 intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
 {
 	u32 pixel_rate;
diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
index e3573e1e16e3..454e92c06dff 100644
--- a/drivers/gpu/drm/i915/intel_pm.h
+++ b/drivers/gpu/drm/i915/intel_pm.h
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 
+#include "i915_drv.h"
 #include "i915_reg.h"
 
 struct drm_device;
@@ -76,6 +77,7 @@ u64 intel_rc6_residency_ns(struct drm_i915_private *dev_priv, i915_reg_t reg);
 u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv, i915_reg_t reg);
 
 u32 intel_get_cagf(struct drm_i915_private *dev_priv, u32 rpstat1);
+uint_fixed_16_16_t intel_get_linetime_us(const struct intel_crtc_state *cstate);
 
 unsigned long i915_chipset_val(struct drm_i915_private *dev_priv);
 unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 5/7] drm/i915/tgl: DC3CO PSR2 helper
  2019-09-03 17:59 [PATCH v6 0/7] DC3CO Support for TGL Anshuman Gupta
                   ` (3 preceding siblings ...)
  2019-09-03 17:59 ` [PATCH v6 4/7] drm/i915/tgl: Add helper function for DC3CO exitline Anshuman Gupta
@ 2019-09-03 17:59 ` Anshuman Gupta
  2019-09-03 17:59 ` [PATCH v6 6/7] drm/i915/tgl: switch between dc3co and dc5 based on display idleness Anshuman Gupta
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anshuman Gupta @ 2019-09-03 17:59 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Add dc3co helper functions to enable/disable psr2 deep sleep.
Adhere B.Specs by disallow DC3CO state before PSR2 exit.
Enable PSR2 exitline event and program the desired scanlines
to exit DC3CO in intel_psr_enable function at modeset path.

v1: moved calling of tgl_enable_psr2_transcoder_exitline() to
    intel_psr_enable(). [Imre]

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Cc: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 43 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_psr.h |  2 ++
 2 files changed, 45 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 629b8b98a97f..0098465ef573 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -549,6 +549,44 @@ transcoder_has_psr2(struct drm_i915_private *dev_priv, enum transcoder trans)
 		return trans == TRANSCODER_EDP;
 }
 
+static void psr2_program_idle_frames(struct drm_i915_private *dev_priv,
+				     u32 idle_frames)
+{
+	u32 val;
+
+	idle_frames <<=  EDP_PSR2_IDLE_FRAME_SHIFT;
+	val = I915_READ(EDP_PSR2_CTL(dev_priv->psr.transcoder));
+	val &= ~EDP_PSR2_IDLE_FRAME_MASK;
+	val |= idle_frames;
+	I915_WRITE(EDP_PSR2_CTL(dev_priv->psr.transcoder), val);
+}
+
+void tgl_psr2_deep_sleep_disable(struct drm_i915_private *dev_priv)
+{
+	int idle_frames = 0;
+
+	psr2_program_idle_frames(dev_priv, idle_frames);
+}
+
+void tgl_psr2_deep_sleep_enable(struct drm_i915_private *dev_priv)
+{
+	int idle_frames;
+
+	/*
+	 * Let's use 6 as the minimum to cover all known cases including the
+	 * off-by-one issue that HW has in some cases.
+	 */
+	idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
+	idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1);
+	psr2_program_idle_frames(dev_priv, idle_frames);
+}
+
+static void tgl_disallow_dc3co_on_psr2_exit(struct drm_i915_private *dev_priv)
+{
+	/* Before PSR2 exit disallow dc3co*/
+	tgl_set_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
+}
+
 static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 				    struct intel_crtc_state *crtc_state)
 {
@@ -809,6 +847,10 @@ void intel_psr_enable(struct intel_dp *intel_dp,
 
 	WARN_ON(dev_priv->drrs.dp);
 
+	/* Enable PSR2 transcoder exit line */
+	if (crtc_state->has_psr2)
+		tgl_enable_psr2_transcoder_exitline(crtc_state);
+
 	mutex_lock(&dev_priv->psr.lock);
 
 	if (!psr_global_enabled(dev_priv->psr.debug)) {
@@ -839,6 +881,7 @@ static void intel_psr_exit(struct drm_i915_private *dev_priv)
 	}
 
 	if (dev_priv->psr.psr2_enabled) {
+		tgl_disallow_dc3co_on_psr2_exit(dev_priv);
 		val = I915_READ(EDP_PSR2_CTL(dev_priv->psr.transcoder));
 		WARN_ON(!(val & EDP_PSR2_ENABLE));
 		val &= ~EDP_PSR2_ENABLE;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index 46e4de8b8cd5..75a9862f36fd 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -35,5 +35,7 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp);
 int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
 			    u32 *out_value);
 bool intel_psr_enabled(struct intel_dp *intel_dp);
+void tgl_psr2_deep_sleep_disable(struct drm_i915_private *dev_priv);
+void tgl_psr2_deep_sleep_enable(struct drm_i915_private *dev_priv);
 
 #endif /* __INTEL_PSR_H__ */
-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 6/7] drm/i915/tgl: switch between dc3co and dc5 based on display idleness
  2019-09-03 17:59 [PATCH v6 0/7] DC3CO Support for TGL Anshuman Gupta
                   ` (4 preceding siblings ...)
  2019-09-03 17:59 ` [PATCH v6 5/7] drm/i915/tgl: DC3CO PSR2 helper Anshuman Gupta
@ 2019-09-03 17:59 ` Anshuman Gupta
  2019-09-03 17:59 ` [PATCH v6 7/7] drm/i915/tgl: Add DC3CO counter in i915_dmc_info Anshuman Gupta
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anshuman Gupta @ 2019-09-03 17:59 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

DC3CO is useful power state, when DMC detects PSR2 idle frame
while an active video playback, playing 30fps video on 60hz panel
is the classic example of this use case.
DC5 and DC6 saves more power, but can't be entered during video
playback because there are not enough idle frames in a row to meet
most PSR2 panel deep sleep entry requirement typically 4 frames.

It will be worthy to enable DC3CO after completion of each flip
and switch back to DC5 when display is idle, as driver doesn't
differentiate between video playback and a normal flip.
It is safer to allow DC5 after 6 idle frame, as PSR2 requires
minimum 6 idle frame.

v2: calculated s/w state to switch over dc3co when there is an
    update. [Imre]
    used cancel_delayed_work_sync() in order to avoid any race
    with already scheduled delayed work. [Imre]
v3: cancel_delayed_work_sync() may blocked the commit work.
    Hence dropping it, dc5_idle_thread() checks the valid wakeref before
    putting the reference count, which avoids any chances of dropping
    a zero wakeref. [Imre (IRC)]
v4: use frontbuffer flush mechanism. [Imre]

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  |  2 +
 .../drm/i915/display/intel_display_power.c    | 75 +++++++++++++++++++
 .../drm/i915/display/intel_display_power.h    |  7 ++
 .../gpu/drm/i915/display/intel_frontbuffer.c  |  1 +
 drivers/gpu/drm/i915/display/intel_psr.c      |  1 +
 drivers/gpu/drm/i915/i915_drv.h               |  1 +
 6 files changed, 87 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 01b23443c96b..94ee4fe6cc85 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -16166,6 +16166,7 @@ int intel_modeset_init(struct drm_device *dev)
 	init_llist_head(&dev_priv->atomic_helper.free_list);
 	INIT_WORK(&dev_priv->atomic_helper.free_work,
 		  intel_atomic_helper_free_state_worker);
+	INIT_DELAYED_WORK(&dev_priv->csr.idle_work, tgl_dc5_idle_thread);
 
 	intel_init_quirks(dev_priv);
 
@@ -17107,6 +17108,7 @@ void intel_modeset_driver_remove(struct drm_device *dev)
 	flush_workqueue(dev_priv->modeset_wq);
 
 	flush_work(&dev_priv->atomic_helper.free_work);
+	flush_delayed_work(&dev_priv->csr.idle_work);
 	WARN_ON(!llist_empty(&dev_priv->atomic_helper.free_list));
 
 	/*
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 95f352bf0173..57248a2a6ad7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -20,6 +20,7 @@
 #include "intel_sideband.h"
 #include "intel_tc.h"
 #include "intel_pm.h"
+#include "intel_psr.h"
 
 bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
 					 enum i915_power_well_id power_well_id);
@@ -773,6 +774,27 @@ static void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state)
 	dev_priv->csr.dc_state = val & mask;
 }
 
+static u32 intel_get_frame_time_us(const struct intel_crtc_state *cstate)
+{
+	u32 pixel_rate, crtc_htotal, crtc_vtotal;
+	u32 frametime_us;
+
+	if (!cstate || !cstate->base.active)
+		return 0;
+
+	pixel_rate = cstate->pixel_rate;
+
+	if (WARN_ON(pixel_rate == 0))
+		return 0;
+
+	crtc_htotal = cstate->base.adjusted_mode.crtc_htotal;
+	crtc_vtotal = cstate->base.adjusted_mode.crtc_vtotal;
+	frametime_us = DIV_ROUND_UP(crtc_htotal * crtc_vtotal * 1000ULL,
+				    pixel_rate);
+
+	return frametime_us;
+}
+
 void tgl_enable_psr2_transcoder_exitline(const struct intel_crtc_state *cstate)
 {
 	u32 linetime_us, val, exit_scanlines;
@@ -801,6 +823,50 @@ void tgl_enable_psr2_transcoder_exitline(const struct intel_crtc_state *cstate)
 	I915_WRITE(EXITLINE(cstate->cpu_transcoder), val);
 }
 
+void tgl_dc3co_flush(struct drm_i915_private *dev_priv,
+		     unsigned int frontbuffer_bits, enum fb_op_origin origin)
+{
+	struct intel_crtc_state *cstate;
+	u32 delay;
+	unsigned int busy_frontbuffer_bits;
+
+	if (!IS_TIGERLAKE(dev_priv))
+		return;
+
+	if (origin != ORIGIN_FLIP)
+		return;
+
+	if (!dev_priv->csr.dc3co_crtc)
+		return;
+
+	cstate = to_intel_crtc_state(dev_priv->csr.dc3co_crtc->base.state);
+	frontbuffer_bits &=
+		INTEL_FRONTBUFFER_ALL_MASK(dev_priv->csr.dc3co_crtc->pipe);
+	busy_frontbuffer_bits &= ~frontbuffer_bits;
+
+	mutex_lock(&dev_priv->psr.lock);
+
+	if (!dev_priv->psr.psr2_enabled || !dev_priv->psr.active)
+		goto unlock;
+
+	/*
+	 * At every flip frontbuffer flush first cancel the delayed work,
+	 * when delayed schedules that means display has been idle
+	 * for the 6 idle frame.
+	 */
+	if (!busy_frontbuffer_bits) {
+		cancel_delayed_work(&dev_priv->csr.idle_work);
+		tgl_psr2_deep_sleep_disable(dev_priv);
+		tgl_set_target_dc_state(dev_priv, DC_STATE_EN_DC3CO);
+		delay = DC5_REQ_IDLE_FRAMES * intel_get_frame_time_us(cstate);
+		schedule_delayed_work(&dev_priv->csr.idle_work,
+				      usecs_to_jiffies(delay));
+	}
+
+unlock:
+	mutex_unlock(&dev_priv->psr.lock);
+}
+
 static bool tgl_dc3co_is_edp_connected(struct intel_crtc_state  *crtc_state)
 {
 	struct drm_atomic_state *state = crtc_state->base.state;
@@ -867,6 +933,15 @@ void tgl_compute_dc3co_crtc(struct intel_crtc_state *crtc_state)
 	}
 }
 
+void tgl_dc5_idle_thread(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, typeof(*dev_priv), csr.idle_work.work);
+
+	tgl_set_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
+	tgl_psr2_deep_sleep_enable(dev_priv);
+}
+
 static void tgl_allow_dc3co(struct drm_i915_private *dev_priv)
 {
 	if (!dev_priv->psr.sink_psr2_support)
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index c37c4ce24a5f..aefdb72db131 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -9,6 +9,9 @@
 #include "intel_display.h"
 #include "intel_runtime_pm.h"
 #include "i915_reg.h"
+#include "intel_frontbuffer.h"
+
+#define DC5_REQ_IDLE_FRAMES	6
 
 struct drm_i915_private;
 struct intel_encoder;
@@ -259,11 +262,15 @@ void intel_display_power_suspend_late(struct drm_i915_private *i915);
 void intel_display_power_resume_early(struct drm_i915_private *i915);
 void intel_display_power_suspend(struct drm_i915_private *i915);
 void intel_display_power_resume(struct drm_i915_private *i915);
+
 void tgl_set_target_dc_state(struct drm_i915_private *dev_priv, u32 state);
 bool tgl_dc3co_can_enable_fastset(struct intel_crtc_state *crtc_state);
 void tgl_compute_dc3co_crtc(struct intel_crtc_state *crtc_state);
 void tgl_dc5_idle_thread(struct work_struct *work);
 void tgl_enable_psr2_transcoder_exitline(const struct intel_crtc_state *cstate);
+void tgl_dc5_idle_thread(struct work_struct *work);
+void tgl_dc3co_flush(struct drm_i915_private *dev_priv,
+		     unsigned int frontbuffer_bits, enum fb_op_origin origin);
 
 const char *
 intel_display_power_domain_str(enum intel_display_power_domain domain);
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
index fc40dc1fdbcc..c3b10f6e4382 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
@@ -90,6 +90,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
 	might_sleep();
 	intel_edp_drrs_flush(i915, frontbuffer_bits);
 	intel_psr_flush(i915, frontbuffer_bits, origin);
+	tgl_dc3co_flush(i915, frontbuffer_bits, origin);
 	intel_fbc_flush(i915, frontbuffer_bits, origin);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 0098465ef573..cfa4f306af7e 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -583,6 +583,7 @@ void tgl_psr2_deep_sleep_enable(struct drm_i915_private *dev_priv)
 
 static void tgl_disallow_dc3co_on_psr2_exit(struct drm_i915_private *dev_priv)
 {
+	cancel_delayed_work(&dev_priv->csr.idle_work);
 	/* Before PSR2 exit disallow dc3co*/
 	tgl_set_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d593980e3d51..c7f145791311 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -338,6 +338,7 @@ struct intel_csr {
 	u32 dc_state;
 	u32 max_dc_state;
 	u32 allowed_dc_mask;
+	struct delayed_work idle_work;
 	intel_wakeref_t wakeref;
 	bool dc3co_boot_modeset;
 	/* cache the crtc on which DC3CO will be allowed */
-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 7/7] drm/i915/tgl: Add DC3CO counter in i915_dmc_info
  2019-09-03 17:59 [PATCH v6 0/7] DC3CO Support for TGL Anshuman Gupta
                   ` (5 preceding siblings ...)
  2019-09-03 17:59 ` [PATCH v6 6/7] drm/i915/tgl: switch between dc3co and dc5 based on display idleness Anshuman Gupta
@ 2019-09-03 17:59 ` Anshuman Gupta
  2019-09-03 18:20 ` ✗ Fi.CI.CHECKPATCH: warning for DC3CO Support for TGL (rev6) Patchwork
  2019-09-03 18:43 ` ✗ Fi.CI.BAT: failure " Patchwork
  8 siblings, 0 replies; 10+ messages in thread
From: Anshuman Gupta @ 2019-09-03 17:59 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Adding DC3CO counter in i915_dmc_info debugfs will be
useful for DC3CO validation.
DMC firmware uses DMC_DEBUG3 register as DC3CO counter
register on TGL, as per B.Specs DMC_DEBUG3 is general
purpose register.

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 6 ++++++
 drivers/gpu/drm/i915/i915_reg.h     | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 9798f27a697a..957b6ef37434 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2391,6 +2391,12 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
 	seq_printf(m, "version: %d.%d\n", CSR_VERSION_MAJOR(csr->version),
 		   CSR_VERSION_MINOR(csr->version));
 
+	/*
+	 * TGL DMC f/w uses DMC_DEBUG3 register for DC3CO counter.
+	 */
+	if (IS_TIGERLAKE(dev_priv))
+		seq_printf(m, "DC3CO count: %d\n", I915_READ(DMC_DEBUG3));
+
 	if (INTEL_GEN(dev_priv) >= 12) {
 		dc5_reg = TGL_DMC_DEBUG_DC5_COUNT;
 		dc6_reg = TGL_DMC_DEBUG_DC6_COUNT;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e1bdd54b1816..f751c67c3a5e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7238,6 +7238,8 @@ enum {
 #define TGL_DMC_DEBUG_DC5_COUNT	_MMIO(0x101084)
 #define TGL_DMC_DEBUG_DC6_COUNT	_MMIO(0x101088)
 
+#define DMC_DEBUG3		_MMIO(0x101090)
+
 /* interrupts */
 #define DE_MASTER_IRQ_CONTROL   (1 << 31)
 #define DE_SPRITEB_FLIP_DONE    (1 << 29)
-- 
2.21.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* ✗ Fi.CI.CHECKPATCH: warning for DC3CO Support for TGL (rev6)
  2019-09-03 17:59 [PATCH v6 0/7] DC3CO Support for TGL Anshuman Gupta
                   ` (6 preceding siblings ...)
  2019-09-03 17:59 ` [PATCH v6 7/7] drm/i915/tgl: Add DC3CO counter in i915_dmc_info Anshuman Gupta
@ 2019-09-03 18:20 ` Patchwork
  2019-09-03 18:43 ` ✗ Fi.CI.BAT: failure " Patchwork
  8 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2019-09-03 18:20 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx

== Series Details ==

Series: DC3CO Support for TGL (rev6)
URL   : https://patchwork.freedesktop.org/series/64923/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
f99eddda47f0 drm/i915/tgl: Add DC3CO required register and bits
48ad8fa95f1a drm/i915/tgl: Add DC3CO mask to allowed_dc_mask and gen9_dc_mask
2f51045a1df1 drm/i915/tgl: Enable DC3CO state in "DC Off" power well
-:56: CHECK:USLEEP_RANGE: usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst
#56: FILE: drivers/gpu/drm/i915/display/intel_display_power.c:795:
+	udelay(200);

total: 0 errors, 0 warnings, 1 checks, 167 lines checked
d1df3094eb5f drm/i915/tgl: Add helper function for DC3CO exitline.
bbe23a634ddd drm/i915/tgl: DC3CO PSR2 helper
6cde5d766d74 drm/i915/tgl: switch between dc3co and dc5 based on display idleness
64428dde03af drm/i915/tgl: Add DC3CO counter in i915_dmc_info

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 10+ messages in thread

* ✗ Fi.CI.BAT: failure for DC3CO Support for TGL (rev6)
  2019-09-03 17:59 [PATCH v6 0/7] DC3CO Support for TGL Anshuman Gupta
                   ` (7 preceding siblings ...)
  2019-09-03 18:20 ` ✗ Fi.CI.CHECKPATCH: warning for DC3CO Support for TGL (rev6) Patchwork
@ 2019-09-03 18:43 ` Patchwork
  8 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2019-09-03 18:43 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx

== Series Details ==

Series: DC3CO Support for TGL (rev6)
URL   : https://patchwork.freedesktop.org/series/64923/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_6828 -> Patchwork_14268
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_14268 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_14268, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14268/

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_14268:

### IGT changes ###

#### Possible regressions ####

  * igt@runner@aborted:
    - fi-whl-u:           NOTRUN -> [FAIL][1]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14268/fi-whl-u/igt@runner@aborted.html

  
Known issues
------------

  Here are the changes found in Patchwork_14268 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_busy@basic-flip-c:
    - fi-kbl-7500u:       [PASS][2] -> [SKIP][3] ([fdo#109271] / [fdo#109278]) +2 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6828/fi-kbl-7500u/igt@kms_busy@basic-flip-c.html
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14268/fi-kbl-7500u/igt@kms_busy@basic-flip-c.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s3:
    - fi-blb-e6850:       [INCOMPLETE][4] ([fdo#107718]) -> [PASS][5]
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6828/fi-blb-e6850/igt@gem_exec_suspend@basic-s3.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14268/fi-blb-e6850/igt@gem_exec_suspend@basic-s3.html

  * igt@gem_exec_suspend@basic-s4-devices:
    - fi-kbl-7500u:       [DMESG-WARN][6] ([fdo#105128] / [fdo#107139]) -> [PASS][7]
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6828/fi-kbl-7500u/igt@gem_exec_suspend@basic-s4-devices.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14268/fi-kbl-7500u/igt@gem_exec_suspend@basic-s4-devices.html

  
  [fdo#105128]: https://bugs.freedesktop.org/show_bug.cgi?id=105128
  [fdo#107139]: https://bugs.freedesktop.org/show_bug.cgi?id=107139
  [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278


Participating hosts (53 -> 46)
------------------------------

  Missing    (7): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-icl-y fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_6828 -> Patchwork_14268

  CI-20190529: 20190529
  CI_DRM_6828: 6e043dde15a1b2b97d908d0467e9197ffa8934c2 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5164: 90babd3f12707dfabaa58bb18f6b8e22636b6895 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_14268: 64428dde03af0bbd6fb7716c43ef0b03a7c5ddb6 @ git://anongit.freedesktop.org/gfx-ci/linux


== Kernel 32bit build ==

Warning: Kernel 32bit buildtest failed:
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14268/build_32bit.log

  CALL    scripts/checksyscalls.sh
  CALL    scripts/atomic/check-atomics.sh
  CHK     include/generated/compile.h
Kernel: arch/x86/boot/bzImage is ready  (#1)
  Building modules, stage 2.
  MODPOST 117 modules
ERROR: "__udivdi3" [drivers/gpu/drm/i915/i915.ko] undefined!
ERROR: "__divdi3" [drivers/gpu/drm/i915/i915.ko] undefined!
scripts/Makefile.modpost:103: recipe for target 'modules-modpost' failed
make[1]: *** [modules-modpost] Error 1
Makefile:1301: recipe for target 'modules' failed
make: *** [modules] Error 2


== Linux commits ==

64428dde03af drm/i915/tgl: Add DC3CO counter in i915_dmc_info
6cde5d766d74 drm/i915/tgl: switch between dc3co and dc5 based on display idleness
bbe23a634ddd drm/i915/tgl: DC3CO PSR2 helper
d1df3094eb5f drm/i915/tgl: Add helper function for DC3CO exitline.
2f51045a1df1 drm/i915/tgl: Enable DC3CO state in "DC Off" power well
48ad8fa95f1a drm/i915/tgl: Add DC3CO mask to allowed_dc_mask and gen9_dc_mask
f99eddda47f0 drm/i915/tgl: Add DC3CO required register and bits

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14268/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-09-03 18:43 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-03 17:59 [PATCH v6 0/7] DC3CO Support for TGL Anshuman Gupta
2019-09-03 17:59 ` [PATCH v6 1/7] drm/i915/tgl: Add DC3CO required register and bits Anshuman Gupta
2019-09-03 17:59 ` [PATCH v6 2/7] drm/i915/tgl: Add DC3CO mask to allowed_dc_mask and gen9_dc_mask Anshuman Gupta
2019-09-03 17:59 ` [PATCH v6 3/7] drm/i915/tgl: Enable DC3CO state in "DC Off" power well Anshuman Gupta
2019-09-03 17:59 ` [PATCH v6 4/7] drm/i915/tgl: Add helper function for DC3CO exitline Anshuman Gupta
2019-09-03 17:59 ` [PATCH v6 5/7] drm/i915/tgl: DC3CO PSR2 helper Anshuman Gupta
2019-09-03 17:59 ` [PATCH v6 6/7] drm/i915/tgl: switch between dc3co and dc5 based on display idleness Anshuman Gupta
2019-09-03 17:59 ` [PATCH v6 7/7] drm/i915/tgl: Add DC3CO counter in i915_dmc_info Anshuman Gupta
2019-09-03 18:20 ` ✗ Fi.CI.CHECKPATCH: warning for DC3CO Support for TGL (rev6) Patchwork
2019-09-03 18:43 ` ✗ Fi.CI.BAT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.