All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/31] Add support for GuC-based SLPC
@ 2017-09-19 17:41 Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 01/31] drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing Sagar Arun Kamble
                   ` (30 more replies)
  0 siblings, 31 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Beuchat, Marc, Daniel Vetter

SLPC (Single Loop Power Controller) is a replacement for some host-based
power management features. The SLPC implementation runs in GuC firmware.
This series has been tested with SKL/APL/KBL GuC firmware v9 and v10
which are yet to be released on 01.org.

The graphics power management features in SLPC are called GTPERF,
BALANCER, and DCC.
1. GTPERF is a combination of DFPS (Dynamic FPS) and Turbo. DFPS adjusts
requested graphics frequency to maintain target framerate. Turbo adjusts
requested graphics frequency to maintain target GT busyness.
2. BALANCER adjusts balance between power budgets for IA and GT in power
limited scenarios.
3. DCC (Duty Cycle Control) adjusts requested graphics frequency and stalls
guc-scheduler to maintain actual graphics frequency in efficient range.

This series activates GTPERF Turbo and BALANCER in GuC SLPC.
Patch to enable SLPC by default on platforms having support is removed
from this series as there are following new changes to be added in future
before we enable GuC/SLPC by default:
1. Link waitboost with SLPC.
2. Handle CPG as part of SLPC.
3. IA p-state logic update with GuC submission.

In order to enable CI/PnP testing of SLPC and to avoid frequent
rebase, this series should be safe for merge with feature in disabled
state.

v2: Addressed review comments on v1. Removed patch to enable SLPC by
    default.

v3: Addressed WARNING in igt@drv_module_reload_basic flagged by trybot BAT.
    Added change for sanitizing GT PM during reset. Added separate patch
    for sysfs interface to know HW requested frequency. Also, earlier
    patches did not go as series hence were not correctly picked up by BAT.

v4: Changes to multiple patches. CI BAT is passing. Performance run on SKL
    GT2 done and shows perf at parity with Host Turbo. For BXT, SLPC
    improves performance when GuC is enabled compared to Host Turbo.
    This series keeps only support of 9.18 firmware for better readability.
    If needed, other SLPC interfaces for different GuC version will be
    added later.

v5: This series incorporates feedback from code reviews on earlier series
    and adds following new changes:
	1. More changes for separation of RPS and RC6 handling for Gen9.
	2. Tied up SLPC enabling with GuC load/GuC submission sequence.
	3. SLPC structures are defined explicitly for event input/output.
	4. Definition of SLPC parameter control and task control functions
	   agnostic to the underlying param definitions as they might
	   change with GuC versions and prepared helpers for common tasks.
	5. Transition of i915 overrides done through host to guc events
	   to shared data and single reset event.
	6. Handling SLPC status post reset through shared memory.
	7. Derived helpers for setting frequency limits.
	8. Removed sysfs interface to know RPNSWREQ as it is available in
	   debugfs interface i915_frequency_info.
	9. Simple igt test to verify SLPC configuration by i915 in various
	   driver scenarios is prepared.

v6: This series adds following new changes:
	1. Updated intel_guc_send for SLPC to receive output data from GuC.
	2. Added task overrides and min frequency overrides in intel_slpc_init.
	   min frequency is set to Rpe.
	3. New debugfs interface added to set/unset/read SLPC parameters
	   other than tasks and frequencies. SLPC reset post parameter update
	   added.
	4. SLPC parameters persist as part of i915-GuC shared data hence not
	   overriding frequency limits while re-enabling SLPC.
	5. Other minor fixes to clear pm_rps_events, clflush the shared data.

v7: This series adds following new changes:
	1. Reordered patches. SLPC communication interfaces (structures and
	   functions) are pulled into patches earlier in the series.
	2. Eliminated dependency on i915.enable_slpc at various functions where
	   rps_enabled is available.
	3. s/i915_ggtt_offset/guc_ggtt_offset and sanitization of parameter
	   in intel_uc_sanitize_options.

v8: Activated Balancer. Changed prototype of SLPC functions to accept
    struct intel_slpc as parameter instead of drm_i915_private.

v9: Separated RPS, RC6 and Ring frequency configuration for gen6+.
    Added TDR specific handling of SLPC reset. Some more improvements for
    support of function pointers for rps busy, idle, boost functions.
    This series is based on GuC code restructuring and fixes series at
    https://patchwork.freedesktop.org/series/30351/.
    
VIZ-6889, VIZ-6890

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Beuchat, Marc <marc.beuchat@intel.com>
Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
Cc: Jeff McGee <jeff.mcgee@intel.com>
Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Cc: Oscar Mateo <oscar.mateo@intel.com>
Cc: Michał Winiarski <michal.winiarski@intel.com>
Tested-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>

Sagar Arun Kamble (22):
  drm/i915/debugfs: Create generic string tokenize function and update
    CRC control parsing
  drm/i915: Separate RPS and RC6 handling for gen6+
  drm/i915: Separate RPS and RC6 handling for BDW
  drm/i915: Separate RPS and RC6 handling for VLV
  drm/i915: Separate RPS and RC6 handling for CHV
  drm/i915: Name i915_runtime_pm structure in dev_priv as "rpm"
  drm/i915: Name structure in dev_priv that contains RPS/RC6 state as
    "pm"
  drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled
  drm/i915: Create generic function to setup ring frequency table
  drm/i915: Create generic functions to control RC6, RPS
  drm/i915: Introduce separate status variable for RC6 and Ring
    frequency setup
  drm/i915: Define RPS idle, busy, boost function pointers
  drm/i915/slpc: Lay out SLPC init/enable/disable/cleanup helpers
  drm/i915/slpc: Add SLPC communication interfaces
  drm/i915/slpc: Allocate/Release/Initialize SLPC shared data
  drm/i915/slpc: Add parameter set/unset/get, task control/status
    functions
  drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR
  drm/i915/slpc: Add support for min/max frequency control
  drm/i915/slpc: Add debugfs support to read/write/revert the parameters
  drm/i915/slpc: Add SLPC banner to RPS debugfs interfaces.
  drm/i915/slpc: Add Kabylake SLPC support
  drm/i915/slpc: Add Geminilake SLPC support

Tom O'Rourke (9):
  drm/i915/slpc: Add has_slpc capability flag
  drm/i915/slpc: Add enable_slpc module parameter
  drm/i915/slpc: Sanitize GuC version
  drm/i915/slpc: Enable SLPC in GuC if supported
  drm/i915/slpc: Send SHUTDOWN event
  drm/i915/slpc: Add enable/disable controls for SLPC tasks
  drm/i915/slpc: Add i915_slpc_info to debugfs
  drm/i915/slpc: Add SKL SLPC Support
  drm/i915/slpc: Add Broxton SLPC support

 drivers/gpu/drm/i915/Makefile              |    1 +
 drivers/gpu/drm/i915/i915_debugfs.c        |  383 ++++++++---
 drivers/gpu/drm/i915/i915_drv.c            |   12 +-
 drivers/gpu/drm/i915/i915_drv.h            |   44 +-
 drivers/gpu/drm/i915/i915_gem.c            |    6 +-
 drivers/gpu/drm/i915/i915_gem_request.c    |    4 +-
 drivers/gpu/drm/i915/i915_gpu_error.c      |    4 +-
 drivers/gpu/drm/i915/i915_guc_submission.c |    8 +-
 drivers/gpu/drm/i915/i915_irq.c            |  101 +--
 drivers/gpu/drm/i915/i915_params.c         |    5 +
 drivers/gpu/drm/i915/i915_params.h         |    1 +
 drivers/gpu/drm/i915/i915_pci.c            |    4 +
 drivers/gpu/drm/i915/i915_sysfs.c          |  104 +--
 drivers/gpu/drm/i915/intel_cdclk.c         |   40 +-
 drivers/gpu/drm/i915/intel_csr.c           |   15 +-
 drivers/gpu/drm/i915/intel_display.c       |   14 +-
 drivers/gpu/drm/i915/intel_drv.h           |   15 +-
 drivers/gpu/drm/i915/intel_guc.c           |   27 +-
 drivers/gpu/drm/i915/intel_guc.h           |    6 +
 drivers/gpu/drm/i915/intel_guc_loader.c    |   18 +
 drivers/gpu/drm/i915/intel_pipe_crc.c      |   88 +--
 drivers/gpu/drm/i915/intel_pm.c            |  673 +++++++++++-------
 drivers/gpu/drm/i915/intel_runtime_pm.c    |   26 +-
 drivers/gpu/drm/i915/intel_sideband.c      |    6 +-
 drivers/gpu/drm/i915/intel_slpc.c          | 1028 ++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h          |  286 ++++++++
 drivers/gpu/drm/i915/intel_uc.c            |   37 +
 drivers/gpu/drm/i915/intel_uc_common.h     |    2 +
 28 files changed, 2419 insertions(+), 539 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_slpc.c
 create mode 100644 drivers/gpu/drm/i915/intel_slpc.h

-- 
1.9.1

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

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

* [PATCH 01/31] drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-21 15:12   ` Michal Wajdeczko
  2017-09-19 17:41 ` [PATCH 02/31] drm/i915: Separate RPS and RC6 handling for gen6+ Sagar Arun Kamble
                   ` (29 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tomeu Vizoso

Input string parsing used in CRC control parameter parsing is generic
and can be reused for other debugfs interfaces. Hence name it as
buffer_tokenize instead of tieing to display_crc. Also fix the function
desciption for CRC control parsing that was misplaced at tokenize function.

Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Acked-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h       |  1 +
 drivers/gpu/drm/i915/intel_pipe_crc.c | 88 +++++++++++++++++------------------
 2 files changed, 45 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6d7d871..4d5ffde 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3847,6 +3847,7 @@ u32 i915_gem_fence_alignment(struct drm_i915_private *dev_priv, u32 size,
 int i915_debugfs_register(struct drm_i915_private *dev_priv);
 int i915_debugfs_connector_add(struct drm_connector *connector);
 void intel_display_crc_init(struct drm_i915_private *dev_priv);
+int buffer_tokenize(char *buf, char *words[], int max_words);
 #else
 static inline int i915_debugfs_register(struct drm_i915_private *dev_priv) {return 0;}
 static inline int i915_debugfs_connector_add(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c
index 96043a5..2e312b8 100644
--- a/drivers/gpu/drm/i915/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
@@ -710,49 +710,6 @@ static int pipe_crc_set_source(struct drm_i915_private *dev_priv,
 	return ret;
 }
 
-/*
- * Parse pipe CRC command strings:
- *   command: wsp* object wsp+ name wsp+ source wsp*
- *   object: 'pipe'
- *   name: (A | B | C)
- *   source: (none | plane1 | plane2 | pf)
- *   wsp: (#0x20 | #0x9 | #0xA)+
- *
- * eg.:
- *  "pipe A plane1"  ->  Start CRC computations on plane1 of pipe A
- *  "pipe A none"    ->  Stop CRC
- */
-static int display_crc_ctl_tokenize(char *buf, char *words[], int max_words)
-{
-	int n_words = 0;
-
-	while (*buf) {
-		char *end;
-
-		/* skip leading white space */
-		buf = skip_spaces(buf);
-		if (!*buf)
-			break;	/* end of buffer */
-
-		/* find end of word */
-		for (end = buf; *end && !isspace(*end); end++)
-			;
-
-		if (n_words == max_words) {
-			DRM_DEBUG_DRIVER("too many words, allowed <= %d\n",
-					 max_words);
-			return -EINVAL;	/* ran out of words[] before bytes */
-		}
-
-		if (*end)
-			*end++ = '\0';
-		words[n_words++] = buf;
-		buf = end;
-	}
-
-	return n_words;
-}
-
 enum intel_pipe_crc_object {
 	PIPE_CRC_OBJECT_PIPE,
 };
@@ -806,6 +763,49 @@ static int display_crc_ctl_parse_pipe(const char *buf, enum pipe *pipe)
 	return -EINVAL;
 }
 
+int buffer_tokenize(char *buf, char *words[], int max_words)
+{
+	int n_words = 0;
+
+	while (*buf) {
+		char *end;
+
+		/* skip leading white space */
+		buf = skip_spaces(buf);
+		if (!*buf)
+			break;	/* end of buffer */
+
+		/* find end of word */
+		for (end = buf; *end && !isspace(*end); end++)
+			;
+
+		if (n_words == max_words) {
+			DRM_DEBUG_DRIVER("too many words, allowed <= %d\n",
+					 max_words);
+			return -EINVAL;	/* ran out of words[] before bytes */
+		}
+
+		if (*end)
+			*end++ = '\0';
+		words[n_words++] = buf;
+		buf = end;
+	}
+
+	return n_words;
+}
+
+/*
+ * Parse pipe CRC command strings:
+ *   command: wsp* object wsp+ name wsp+ source wsp*
+ *   object: 'pipe'
+ *   name: (A | B | C)
+ *   source: (none | plane1 | plane2 | pf)
+ *   wsp: (#0x20 | #0x9 | #0xA)+
+ *
+ * eg.:
+ *  "pipe A plane1"  ->  Start CRC computations on plane1 of pipe A
+ *  "pipe A none"    ->  Stop CRC
+ */
 static int display_crc_ctl_parse(struct drm_i915_private *dev_priv,
 				 char *buf, size_t len)
 {
@@ -816,7 +816,7 @@ static int display_crc_ctl_parse(struct drm_i915_private *dev_priv,
 	enum intel_pipe_crc_object object;
 	enum intel_pipe_crc_source source;
 
-	n_words = display_crc_ctl_tokenize(buf, words, N_WORDS);
+	n_words = buffer_tokenize(buf, words, N_WORDS);
 	if (n_words != N_WORDS) {
 		DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n",
 				 N_WORDS);
-- 
1.9.1

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

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

* [PATCH 02/31] drm/i915: Separate RPS and RC6 handling for gen6+
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 01/31] drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-20 12:29   ` Szwichtenberg, Radoslaw
  2017-09-19 17:41 ` [PATCH 03/31] drm/i915: Separate RPS and RC6 handling for BDW Sagar Arun Kamble
                   ` (28 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

This patch separates enable/disable of RC6 and RPS for gen6+
platforms prior to VLV.

Cc: Imre Deak <imre.deak@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 17 +++++++-------
 drivers/gpu/drm/i915/intel_pm.c     | 44 +++++++++++++++++++++++++------------
 2 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index ca6fa6d..3e4677b 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1136,6 +1136,13 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 			pm_iir = I915_READ(GEN8_GT_IIR(2));
 			pm_mask = I915_READ(GEN6_PMINTRMSK);
 		}
+		seq_printf(m, "Video Turbo Mode: %s\n",
+			   yesno(rpmodectl & GEN6_RP_MEDIA_TURBO));
+		seq_printf(m, "HW control enabled: %s\n",
+			   yesno(rpmodectl & GEN6_RP_ENABLE));
+		seq_printf(m, "SW control enabled: %s\n",
+			   yesno((rpmodectl & GEN6_RP_MEDIA_MODE_MASK) ==
+				  GEN6_RP_MEDIA_SW_MODE));
 		seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n",
 			   pm_ier, pm_imr, pm_isr, pm_iir, pm_mask);
 		seq_printf(m, "pm_intrmsk_mbz: 0x%08x\n",
@@ -1479,7 +1486,7 @@ static int vlv_drpc_info(struct seq_file *m)
 static int gen6_drpc_info(struct seq_file *m)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
-	u32 rpmodectl1, gt_core_status, rcctl1, rc6vids = 0;
+	u32 gt_core_status, rcctl1, rc6vids = 0;
 	u32 gen9_powergate_enable = 0, gen9_powergate_status = 0;
 	unsigned forcewake_count;
 	int count = 0;
@@ -1498,7 +1505,6 @@ static int gen6_drpc_info(struct seq_file *m)
 	gt_core_status = I915_READ_FW(GEN6_GT_CORE_STATUS);
 	trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4, true);
 
-	rpmodectl1 = I915_READ(GEN6_RP_CONTROL);
 	rcctl1 = I915_READ(GEN6_RC_CONTROL);
 	if (INTEL_GEN(dev_priv) >= 9) {
 		gen9_powergate_enable = I915_READ(GEN9_PG_ENABLE);
@@ -1509,13 +1515,6 @@ static int gen6_drpc_info(struct seq_file *m)
 	sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids);
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
-	seq_printf(m, "Video Turbo Mode: %s\n",
-		   yesno(rpmodectl1 & GEN6_RP_MEDIA_TURBO));
-	seq_printf(m, "HW control enabled: %s\n",
-		   yesno(rpmodectl1 & GEN6_RP_ENABLE));
-	seq_printf(m, "SW control enabled: %s\n",
-		   yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) ==
-			  GEN6_RP_MEDIA_SW_MODE));
 	seq_printf(m, "RC1e Enabled: %s\n",
 		   yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
 	seq_printf(m, "RC6 Enabled: %s\n",
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index adfeb7b..f78a1e8 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6326,9 +6326,13 @@ static void gen9_disable_rps(struct drm_i915_private *dev_priv)
 	I915_WRITE(GEN6_RP_CONTROL, 0);
 }
 
-static void gen6_disable_rps(struct drm_i915_private *dev_priv)
+static void gen6_disable_rc6(struct drm_i915_private *dev_priv)
 {
 	I915_WRITE(GEN6_RC_CONTROL, 0);
+}
+
+static void gen6_disable_rps(struct drm_i915_private *dev_priv)
+{
 	I915_WRITE(GEN6_RPNSWREQ, 1 << 31);
 	I915_WRITE(GEN6_RP_CONTROL, 0);
 }
@@ -6686,7 +6690,7 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv)
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
-static void gen6_enable_rps(struct drm_i915_private *dev_priv)
+static void gen6_enable_rc6(struct drm_i915_private *dev_priv)
 {
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
@@ -6697,12 +6701,6 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv)
 
 	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
 
-	/* Here begins a magic sequence of register writes to enable
-	 * auto-downclocking.
-	 *
-	 * Perhaps there might be some value in exposing these to
-	 * userspace...
-	 */
 	I915_WRITE(GEN6_RC_STATE, 0);
 
 	/* Clear the DBG now so we don't confuse earlier errors */
@@ -6756,12 +6754,6 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv)
 		   GEN6_RC_CTL_EI_MODE(1) |
 		   GEN6_RC_CTL_HW_ENABLE);
 
-	/* Power down if completely idle for over 50ms */
-	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 50000);
-	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
-
-	reset_rps(dev_priv, gen6_set_rps);
-
 	rc6vids = 0;
 	ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids);
 	if (IS_GEN6(dev_priv) && ret) {
@@ -6779,6 +6771,28 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv)
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
+
+static void gen6_enable_rps(struct drm_i915_private *dev_priv)
+{
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	/* Here begins a magic sequence of register writes to enable
+	 * auto-downclocking.
+	 *
+	 * Perhaps there might be some value in exposing these to
+	 * userspace...
+	 */
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	/* Power down if completely idle for over 50ms */
+	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 50000);
+	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
+
+	reset_rps(dev_priv, gen6_set_rps);
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
 static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 {
 	int min_freq = 15;
@@ -7928,6 +7942,7 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
 	} else if (IS_VALLEYVIEW(dev_priv)) {
 		valleyview_disable_rps(dev_priv);
 	} else if (INTEL_GEN(dev_priv) >= 6) {
+		gen6_disable_rc6(dev_priv);
 		gen6_disable_rps(dev_priv);
 	}  else if (IS_IRONLAKE_M(dev_priv)) {
 		ironlake_disable_drps(dev_priv);
@@ -7964,6 +7979,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 		gen8_enable_rps(dev_priv);
 		gen6_update_ring_freq(dev_priv);
 	} else if (INTEL_GEN(dev_priv) >= 6) {
+		gen6_enable_rc6(dev_priv);
 		gen6_enable_rps(dev_priv);
 		gen6_update_ring_freq(dev_priv);
 	} else if (IS_IRONLAKE_M(dev_priv)) {
-- 
1.9.1

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

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

* [PATCH 03/31] drm/i915: Separate RPS and RC6 handling for BDW
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 01/31] drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 02/31] drm/i915: Separate RPS and RC6 handling for gen6+ Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-20 11:14   ` Szwichtenberg, Radoslaw
  2017-09-19 17:41 ` [PATCH 04/31] drm/i915: Separate RPS and RC6 handling for VLV Sagar Arun Kamble
                   ` (27 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

This patch separates RC6 and RPS enabling for BDW.
RC6/RPS Disabling are handled through gen6 functions.

Cc: Imre Deak <imre.deak@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index f78a1e8..6de69ae 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6613,7 +6613,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
-static void gen8_enable_rps(struct drm_i915_private *dev_priv)
+static void gen8_enable_rc6(struct drm_i915_private *dev_priv)
 {
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
@@ -6645,16 +6645,18 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv)
 	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
 		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
 	intel_print_rc6_info(dev_priv, rc6_mask);
-	if (IS_BROADWELL(dev_priv))
-		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
-				GEN7_RC_CTL_TO_MODE |
-				rc6_mask);
-	else
-		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
-				GEN6_RC_CTL_EI_MODE(1) |
-				rc6_mask);
+	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
+			GEN7_RC_CTL_TO_MODE |
+			rc6_mask);
 
-	/* 4 Program defaults and thresholds for RPS*/
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static void gen8_enable_rps(struct drm_i915_private *dev_priv)
+{
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	/* 1 Program defaults and thresholds for RPS*/
 	I915_WRITE(GEN6_RPNSWREQ,
 		   HSW_FREQUENCY(dev_priv->rps.rp1_freq));
 	I915_WRITE(GEN6_RC_VIDEO_FREQ,
@@ -6674,7 +6676,7 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv)
 
 	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
 
-	/* 5: Enable RPS */
+	/* 2: Enable RPS */
 	I915_WRITE(GEN6_RP_CONTROL,
 		   GEN6_RP_MEDIA_TURBO |
 		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
@@ -6683,7 +6685,7 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv)
 		   GEN6_RP_UP_BUSY_AVG |
 		   GEN6_RP_DOWN_IDLE_AVG);
 
-	/* 6: Ring frequency + overclocking (our driver does this later */
+	/* 3: Ring frequency + overclocking (our driver does this later */
 
 	reset_rps(dev_priv, gen6_set_rps);
 
@@ -7976,6 +7978,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 		if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv))
 			gen6_update_ring_freq(dev_priv);
 	} else if (IS_BROADWELL(dev_priv)) {
+		gen8_enable_rc6(dev_priv);
 		gen8_enable_rps(dev_priv);
 		gen6_update_ring_freq(dev_priv);
 	} else if (INTEL_GEN(dev_priv) >= 6) {
-- 
1.9.1

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

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

* [PATCH 04/31] drm/i915: Separate RPS and RC6 handling for VLV
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (2 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 03/31] drm/i915: Separate RPS and RC6 handling for BDW Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-20 12:30   ` Szwichtenberg, Radoslaw
  2017-09-19 17:41 ` [PATCH 05/31] drm/i915: Separate RPS and RC6 handling for CHV Sagar Arun Kamble
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

This patch separates enable/disable of RC6 and RPS for VLV.

Cc: Imre Deak <imre.deak@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 12 +-------
 drivers/gpu/drm/i915/intel_pm.c     | 57 ++++++++++++++++++++++++-------------
 2 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 3e4677b..8126c2c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1454,21 +1454,11 @@ static void print_rc6_res(struct seq_file *m,
 static int vlv_drpc_info(struct seq_file *m)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
-	u32 rpmodectl1, rcctl1, pw_status;
+	u32 rcctl1, pw_status;
 
 	pw_status = I915_READ(VLV_GTLC_PW_STATUS);
-	rpmodectl1 = I915_READ(GEN6_RP_CONTROL);
 	rcctl1 = I915_READ(GEN6_RC_CONTROL);
 
-	seq_printf(m, "Video Turbo Mode: %s\n",
-		   yesno(rpmodectl1 & GEN6_RP_MEDIA_TURBO));
-	seq_printf(m, "Turbo enabled: %s\n",
-		   yesno(rpmodectl1 & GEN6_RP_ENABLE));
-	seq_printf(m, "HW control enabled: %s\n",
-		   yesno(rpmodectl1 & GEN6_RP_ENABLE));
-	seq_printf(m, "SW control enabled: %s\n",
-		   yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) ==
-			  GEN6_RP_MEDIA_SW_MODE));
 	seq_printf(m, "RC6 Enabled: %s\n",
 		   yesno(rcctl1 & (GEN7_RC_CTL_TO_MODE |
 					GEN6_RC_CTL_EI_MODE(1))));
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6de69ae..8bbe037 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6342,7 +6342,7 @@ static void cherryview_disable_rps(struct drm_i915_private *dev_priv)
 	I915_WRITE(GEN6_RC_CONTROL, 0);
 }
 
-static void valleyview_disable_rps(struct drm_i915_private *dev_priv)
+static void valleyview_disable_rc6(struct drm_i915_private *dev_priv)
 {
 	/* we're doing forcewake before Disabling RC6,
 	 * This what the BIOS expects when going into suspend */
@@ -6353,6 +6353,11 @@ static void valleyview_disable_rps(struct drm_i915_private *dev_priv)
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
+static void valleyview_disable_rps(struct drm_i915_private *dev_priv)
+{
+	I915_WRITE(GEN6_RP_CONTROL, 0);
+}
+
 static void intel_print_rc6_info(struct drm_i915_private *dev_priv, u32 mode)
 {
 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
@@ -7280,11 +7285,11 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
-static void valleyview_enable_rps(struct drm_i915_private *dev_priv)
+static void valleyview_enable_rc6(struct drm_i915_private *dev_priv)
 {
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
-	u32 gtfifodbg, val, rc6_mode = 0;
+	u32 gtfifodbg, rc6_mode = 0;
 
 	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
 
@@ -7303,22 +7308,6 @@ static void valleyview_enable_rps(struct drm_i915_private *dev_priv)
 	/*  Disable RC states. */
 	I915_WRITE(GEN6_RC_CONTROL, 0);
 
-	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
-	I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
-	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
-	I915_WRITE(GEN6_RP_UP_EI, 66000);
-	I915_WRITE(GEN6_RP_DOWN_EI, 350000);
-
-	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
-
-	I915_WRITE(GEN6_RP_CONTROL,
-		   GEN6_RP_MEDIA_TURBO |
-		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
-		   GEN6_RP_MEDIA_IS_GFX |
-		   GEN6_RP_ENABLE |
-		   GEN6_RP_UP_BUSY_AVG |
-		   GEN6_RP_DOWN_IDLE_CONT);
-
 	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000);
 	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
 	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
@@ -7343,6 +7332,34 @@ static void valleyview_enable_rps(struct drm_i915_private *dev_priv)
 
 	I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
 
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static void valleyview_enable_rps(struct drm_i915_private *dev_priv)
+{
+	u32 val;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	/* If VLV, Forcewake all wells, else re-direct to regular path */
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
+	I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
+	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
+	I915_WRITE(GEN6_RP_UP_EI, 66000);
+	I915_WRITE(GEN6_RP_DOWN_EI, 350000);
+
+	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
+
+	I915_WRITE(GEN6_RP_CONTROL,
+		   GEN6_RP_MEDIA_TURBO |
+		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
+		   GEN6_RP_MEDIA_IS_GFX |
+		   GEN6_RP_ENABLE |
+		   GEN6_RP_UP_BUSY_AVG |
+		   GEN6_RP_DOWN_IDLE_CONT);
+
 	/* Setting Fixed Bias */
 	val = VLV_OVERRIDE_EN |
 		  VLV_SOC_TDP_EN |
@@ -7942,6 +7959,7 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
 	} else if (IS_CHERRYVIEW(dev_priv)) {
 		cherryview_disable_rps(dev_priv);
 	} else if (IS_VALLEYVIEW(dev_priv)) {
+		valleyview_disable_rc6(dev_priv);
 		valleyview_disable_rps(dev_priv);
 	} else if (INTEL_GEN(dev_priv) >= 6) {
 		gen6_disable_rc6(dev_priv);
@@ -7971,6 +7989,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 	if (IS_CHERRYVIEW(dev_priv)) {
 		cherryview_enable_rps(dev_priv);
 	} else if (IS_VALLEYVIEW(dev_priv)) {
+		valleyview_enable_rc6(dev_priv);
 		valleyview_enable_rps(dev_priv);
 	} else if (INTEL_GEN(dev_priv) >= 9) {
 		gen9_enable_rc6(dev_priv);
-- 
1.9.1

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

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

* [PATCH 05/31] drm/i915: Separate RPS and RC6 handling for CHV
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (3 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 04/31] drm/i915: Separate RPS and RC6 handling for VLV Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-20 12:32   ` Szwichtenberg, Radoslaw
  2017-09-19 17:41 ` [PATCH 06/31] drm/i915: Name i915_runtime_pm structure in dev_priv as "rpm" Sagar Arun Kamble
                   ` (25 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

This patch separates enable/disable of RC6 and RPS for CHV.

Cc: Imre Deak <imre.deak@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8bbe037..f8bfcff 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6337,11 +6337,16 @@ static void gen6_disable_rps(struct drm_i915_private *dev_priv)
 	I915_WRITE(GEN6_RP_CONTROL, 0);
 }
 
-static void cherryview_disable_rps(struct drm_i915_private *dev_priv)
+static void cherryview_disable_rc6(struct drm_i915_private *dev_priv)
 {
 	I915_WRITE(GEN6_RC_CONTROL, 0);
 }
 
+static void cherryview_disable_rps(struct drm_i915_private *dev_priv)
+{
+	I915_WRITE(GEN6_RP_CONTROL, 0);
+}
+
 static void valleyview_disable_rc6(struct drm_i915_private *dev_priv)
 {
 	/* we're doing forcewake before Disabling RC6,
@@ -7196,11 +7201,11 @@ static void valleyview_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
 	valleyview_cleanup_pctx(dev_priv);
 }
 
-static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
+static void cherryview_enable_rc6(struct drm_i915_private *dev_priv)
 {
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
-	u32 gtfifodbg, val, rc6_mode = 0, pcbr;
+	u32 gtfifodbg, rc6_mode = 0, pcbr;
 
 	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
 
@@ -7249,7 +7254,19 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
 
 	I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
 
-	/* 4 Program defaults and thresholds for RPS*/
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
+{
+	u32 val;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	/* 1: Program defaults and thresholds for RPS*/
 	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
 	I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
 	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
@@ -7258,7 +7275,7 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
 
 	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
 
-	/* 5: Enable RPS */
+	/* 2: Enable RPS */
 	I915_WRITE(GEN6_RP_CONTROL,
 		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
 		   GEN6_RP_MEDIA_IS_GFX |
@@ -7957,6 +7974,7 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
 		gen9_disable_rc6(dev_priv);
 		gen9_disable_rps(dev_priv);
 	} else if (IS_CHERRYVIEW(dev_priv)) {
+		cherryview_disable_rc6(dev_priv);
 		cherryview_disable_rps(dev_priv);
 	} else if (IS_VALLEYVIEW(dev_priv)) {
 		valleyview_disable_rc6(dev_priv);
@@ -7987,6 +8005,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 	mutex_lock(&dev_priv->rps.hw_lock);
 
 	if (IS_CHERRYVIEW(dev_priv)) {
+		cherryview_enable_rc6(dev_priv);
 		cherryview_enable_rps(dev_priv);
 	} else if (IS_VALLEYVIEW(dev_priv)) {
 		valleyview_enable_rc6(dev_priv);
-- 
1.9.1

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

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

* [PATCH 06/31] drm/i915: Name i915_runtime_pm structure in dev_priv as "rpm"
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (4 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 05/31] drm/i915: Separate RPS and RC6 handling for CHV Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-20 12:34   ` Szwichtenberg, Radoslaw
  2017-09-19 17:41 ` [PATCH 07/31] drm/i915: Name structure in dev_priv that contains RPS/RC6 state as "pm" Sagar Arun Kamble
                   ` (24 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

Will be using pm for state containing RPS/RC6 state in the next patch.

Cc: Imre Deak <imre.deak@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c         |  8 ++++----
 drivers/gpu/drm/i915/i915_drv.h         |  2 +-
 drivers/gpu/drm/i915/i915_gpu_error.c   |  4 ++--
 drivers/gpu/drm/i915/i915_irq.c         |  8 ++++----
 drivers/gpu/drm/i915/intel_drv.h        | 10 +++++-----
 drivers/gpu/drm/i915/intel_pm.c         |  4 ++--
 drivers/gpu/drm/i915/intel_runtime_pm.c | 10 +++++-----
 7 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index ec0e770..d155316 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2533,12 +2533,12 @@ static int intel_runtime_suspend(struct device *kdev)
 	intel_uncore_suspend(dev_priv);
 
 	enable_rpm_wakeref_asserts(dev_priv);
-	WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count));
+	WARN_ON_ONCE(atomic_read(&dev_priv->rpm.wakeref_count));
 
 	if (intel_uncore_arm_unclaimed_mmio_detection(dev_priv))
 		DRM_ERROR("Unclaimed access detected prior to suspending\n");
 
-	dev_priv->pm.suspended = true;
+	dev_priv->rpm.suspended = true;
 
 	/*
 	 * FIXME: We really should find a document that references the arguments
@@ -2584,11 +2584,11 @@ static int intel_runtime_resume(struct device *kdev)
 
 	DRM_DEBUG_KMS("Resuming device\n");
 
-	WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count));
+	WARN_ON_ONCE(atomic_read(&dev_priv->rpm.wakeref_count));
 	disable_rpm_wakeref_asserts(dev_priv);
 
 	intel_opregion_notify_adapter(dev_priv, PCI_D0);
-	dev_priv->pm.suspended = false;
+	dev_priv->rpm.suspended = false;
 	if (intel_uncore_unclaimed_mmio(dev_priv))
 		DRM_DEBUG_DRIVER("Unclaimed access during suspend, bios?\n");
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4d5ffde..49dfc3d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2512,7 +2512,7 @@ struct drm_i915_private {
 		bool distrust_bios_wm;
 	} wm;
 
-	struct i915_runtime_pm pm;
+	struct i915_runtime_pm rpm;
 
 	struct {
 		bool initialized;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 0c77967..23e9abf 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1665,8 +1665,8 @@ static void i915_capture_gen_state(struct drm_i915_private *dev_priv,
 				   struct i915_gpu_state *error)
 {
 	error->awake = dev_priv->gt.awake;
-	error->wakelock = atomic_read(&dev_priv->pm.wakeref_count);
-	error->suspended = dev_priv->pm.suspended;
+	error->wakelock = atomic_read(&dev_priv->rpm.wakeref_count);
+	error->suspended = dev_priv->rpm.suspended;
 
 	error->iommu = -1;
 #ifdef CONFIG_INTEL_IOMMU
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4d0e8f7..e44d894 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -4118,7 +4118,7 @@ int intel_irq_install(struct drm_i915_private *dev_priv)
 	 * interrupts as enabled _before_ actually enabling them to avoid
 	 * special cases in our ordering checks.
 	 */
-	dev_priv->pm.irqs_enabled = true;
+	dev_priv->rpm.irqs_enabled = true;
 
 	return drm_irq_install(&dev_priv->drm, dev_priv->drm.pdev->irq);
 }
@@ -4134,7 +4134,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv)
 {
 	drm_irq_uninstall(&dev_priv->drm);
 	intel_hpd_cancel_work(dev_priv);
-	dev_priv->pm.irqs_enabled = false;
+	dev_priv->rpm.irqs_enabled = false;
 }
 
 /**
@@ -4147,7 +4147,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv)
 void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
 {
 	dev_priv->drm.driver->irq_uninstall(&dev_priv->drm);
-	dev_priv->pm.irqs_enabled = false;
+	dev_priv->rpm.irqs_enabled = false;
 	synchronize_irq(dev_priv->drm.irq);
 }
 
@@ -4160,7 +4160,7 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
  */
 void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv)
 {
-	dev_priv->pm.irqs_enabled = true;
+	dev_priv->rpm.irqs_enabled = true;
 	dev_priv->drm.driver->irq_preinstall(&dev_priv->drm);
 	dev_priv->drm.driver->irq_postinstall(&dev_priv->drm);
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3078076..76ef34b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1252,7 +1252,7 @@ static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
 	 * We only use drm_irq_uninstall() at unload and VT switch, so
 	 * this is the only thing we need to check.
 	 */
-	return dev_priv->pm.irqs_enabled;
+	return dev_priv->rpm.irqs_enabled;
 }
 
 int intel_get_crtc_scanline(struct intel_crtc *crtc);
@@ -1788,7 +1788,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 static inline void
 assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
 {
-	WARN_ONCE(dev_priv->pm.suspended,
+	WARN_ONCE(dev_priv->rpm.suspended,
 		  "Device suspended during HW access\n");
 }
 
@@ -1796,7 +1796,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 assert_rpm_wakelock_held(struct drm_i915_private *dev_priv)
 {
 	assert_rpm_device_not_suspended(dev_priv);
-	WARN_ONCE(!atomic_read(&dev_priv->pm.wakeref_count),
+	WARN_ONCE(!atomic_read(&dev_priv->rpm.wakeref_count),
 		  "RPM wakelock ref not held during HW access");
 }
 
@@ -1821,7 +1821,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 static inline void
 disable_rpm_wakeref_asserts(struct drm_i915_private *dev_priv)
 {
-	atomic_inc(&dev_priv->pm.wakeref_count);
+	atomic_inc(&dev_priv->rpm.wakeref_count);
 }
 
 /**
@@ -1838,7 +1838,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 static inline void
 enable_rpm_wakeref_asserts(struct drm_i915_private *dev_priv)
 {
-	atomic_dec(&dev_priv->pm.wakeref_count);
+	atomic_dec(&dev_priv->rpm.wakeref_count);
 }
 
 void intel_runtime_pm_get(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index f8bfcff..a54dae5 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -9351,8 +9351,8 @@ void intel_pm_setup(struct drm_i915_private *dev_priv)
 			  __intel_autoenable_gt_powersave);
 	atomic_set(&dev_priv->rps.num_waiters, 0);
 
-	dev_priv->pm.suspended = false;
-	atomic_set(&dev_priv->pm.wakeref_count, 0);
+	dev_priv->rpm.suspended = false;
+	atomic_set(&dev_priv->rpm.wakeref_count, 0);
 }
 
 static u64 vlv_residency_raw(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index a3bfb9f..af28a8b 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -187,7 +187,7 @@ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
 	struct i915_power_well *power_well;
 	bool is_enabled;
 
-	if (dev_priv->pm.suspended)
+	if (dev_priv->rpm.suspended)
 		return false;
 
 	is_enabled = true;
@@ -3124,7 +3124,7 @@ void intel_runtime_pm_get(struct drm_i915_private *dev_priv)
 	ret = pm_runtime_get_sync(kdev);
 	WARN_ONCE(ret < 0, "pm_runtime_get_sync() failed: %d\n", ret);
 
-	atomic_inc(&dev_priv->pm.wakeref_count);
+	atomic_inc(&dev_priv->rpm.wakeref_count);
 	assert_rpm_wakelock_held(dev_priv);
 }
 
@@ -3158,7 +3158,7 @@ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv)
 			return false;
 	}
 
-	atomic_inc(&dev_priv->pm.wakeref_count);
+	atomic_inc(&dev_priv->rpm.wakeref_count);
 	assert_rpm_wakelock_held(dev_priv);
 
 	return true;
@@ -3189,7 +3189,7 @@ void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv)
 	assert_rpm_wakelock_held(dev_priv);
 	pm_runtime_get_noresume(kdev);
 
-	atomic_inc(&dev_priv->pm.wakeref_count);
+	atomic_inc(&dev_priv->rpm.wakeref_count);
 }
 
 /**
@@ -3206,7 +3206,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv)
 	struct device *kdev = &pdev->dev;
 
 	assert_rpm_wakelock_held(dev_priv);
-	atomic_dec(&dev_priv->pm.wakeref_count);
+	atomic_dec(&dev_priv->rpm.wakeref_count);
 
 	pm_runtime_mark_last_busy(kdev);
 	pm_runtime_put_autosuspend(kdev);
-- 
1.9.1

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

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

* [PATCH 07/31] drm/i915: Name structure in dev_priv that contains RPS/RC6 state as "pm"
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (5 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 06/31] drm/i915: Name i915_runtime_pm structure in dev_priv as "rpm" Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-21  8:23   ` Szwichtenberg, Radoslaw
  2017-09-19 17:41 ` [PATCH 08/31] drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled Sagar Arun Kamble
                   ` (23 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

Prepared substructure rps for RPS related state. autoenable_work and
pcu_lock are used for RC6 hence they are defined outside rps structure.
Renamed the RPS lock as pcu_lock.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Imre Deak <imre.deak@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c        | 117 +++++-----
 drivers/gpu/drm/i915/i915_drv.c            |   2 +-
 drivers/gpu/drm/i915/i915_drv.h            |  12 +-
 drivers/gpu/drm/i915/i915_gem_request.c    |   2 +-
 drivers/gpu/drm/i915/i915_guc_submission.c |   8 +-
 drivers/gpu/drm/i915/i915_irq.c            |  86 +++----
 drivers/gpu/drm/i915/i915_sysfs.c          |  70 +++---
 drivers/gpu/drm/i915/intel_cdclk.c         |  40 ++--
 drivers/gpu/drm/i915/intel_display.c       |  12 +-
 drivers/gpu/drm/i915/intel_drv.h           |   2 +-
 drivers/gpu/drm/i915/intel_pm.c            | 363 +++++++++++++++--------------
 drivers/gpu/drm/i915/intel_runtime_pm.c    |  16 +-
 drivers/gpu/drm/i915/intel_sideband.c      |   6 +-
 13 files changed, 379 insertions(+), 357 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 8126c2c..9356a69 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1026,6 +1026,7 @@ static int i915_error_state_open(struct inode *inode, struct file *file)
 static int i915_frequency_info(struct seq_file *m, void *unused)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
+	struct intel_rps *rps = &dev_priv->pm.rps;
 	int ret = 0;
 
 	intel_runtime_pm_get(dev_priv);
@@ -1043,7 +1044,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
 		u32 freq_sts;
 
-		mutex_lock(&dev_priv->rps.hw_lock);
+		mutex_lock(&dev_priv->pm.pcu_lock);
 		freq_sts = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
 		seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts);
 		seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq);
@@ -1052,21 +1053,21 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 			   intel_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff));
 
 		seq_printf(m, "current GPU freq: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq));
+			   intel_gpu_freq(dev_priv, rps->cur_freq));
 
 		seq_printf(m, "max GPU freq: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+			   intel_gpu_freq(dev_priv, rps->max_freq));
 
 		seq_printf(m, "min GPU freq: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq));
+			   intel_gpu_freq(dev_priv, rps->min_freq));
 
 		seq_printf(m, "idle GPU freq: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq));
+			   intel_gpu_freq(dev_priv, rps->idle_freq));
 
 		seq_printf(m,
 			   "efficient (RPe) frequency: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
-		mutex_unlock(&dev_priv->rps.hw_lock);
+			   intel_gpu_freq(dev_priv, rps->efficient_freq));
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 	} else if (INTEL_GEN(dev_priv) >= 6) {
 		u32 rp_state_limits;
 		u32 gt_perf_status;
@@ -1146,7 +1147,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 		seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n",
 			   pm_ier, pm_imr, pm_isr, pm_iir, pm_mask);
 		seq_printf(m, "pm_intrmsk_mbz: 0x%08x\n",
-			   dev_priv->rps.pm_intrmsk_mbz);
+			   rps->pm_intrmsk_mbz);
 		seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
 		seq_printf(m, "Render p-state ratio: %d\n",
 			   (gt_perf_status & (INTEL_GEN(dev_priv) >= 9 ? 0x1ff00 : 0xff00)) >> 8);
@@ -1166,8 +1167,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 			   rpcurup, GT_PM_INTERVAL_TO_US(dev_priv, rpcurup));
 		seq_printf(m, "RP PREV UP: %d (%dus)\n",
 			   rpprevup, GT_PM_INTERVAL_TO_US(dev_priv, rpprevup));
-		seq_printf(m, "Up threshold: %d%%\n",
-			   dev_priv->rps.up_threshold);
+		seq_printf(m, "Up threshold: %d%%\n", rps->up_threshold);
 
 		seq_printf(m, "RP CUR DOWN EI: %d (%dus)\n",
 			   rpdownei, GT_PM_INTERVAL_TO_US(dev_priv, rpdownei));
@@ -1175,8 +1175,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 			   rpcurdown, GT_PM_INTERVAL_TO_US(dev_priv, rpcurdown));
 		seq_printf(m, "RP PREV DOWN: %d (%dus)\n",
 			   rpprevdown, GT_PM_INTERVAL_TO_US(dev_priv, rpprevdown));
-		seq_printf(m, "Down threshold: %d%%\n",
-			   dev_priv->rps.down_threshold);
+		seq_printf(m, "Down threshold: %d%%\n", rps->down_threshold);
 
 		max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 :
 			    rp_state_cap >> 16) & 0xff;
@@ -1198,22 +1197,22 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 		seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
 			   intel_gpu_freq(dev_priv, max_freq));
 		seq_printf(m, "Max overclocked frequency: %dMHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+			   intel_gpu_freq(dev_priv, rps->max_freq));
 
 		seq_printf(m, "Current freq: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq));
+			   intel_gpu_freq(dev_priv, rps->cur_freq));
 		seq_printf(m, "Actual freq: %d MHz\n", cagf);
 		seq_printf(m, "Idle freq: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq));
+			   intel_gpu_freq(dev_priv, rps->idle_freq));
 		seq_printf(m, "Min freq: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq));
+			   intel_gpu_freq(dev_priv, rps->min_freq));
 		seq_printf(m, "Boost freq: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq));
+			   intel_gpu_freq(dev_priv, rps->boost_freq));
 		seq_printf(m, "Max freq: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+			   intel_gpu_freq(dev_priv, rps->max_freq));
 		seq_printf(m,
 			   "efficient (RPe) frequency: %d MHz\n",
-			   intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
+			   intel_gpu_freq(dev_priv, rps->efficient_freq));
 	} else {
 		seq_puts(m, "no P-state info available\n");
 	}
@@ -1501,9 +1500,9 @@ static int gen6_drpc_info(struct seq_file *m)
 		gen9_powergate_status = I915_READ(GEN9_PWRGT_DOMAIN_STATUS);
 	}
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids);
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	seq_printf(m, "RC1e Enabled: %s\n",
 		   yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
@@ -1778,19 +1777,19 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
 
 	intel_runtime_pm_get(dev_priv);
 
-	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
+	ret = mutex_lock_interruptible(&dev_priv->pm.pcu_lock);
 	if (ret)
 		goto out;
 
 	if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
 		/* Convert GT frequency to 50 HZ units */
 		min_gpu_freq =
-			dev_priv->rps.min_freq_softlimit / GEN9_FREQ_SCALER;
+			dev_priv->pm.rps.min_freq_softlimit / GEN9_FREQ_SCALER;
 		max_gpu_freq =
-			dev_priv->rps.max_freq_softlimit / GEN9_FREQ_SCALER;
+			dev_priv->pm.rps.max_freq_softlimit / GEN9_FREQ_SCALER;
 	} else {
-		min_gpu_freq = dev_priv->rps.min_freq_softlimit;
-		max_gpu_freq = dev_priv->rps.max_freq_softlimit;
+		min_gpu_freq = dev_priv->pm.rps.min_freq_softlimit;
+		max_gpu_freq = dev_priv->pm.rps.max_freq_softlimit;
 	}
 
 	seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n");
@@ -1809,7 +1808,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
 			   ((ia_freq >> 8) & 0xff) * 100);
 	}
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 out:
 	intel_runtime_pm_put(dev_priv);
@@ -2243,25 +2242,26 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
 	struct drm_device *dev = &dev_priv->drm;
+	struct intel_rps *rps = &dev_priv->pm.rps;
 	struct drm_file *file;
 
-	seq_printf(m, "RPS enabled? %d\n", dev_priv->rps.enabled);
+	seq_printf(m, "RPS enabled? %d\n", rps->enabled);
 	seq_printf(m, "GPU busy? %s [%d requests]\n",
 		   yesno(dev_priv->gt.awake), dev_priv->gt.active_requests);
 	seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv));
 	seq_printf(m, "Boosts outstanding? %d\n",
-		   atomic_read(&dev_priv->rps.num_waiters));
+		   atomic_read(&rps->num_waiters));
 	seq_printf(m, "Frequency requested %d\n",
-		   intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq));
+		   intel_gpu_freq(dev_priv, rps->cur_freq));
 	seq_printf(m, "  min hard:%d, soft:%d; max soft:%d, hard:%d\n",
-		   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq),
-		   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit),
-		   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit),
-		   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+		   intel_gpu_freq(dev_priv, rps->min_freq),
+		   intel_gpu_freq(dev_priv, rps->min_freq_softlimit),
+		   intel_gpu_freq(dev_priv, rps->max_freq_softlimit),
+		   intel_gpu_freq(dev_priv, rps->max_freq));
 	seq_printf(m, "  idle:%d, efficient:%d, boost:%d\n",
-		   intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq),
-		   intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
-		   intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq));
+		   intel_gpu_freq(dev_priv, rps->idle_freq),
+		   intel_gpu_freq(dev_priv, rps->efficient_freq),
+		   intel_gpu_freq(dev_priv, rps->boost_freq));
 
 	mutex_lock(&dev->filelist_mutex);
 	list_for_each_entry_reverse(file, &dev->filelist, lhead) {
@@ -2277,11 +2277,11 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
 		rcu_read_unlock();
 	}
 	seq_printf(m, "Kernel (anonymous) boosts: %d\n",
-		   atomic_read(&dev_priv->rps.boosts));
+		   atomic_read(&rps->boosts));
 	mutex_unlock(&dev->filelist_mutex);
 
 	if (INTEL_GEN(dev_priv) >= 6 &&
-	    dev_priv->rps.enabled &&
+	    rps->enabled &&
 	    dev_priv->gt.active_requests) {
 		u32 rpup, rpupei;
 		u32 rpdown, rpdownei;
@@ -2294,13 +2294,13 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
 		intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 
 		seq_printf(m, "\nRPS Autotuning (current \"%s\" window):\n",
-			   rps_power_to_str(dev_priv->rps.power));
+			   rps_power_to_str(rps->power));
 		seq_printf(m, "  Avg. up: %d%% [above threshold? %d%%]\n",
 			   rpup && rpupei ? 100 * rpup / rpupei : 0,
-			   dev_priv->rps.up_threshold);
+			   rps->up_threshold);
 		seq_printf(m, "  Avg. down: %d%% [below threshold? %d%%]\n",
 			   rpdown && rpdownei ? 100 * rpdown / rpdownei : 0,
-			   dev_priv->rps.down_threshold);
+			   rps->down_threshold);
 	} else {
 		seq_puts(m, "\nRPS Autotuning inactive\n");
 	}
@@ -4381,7 +4381,7 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 	if (INTEL_GEN(dev_priv) < 6)
 		return -ENODEV;
 
-	*val = intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit);
+	*val = intel_gpu_freq(dev_priv, dev_priv->pm.rps.max_freq_softlimit);
 	return 0;
 }
 
@@ -4389,6 +4389,7 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 i915_max_freq_set(void *data, u64 val)
 {
 	struct drm_i915_private *dev_priv = data;
+	struct intel_rps *rps = &dev_priv->pm.rps;
 	u32 hw_max, hw_min;
 	int ret;
 
@@ -4397,7 +4398,7 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 
 	DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val);
 
-	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
+	ret = mutex_lock_interruptible(&dev_priv->pm.pcu_lock);
 	if (ret)
 		return ret;
 
@@ -4406,20 +4407,20 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 	 */
 	val = intel_freq_opcode(dev_priv, val);
 
-	hw_max = dev_priv->rps.max_freq;
-	hw_min = dev_priv->rps.min_freq;
+	hw_max = rps->max_freq;
+	hw_min = rps->min_freq;
 
-	if (val < hw_min || val > hw_max || val < dev_priv->rps.min_freq_softlimit) {
-		mutex_unlock(&dev_priv->rps.hw_lock);
+	if (val < hw_min || val > hw_max || val < rps->min_freq_softlimit) {
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 		return -EINVAL;
 	}
 
-	dev_priv->rps.max_freq_softlimit = val;
+	rps->max_freq_softlimit = val;
 
 	if (intel_set_rps(dev_priv, val))
 		DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n");
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	return 0;
 }
@@ -4436,7 +4437,7 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 	if (INTEL_GEN(dev_priv) < 6)
 		return -ENODEV;
 
-	*val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit);
+	*val = intel_gpu_freq(dev_priv, dev_priv->pm.rps.min_freq_softlimit);
 	return 0;
 }
 
@@ -4452,7 +4453,7 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 
 	DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val);
 
-	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
+	ret = mutex_lock_interruptible(&dev_priv->pm.pcu_lock);
 	if (ret)
 		return ret;
 
@@ -4461,21 +4462,21 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 	 */
 	val = intel_freq_opcode(dev_priv, val);
 
-	hw_max = dev_priv->rps.max_freq;
-	hw_min = dev_priv->rps.min_freq;
+	hw_max = dev_priv->pm.rps.max_freq;
+	hw_min = dev_priv->pm.rps.min_freq;
 
 	if (val < hw_min ||
-	    val > hw_max || val > dev_priv->rps.max_freq_softlimit) {
-		mutex_unlock(&dev_priv->rps.hw_lock);
+	    val > hw_max || val > dev_priv->pm.rps.max_freq_softlimit) {
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 		return -EINVAL;
 	}
 
-	dev_priv->rps.min_freq_softlimit = val;
+	dev_priv->pm.rps.min_freq_softlimit = val;
 
 	if (intel_set_rps(dev_priv, val))
 		DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n");
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index d155316..6cc1162 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2486,7 +2486,7 @@ static int intel_runtime_suspend(struct device *kdev)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	int ret;
 
-	if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6())))
+	if (WARN_ON_ONCE(!(dev_priv->pm.rps.enabled && intel_enable_rc6())))
 		return -ENODEV;
 
 	if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv)))
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 49dfc3d..e3264e5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1304,7 +1304,7 @@ struct intel_rps_ei {
 	u32 media_c0;
 };
 
-struct intel_gen6_power_mgmt {
+struct intel_rps {
 	/*
 	 * work, interrupts_enabled and pm_iir are protected by
 	 * dev_priv->irq_lock
@@ -1345,12 +1345,16 @@ struct intel_gen6_power_mgmt {
 	enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
 
 	bool enabled;
-	struct delayed_work autoenable_work;
 	atomic_t num_waiters;
 	atomic_t boosts;
 
 	/* manual wa residency calculations */
 	struct intel_rps_ei ei;
+};
+
+struct intel_gen6_power_mgmt {
+	struct intel_rps rps;
+	struct delayed_work autoenable_work;
 
 	/*
 	 * Protects RPS/RC6 register access and PCU communication.
@@ -1358,7 +1362,7 @@ struct intel_gen6_power_mgmt {
 	 * this lock may be held for long periods of time when
 	 * talking to hw - so only take it when talking to hw!
 	 */
-	struct mutex hw_lock;
+	struct mutex pcu_lock;
 };
 
 /* defined intel_pm.c */
@@ -2401,7 +2405,7 @@ struct drm_i915_private {
 	u32 edram_cap;
 
 	/* gen6+ rps state */
-	struct intel_gen6_power_mgmt rps;
+	struct intel_gen6_power_mgmt pm;
 
 	/* ilk-only ips/rps state. Everything in here is protected by the global
 	 * mchdev_lock in intel_pm.c */
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 813a3b5..023af2d 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -416,7 +416,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
 
 	spin_lock_irq(&request->lock);
 	if (request->waitboost)
-		atomic_dec(&request->i915->rps.num_waiters);
+		atomic_dec(&request->i915->pm.rps.num_waiters);
 	dma_fence_signal_locked(&request->fence);
 	spin_unlock_irq(&request->lock);
 
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 12f1195..2a4b6f9 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -1099,8 +1099,8 @@ static void guc_interrupts_capture(struct drm_i915_private *dev_priv)
 	 * Here we CLEAR REDIRECT_TO_GUC bit in pm_intrmsk_mbz, which will
 	 * result in the register bit being left SET!
 	 */
-	dev_priv->rps.pm_intrmsk_mbz |= ARAT_EXPIRED_INTRMSK;
-	dev_priv->rps.pm_intrmsk_mbz &= ~GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
+	dev_priv->pm.rps.pm_intrmsk_mbz |= ARAT_EXPIRED_INTRMSK;
+	dev_priv->pm.rps.pm_intrmsk_mbz &= ~GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
 }
 
 static void guc_interrupts_release(struct drm_i915_private *dev_priv)
@@ -1123,8 +1123,8 @@ static void guc_interrupts_release(struct drm_i915_private *dev_priv)
 	I915_WRITE(GUC_VCS2_VCS1_IER, 0);
 	I915_WRITE(GUC_WD_VECS_IER, 0);
 
-	dev_priv->rps.pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
-	dev_priv->rps.pm_intrmsk_mbz &= ~ARAT_EXPIRED_INTRMSK;
+	dev_priv->pm.rps.pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
+	dev_priv->pm.rps.pm_intrmsk_mbz &= ~ARAT_EXPIRED_INTRMSK;
 }
 
 int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index e44d894..4a1554c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -404,19 +404,19 @@ void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv)
 {
 	spin_lock_irq(&dev_priv->irq_lock);
 	gen6_reset_pm_iir(dev_priv, dev_priv->pm_rps_events);
-	dev_priv->rps.pm_iir = 0;
+	dev_priv->pm.rps.pm_iir = 0;
 	spin_unlock_irq(&dev_priv->irq_lock);
 }
 
 void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv)
 {
-	if (READ_ONCE(dev_priv->rps.interrupts_enabled))
+	if (READ_ONCE(dev_priv->pm.rps.interrupts_enabled))
 		return;
 
 	spin_lock_irq(&dev_priv->irq_lock);
-	WARN_ON_ONCE(dev_priv->rps.pm_iir);
+	WARN_ON_ONCE(dev_priv->pm.rps.pm_iir);
 	WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events);
-	dev_priv->rps.interrupts_enabled = true;
+	dev_priv->pm.rps.interrupts_enabled = true;
 	gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
 
 	spin_unlock_irq(&dev_priv->irq_lock);
@@ -424,11 +424,11 @@ void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv)
 
 void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv)
 {
-	if (!READ_ONCE(dev_priv->rps.interrupts_enabled))
+	if (!READ_ONCE(dev_priv->pm.rps.interrupts_enabled))
 		return;
 
 	spin_lock_irq(&dev_priv->irq_lock);
-	dev_priv->rps.interrupts_enabled = false;
+	dev_priv->pm.rps.interrupts_enabled = false;
 
 	I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0u));
 
@@ -442,7 +442,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv)
 	 * we will reset the GPU to minimum frequencies, so the current
 	 * state of the worker can be discarded.
 	 */
-	cancel_work_sync(&dev_priv->rps.work);
+	cancel_work_sync(&dev_priv->pm.rps.work);
 	gen6_reset_rps_interrupts(dev_priv);
 }
 
@@ -1079,12 +1079,12 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv,
 
 void gen6_rps_reset_ei(struct drm_i915_private *dev_priv)
 {
-	memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei));
+	memset(&dev_priv->pm.rps.ei, 0, sizeof(dev_priv->pm.rps.ei));
 }
 
 static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
 {
-	const struct intel_rps_ei *prev = &dev_priv->rps.ei;
+	const struct intel_rps_ei *prev = &dev_priv->pm.rps.ei;
 	struct intel_rps_ei now;
 	u32 events = 0;
 
@@ -1111,28 +1111,29 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
 		c0 = max(render, media);
 		c0 *= 1000 * 100 << 8; /* to usecs and scale to threshold% */
 
-		if (c0 > time * dev_priv->rps.up_threshold)
+		if (c0 > time * dev_priv->pm.rps.up_threshold)
 			events = GEN6_PM_RP_UP_THRESHOLD;
-		else if (c0 < time * dev_priv->rps.down_threshold)
+		else if (c0 < time * dev_priv->pm.rps.down_threshold)
 			events = GEN6_PM_RP_DOWN_THRESHOLD;
 	}
 
-	dev_priv->rps.ei = now;
+	dev_priv->pm.rps.ei = now;
 	return events;
 }
 
 static void gen6_pm_rps_work(struct work_struct *work)
 {
 	struct drm_i915_private *dev_priv =
-		container_of(work, struct drm_i915_private, rps.work);
+		container_of(work, struct drm_i915_private, pm.rps.work);
+	struct intel_rps *rps = &dev_priv->pm.rps;
 	bool client_boost = false;
 	int new_delay, adj, min, max;
 	u32 pm_iir = 0;
 
 	spin_lock_irq(&dev_priv->irq_lock);
-	if (dev_priv->rps.interrupts_enabled) {
-		pm_iir = fetch_and_zero(&dev_priv->rps.pm_iir);
-		client_boost = atomic_read(&dev_priv->rps.num_waiters);
+	if (rps->interrupts_enabled) {
+		pm_iir = fetch_and_zero(&rps->pm_iir);
+		client_boost = atomic_read(&rps->num_waiters);
 	}
 	spin_unlock_irq(&dev_priv->irq_lock);
 
@@ -1141,18 +1142,18 @@ static void gen6_pm_rps_work(struct work_struct *work)
 	if ((pm_iir & dev_priv->pm_rps_events) == 0 && !client_boost)
 		goto out;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	pm_iir |= vlv_wa_c0_ei(dev_priv, pm_iir);
 
-	adj = dev_priv->rps.last_adj;
-	new_delay = dev_priv->rps.cur_freq;
-	min = dev_priv->rps.min_freq_softlimit;
-	max = dev_priv->rps.max_freq_softlimit;
+	adj = rps->last_adj;
+	new_delay = rps->cur_freq;
+	min = rps->min_freq_softlimit;
+	max = rps->max_freq_softlimit;
 	if (client_boost)
-		max = dev_priv->rps.max_freq;
-	if (client_boost && new_delay < dev_priv->rps.boost_freq) {
-		new_delay = dev_priv->rps.boost_freq;
+		max = rps->max_freq;
+	if (client_boost && new_delay < rps->boost_freq) {
+		new_delay = rps->boost_freq;
 		adj = 0;
 	} else if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
 		if (adj > 0)
@@ -1160,15 +1161,15 @@ static void gen6_pm_rps_work(struct work_struct *work)
 		else /* CHV needs even encode values */
 			adj = IS_CHERRYVIEW(dev_priv) ? 2 : 1;
 
-		if (new_delay >= dev_priv->rps.max_freq_softlimit)
+		if (new_delay >= rps->max_freq_softlimit)
 			adj = 0;
 	} else if (client_boost) {
 		adj = 0;
 	} else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) {
-		if (dev_priv->rps.cur_freq > dev_priv->rps.efficient_freq)
-			new_delay = dev_priv->rps.efficient_freq;
-		else if (dev_priv->rps.cur_freq > dev_priv->rps.min_freq_softlimit)
-			new_delay = dev_priv->rps.min_freq_softlimit;
+		if (rps->cur_freq > rps->efficient_freq)
+			new_delay = rps->efficient_freq;
+		else if (rps->cur_freq > rps->min_freq_softlimit)
+			new_delay = rps->min_freq_softlimit;
 		adj = 0;
 	} else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
 		if (adj < 0)
@@ -1176,13 +1177,13 @@ static void gen6_pm_rps_work(struct work_struct *work)
 		else /* CHV needs even encode values */
 			adj = IS_CHERRYVIEW(dev_priv) ? -2 : -1;
 
-		if (new_delay <= dev_priv->rps.min_freq_softlimit)
+		if (new_delay <= rps->min_freq_softlimit)
 			adj = 0;
 	} else { /* unknown event */
 		adj = 0;
 	}
 
-	dev_priv->rps.last_adj = adj;
+	rps->last_adj = adj;
 
 	/* sysfs frequency interfaces may have snuck in while servicing the
 	 * interrupt
@@ -1192,15 +1193,15 @@ static void gen6_pm_rps_work(struct work_struct *work)
 
 	if (intel_set_rps(dev_priv, new_delay)) {
 		DRM_DEBUG_DRIVER("Failed to set new GPU frequency\n");
-		dev_priv->rps.last_adj = 0;
+		rps->last_adj = 0;
 	}
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 out:
 	/* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */
 	spin_lock_irq(&dev_priv->irq_lock);
-	if (dev_priv->rps.interrupts_enabled)
+	if (rps->interrupts_enabled)
 		gen6_unmask_pm_irq(dev_priv, dev_priv->pm_rps_events);
 	spin_unlock_irq(&dev_priv->irq_lock);
 }
@@ -1682,12 +1683,14 @@ static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
  * the work queue. */
 static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
 {
+	struct intel_rps *rps = &dev_priv->pm.rps;
+
 	if (pm_iir & dev_priv->pm_rps_events) {
 		spin_lock(&dev_priv->irq_lock);
 		gen6_mask_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events);
-		if (dev_priv->rps.interrupts_enabled) {
-			dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events;
-			schedule_work(&dev_priv->rps.work);
+		if (rps->interrupts_enabled) {
+			rps->pm_iir |= pm_iir & dev_priv->pm_rps_events;
+			schedule_work(&rps->work);
 		}
 		spin_unlock(&dev_priv->irq_lock);
 	}
@@ -3952,11 +3955,12 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
 void intel_irq_init(struct drm_i915_private *dev_priv)
 {
 	struct drm_device *dev = &dev_priv->drm;
+	struct intel_rps *rps = &dev_priv->pm.rps;
 	int i;
 
 	intel_hpd_init_work(dev_priv);
 
-	INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
+	INIT_WORK(&rps->work, gen6_pm_rps_work);
 
 	INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
 	for (i = 0; i < MAX_L3_SLICES; ++i)
@@ -3972,7 +3976,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
 	else
 		dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
 
-	dev_priv->rps.pm_intrmsk_mbz = 0;
+	rps->pm_intrmsk_mbz = 0;
 
 	/*
 	 * SNB,IVB,HSW can while VLV,CHV may hard hang on looping batchbuffer
@@ -3981,10 +3985,10 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
 	 * TODO: verify if this can be reproduced on VLV,CHV.
 	 */
 	if (INTEL_GEN(dev_priv) <= 7)
-		dev_priv->rps.pm_intrmsk_mbz |= GEN6_PM_RP_UP_EI_EXPIRED;
+		rps->pm_intrmsk_mbz |= GEN6_PM_RP_UP_EI_EXPIRED;
 
 	if (INTEL_GEN(dev_priv) >= 8)
-		dev_priv->rps.pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
+		rps->pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
 
 	if (IS_GEN2(dev_priv)) {
 		/* Gen2 doesn't have a hardware frame counter */
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index d61c872..c16e907 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -246,7 +246,7 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev,
 
 	intel_runtime_pm_get(dev_priv);
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
 		u32 freq;
 		freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
@@ -261,7 +261,7 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev,
 			ret = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
 		ret = intel_gpu_freq(dev_priv, ret);
 	}
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	intel_runtime_pm_put(dev_priv);
 
@@ -275,7 +275,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
 
 	return snprintf(buf, PAGE_SIZE, "%d\n",
 			intel_gpu_freq(dev_priv,
-				       dev_priv->rps.cur_freq));
+				       dev_priv->pm.rps.cur_freq));
 }
 
 static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
@@ -284,7 +284,7 @@ static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribu
 
 	return snprintf(buf, PAGE_SIZE, "%d\n",
 			intel_gpu_freq(dev_priv,
-				       dev_priv->rps.boost_freq));
+				       dev_priv->pm.rps.boost_freq));
 }
 
 static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
@@ -301,12 +301,12 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
 
 	/* Validate against (static) hardware limits */
 	val = intel_freq_opcode(dev_priv, val);
-	if (val < dev_priv->rps.min_freq || val > dev_priv->rps.max_freq)
+	if (val < dev_priv->pm.rps.min_freq || val > dev_priv->pm.rps.max_freq)
 		return -EINVAL;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
-	dev_priv->rps.boost_freq = val;
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
+	dev_priv->pm.rps.boost_freq = val;
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	return count;
 }
@@ -318,7 +318,7 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
 
 	return snprintf(buf, PAGE_SIZE, "%d\n",
 			intel_gpu_freq(dev_priv,
-				       dev_priv->rps.efficient_freq));
+				       dev_priv->pm.rps.efficient_freq));
 }
 
 static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
@@ -327,7 +327,7 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute
 
 	return snprintf(buf, PAGE_SIZE, "%d\n",
 			intel_gpu_freq(dev_priv,
-				       dev_priv->rps.max_freq_softlimit));
+				       dev_priv->pm.rps.max_freq_softlimit));
 }
 
 static ssize_t gt_max_freq_mhz_store(struct device *kdev,
@@ -344,34 +344,34 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
 
 	intel_runtime_pm_get(dev_priv);
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	val = intel_freq_opcode(dev_priv, val);
 
-	if (val < dev_priv->rps.min_freq ||
-	    val > dev_priv->rps.max_freq ||
-	    val < dev_priv->rps.min_freq_softlimit) {
-		mutex_unlock(&dev_priv->rps.hw_lock);
+	if (val < dev_priv->pm.rps.min_freq ||
+	    val > dev_priv->pm.rps.max_freq ||
+	    val < dev_priv->pm.rps.min_freq_softlimit) {
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 		intel_runtime_pm_put(dev_priv);
 		return -EINVAL;
 	}
 
-	if (val > dev_priv->rps.rp0_freq)
+	if (val > dev_priv->pm.rps.rp0_freq)
 		DRM_DEBUG("User requested overclocking to %d\n",
 			  intel_gpu_freq(dev_priv, val));
 
-	dev_priv->rps.max_freq_softlimit = val;
+	dev_priv->pm.rps.max_freq_softlimit = val;
 
-	val = clamp_t(int, dev_priv->rps.cur_freq,
-		      dev_priv->rps.min_freq_softlimit,
-		      dev_priv->rps.max_freq_softlimit);
+	val = clamp_t(int, dev_priv->pm.rps.cur_freq,
+		      dev_priv->pm.rps.min_freq_softlimit,
+		      dev_priv->pm.rps.max_freq_softlimit);
 
 	/* We still need *_set_rps to process the new max_delay and
 	 * update the interrupt limits and PMINTRMSK even though
 	 * frequency request may be unchanged. */
 	ret = intel_set_rps(dev_priv, val);
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	intel_runtime_pm_put(dev_priv);
 
@@ -384,7 +384,7 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute
 
 	return snprintf(buf, PAGE_SIZE, "%d\n",
 			intel_gpu_freq(dev_priv,
-				       dev_priv->rps.min_freq_softlimit));
+				       dev_priv->pm.rps.min_freq_softlimit));
 }
 
 static ssize_t gt_min_freq_mhz_store(struct device *kdev,
@@ -401,30 +401,30 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
 
 	intel_runtime_pm_get(dev_priv);
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	val = intel_freq_opcode(dev_priv, val);
 
-	if (val < dev_priv->rps.min_freq ||
-	    val > dev_priv->rps.max_freq ||
-	    val > dev_priv->rps.max_freq_softlimit) {
-		mutex_unlock(&dev_priv->rps.hw_lock);
+	if (val < dev_priv->pm.rps.min_freq ||
+	    val > dev_priv->pm.rps.max_freq ||
+	    val > dev_priv->pm.rps.max_freq_softlimit) {
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 		intel_runtime_pm_put(dev_priv);
 		return -EINVAL;
 	}
 
-	dev_priv->rps.min_freq_softlimit = val;
+	dev_priv->pm.rps.min_freq_softlimit = val;
 
-	val = clamp_t(int, dev_priv->rps.cur_freq,
-		      dev_priv->rps.min_freq_softlimit,
-		      dev_priv->rps.max_freq_softlimit);
+	val = clamp_t(int, dev_priv->pm.rps.cur_freq,
+		      dev_priv->pm.rps.min_freq_softlimit,
+		      dev_priv->pm.rps.max_freq_softlimit);
 
 	/* We still need *_set_rps to process the new min_delay and
 	 * update the interrupt limits and PMINTRMSK even though
 	 * frequency request may be unchanged. */
 	ret = intel_set_rps(dev_priv, val);
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	intel_runtime_pm_put(dev_priv);
 
@@ -451,11 +451,11 @@ static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr
 	u32 val;
 
 	if (attr == &dev_attr_gt_RP0_freq_mhz)
-		val = intel_gpu_freq(dev_priv, dev_priv->rps.rp0_freq);
+		val = intel_gpu_freq(dev_priv, dev_priv->pm.rps.rp0_freq);
 	else if (attr == &dev_attr_gt_RP1_freq_mhz)
-		val = intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq);
+		val = intel_gpu_freq(dev_priv, dev_priv->pm.rps.rp1_freq);
 	else if (attr == &dev_attr_gt_RPn_freq_mhz)
-		val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq);
+		val = intel_gpu_freq(dev_priv, dev_priv->pm.rps.min_freq);
 	else
 		BUG();
 
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 87fc42b..6cf7eef 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -503,7 +503,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 	else
 		cmd = 0;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK;
 	val |= (cmd << DSPFREQGUAR_SHIFT);
@@ -513,7 +513,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 		     50)) {
 		DRM_ERROR("timed out waiting for CDclk change\n");
 	}
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	mutex_lock(&dev_priv->sb_lock);
 
@@ -590,7 +590,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 	 */
 	cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK_CHV;
 	val |= (cmd << DSPFREQGUAR_SHIFT_CHV);
@@ -600,7 +600,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 		     50)) {
 		DRM_ERROR("timed out waiting for CDclk change\n");
 	}
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	intel_update_cdclk(dev_priv);
 
@@ -656,10 +656,10 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 		 "trying to change cdclk frequency with cdclk not enabled\n"))
 		return;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	ret = sandybridge_pcode_write(dev_priv,
 				      BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 	if (ret) {
 		DRM_ERROR("failed to inform pcode about cdclk change\n");
 		return;
@@ -712,9 +712,9 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 			LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
 		DRM_ERROR("Switching back to LCPLL failed\n");
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
 
@@ -928,12 +928,12 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
 
 	WARN_ON((cdclk == 24000) != (vco == 0));
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
 				SKL_CDCLK_PREPARE_FOR_CHANGE,
 				SKL_CDCLK_READY_FOR_CHANGE,
 				SKL_CDCLK_READY_FOR_CHANGE, 3);
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 	if (ret) {
 		DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
 			  ret);
@@ -975,9 +975,9 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
 	POSTING_READ(CDCLK_CTL);
 
 	/* inform PCU of the change */
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	intel_update_cdclk(dev_priv);
 }
@@ -1268,10 +1268,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 	}
 
 	/* Inform power controller of upcoming frequency change */
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
 				      0x80000000);
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	if (ret) {
 		DRM_ERROR("PCode CDCLK freq change notify failed (err %d, freq %d)\n",
@@ -1300,10 +1300,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 		val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
 	I915_WRITE(CDCLK_CTL, val);
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
 				      DIV_ROUND_UP(cdclk, 25000));
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	if (ret) {
 		DRM_ERROR("PCode CDCLK freq set failed, (err %d, freq %d)\n",
@@ -1518,12 +1518,12 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 	u32 val, divider, pcu_ack;
 	int ret;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
 				SKL_CDCLK_PREPARE_FOR_CHANGE,
 				SKL_CDCLK_READY_FOR_CHANGE,
 				SKL_CDCLK_READY_FOR_CHANGE, 3);
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 	if (ret) {
 		DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
 			  ret);
@@ -1575,9 +1575,9 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 	I915_WRITE(CDCLK_CTL, val);
 
 	/* inform PCU of the change */
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	intel_update_cdclk(dev_priv);
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8599e42..eb53093 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4955,10 +4955,10 @@ void hsw_enable_ips(struct intel_crtc *crtc)
 
 	assert_plane_enabled(dev_priv, crtc->plane);
 	if (IS_BROADWELL(dev_priv)) {
-		mutex_lock(&dev_priv->rps.hw_lock);
+		mutex_lock(&dev_priv->pm.pcu_lock);
 		WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL,
 						IPS_ENABLE | IPS_PCODE_CONTROL));
-		mutex_unlock(&dev_priv->rps.hw_lock);
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 		/* Quoting Art Runyan: "its not safe to expect any particular
 		 * value in IPS_CTL bit 31 after enabling IPS through the
 		 * mailbox." Moreover, the mailbox may return a bogus state,
@@ -4988,9 +4988,9 @@ void hsw_disable_ips(struct intel_crtc *crtc)
 
 	assert_plane_enabled(dev_priv, crtc->plane);
 	if (IS_BROADWELL(dev_priv)) {
-		mutex_lock(&dev_priv->rps.hw_lock);
+		mutex_lock(&dev_priv->pm.pcu_lock);
 		WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
-		mutex_unlock(&dev_priv->rps.hw_lock);
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 		/* wait for pcode to finish disabling IPS, which may take up to 42ms */
 		if (intel_wait_for_register(dev_priv,
 					    IPS_CTL, IPS_ENABLE, 0,
@@ -8846,11 +8846,11 @@ static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv)
 static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val)
 {
 	if (IS_HASWELL(dev_priv)) {
-		mutex_lock(&dev_priv->rps.hw_lock);
+		mutex_lock(&dev_priv->pm.pcu_lock);
 		if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP,
 					    val))
 			DRM_DEBUG_KMS("Failed to write to D_COMP\n");
-		mutex_unlock(&dev_priv->rps.hw_lock);
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 	} else {
 		I915_WRITE(D_COMP_BDW, val);
 		POSTING_READ(D_COMP_BDW);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 76ef34b..f7db720 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1241,7 +1241,7 @@ void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
 static inline u32 gen6_sanitize_rps_pm_mask(const struct drm_i915_private *i915,
 					    u32 mask)
 {
-	return mask & ~i915->rps.pm_intrmsk_mbz;
+	return mask & ~i915->pm.rps.pm_intrmsk_mbz;
 }
 
 void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a54dae5..b89677a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -322,7 +322,7 @@ static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable)
 {
 	u32 val;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
 	if (enable)
@@ -337,14 +337,14 @@ static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable)
 		      FORCE_DDR_FREQ_REQ_ACK) == 0, 3))
 		DRM_ERROR("timed out waiting for Punit DDR DVFS request\n");
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
 static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable)
 {
 	u32 val;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	if (enable)
@@ -353,7 +353,7 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable)
 		val &= ~DSP_MAXFIFO_PM5_ENABLE;
 	vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
 #define FW_WM(value, plane) \
@@ -2790,11 +2790,11 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
 
 		/* read the first set of memory latencies[0:3] */
 		val = 0; /* data0 to be programmed to 0 for first set */
-		mutex_lock(&dev_priv->rps.hw_lock);
+		mutex_lock(&dev_priv->pm.pcu_lock);
 		ret = sandybridge_pcode_read(dev_priv,
 					     GEN9_PCODE_READ_MEM_LATENCY,
 					     &val);
-		mutex_unlock(&dev_priv->rps.hw_lock);
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 
 		if (ret) {
 			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
@@ -2811,11 +2811,11 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
 
 		/* read the second set of memory latencies[4:7] */
 		val = 1; /* data0 to be programmed to 1 for second set */
-		mutex_lock(&dev_priv->rps.hw_lock);
+		mutex_lock(&dev_priv->pm.pcu_lock);
 		ret = sandybridge_pcode_read(dev_priv,
 					     GEN9_PCODE_READ_MEM_LATENCY,
 					     &val);
-		mutex_unlock(&dev_priv->rps.hw_lock);
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 		if (ret) {
 			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
 			return;
@@ -3608,13 +3608,13 @@ static bool skl_needs_memory_bw_wa(struct intel_atomic_state *state)
 		return 0;
 
 	DRM_DEBUG_KMS("Enabling the SAGV\n");
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	ret = sandybridge_pcode_write(dev_priv, GEN9_PCODE_SAGV_CONTROL,
 				      GEN9_SAGV_ENABLE);
 
 	/* We don't need to wait for the SAGV when enabling */
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	/*
 	 * Some skl systems, pre-release machines in particular,
@@ -3645,14 +3645,14 @@ static bool skl_needs_memory_bw_wa(struct intel_atomic_state *state)
 		return 0;
 
 	DRM_DEBUG_KMS("Disabling the SAGV\n");
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	/* bspec says to keep retrying for at least 1 ms */
 	ret = skl_pcode_request(dev_priv, GEN9_PCODE_SAGV_CONTROL,
 				GEN9_SAGV_DISABLE,
 				GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED,
 				1);
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	/*
 	 * Some skl systems, pre-release machines in particular,
@@ -5619,7 +5619,7 @@ void vlv_wm_get_hw_state(struct drm_device *dev)
 	wm->level = VLV_WM_LEVEL_PM2;
 
 	if (IS_CHERRYVIEW(dev_priv)) {
-		mutex_lock(&dev_priv->rps.hw_lock);
+		mutex_lock(&dev_priv->pm.pcu_lock);
 
 		val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 		if (val & DSP_MAXFIFO_PM5_ENABLE)
@@ -5649,7 +5649,7 @@ void vlv_wm_get_hw_state(struct drm_device *dev)
 				wm->level = VLV_WM_LEVEL_DDR_DVFS;
 		}
 
-		mutex_unlock(&dev_priv->rps.hw_lock);
+		mutex_unlock(&dev_priv->pm.pcu_lock);
 	}
 
 	for_each_intel_crtc(dev, crtc) {
@@ -5989,13 +5989,13 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
 	 * frequency, if the down threshold expires in that window we will not
 	 * receive a down interrupt. */
 	if (INTEL_GEN(dev_priv) >= 9) {
-		limits = (dev_priv->rps.max_freq_softlimit) << 23;
-		if (val <= dev_priv->rps.min_freq_softlimit)
-			limits |= (dev_priv->rps.min_freq_softlimit) << 14;
+		limits = (dev_priv->pm.rps.max_freq_softlimit) << 23;
+		if (val <= dev_priv->pm.rps.min_freq_softlimit)
+			limits |= (dev_priv->pm.rps.min_freq_softlimit) << 14;
 	} else {
-		limits = dev_priv->rps.max_freq_softlimit << 24;
-		if (val <= dev_priv->rps.min_freq_softlimit)
-			limits |= dev_priv->rps.min_freq_softlimit << 16;
+		limits = dev_priv->pm.rps.max_freq_softlimit << 24;
+		if (val <= dev_priv->pm.rps.min_freq_softlimit)
+			limits |= dev_priv->pm.rps.min_freq_softlimit << 16;
 	}
 
 	return limits;
@@ -6003,39 +6003,40 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
 
 static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
 {
+	struct intel_rps *rps = &dev_priv->pm.rps;
 	int new_power;
 	u32 threshold_up = 0, threshold_down = 0; /* in % */
 	u32 ei_up = 0, ei_down = 0;
 
-	new_power = dev_priv->rps.power;
-	switch (dev_priv->rps.power) {
+	new_power = rps->power;
+	switch (rps->power) {
 	case LOW_POWER:
-		if (val > dev_priv->rps.efficient_freq + 1 &&
-		    val > dev_priv->rps.cur_freq)
+		if (val > rps->efficient_freq + 1 &&
+		    val > rps->cur_freq)
 			new_power = BETWEEN;
 		break;
 
 	case BETWEEN:
-		if (val <= dev_priv->rps.efficient_freq &&
-		    val < dev_priv->rps.cur_freq)
+		if (val <= rps->efficient_freq &&
+		    val < rps->cur_freq)
 			new_power = LOW_POWER;
-		else if (val >= dev_priv->rps.rp0_freq &&
-			 val > dev_priv->rps.cur_freq)
+		else if (val >= rps->rp0_freq &&
+			 val > rps->cur_freq)
 			new_power = HIGH_POWER;
 		break;
 
 	case HIGH_POWER:
-		if (val < (dev_priv->rps.rp1_freq + dev_priv->rps.rp0_freq) >> 1 &&
-		    val < dev_priv->rps.cur_freq)
+		if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 &&
+		    val < rps->cur_freq)
 			new_power = BETWEEN;
 		break;
 	}
 	/* Max/min bins are special */
-	if (val <= dev_priv->rps.min_freq_softlimit)
+	if (val <= rps->min_freq_softlimit)
 		new_power = LOW_POWER;
-	if (val >= dev_priv->rps.max_freq_softlimit)
+	if (val >= rps->max_freq_softlimit)
 		new_power = HIGH_POWER;
-	if (new_power == dev_priv->rps.power)
+	if (new_power == rps->power)
 		return;
 
 	/* Note the units here are not exactly 1us, but 1280ns. */
@@ -6098,10 +6099,10 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
 		   GEN6_RP_DOWN_IDLE_AVG);
 
 skip_hw_write:
-	dev_priv->rps.power = new_power;
-	dev_priv->rps.up_threshold = threshold_up;
-	dev_priv->rps.down_threshold = threshold_down;
-	dev_priv->rps.last_adj = 0;
+	rps->power = new_power;
+	rps->up_threshold = threshold_up;
+	rps->down_threshold = threshold_down;
+	rps->last_adj = 0;
 }
 
 static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
@@ -6109,9 +6110,9 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
 	u32 mask = 0;
 
 	/* We use UP_EI_EXPIRED interupts for both up/down in manual mode */
-	if (val > dev_priv->rps.min_freq_softlimit)
+	if (val > dev_priv->pm.rps.min_freq_softlimit)
 		mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT;
-	if (val < dev_priv->rps.max_freq_softlimit)
+	if (val < dev_priv->pm.rps.max_freq_softlimit)
 		mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD;
 
 	mask &= dev_priv->pm_rps_events;
@@ -6127,7 +6128,7 @@ static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val)
 	/* min/max delay may still have been modified so be sure to
 	 * write the limits value.
 	 */
-	if (val != dev_priv->rps.cur_freq) {
+	if (val != dev_priv->pm.rps.cur_freq) {
 		gen6_set_rps_thresholds(dev_priv, val);
 
 		if (INTEL_GEN(dev_priv) >= 9)
@@ -6149,7 +6150,7 @@ static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val)
 	I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, intel_rps_limits(dev_priv, val));
 	I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
 
-	dev_priv->rps.cur_freq = val;
+	dev_priv->pm.rps.cur_freq = val;
 	trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
 
 	return 0;
@@ -6165,7 +6166,7 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val)
 
 	I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
 
-	if (val != dev_priv->rps.cur_freq) {
+	if (val != dev_priv->pm.rps.cur_freq) {
 		err = vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val);
 		if (err)
 			return err;
@@ -6173,7 +6174,7 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val)
 		gen6_set_rps_thresholds(dev_priv, val);
 	}
 
-	dev_priv->rps.cur_freq = val;
+	dev_priv->pm.rps.cur_freq = val;
 	trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
 
 	return 0;
@@ -6188,10 +6189,10 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val)
 */
 static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
 {
-	u32 val = dev_priv->rps.idle_freq;
+	u32 val = dev_priv->pm.rps.idle_freq;
 	int err;
 
-	if (dev_priv->rps.cur_freq <= val)
+	if (dev_priv->pm.rps.cur_freq <= val)
 		return;
 
 	/* The punit delays the write of the frequency and voltage until it
@@ -6216,30 +6217,32 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
 
 void gen6_rps_busy(struct drm_i915_private *dev_priv)
 {
-	mutex_lock(&dev_priv->rps.hw_lock);
-	if (dev_priv->rps.enabled) {
+	struct intel_rps *rps = &dev_priv->pm.rps;
+
+	mutex_lock(&dev_priv->pm.pcu_lock);
+	if (rps->enabled) {
 		u8 freq;
 
 		if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED)
 			gen6_rps_reset_ei(dev_priv);
 		I915_WRITE(GEN6_PMINTRMSK,
-			   gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq));
+			   gen6_rps_pm_mask(dev_priv, rps->cur_freq));
 
 		gen6_enable_rps_interrupts(dev_priv);
 
 		/* Use the user's desired frequency as a guide, but for better
 		 * performance, jump directly to RPe as our starting frequency.
 		 */
-		freq = max(dev_priv->rps.cur_freq,
-			   dev_priv->rps.efficient_freq);
+		freq = max(rps->cur_freq,
+			   rps->efficient_freq);
 
 		if (intel_set_rps(dev_priv,
 				  clamp(freq,
-					dev_priv->rps.min_freq_softlimit,
-					dev_priv->rps.max_freq_softlimit)))
+					rps->min_freq_softlimit,
+					rps->max_freq_softlimit)))
 			DRM_DEBUG_DRIVER("Failed to set idle frequency\n");
 	}
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
 void gen6_rps_idle(struct drm_i915_private *dev_priv)
@@ -6251,17 +6254,17 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
 	 */
 	gen6_disable_rps_interrupts(dev_priv);
 
-	mutex_lock(&dev_priv->rps.hw_lock);
-	if (dev_priv->rps.enabled) {
+	mutex_lock(&dev_priv->pm.pcu_lock);
+	if (dev_priv->pm.rps.enabled) {
 		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
 			vlv_set_rps_idle(dev_priv);
 		else
-			gen6_set_rps(dev_priv, dev_priv->rps.idle_freq);
-		dev_priv->rps.last_adj = 0;
+			gen6_set_rps(dev_priv, dev_priv->pm.rps.idle_freq);
+		dev_priv->pm.rps.last_adj = 0;
 		I915_WRITE(GEN6_PMINTRMSK,
 			   gen6_sanitize_rps_pm_mask(dev_priv, ~0));
 	}
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
 void gen6_rps_boost(struct drm_i915_gem_request *rq,
@@ -6274,13 +6277,13 @@ void gen6_rps_boost(struct drm_i915_gem_request *rq,
 	/* This is intentionally racy! We peek at the state here, then
 	 * validate inside the RPS worker.
 	 */
-	if (!i915->rps.enabled)
+	if (!i915->pm.rps.enabled)
 		return;
 
 	boost = false;
 	spin_lock_irqsave(&rq->lock, flags);
 	if (!rq->waitboost && !i915_gem_request_completed(rq)) {
-		atomic_inc(&i915->rps.num_waiters);
+		atomic_inc(&i915->pm.rps.num_waiters);
 		rq->waitboost = true;
 		boost = true;
 	}
@@ -6288,22 +6291,22 @@ void gen6_rps_boost(struct drm_i915_gem_request *rq,
 	if (!boost)
 		return;
 
-	if (READ_ONCE(i915->rps.cur_freq) < i915->rps.boost_freq)
-		schedule_work(&i915->rps.work);
+	if (READ_ONCE(i915->pm.rps.cur_freq) < i915->pm.rps.boost_freq)
+		schedule_work(&i915->pm.rps.work);
 
-	atomic_inc(rps ? &rps->boosts : &i915->rps.boosts);
+	atomic_inc(rps ? &rps->boosts : &i915->pm.rps.boosts);
 }
 
 int intel_set_rps(struct drm_i915_private *dev_priv, u8 val)
 {
 	int err;
 
-	lockdep_assert_held(&dev_priv->rps.hw_lock);
-	GEM_BUG_ON(val > dev_priv->rps.max_freq);
-	GEM_BUG_ON(val < dev_priv->rps.min_freq);
+	lockdep_assert_held(&dev_priv->pm.pcu_lock);
+	GEM_BUG_ON(val > dev_priv->pm.rps.max_freq);
+	GEM_BUG_ON(val < dev_priv->pm.rps.min_freq);
 
-	if (!dev_priv->rps.enabled) {
-		dev_priv->rps.cur_freq = val;
+	if (!dev_priv->pm.rps.enabled) {
+		dev_priv->pm.rps.cur_freq = val;
 		return 0;
 	}
 
@@ -6490,19 +6493,19 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
 	/* static values from HW: RP0 > RP1 > RPn (min_freq) */
 	if (IS_GEN9_LP(dev_priv)) {
 		u32 rp_state_cap = I915_READ(BXT_RP_STATE_CAP);
-		dev_priv->rps.rp0_freq = (rp_state_cap >> 16) & 0xff;
-		dev_priv->rps.rp1_freq = (rp_state_cap >>  8) & 0xff;
-		dev_priv->rps.min_freq = (rp_state_cap >>  0) & 0xff;
+		dev_priv->pm.rps.rp0_freq = (rp_state_cap >> 16) & 0xff;
+		dev_priv->pm.rps.rp1_freq = (rp_state_cap >>  8) & 0xff;
+		dev_priv->pm.rps.min_freq = (rp_state_cap >>  0) & 0xff;
 	} else {
 		u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
-		dev_priv->rps.rp0_freq = (rp_state_cap >>  0) & 0xff;
-		dev_priv->rps.rp1_freq = (rp_state_cap >>  8) & 0xff;
-		dev_priv->rps.min_freq = (rp_state_cap >> 16) & 0xff;
+		dev_priv->pm.rps.rp0_freq = (rp_state_cap >>  0) & 0xff;
+		dev_priv->pm.rps.rp1_freq = (rp_state_cap >>  8) & 0xff;
+		dev_priv->pm.rps.min_freq = (rp_state_cap >> 16) & 0xff;
 	}
 	/* hw_max = RP0 until we check for overclocking */
-	dev_priv->rps.max_freq = dev_priv->rps.rp0_freq;
+	dev_priv->pm.rps.max_freq = dev_priv->pm.rps.rp0_freq;
 
-	dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq;
+	dev_priv->pm.rps.efficient_freq = dev_priv->pm.rps.rp1_freq;
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
 	    IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
 		u32 ddcc_status = 0;
@@ -6510,33 +6513,33 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
 		if (sandybridge_pcode_read(dev_priv,
 					   HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL,
 					   &ddcc_status) == 0)
-			dev_priv->rps.efficient_freq =
+			dev_priv->pm.rps.efficient_freq =
 				clamp_t(u8,
 					((ddcc_status >> 8) & 0xff),
-					dev_priv->rps.min_freq,
-					dev_priv->rps.max_freq);
+					dev_priv->pm.rps.min_freq,
+					dev_priv->pm.rps.max_freq);
 	}
 
 	if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
 		/* Store the frequency values in 16.66 MHZ units, which is
 		 * the natural hardware unit for SKL
 		 */
-		dev_priv->rps.rp0_freq *= GEN9_FREQ_SCALER;
-		dev_priv->rps.rp1_freq *= GEN9_FREQ_SCALER;
-		dev_priv->rps.min_freq *= GEN9_FREQ_SCALER;
-		dev_priv->rps.max_freq *= GEN9_FREQ_SCALER;
-		dev_priv->rps.efficient_freq *= GEN9_FREQ_SCALER;
+		dev_priv->pm.rps.rp0_freq *= GEN9_FREQ_SCALER;
+		dev_priv->pm.rps.rp1_freq *= GEN9_FREQ_SCALER;
+		dev_priv->pm.rps.min_freq *= GEN9_FREQ_SCALER;
+		dev_priv->pm.rps.max_freq *= GEN9_FREQ_SCALER;
+		dev_priv->pm.rps.efficient_freq *= GEN9_FREQ_SCALER;
 	}
 }
 
 static void reset_rps(struct drm_i915_private *dev_priv,
 		      int (*set)(struct drm_i915_private *, u8))
 {
-	u8 freq = dev_priv->rps.cur_freq;
+	u8 freq = dev_priv->pm.rps.cur_freq;
 
 	/* force a reset */
-	dev_priv->rps.power = -1;
-	dev_priv->rps.cur_freq = -1;
+	dev_priv->pm.rps.power = -1;
+	dev_priv->pm.rps.cur_freq = -1;
 
 	if (set(dev_priv, freq))
 		DRM_ERROR("Failed to reset RPS to initial values\n");
@@ -6549,7 +6552,7 @@ static void gen9_enable_rps(struct drm_i915_private *dev_priv)
 
 	/* Program defaults and thresholds for RPS*/
 	I915_WRITE(GEN6_RC_VIDEO_FREQ,
-		GEN9_FREQUENCY(dev_priv->rps.rp1_freq));
+		GEN9_FREQUENCY(dev_priv->pm.rps.rp1_freq));
 
 	/* 1 second timeout*/
 	I915_WRITE(GEN6_RP_DOWN_TIMEOUT,
@@ -6668,16 +6671,16 @@ static void gen8_enable_rps(struct drm_i915_private *dev_priv)
 
 	/* 1 Program defaults and thresholds for RPS*/
 	I915_WRITE(GEN6_RPNSWREQ,
-		   HSW_FREQUENCY(dev_priv->rps.rp1_freq));
+		   HSW_FREQUENCY(dev_priv->pm.rps.rp1_freq));
 	I915_WRITE(GEN6_RC_VIDEO_FREQ,
-		   HSW_FREQUENCY(dev_priv->rps.rp1_freq));
+		   HSW_FREQUENCY(dev_priv->pm.rps.rp1_freq));
 	/* NB: Docs say 1s, and 1000000 - which aren't equivalent */
 	I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */
 
 	/* Docs recommend 900MHz, and 300 MHz respectively */
 	I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
-		   dev_priv->rps.max_freq_softlimit << 24 |
-		   dev_priv->rps.min_freq_softlimit << 16);
+		   dev_priv->pm.rps.max_freq_softlimit << 24 |
+		   dev_priv->pm.rps.min_freq_softlimit << 16);
 
 	I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */
 	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/
@@ -6711,7 +6714,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv)
 	int rc6_mode;
 	int ret;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	I915_WRITE(GEN6_RC_STATE, 0);
 
@@ -6786,7 +6789,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv)
 
 static void gen6_enable_rps(struct drm_i915_private *dev_priv)
 {
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	/* Here begins a magic sequence of register writes to enable
 	 * auto-downclocking.
@@ -6814,7 +6817,7 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 	int scaling_factor = 180;
 	struct cpufreq_policy *policy;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	policy = cpufreq_cpu_get(0);
 	if (policy) {
@@ -6837,11 +6840,11 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 
 	if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
 		/* Convert GT frequency to 50 HZ units */
-		min_gpu_freq = dev_priv->rps.min_freq / GEN9_FREQ_SCALER;
-		max_gpu_freq = dev_priv->rps.max_freq / GEN9_FREQ_SCALER;
+		min_gpu_freq = dev_priv->pm.rps.min_freq / GEN9_FREQ_SCALER;
+		max_gpu_freq = dev_priv->pm.rps.max_freq / GEN9_FREQ_SCALER;
 	} else {
-		min_gpu_freq = dev_priv->rps.min_freq;
-		max_gpu_freq = dev_priv->rps.max_freq;
+		min_gpu_freq = dev_priv->pm.rps.min_freq;
+		max_gpu_freq = dev_priv->pm.rps.max_freq;
 	}
 
 	/*
@@ -7092,17 +7095,18 @@ static void valleyview_cleanup_pctx(struct drm_i915_private *dev_priv)
 
 static void vlv_init_gpll_ref_freq(struct drm_i915_private *dev_priv)
 {
-	dev_priv->rps.gpll_ref_freq =
+	dev_priv->pm.rps.gpll_ref_freq =
 		vlv_get_cck_clock(dev_priv, "GPLL ref",
 				  CCK_GPLL_CLOCK_CONTROL,
 				  dev_priv->czclk_freq);
 
 	DRM_DEBUG_DRIVER("GPLL reference freq: %d kHz\n",
-			 dev_priv->rps.gpll_ref_freq);
+			 dev_priv->pm.rps.gpll_ref_freq);
 }
 
 static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv)
 {
+	struct intel_rps *rps = &dev_priv->pm.rps;
 	u32 val;
 
 	valleyview_setup_pctx(dev_priv);
@@ -7124,30 +7128,31 @@ static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv)
 	}
 	DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq);
 
-	dev_priv->rps.max_freq = valleyview_rps_max_freq(dev_priv);
-	dev_priv->rps.rp0_freq = dev_priv->rps.max_freq;
+	rps->max_freq = valleyview_rps_max_freq(dev_priv);
+	rps->rp0_freq = rps->max_freq;
 	DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(dev_priv, dev_priv->rps.max_freq),
-			 dev_priv->rps.max_freq);
+			 intel_gpu_freq(dev_priv, rps->max_freq),
+			 rps->max_freq);
 
-	dev_priv->rps.efficient_freq = valleyview_rps_rpe_freq(dev_priv);
+	rps->efficient_freq = valleyview_rps_rpe_freq(dev_priv);
 	DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
-			 dev_priv->rps.efficient_freq);
+			 intel_gpu_freq(dev_priv, rps->efficient_freq),
+			 rps->efficient_freq);
 
-	dev_priv->rps.rp1_freq = valleyview_rps_guar_freq(dev_priv);
+	rps->rp1_freq = valleyview_rps_guar_freq(dev_priv);
 	DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
-			 dev_priv->rps.rp1_freq);
+			 intel_gpu_freq(dev_priv, rps->rp1_freq),
+			 rps->rp1_freq);
 
-	dev_priv->rps.min_freq = valleyview_rps_min_freq(dev_priv);
+	rps->min_freq = valleyview_rps_min_freq(dev_priv);
 	DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(dev_priv, dev_priv->rps.min_freq),
-			 dev_priv->rps.min_freq);
+			 intel_gpu_freq(dev_priv, rps->min_freq),
+			 rps->min_freq);
 }
 
 static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv)
 {
+	struct intel_rps *rps = &dev_priv->pm.rps;
 	u32 val;
 
 	cherryview_setup_pctx(dev_priv);
@@ -7168,31 +7173,29 @@ static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv)
 	}
 	DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq);
 
-	dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv);
-	dev_priv->rps.rp0_freq = dev_priv->rps.max_freq;
+	rps->max_freq = cherryview_rps_max_freq(dev_priv);
+	rps->rp0_freq = rps->max_freq;
 	DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(dev_priv, dev_priv->rps.max_freq),
-			 dev_priv->rps.max_freq);
+			 intel_gpu_freq(dev_priv, rps->max_freq),
+			 rps->max_freq);
 
-	dev_priv->rps.efficient_freq = cherryview_rps_rpe_freq(dev_priv);
+	rps->efficient_freq = cherryview_rps_rpe_freq(dev_priv);
 	DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
-			 dev_priv->rps.efficient_freq);
+			 intel_gpu_freq(dev_priv, rps->efficient_freq),
+			 rps->efficient_freq);
 
-	dev_priv->rps.rp1_freq = cherryview_rps_guar_freq(dev_priv);
+	rps->rp1_freq = cherryview_rps_guar_freq(dev_priv);
 	DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
-			 dev_priv->rps.rp1_freq);
+			 intel_gpu_freq(dev_priv, rps->rp1_freq),
+			 rps->rp1_freq);
 
-	dev_priv->rps.min_freq = cherryview_rps_min_freq(dev_priv);
+	rps->min_freq = cherryview_rps_min_freq(dev_priv);
 	DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
-			 intel_gpu_freq(dev_priv, dev_priv->rps.min_freq),
-			 dev_priv->rps.min_freq);
+			 intel_gpu_freq(dev_priv, rps->min_freq),
+			 rps->min_freq);
 
-	WARN_ONCE((dev_priv->rps.max_freq |
-		   dev_priv->rps.efficient_freq |
-		   dev_priv->rps.rp1_freq |
-		   dev_priv->rps.min_freq) & 1,
+	WARN_ONCE((rps->max_freq | rps->efficient_freq | rps->rp1_freq |
+		   rps->min_freq) & 1,
 		  "Odd GPU freq values\n");
 }
 
@@ -7207,7 +7210,7 @@ static void cherryview_enable_rc6(struct drm_i915_private *dev_priv)
 	enum intel_engine_id id;
 	u32 gtfifodbg, rc6_mode = 0, pcbr;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	gtfifodbg = I915_READ(GTFIFODBG) & ~(GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV |
 					     GT_FIFO_FREE_ENTRIES_CHV);
@@ -7261,7 +7264,7 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
 {
 	u32 val;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 
 	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
@@ -7308,7 +7311,7 @@ static void valleyview_enable_rc6(struct drm_i915_private *dev_priv)
 	enum intel_engine_id id;
 	u32 gtfifodbg, rc6_mode = 0;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	valleyview_check_pctx(dev_priv);
 
@@ -7356,7 +7359,7 @@ static void valleyview_enable_rps(struct drm_i915_private *dev_priv)
 {
 	u32 val;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	/* If VLV, Forcewake all wells, else re-direct to regular path */
 	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
@@ -7584,7 +7587,7 @@ static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv)
 
 	lockdep_assert_held(&mchdev_lock);
 
-	pxvid = I915_READ(PXVFREQ(dev_priv->rps.cur_freq));
+	pxvid = I915_READ(PXVFREQ(dev_priv->pm.rps.cur_freq));
 	pxvid = (pxvid >> 24) & 0x7f;
 	ext_v = pvid_to_extvid(dev_priv, pxvid);
 
@@ -7871,6 +7874,8 @@ static void intel_init_emon(struct drm_i915_private *dev_priv)
 
 void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 {
+	struct intel_rps *rps = &dev_priv->pm.rps;
+
 	/*
 	 * RPM depends on RC6 to save restore the GT HW context, so make RC6 a
 	 * requirement.
@@ -7881,7 +7886,7 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 	}
 
 	mutex_lock(&dev_priv->drm.struct_mutex);
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	/* Initialize RPS limits (for userspace) */
 	if (IS_CHERRYVIEW(dev_priv))
@@ -7892,16 +7897,16 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 		gen6_init_rps_frequencies(dev_priv);
 
 	/* Derive initial user preferences/limits from the hardware limits */
-	dev_priv->rps.idle_freq = dev_priv->rps.min_freq;
-	dev_priv->rps.cur_freq = dev_priv->rps.idle_freq;
+	rps->idle_freq = rps->min_freq;
+	rps->cur_freq = rps->idle_freq;
 
-	dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq;
-	dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq;
+	rps->max_freq_softlimit = rps->max_freq;
+	rps->min_freq_softlimit = rps->min_freq;
 
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-		dev_priv->rps.min_freq_softlimit =
+		rps->min_freq_softlimit =
 			max_t(int,
-			      dev_priv->rps.efficient_freq,
+			      rps->efficient_freq,
 			      intel_freq_opcode(dev_priv, 450));
 
 	/* After setting max-softlimit, find the overclock max freq */
@@ -7912,16 +7917,16 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 		sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, &params);
 		if (params & BIT(31)) { /* OC supported */
 			DRM_DEBUG_DRIVER("Overclocking supported, max: %dMHz, overclock: %dMHz\n",
-					 (dev_priv->rps.max_freq & 0xff) * 50,
+					 (rps->max_freq & 0xff) * 50,
 					 (params & 0xff) * 50);
-			dev_priv->rps.max_freq = params & 0xff;
+			rps->max_freq = params & 0xff;
 		}
 	}
 
 	/* Finally allow us to boost to max by default */
-	dev_priv->rps.boost_freq = dev_priv->rps.max_freq;
+	rps->boost_freq = rps->max_freq;
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
 	intel_autoenable_gt_powersave(dev_priv);
@@ -7949,7 +7954,7 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv)
 	if (INTEL_GEN(dev_priv) < 6)
 		return;
 
-	if (cancel_delayed_work_sync(&dev_priv->rps.autoenable_work))
+	if (cancel_delayed_work_sync(&dev_priv->pm.autoenable_work))
 		intel_runtime_pm_put(dev_priv);
 
 	/* gen6_rps_idle() will be called later to disable interrupts */
@@ -7957,7 +7962,7 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv)
 
 void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
 {
-	dev_priv->rps.enabled = true; /* force disabling */
+	dev_priv->pm.rps.enabled = true; /* force disabling */
 	intel_disable_gt_powersave(dev_priv);
 
 	gen6_reset_rps_interrupts(dev_priv);
@@ -7965,10 +7970,10 @@ void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
 
 void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
 {
-	if (!READ_ONCE(dev_priv->rps.enabled))
+	if (!READ_ONCE(dev_priv->pm.rps.enabled))
 		return;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	if (INTEL_GEN(dev_priv) >= 9) {
 		gen9_disable_rc6(dev_priv);
@@ -7986,8 +7991,8 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
 		ironlake_disable_drps(dev_priv);
 	}
 
-	dev_priv->rps.enabled = false;
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	dev_priv->pm.rps.enabled = false;
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
 void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
@@ -7995,14 +8000,14 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 	/* We shouldn't be disabling as we submit, so this should be less
 	 * racy than it appears!
 	 */
-	if (READ_ONCE(dev_priv->rps.enabled))
+	if (READ_ONCE(dev_priv->pm.rps.enabled))
 		return;
 
 	/* Powersaving is controlled by the host when inside a VM */
 	if (intel_vgpu_active(dev_priv))
 		return;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	if (IS_CHERRYVIEW(dev_priv)) {
 		cherryview_enable_rc6(dev_priv);
@@ -8028,24 +8033,24 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 		intel_init_emon(dev_priv);
 	}
 
-	WARN_ON(dev_priv->rps.max_freq < dev_priv->rps.min_freq);
-	WARN_ON(dev_priv->rps.idle_freq > dev_priv->rps.max_freq);
+	WARN_ON(dev_priv->pm.rps.max_freq < dev_priv->pm.rps.min_freq);
+	WARN_ON(dev_priv->pm.rps.idle_freq > dev_priv->pm.rps.max_freq);
 
-	WARN_ON(dev_priv->rps.efficient_freq < dev_priv->rps.min_freq);
-	WARN_ON(dev_priv->rps.efficient_freq > dev_priv->rps.max_freq);
+	WARN_ON(dev_priv->pm.rps.efficient_freq < dev_priv->pm.rps.min_freq);
+	WARN_ON(dev_priv->pm.rps.efficient_freq > dev_priv->pm.rps.max_freq);
 
-	dev_priv->rps.enabled = true;
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	dev_priv->pm.rps.enabled = true;
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
 static void __intel_autoenable_gt_powersave(struct work_struct *work)
 {
 	struct drm_i915_private *dev_priv =
-		container_of(work, typeof(*dev_priv), rps.autoenable_work.work);
+		container_of(work, typeof(*dev_priv), pm.autoenable_work.work);
 	struct intel_engine_cs *rcs;
 	struct drm_i915_gem_request *req;
 
-	if (READ_ONCE(dev_priv->rps.enabled))
+	if (READ_ONCE(dev_priv->pm.rps.enabled))
 		goto out;
 
 	rcs = dev_priv->engine[RCS];
@@ -8075,7 +8080,7 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work)
 
 void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv)
 {
-	if (READ_ONCE(dev_priv->rps.enabled))
+	if (READ_ONCE(dev_priv->pm.rps.enabled))
 		return;
 
 	if (IS_IRONLAKE_M(dev_priv)) {
@@ -8095,7 +8100,7 @@ void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv)
 		 * runtime resume it's necessary).
 		 */
 		if (queue_delayed_work(dev_priv->wq,
-				       &dev_priv->rps.autoenable_work,
+				       &dev_priv->pm.autoenable_work,
 				       round_jiffies_up_relative(HZ)))
 			intel_runtime_pm_get_noresume(dev_priv);
 	}
@@ -9124,7 +9129,7 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
 {
 	int status;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	/* GEN6_PCODE_* are outside of the forcewake domain, we can
 	 * use te fw I915_READ variants to reduce the amount of work
@@ -9171,7 +9176,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
 {
 	int status;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	/* GEN6_PCODE_* are outside of the forcewake domain, we can
 	 * use te fw I915_READ variants to reduce the amount of work
@@ -9248,7 +9253,7 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
 	u32 status;
 	int ret;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 #define COND skl_pcode_try_request(dev_priv, mbox, request, reply_mask, reply, \
 				   &status)
@@ -9290,31 +9295,39 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
 
 static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
 {
+	struct intel_rps *rps = &dev_priv->pm.rps;
+
 	/*
 	 * N = val - 0xb7
 	 * Slow = Fast = GPLL ref * N
 	 */
-	return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * (val - 0xb7), 1000);
+	return DIV_ROUND_CLOSEST(rps->gpll_ref_freq * (val - 0xb7), 1000);
 }
 
 static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
 {
-	return DIV_ROUND_CLOSEST(1000 * val, dev_priv->rps.gpll_ref_freq) + 0xb7;
+	struct intel_rps *rps = &dev_priv->pm.rps;
+
+	return DIV_ROUND_CLOSEST(1000 * val, rps->gpll_ref_freq) + 0xb7;
 }
 
 static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
 {
+	struct intel_rps *rps = &dev_priv->pm.rps;
+
 	/*
 	 * N = val / 2
 	 * CU (slow) = CU2x (fast) / 2 = GPLL ref * N / 2
 	 */
-	return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * val, 2 * 2 * 1000);
+	return DIV_ROUND_CLOSEST(rps->gpll_ref_freq * val, 2 * 2 * 1000);
 }
 
 static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
 {
+	struct intel_rps *rps = &dev_priv->pm.rps;
+
 	/* CHV needs even values */
-	return DIV_ROUND_CLOSEST(2 * 1000 * val, dev_priv->rps.gpll_ref_freq) * 2;
+	return DIV_ROUND_CLOSEST(2 * 1000 * val, rps->gpll_ref_freq) * 2;
 }
 
 int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
@@ -9345,11 +9358,11 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
 
 void intel_pm_setup(struct drm_i915_private *dev_priv)
 {
-	mutex_init(&dev_priv->rps.hw_lock);
+	mutex_init(&dev_priv->pm.pcu_lock);
 
-	INIT_DELAYED_WORK(&dev_priv->rps.autoenable_work,
+	INIT_DELAYED_WORK(&dev_priv->pm.autoenable_work,
 			  __intel_autoenable_gt_powersave);
-	atomic_set(&dev_priv->rps.num_waiters, 0);
+	atomic_set(&dev_priv->pm.rps.num_waiters, 0);
 
 	dev_priv->rpm.suspended = false;
 	atomic_set(&dev_priv->rpm.wakeref_count, 0);
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index af28a8b..9eaa709 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -785,7 +785,7 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv,
 	state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) :
 			 PUNIT_PWRGT_PWR_GATE(power_well_id);
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 #define COND \
 	((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state)
@@ -806,7 +806,7 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv,
 #undef COND
 
 out:
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
 static void vlv_power_well_enable(struct drm_i915_private *dev_priv,
@@ -833,7 +833,7 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
 	mask = PUNIT_PWRGT_MASK(power_well_id);
 	ctrl = PUNIT_PWRGT_PWR_ON(power_well_id);
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask;
 	/*
@@ -852,7 +852,7 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
 	ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask;
 	WARN_ON(ctrl != state);
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	return enabled;
 }
@@ -1364,7 +1364,7 @@ static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv,
 	bool enabled;
 	u32 state, ctrl;
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	state = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe);
 	/*
@@ -1381,7 +1381,7 @@ static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv,
 	ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSC_MASK(pipe);
 	WARN_ON(ctrl << 16 != state);
 
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 
 	return enabled;
 }
@@ -1396,7 +1396,7 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv,
 
 	state = enable ? DP_SSS_PWR_ON(pipe) : DP_SSS_PWR_GATE(pipe);
 
-	mutex_lock(&dev_priv->rps.hw_lock);
+	mutex_lock(&dev_priv->pm.pcu_lock);
 
 #define COND \
 	((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe)) == state)
@@ -1417,7 +1417,7 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv,
 #undef COND
 
 out:
-	mutex_unlock(&dev_priv->rps.hw_lock);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
 static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 7d971cb..6a71a54 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -81,7 +81,7 @@ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
 {
 	u32 val = 0;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	mutex_lock(&dev_priv->sb_lock);
 	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
@@ -95,7 +95,7 @@ int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
 {
 	int err;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	mutex_lock(&dev_priv->sb_lock);
 	err = vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
@@ -125,7 +125,7 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
 {
 	u32 val = 0;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(!mutex_is_locked(&dev_priv->pm.pcu_lock));
 
 	mutex_lock(&dev_priv->sb_lock);
 	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_NC,
-- 
1.9.1

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

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

* [PATCH 08/31] drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (6 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 07/31] drm/i915: Name structure in dev_priv that contains RPS/RC6 state as "pm" Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-21  8:26   ` Szwichtenberg, Radoslaw
  2017-09-26  7:41   ` Ewelina Musial
  2017-09-19 17:41 ` [PATCH 09/31] drm/i915: Create generic function to setup ring frequency table Sagar Arun Kamble
                   ` (22 subsequent siblings)
  30 siblings, 2 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

This function gives the status of RC6, whether disabled or if
enabled then which state. intel_enable_rc6 will be used for
enabling RC6 in the next patch.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Imre Deak <imre.deak@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c   |  2 +-
 drivers/gpu/drm/i915/i915_sysfs.c |  2 +-
 drivers/gpu/drm/i915/intel_drv.h  |  2 +-
 drivers/gpu/drm/i915/intel_guc.c  |  3 ++-
 drivers/gpu/drm/i915/intel_pm.c   | 12 ++++++------
 5 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6cc1162..a6dbad3 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2486,7 +2486,7 @@ static int intel_runtime_suspend(struct device *kdev)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	int ret;
 
-	if (WARN_ON_ONCE(!(dev_priv->pm.rps.enabled && intel_enable_rc6())))
+	if (WARN_ON_ONCE(!(dev_priv->pm.rps.enabled && intel_rc6_enabled())))
 		return -ENODEV;
 
 	if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv)))
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index c16e907..8add849 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -49,7 +49,7 @@ static u32 calc_residency(struct drm_i915_private *dev_priv,
 static ssize_t
 show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%x\n", intel_enable_rc6());
+	return snprintf(buf, PAGE_SIZE, "%x\n", intel_rc6_enabled());
 }
 
 static ssize_t
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f7db720..0cf04eb 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1900,7 +1900,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 				  struct intel_crtc_state *cstate);
 void intel_init_ipc(struct drm_i915_private *dev_priv);
 void intel_enable_ipc(struct drm_i915_private *dev_priv);
-static inline int intel_enable_rc6(void)
+static inline int intel_rc6_enabled(void)
 {
 	return i915.enable_rc6;
 }
diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
index c731cff..f4dc708 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -128,7 +128,8 @@ int intel_guc_sample_forcewake(struct intel_guc *guc)
 
 	action[0] = INTEL_GUC_ACTION_SAMPLE_FORCEWAKE;
 	/* WaRsDisableCoarsePowerGating:skl,bxt */
-	if (!intel_enable_rc6() || NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
+	if (!intel_rc6_enabled() ||
+	    NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
 		action[1] = 0;
 	else
 		/* bit 0 and 1 are for Render and Media domain separately */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b89677a..b83751e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6606,7 +6606,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
 	I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 25);
 
 	/* 3a: Enable RC6 */
-	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
+	if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
 		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
 	DRM_INFO("RC6 %s\n", onoff(rc6_mask & GEN6_RC_CTL_RC6_ENABLE));
 	I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
@@ -6655,7 +6655,7 @@ static void gen8_enable_rc6(struct drm_i915_private *dev_priv)
 		I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
 
 	/* 3: Enable RC6 */
-	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
+	if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
 		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
 	intel_print_rc6_info(dev_priv, rc6_mask);
 	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
@@ -6749,7 +6749,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv)
 	I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
 
 	/* Check if we are enabling RC6 */
-	rc6_mode = intel_enable_rc6();
+	rc6_mode = intel_rc6_enabled();
 	if (rc6_mode & INTEL_RC6_ENABLE)
 		rc6_mask |= GEN6_RC_CTL_RC6_ENABLE;
 
@@ -7251,7 +7251,7 @@ static void cherryview_enable_rc6(struct drm_i915_private *dev_priv)
 	pcbr = I915_READ(VLV_PCBR);
 
 	/* 3: Enable RC6 */
-	if ((intel_enable_rc6() & INTEL_RC6_ENABLE) &&
+	if ((intel_rc6_enabled() & INTEL_RC6_ENABLE) &&
 	    (pcbr >> VLV_PCBR_ADDR_SHIFT))
 		rc6_mode = GEN7_RC_CTL_TO_MODE;
 
@@ -7345,7 +7345,7 @@ static void valleyview_enable_rc6(struct drm_i915_private *dev_priv)
 				      VLV_MEDIA_RC6_COUNT_EN |
 				      VLV_RENDER_RC6_COUNT_EN));
 
-	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
+	if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
 		rc6_mode = GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
 
 	intel_print_rc6_info(dev_priv, rc6_mode);
@@ -9418,7 +9418,7 @@ u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv,
 {
 	u64 time_hw, units, div;
 
-	if (!intel_enable_rc6())
+	if (!intel_rc6_enabled())
 		return 0;
 
 	intel_runtime_pm_get(dev_priv);
-- 
1.9.1

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

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

* [PATCH 09/31] drm/i915: Create generic function to setup ring frequency table
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (7 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 08/31] drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 10/31] drm/i915: Create generic functions to control RC6, RPS Sagar Arun Kamble
                   ` (21 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

Prepared intel_update_ring_freq function to setup ring frequency
for applicable platforms determined by macro - NEEDS_RING_FREQ_UPDATE

Cc: Imre Deak <imre.deak@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b83751e..54e7577 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7872,6 +7872,19 @@ static void intel_init_emon(struct drm_i915_private *dev_priv)
 	dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK);
 }
 
+#define NEEDS_RING_FREQ_UPDATE(i915) \
+	   (((INTEL_GEN(i915) >= 9) && \
+	     (IS_GEN9_BC(i915) || IS_CANNONLAKE(i915))) || \
+	    (IS_BROADWELL(i915)) || \
+	    ((INTEL_GEN(i915) >= 6) && \
+	     (!IS_CHERRYVIEW(i915) && !IS_VALLEYVIEW(i915))))
+
+static inline void intel_update_ring_freq(struct drm_i915_private *i915)
+{
+	if (NEEDS_RING_FREQ_UPDATE(i915))
+		gen6_update_ring_freq(i915);
+}
+
 void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 {
 	struct intel_rps *rps = &dev_priv->pm.rps;
@@ -8018,21 +8031,19 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 	} else if (INTEL_GEN(dev_priv) >= 9) {
 		gen9_enable_rc6(dev_priv);
 		gen9_enable_rps(dev_priv);
-		if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv))
-			gen6_update_ring_freq(dev_priv);
 	} else if (IS_BROADWELL(dev_priv)) {
 		gen8_enable_rc6(dev_priv);
 		gen8_enable_rps(dev_priv);
-		gen6_update_ring_freq(dev_priv);
 	} else if (INTEL_GEN(dev_priv) >= 6) {
 		gen6_enable_rc6(dev_priv);
 		gen6_enable_rps(dev_priv);
-		gen6_update_ring_freq(dev_priv);
 	} else if (IS_IRONLAKE_M(dev_priv)) {
 		ironlake_enable_drps(dev_priv);
 		intel_init_emon(dev_priv);
 	}
 
+	intel_update_ring_freq(dev_priv);
+
 	WARN_ON(dev_priv->pm.rps.max_freq < dev_priv->pm.rps.min_freq);
 	WARN_ON(dev_priv->pm.rps.idle_freq > dev_priv->pm.rps.max_freq);
 
-- 
1.9.1

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

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

* [PATCH 10/31] drm/i915: Create generic functions to control RC6, RPS
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (8 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 09/31] drm/i915: Create generic function to setup ring frequency table Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 11/31] drm/i915: Introduce separate status variable for RC6 and Ring frequency setup Sagar Arun Kamble
                   ` (20 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

Prepared generic functions intel_enable_rc6, intel_disable_rc6,
intel_enable_rps and intel_disable_rps functions to setup RC6/RPS
based on platforms.

Cc: Imre Deak <imre.deak@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 95 ++++++++++++++++++++++++++---------------
 1 file changed, 61 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 54e7577..0c46f81 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7981,74 +7981,101 @@ void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
 	gen6_reset_rps_interrupts(dev_priv);
 }
 
-void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
+void intel_disable_rc6(struct drm_i915_private *dev_priv)
 {
-	if (!READ_ONCE(dev_priv->pm.rps.enabled))
-		return;
-
-	mutex_lock(&dev_priv->pm.pcu_lock);
-
-	if (INTEL_GEN(dev_priv) >= 9) {
+	if (INTEL_GEN(dev_priv) >= 9)
 		gen9_disable_rc6(dev_priv);
-		gen9_disable_rps(dev_priv);
-	} else if (IS_CHERRYVIEW(dev_priv)) {
+	else if (IS_CHERRYVIEW(dev_priv))
 		cherryview_disable_rc6(dev_priv);
-		cherryview_disable_rps(dev_priv);
-	} else if (IS_VALLEYVIEW(dev_priv)) {
+	else if (IS_VALLEYVIEW(dev_priv))
 		valleyview_disable_rc6(dev_priv);
-		valleyview_disable_rps(dev_priv);
-	} else if (INTEL_GEN(dev_priv) >= 6) {
+	else if (INTEL_GEN(dev_priv) >= 6)
 		gen6_disable_rc6(dev_priv);
+}
+
+void intel_disable_rps(struct drm_i915_private *dev_priv)
+{
+	if (INTEL_GEN(dev_priv) >= 9)
+		gen9_disable_rps(dev_priv);
+	else if (IS_CHERRYVIEW(dev_priv))
+		cherryview_disable_rps(dev_priv);
+	else if (IS_VALLEYVIEW(dev_priv))
+		valleyview_disable_rps(dev_priv);
+	else if (INTEL_GEN(dev_priv) >= 6)
 		gen6_disable_rps(dev_priv);
-	}  else if (IS_IRONLAKE_M(dev_priv)) {
+	else if (IS_IRONLAKE_M(dev_priv))
 		ironlake_disable_drps(dev_priv);
-	}
-
-	dev_priv->pm.rps.enabled = false;
-	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
-void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
+void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
 {
-	/* We shouldn't be disabling as we submit, so this should be less
-	 * racy than it appears!
-	 */
-	if (READ_ONCE(dev_priv->pm.rps.enabled))
-		return;
-
-	/* Powersaving is controlled by the host when inside a VM */
-	if (intel_vgpu_active(dev_priv))
+	if (!READ_ONCE(dev_priv->pm.rps.enabled))
 		return;
 
 	mutex_lock(&dev_priv->pm.pcu_lock);
 
-	if (IS_CHERRYVIEW(dev_priv)) {
+	intel_disable_rc6(dev_priv);
+	intel_disable_rps(dev_priv);
+
+	dev_priv->pm.rps.enabled = false;
+	mutex_unlock(&dev_priv->pm.pcu_lock);
+}
+
+void intel_enable_rc6(struct drm_i915_private *dev_priv)
+{
+	if (IS_CHERRYVIEW(dev_priv))
 		cherryview_enable_rc6(dev_priv);
+	else if (IS_VALLEYVIEW(dev_priv))
+		valleyview_enable_rc6(dev_priv);
+	else if (INTEL_GEN(dev_priv) >= 9)
+		gen9_enable_rc6(dev_priv);
+	else if (IS_BROADWELL(dev_priv))
+		gen8_enable_rc6(dev_priv);
+	else if (INTEL_GEN(dev_priv) >= 6)
+		gen6_enable_rc6(dev_priv);
+}
+
+void intel_enable_rps(struct drm_i915_private *dev_priv)
+{
+	if (IS_CHERRYVIEW(dev_priv)) {
 		cherryview_enable_rps(dev_priv);
 	} else if (IS_VALLEYVIEW(dev_priv)) {
-		valleyview_enable_rc6(dev_priv);
 		valleyview_enable_rps(dev_priv);
 	} else if (INTEL_GEN(dev_priv) >= 9) {
-		gen9_enable_rc6(dev_priv);
 		gen9_enable_rps(dev_priv);
 	} else if (IS_BROADWELL(dev_priv)) {
-		gen8_enable_rc6(dev_priv);
 		gen8_enable_rps(dev_priv);
 	} else if (INTEL_GEN(dev_priv) >= 6) {
-		gen6_enable_rc6(dev_priv);
 		gen6_enable_rps(dev_priv);
 	} else if (IS_IRONLAKE_M(dev_priv)) {
 		ironlake_enable_drps(dev_priv);
 		intel_init_emon(dev_priv);
 	}
 
-	intel_update_ring_freq(dev_priv);
-
 	WARN_ON(dev_priv->pm.rps.max_freq < dev_priv->pm.rps.min_freq);
 	WARN_ON(dev_priv->pm.rps.idle_freq > dev_priv->pm.rps.max_freq);
 
 	WARN_ON(dev_priv->pm.rps.efficient_freq < dev_priv->pm.rps.min_freq);
 	WARN_ON(dev_priv->pm.rps.efficient_freq > dev_priv->pm.rps.max_freq);
+}
+
+void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
+{
+	/* We shouldn't be disabling as we submit, so this should be less
+	 * racy than it appears!
+	 */
+	if (READ_ONCE(dev_priv->pm.rps.enabled))
+		return;
+
+	/* Powersaving is controlled by the host when inside a VM */
+	if (intel_vgpu_active(dev_priv))
+		return;
+
+	mutex_lock(&dev_priv->pm.pcu_lock);
+
+	intel_enable_rc6(dev_priv);
+	intel_enable_rps(dev_priv);
+	intel_update_ring_freq(dev_priv);
 
 	dev_priv->pm.rps.enabled = true;
 	mutex_unlock(&dev_priv->pm.pcu_lock);
-- 
1.9.1

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

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

* [PATCH 11/31] drm/i915: Introduce separate status variable for RC6 and Ring frequency setup
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (9 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 10/31] drm/i915: Create generic functions to control RC6, RPS Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 12/31] drm/i915: Define RPS idle, busy, boost function pointers Sagar Arun Kamble
                   ` (19 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

Defined new struct intel_rc6 to hold RC6 specific state and
intel_ring_pstate to hold ring specific state.

Cc: Imre Deak <imre.deak@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c |  2 +-
 drivers/gpu/drm/i915/i915_drv.h | 10 +++++++
 drivers/gpu/drm/i915/intel_pm.c | 58 ++++++++++++++++++++++++++++++-----------
 3 files changed, 54 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a6dbad3..f13a3de 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2486,7 +2486,7 @@ static int intel_runtime_suspend(struct device *kdev)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	int ret;
 
-	if (WARN_ON_ONCE(!(dev_priv->pm.rps.enabled && intel_rc6_enabled())))
+	if (WARN_ON_ONCE(!(dev_priv->pm.rc6.enabled && intel_rc6_enabled())))
 		return -ENODEV;
 
 	if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv)))
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e3264e5..a09952d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1352,8 +1352,18 @@ struct intel_rps {
 	struct intel_rps_ei ei;
 };
 
+struct intel_rc6 {
+	bool enabled;
+};
+
+struct intel_ring_pstate {
+	bool configured;
+};
+
 struct intel_gen6_power_mgmt {
 	struct intel_rps rps;
+	struct intel_rc6 rc6;
+	struct intel_ring_pstate ring_pstate;
 	struct delayed_work autoenable_work;
 
 	/*
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0c46f81..ac20dbf 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7881,8 +7881,12 @@ static void intel_init_emon(struct drm_i915_private *dev_priv)
 
 static inline void intel_update_ring_freq(struct drm_i915_private *i915)
 {
-	if (NEEDS_RING_FREQ_UPDATE(i915))
+	if (NEEDS_RING_FREQ_UPDATE(i915)) {
+		if (READ_ONCE(i915->pm.ring_pstate.configured))
+			return;
 		gen6_update_ring_freq(i915);
+		i915->pm.ring_pstate.configured = true;
+	}
 }
 
 void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
@@ -7975,7 +7979,8 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv)
 
 void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
 {
-	dev_priv->pm.rps.enabled = true; /* force disabling */
+	dev_priv->pm.rps.enabled = true; /* force RPS disabling */
+	dev_priv->pm.rc6.enabled = true; /* force RC6 disabling */
 	intel_disable_gt_powersave(dev_priv);
 
 	gen6_reset_rps_interrupts(dev_priv);
@@ -7983,6 +7988,9 @@ void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
 
 void intel_disable_rc6(struct drm_i915_private *dev_priv)
 {
+	if (!READ_ONCE(dev_priv->pm.rc6.enabled))
+		return;
+
 	if (INTEL_GEN(dev_priv) >= 9)
 		gen9_disable_rc6(dev_priv);
 	else if (IS_CHERRYVIEW(dev_priv))
@@ -7991,10 +7999,15 @@ void intel_disable_rc6(struct drm_i915_private *dev_priv)
 		valleyview_disable_rc6(dev_priv);
 	else if (INTEL_GEN(dev_priv) >= 6)
 		gen6_disable_rc6(dev_priv);
+
+	dev_priv->pm.rc6.enabled = false;
 }
 
 void intel_disable_rps(struct drm_i915_private *dev_priv)
 {
+	if (!READ_ONCE(dev_priv->pm.rps.enabled))
+		return;
+
 	if (INTEL_GEN(dev_priv) >= 9)
 		gen9_disable_rps(dev_priv);
 	else if (IS_CHERRYVIEW(dev_priv))
@@ -8005,24 +8018,30 @@ void intel_disable_rps(struct drm_i915_private *dev_priv)
 		gen6_disable_rps(dev_priv);
 	else if (IS_IRONLAKE_M(dev_priv))
 		ironlake_disable_drps(dev_priv);
+
+	dev_priv->pm.rps.enabled = false;
 }
 
 void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
 {
-	if (!READ_ONCE(dev_priv->pm.rps.enabled))
-		return;
-
 	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	intel_disable_rc6(dev_priv);
 	intel_disable_rps(dev_priv);
+	if (NEEDS_RING_FREQ_UPDATE(dev_priv))
+		dev_priv->pm.ring_pstate.configured = false;
 
-	dev_priv->pm.rps.enabled = false;
 	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
 void intel_enable_rc6(struct drm_i915_private *dev_priv)
 {
+	/* We shouldn't be disabling as we submit, so this should be less
+	 * racy than it appears!
+	 */
+	if (READ_ONCE(dev_priv->pm.rc6.enabled))
+		return;
+
 	if (IS_CHERRYVIEW(dev_priv))
 		cherryview_enable_rc6(dev_priv);
 	else if (IS_VALLEYVIEW(dev_priv))
@@ -8033,10 +8052,18 @@ void intel_enable_rc6(struct drm_i915_private *dev_priv)
 		gen8_enable_rc6(dev_priv);
 	else if (INTEL_GEN(dev_priv) >= 6)
 		gen6_enable_rc6(dev_priv);
+
+	dev_priv->pm.rc6.enabled = true;
 }
 
 void intel_enable_rps(struct drm_i915_private *dev_priv)
 {
+	/* We shouldn't be disabling as we submit, so this should be less
+	 * racy than it appears!
+	 */
+	if (READ_ONCE(dev_priv->pm.rps.enabled))
+		return;
+
 	if (IS_CHERRYVIEW(dev_priv)) {
 		cherryview_enable_rps(dev_priv);
 	} else if (IS_VALLEYVIEW(dev_priv)) {
@@ -8057,16 +8084,12 @@ void intel_enable_rps(struct drm_i915_private *dev_priv)
 
 	WARN_ON(dev_priv->pm.rps.efficient_freq < dev_priv->pm.rps.min_freq);
 	WARN_ON(dev_priv->pm.rps.efficient_freq > dev_priv->pm.rps.max_freq);
+
+	dev_priv->pm.rps.enabled = true;
 }
 
 void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 {
-	/* We shouldn't be disabling as we submit, so this should be less
-	 * racy than it appears!
-	 */
-	if (READ_ONCE(dev_priv->pm.rps.enabled))
-		return;
-
 	/* Powersaving is controlled by the host when inside a VM */
 	if (intel_vgpu_active(dev_priv))
 		return;
@@ -8077,7 +8100,6 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 	intel_enable_rps(dev_priv);
 	intel_update_ring_freq(dev_priv);
 
-	dev_priv->pm.rps.enabled = true;
 	mutex_unlock(&dev_priv->pm.pcu_lock);
 }
 
@@ -8088,7 +8110,10 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work)
 	struct intel_engine_cs *rcs;
 	struct drm_i915_gem_request *req;
 
-	if (READ_ONCE(dev_priv->pm.rps.enabled))
+	if (READ_ONCE(dev_priv->pm.rps.enabled) &&
+	    READ_ONCE(dev_priv->pm.rc6.enabled) &&
+	    !(NEEDS_RING_FREQ_UPDATE(dev_priv) ^
+	      READ_ONCE(dev_priv->pm.ring_pstate.configured)))
 		goto out;
 
 	rcs = dev_priv->engine[RCS];
@@ -8118,7 +8143,10 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work)
 
 void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv)
 {
-	if (READ_ONCE(dev_priv->pm.rps.enabled))
+	if (READ_ONCE(dev_priv->pm.rps.enabled) &&
+	    READ_ONCE(dev_priv->pm.rc6.enabled) &&
+	    !(NEEDS_RING_FREQ_UPDATE(dev_priv) ^
+	      READ_ONCE(dev_priv->pm.ring_pstate.configured)))
 		return;
 
 	if (IS_IRONLAKE_M(dev_priv)) {
-- 
1.9.1

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

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

* [PATCH 12/31] drm/i915: Define RPS idle, busy, boost function pointers
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (10 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 11/31] drm/i915: Introduce separate status variable for RC6 and Ring frequency setup Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 13/31] drm/i915/slpc: Add has_slpc capability flag Sagar Arun Kamble
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx

These will allow to define nop functions when SLPC is in use.
Initialized with gen6_rps_idle, gen6_rps_busy and gen6_rps_boost
during intel_enable_rps.

Cc: Imre Deak <imre.deak@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |  5 +++++
 drivers/gpu/drm/i915/i915_gem.c         |  6 +++---
 drivers/gpu/drm/i915/i915_gem_request.c |  2 +-
 drivers/gpu/drm/i915/intel_display.c    |  2 +-
 drivers/gpu/drm/i915/intel_pm.c         | 24 ++++++++++++++++++++++++
 5 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a09952d..5fcebb8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1350,6 +1350,11 @@ struct intel_rps {
 
 	/* manual wa residency calculations */
 	struct intel_rps_ei ei;
+
+	void (*idle)(struct drm_i915_private *dev_priv);
+	void (*busy)(struct drm_i915_private *dev_priv);
+	void (*boost)(struct drm_i915_gem_request *rq,
+		      struct intel_rps_client *rps);
 };
 
 struct intel_rc6 {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 76e1bb2..efea38a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -388,7 +388,7 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj)
 	 */
 	if (rps) {
 		if (INTEL_GEN(rq->i915) >= 6)
-			gen6_rps_boost(rq, rps);
+			rq->i915->pm.rps.boost(rq, rps);
 		else
 			rps = NULL;
 	}
@@ -2991,7 +2991,7 @@ void i915_gem_reset(struct drm_i915_private *dev_priv)
 		intel_sanitize_gt_powersave(dev_priv);
 		intel_enable_gt_powersave(dev_priv);
 		if (INTEL_GEN(dev_priv) >= 6)
-			gen6_rps_busy(dev_priv);
+			dev_priv->pm.rps.busy(dev_priv);
 	}
 }
 
@@ -3199,7 +3199,7 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
 	rearm_hangcheck = false;
 
 	if (INTEL_GEN(dev_priv) >= 6)
-		gen6_rps_idle(dev_priv);
+		dev_priv->pm.rps.idle(dev_priv);
 	intel_runtime_pm_put(dev_priv);
 out_unlock:
 	mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 023af2d..8ebd660 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -257,7 +257,7 @@ static void mark_busy(struct drm_i915_private *i915)
 	intel_enable_gt_powersave(i915);
 	i915_update_gfx_val(i915);
 	if (INTEL_GEN(i915) >= 6)
-		gen6_rps_busy(i915);
+		i915->pm.rps.busy(i915);
 
 	queue_delayed_work(i915->wq,
 			   &i915->gt.retire_work,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index eb53093..7505e3e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12607,7 +12607,7 @@ static int do_rps_boost(struct wait_queue_entry *_wait,
 	struct wait_rps_boost *wait = container_of(_wait, typeof(*wait), wait);
 	struct drm_i915_gem_request *rq = wait->request;
 
-	gen6_rps_boost(rq, NULL);
+	rq->i915->pm.rps.boost(rq, NULL);
 	i915_gem_request_put(rq);
 
 	drm_crtc_vblank_put(wait->crtc);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ac20dbf..20ec8f4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7889,6 +7889,22 @@ static inline void intel_update_ring_freq(struct drm_i915_private *i915)
 	}
 }
 
+static void rps_idle_nop(struct drm_i915_private *dev_priv)
+{
+	DRM_DEBUG_DRIVER("\n");
+}
+
+static void rps_busy_nop(struct drm_i915_private *dev_priv)
+{
+	DRM_DEBUG_DRIVER("\n");
+}
+
+static void rps_boost_nop(struct drm_i915_gem_request *rq,
+			  struct intel_rps_client *rps)
+{
+	DRM_DEBUG_DRIVER("\n");
+}
+
 void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 {
 	struct intel_rps *rps = &dev_priv->pm.rps;
@@ -7943,6 +7959,10 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 	/* Finally allow us to boost to max by default */
 	rps->boost_freq = rps->max_freq;
 
+	dev_priv->pm.rps.idle = rps_idle_nop;
+	dev_priv->pm.rps.busy = rps_busy_nop;
+	dev_priv->pm.rps.boost = rps_boost_nop;
+
 	mutex_unlock(&dev_priv->pm.pcu_lock);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
@@ -8064,6 +8084,10 @@ void intel_enable_rps(struct drm_i915_private *dev_priv)
 	if (READ_ONCE(dev_priv->pm.rps.enabled))
 		return;
 
+	dev_priv->pm.rps.idle = gen6_rps_idle;
+	dev_priv->pm.rps.busy = gen6_rps_busy;
+	dev_priv->pm.rps.boost = gen6_rps_boost;
+
 	if (IS_CHERRYVIEW(dev_priv)) {
 		cherryview_enable_rps(dev_priv);
 	} else if (IS_VALLEYVIEW(dev_priv)) {
-- 
1.9.1

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

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

* [PATCH 13/31] drm/i915/slpc: Add has_slpc capability flag
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (11 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 12/31] drm/i915: Define RPS idle, busy, boost function pointers Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 14/31] drm/i915/slpc: Add enable_slpc module parameter Sagar Arun Kamble
                   ` (17 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

From: Tom O'Rourke <Tom.O'Rourke@intel.com>

Add has_slpc capablity flag to indicate GuC firmware
supports single loop power control (SLPC).  SLPC is
a replacement for some host-based power management
features.

v1: fix whitespace (Sagar)

Reviewed-by: David Weinehall <david.weinehall@linux.intel.com>
Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5fcebb8..428cb1c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -791,6 +791,7 @@ struct intel_csr {
 	func(has_rc6p); \
 	func(has_resource_streamer); \
 	func(has_runtime_pm); \
+	func(has_slpc); \
 	func(has_snoop); \
 	func(unfenced_needs_alignment); \
 	func(cursor_needs_physical); \
@@ -3162,6 +3163,7 @@ static inline unsigned int i915_sg_segment_size(void)
 #define HAS_GUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
 #define HAS_GUC_SCHED(dev_priv)	(HAS_GUC(dev_priv))
 #define HAS_HUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
+#define HAS_SLPC(dev_priv)	((dev_priv)->info.has_slpc)
 
 #define HAS_RESOURCE_STREAMER(dev_priv) ((dev_priv)->info.has_resource_streamer)
 
-- 
1.9.1

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

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

* [PATCH 14/31] drm/i915/slpc: Add enable_slpc module parameter
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (12 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 13/31] drm/i915/slpc: Add has_slpc capability flag Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 15/31] drm/i915/slpc: Sanitize GuC version Sagar Arun Kamble
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

From: Tom O'Rourke <Tom.O'Rourke@intel.com>

i915.enable_slpc is used to override the default for slpc usage.
The expected values are -1=auto, 0=disabled [default], 1=enabled.

Sanitize i915.enable_slpc to either 0 or 1 based on HAS_SLPC() and
GuC load and submission options.

v1: Add early call to sanitize enable_slpc in intel_guc_ucode_init
    Remove sanitize enable_slpc call before firmware version check
    is performed. (ChrisW)
    Version check is added in next patch and that will be done as
    part of slpc_enable_sanitize function in the next patch. (Sagar)
    Updated slpc option sanitize function call for platforms without
    GuC support. This was caught by CI BAT.

v2: Changed parameter to dev_priv for HAS_SLPC macro. (David)
    Code indentation based on checkpatch.

v3: Rebase.

v4: Moved sanitization of SLPC option post GuC load.

v5: Removed function intel_slpc_enabled. Planning to rely only on
    kernel parameter. Moved sanitization prior to GuC load to use the
    parameter during SLPC state setup during to GuC load. (Sagar)

v6: Commit message update. Rebase.

v7: Moved SLPC option sanitization to intel_uc_sanitize_options.

v8: Clearing SLPC option on GuC load failure. Change moved from later
patch. (Sagar)

Suggested-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_params.c |  5 +++++
 drivers/gpu/drm/i915/i915_params.h |  1 +
 drivers/gpu/drm/i915/intel_uc.c    | 15 +++++++++++++++
 3 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index d32d761..a14db53 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -43,6 +43,7 @@ struct i915_params i915 __read_mostly = {
 	.enable_dc = -1,
 	.enable_fbc = -1,
 	.enable_execlists = -1,
+	.enable_slpc = 0,
 	.enable_hangcheck = true,
 	.enable_ppgtt = -1,
 	.enable_psr = -1,
@@ -139,6 +140,10 @@ struct i915_params i915 __read_mostly = {
 	"Override execlists usage. "
 	"(-1=auto [default], 0=disabled, 1=enabled)");
 
+i915_param_named_unsafe(enable_slpc, int, 0400,
+	"Override single-loop-power-controller (slpc) usage. "
+	"(-1=auto, 0=disabled [default], 1=enabled)");
+
 i915_param_named_unsafe(enable_psr, int, 0600,
 	"Enable PSR "
 	"(0=disabled, 1=enabled - link mode chosen per-platform, 2=force link-standby mode, 3=force link-off mode) "
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index ac84470..d5c7bfb 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -41,6 +41,7 @@
 	func(int, enable_ppgtt); \
 	func(int, enable_execlists); \
 	func(int, enable_psr); \
+	func(int, enable_slpc); \
 	func(int, disable_power_well); \
 	func(int, enable_ips); \
 	func(int, invert_brightness); \
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index bb31243..eeec986 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -69,6 +69,7 @@ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv)
 
 		i915.enable_guc_loading = 0;
 		i915.enable_guc_submission = 0;
+		i915.enable_slpc = 0;
 		return;
 	}
 
@@ -92,6 +93,18 @@ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv)
 	/* A negative value means "use platform default" */
 	if (i915.enable_guc_submission < 0)
 		i915.enable_guc_submission = HAS_GUC_SCHED(dev_priv);
+
+	/* slpc requires hardware support and compatible firmware */
+	if (!HAS_SLPC(dev_priv))
+		i915.enable_slpc = 0;
+
+	/* slpc requires guc loaded */
+	if (!i915.enable_guc_loading)
+		i915.enable_slpc = 0;
+
+	/* slpc requires guc submission */
+	if (!i915.enable_guc_submission)
+		i915.enable_slpc = 0;
 }
 
 void intel_uc_init_early(struct drm_i915_private *dev_priv)
@@ -400,6 +413,8 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
 	i915.enable_guc_loading = 0;
 	DRM_NOTE("GuC firmware loading disabled\n");
 
+	i915.enable_slpc = 0;
+
 	return ret;
 }
 
-- 
1.9.1

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

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

* [PATCH 15/31] drm/i915/slpc: Sanitize GuC version
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (13 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 14/31] drm/i915/slpc: Add enable_slpc module parameter Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-21 12:52   ` Michal Wajdeczko
  2017-09-19 17:41 ` [PATCH 16/31] drm/i915/slpc: Lay out SLPC init/enable/disable/cleanup helpers Sagar Arun Kamble
                   ` (15 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

From: Tom O'Rourke <Tom.O'Rourke@intel.com>

The SLPC interface is dependent on GuC version.
Only GuC versions known to be compatible are supported here.

SLPC with GuC firmware v9 is supported with this series.

v1: Updated with modified sanitize_slpc_option in earlier patch.

v2-v3: Rebase.

v4: Updated support for GuC firmware v9.

v5: Commit subject updated.

v6: Commit subject and message update. Add support condition as >=v9.

v7: Sanitizing GuC version in intel_uc_init_fw for SLPC compatibility.
    Added info. print for needed version and pointer to 01.org.

v8: s/FIRMWARE_URL/I915_FIRMWARE_URL, Macro added for SLPC required GuC
    Major version and rearrangement for sanitization. (MichalW, Joonas)

v9: Checking major_ver_found to sanitize SLPC option enable_slpc post
    fetching the firmware as with Custom firmware loaded through
    guc_firmware_path parameter, major_ver_wanted are cleared. (Lukasz)

v10: Moved the I915_FIRMWARE_URL macro to intel_uc_common.h.

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/intel_csr.c        | 15 ++++++---------
 drivers/gpu/drm/i915/intel_guc.h        |  1 +
 drivers/gpu/drm/i915/intel_guc_loader.c | 15 +++++++++++++++
 drivers/gpu/drm/i915/intel_uc.c         |  1 +
 drivers/gpu/drm/i915/intel_uc_common.h  |  2 ++
 5 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c
index 965988f..56c56f5 100644
--- a/drivers/gpu/drm/i915/intel_csr.c
+++ b/drivers/gpu/drm/i915/intel_csr.c
@@ -52,11 +52,6 @@
 MODULE_FIRMWARE(I915_CSR_BXT);
 #define BXT_CSR_VERSION_REQUIRED	CSR_VERSION(1, 7)
 
-#define FIRMWARE_URL  "https://01.org/linuxgraphics/downloads/firmware"
-
-
-
-
 #define CSR_MAX_FW_SIZE			0x2FFF
 #define CSR_DEFAULT_FW_OFFSET		0xFFFFFFFF
 
@@ -309,11 +304,12 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
 
 	if (csr->version != required_version) {
 		DRM_INFO("Refusing to load DMC firmware v%u.%u,"
-			 " please use v%u.%u [" FIRMWARE_URL "].\n",
+			 " please use v%u.%u [%s].\n",
 			 CSR_VERSION_MAJOR(csr->version),
 			 CSR_VERSION_MINOR(csr->version),
 			 CSR_VERSION_MAJOR(required_version),
-			 CSR_VERSION_MINOR(required_version));
+			 CSR_VERSION_MINOR(required_version),
+			 I915_FIRMWARE_URL);
 		return NULL;
 	}
 
@@ -420,8 +416,9 @@ static void csr_load_work_fn(struct work_struct *work)
 	} else {
 		dev_notice(dev_priv->drm.dev,
 			   "Failed to load DMC firmware"
-			   " [" FIRMWARE_URL "],"
-			   " disabling runtime power management.\n");
+			   " [%s],"
+			   " disabling runtime power management.\n",
+			   I915_FIRMWARE_URL);
 	}
 
 	release_firmware(fw);
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index a894991..3821bf2 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -159,6 +159,7 @@ static inline void intel_guc_init_early(struct intel_guc *guc)
 int intel_guc_select_fw(struct intel_guc *guc);
 int intel_guc_init_hw(struct intel_guc *guc);
 u32 intel_guc_wopcm_size(struct intel_guc *guc);
+void intel_guc_fetch_sanitize_options(struct intel_guc *guc);
 
 /* i915_guc_submission.c */
 int i915_guc_submission_init(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 6ee7c16..4550620 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -64,6 +64,8 @@
 #define GLK_FW_MAJOR 10
 #define GLK_FW_MINOR 56
 
+#define I915_SLPC_REQUIRED_GUC_MAJOR 9
+
 #define GUC_FW_PATH(platform, major, minor) \
        "i915/" __stringify(platform) "_guc_ver" __stringify(major) "_" __stringify(minor) ".bin"
 
@@ -418,3 +420,16 @@ int intel_guc_select_fw(struct intel_guc *guc)
 
 	return 0;
 }
+
+void intel_guc_fetch_sanitize_options(struct intel_guc *guc)
+{
+	if (guc->fw.major_ver_found <
+			I915_SLPC_REQUIRED_GUC_MAJOR) {
+		DRM_INFO("SLPC not supported with GuC firmware"
+			 " v%u, please use v%u+ [%s].\n",
+			 guc->fw.major_ver_found,
+			 I915_SLPC_REQUIRED_GUC_MAJOR,
+			 I915_FIRMWARE_URL);
+		i915.enable_slpc = 0;
+	}
+}
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index eeec986..350027f 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -194,6 +194,7 @@ static void fetch_uc_fw(struct drm_i915_private *dev_priv,
 		}
 		uc_fw->major_ver_found = css->guc.sw_version >> 16;
 		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
+		intel_guc_fetch_sanitize_options(&dev_priv->guc);
 		break;
 
 	case INTEL_UC_FW_TYPE_HUC:
diff --git a/drivers/gpu/drm/i915/intel_uc_common.h b/drivers/gpu/drm/i915/intel_uc_common.h
index 3de6823..4726511 100644
--- a/drivers/gpu/drm/i915/intel_uc_common.h
+++ b/drivers/gpu/drm/i915/intel_uc_common.h
@@ -27,6 +27,8 @@
 #include "intel_ringbuffer.h"
 #include "i915_vma.h"
 
+#define I915_FIRMWARE_URL  "https://01.org/linuxgraphics/intel-linux-graphics-firmwares"
+
 enum intel_uc_fw_status {
 	INTEL_UC_FIRMWARE_FAIL = -1,
 	INTEL_UC_FIRMWARE_NONE = 0,
-- 
1.9.1

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

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

* [PATCH 16/31] drm/i915/slpc: Lay out SLPC init/enable/disable/cleanup helpers
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (14 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 15/31] drm/i915/slpc: Sanitize GuC version Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-21 13:00   ` Michal Wajdeczko
  2017-09-19 17:41 ` [PATCH 17/31] drm/i915/slpc: Enable SLPC in GuC if supported Sagar Arun Kamble
                   ` (14 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

SLPC operates based on parameters setup in shared data between
i915 and GuC SLPC. This is to be created/initialized in intel_slpc_init.
From there onwards i915 can control the SLPC operations by Enabling,
Disabling complete SLPC or changing SLPC parameters. During cleanup
SLPC shared data has to be freed.
With this patch on platforms with SLPC support we call intel_slpc_*()
functions from GuC setup functions and do not use Host rps functions.
With SLPC, intel_enable_gt_powersave will only handle RC6. In the later
patch intel_init_gt_powersave will check if SLPC has started running
through shared data and update initial state that i915 needs like
frequency limits if needed.

v1: Return void instead of ignored error code (Paulo)
    enable/disable RC6 in SLPC flows (Sagar)
    replace HAS_SLPC() use with intel_slpc_enabled()
	or intel_slpc_active() (Paulo)
    Fix for renaming gen9_disable_rps to gen9_disable_rc6 in
    "drm/i915/bxt: Explicitly clear the Turbo control register"
    Defer RC6 and SLPC enabling to intel_gen6_powersave_work. (Sagar)
    Performance drop with SLPC was happening as ring frequency table
    was not programmed when SLPC was enabled. This patch programs ring
    frequency table with SLPC. Initial reset of SLPC is based on kernel
    parameter as planning to add slpc state in intel_slpc_active. Cleanup
    is also based on kernel parameter as SLPC gets disabled in
    disable/suspend.(Sagar)

v2: Usage of INTEL_GEN instead of INTEL_INFO->gen (David)
    Checkpatch update.

v3: Rebase

v4: Removed reset functions to comply with *_gt_powersave routines.
    (Sagar)

v5: Removed intel_slpc_active. Relying on slpc.active for control flows
    that are based on SLPC active status in GuC. State setup/cleanup needed
    for SLPC is handled using kernel parameter i915.enable_slpc. Moved SLPC
    init and enabling to GuC enable path as SLPC in GuC can start doing the
    setup post GuC init. Commit message update. (Sagar)

v6: Rearranged function definitions.

v7: Makefile rearrangement. Reducing usage of i915.enable_slpc and relying
    mostly on rps.rps_enabled to bypass Host RPS flows. Commit message
    update.

v8: Changed parameters for SLPC functions to struct intel_slpc*.

v9: Reinstated intel_slpc_active and intel_slpc_enabled as they are more
    meaningful.

v10: Rebase changes due to creation of intel_guc.h. Updates in
     intel_guc_cleanup w.r.t slpc cleanup.

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/Makefile     |  1 +
 drivers/gpu/drm/i915/i915_drv.h   | 12 ++++++++++
 drivers/gpu/drm/i915/intel_guc.c  |  3 +++
 drivers/gpu/drm/i915/intel_guc.h  |  3 +++
 drivers/gpu/drm/i915/intel_pm.c   | 19 +++++++++++-----
 drivers/gpu/drm/i915/intel_slpc.c | 42 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h | 47 +++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_uc.c   | 20 +++++++++++++++++
 8 files changed, 142 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_slpc.c
 create mode 100644 drivers/gpu/drm/i915/intel_slpc.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index d1327f6..62bf4f6e 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -64,6 +64,7 @@ i915-y += intel_uc.o \
 	  intel_guc_log.o \
 	  intel_guc_loader.o \
 	  intel_huc.o \
+	  intel_slpc.o \
 	  i915_guc_submission.o
 
 # autogenerated null render state
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 428cb1c..af633c6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2748,6 +2748,18 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc)
 	return container_of(guc, struct drm_i915_private, guc);
 }
 
+static inline struct intel_guc *slpc_to_guc(struct intel_slpc *slpc)
+{
+	return container_of(slpc, struct intel_guc, slpc);
+}
+
+static inline struct drm_i915_private *slpc_to_i915(struct intel_slpc *slpc)
+{
+	struct intel_guc *guc = slpc_to_guc(slpc);
+
+	return guc_to_i915(guc);
+}
+
 static inline struct drm_i915_private *huc_to_i915(struct intel_huc *huc)
 {
 	return container_of(huc, struct drm_i915_private, huc);
diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
index f4dc708..a92c7e8 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -226,6 +226,9 @@ void intel_guc_cleanup(struct intel_guc *guc)
 
 	if (i915.enable_guc_submission)
 		i915_guc_submission_cleanup(dev_priv);
+
+	if (intel_slpc_enabled())
+		intel_slpc_cleanup(&guc->slpc);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 3821bf2..b835d30 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -28,6 +28,7 @@
 #include "intel_guc_fwif.h"
 #include "i915_guc_reg.h"
 #include "intel_guc_ct.h"
+#include "intel_slpc.h"
 
 /*
  * This structure primarily describes the GEM object shared with the GuC.
@@ -115,6 +116,8 @@ struct intel_guc {
 		enum forcewake_domains fw_domains;
 	} send_regs;
 
+	struct intel_slpc slpc;
+
 	/* To serialize the intel_guc_send actions */
 	struct mutex send_mutex;
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 20ec8f4..e5607e5 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7995,6 +7995,12 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv)
 		intel_runtime_pm_put(dev_priv);
 
 	/* gen6_rps_idle() will be called later to disable interrupts */
+
+	if (intel_slpc_active(&dev_priv->guc.slpc)) {
+		intel_runtime_pm_get(dev_priv);
+		intel_slpc_disable(&dev_priv->guc.slpc);
+		intel_runtime_pm_put(dev_priv);
+	}
 }
 
 void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
@@ -8121,7 +8127,8 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 	mutex_lock(&dev_priv->pm.pcu_lock);
 
 	intel_enable_rc6(dev_priv);
-	intel_enable_rps(dev_priv);
+	if (!intel_slpc_active(&dev_priv->guc.slpc))
+		intel_enable_rps(dev_priv);
 	intel_update_ring_freq(dev_priv);
 
 	mutex_unlock(&dev_priv->pm.pcu_lock);
@@ -8134,8 +8141,9 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work)
 	struct intel_engine_cs *rcs;
 	struct drm_i915_gem_request *req;
 
-	if (READ_ONCE(dev_priv->pm.rps.enabled) &&
-	    READ_ONCE(dev_priv->pm.rc6.enabled) &&
+	if (READ_ONCE(dev_priv->pm.rc6.enabled) &&
+	    !(!(intel_slpc_active(&dev_priv->guc.slpc)) ^
+	      READ_ONCE(dev_priv->pm.rps.enabled)) &&
 	    !(NEEDS_RING_FREQ_UPDATE(dev_priv) ^
 	      READ_ONCE(dev_priv->pm.ring_pstate.configured)))
 		goto out;
@@ -8167,8 +8175,9 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work)
 
 void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv)
 {
-	if (READ_ONCE(dev_priv->pm.rps.enabled) &&
-	    READ_ONCE(dev_priv->pm.rc6.enabled) &&
+	if (READ_ONCE(dev_priv->pm.rc6.enabled) &&
+	    !(!(intel_slpc_active(&dev_priv->guc.slpc)) ^
+	      READ_ONCE(dev_priv->pm.rps.enabled)) &&
 	    !(NEEDS_RING_FREQ_UPDATE(dev_priv) ^
 	      READ_ONCE(dev_priv->pm.ring_pstate.configured)))
 		return;
diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
new file mode 100644
index 0000000..06abda5
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+#include <linux/firmware.h>
+#include "i915_drv.h"
+#include "intel_uc.h"
+
+void intel_slpc_init(struct intel_slpc *slpc)
+{
+}
+
+void intel_slpc_cleanup(struct intel_slpc *slpc)
+{
+}
+
+void intel_slpc_enable(struct intel_slpc *slpc)
+{
+}
+
+void intel_slpc_disable(struct intel_slpc *slpc)
+{
+}
diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h
new file mode 100644
index 0000000..f68671f
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+#ifndef _INTEL_SLPC_H_
+#define _INTEL_SLPC_H_
+
+struct intel_slpc {
+	bool active;
+};
+
+static inline int intel_slpc_enabled(void)
+{
+	return i915.enable_slpc;
+}
+
+static inline bool intel_slpc_active(struct intel_slpc *slpc)
+{
+	return slpc->active;
+}
+
+/* intel_slpc.c */
+void intel_slpc_init(struct intel_slpc *slpc);
+void intel_slpc_cleanup(struct intel_slpc *slpc);
+void intel_slpc_enable(struct intel_slpc *slpc);
+void intel_slpc_disable(struct intel_slpc *slpc);
+
+#endif
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index 350027f..990d84a 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -328,6 +328,9 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
 		ret = i915_guc_submission_init(dev_priv);
 		if (ret)
 			goto err_guc;
+
+		if (intel_slpc_enabled())
+			intel_slpc_init(&dev_priv->guc.slpc);
 	}
 
 	/* init WOPCM */
@@ -369,6 +372,17 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
 		goto err_log_capture;
 
 	intel_huc_auth(&dev_priv->huc);
+
+	/*
+	 * SLPC is enabled by setting up the shared data structure and
+	 * sending reset event to GuC SLPC. Initial data is setup in
+	 * intel_slpc_init. Here we send the reset event. SLPC enabling
+	 * in GuC can happen in parallel in GuC with other initialization
+	 * being done in i915.
+	 */
+	if (intel_slpc_enabled())
+		intel_slpc_enable(&dev_priv->guc.slpc);
+
 	if (i915.enable_guc_submission) {
 		if (i915.guc_log_level >= 0)
 			gen9_enable_guc_interrupts(dev_priv);
@@ -398,6 +412,12 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
 	if (i915.enable_guc_submission)
 		i915_guc_submission_cleanup(dev_priv);
 err_guc:
+	if (intel_slpc_enabled()) {
+		if (intel_slpc_active(&dev_priv->guc.slpc))
+			intel_slpc_disable(&dev_priv->guc.slpc);
+		intel_slpc_cleanup(&dev_priv->guc.slpc);
+	}
+
 	i915_ggtt_disable_guc(dev_priv);
 
 	DRM_ERROR("GuC init failed\n");
-- 
1.9.1

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

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

* [PATCH 17/31] drm/i915/slpc: Enable SLPC in GuC if supported
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (15 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 16/31] drm/i915/slpc: Lay out SLPC init/enable/disable/cleanup helpers Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 18/31] drm/i915/slpc: Add SLPC communication interfaces Sagar Arun Kamble
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

From: Tom O'Rourke <Tom.O'Rourke@intel.com>

If slpc enabled, then add enable SLPC flag to guc
control parameter during guc load.

v1: Use intel_slpc_enabled() (Paulo)

v2-v4: Rebase.

v5: Changed intel_slpc_enabled() to i915.enable_slpc. (Sagar)

v6: Changed i915.enable_slpc to intel_slpc_enabled(). (Sagar)

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_loader.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 4550620..0a71d04 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -131,6 +131,9 @@ static void guc_params_init(struct drm_i915_private *dev_priv)
 	params[GUC_CTL_FEATURE] |= GUC_CTL_DISABLE_SCHEDULER |
 			GUC_CTL_VCS2_ENABLED;
 
+	if (intel_slpc_enabled())
+		params[GUC_CTL_FEATURE] |= GUC_CTL_ENABLE_SLPC;
+
 	params[GUC_CTL_LOG_PARAMS] = guc->log.flags;
 
 	if (i915.guc_log_level >= 0) {
-- 
1.9.1

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

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

* [PATCH 18/31] drm/i915/slpc: Add SLPC communication interfaces
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (16 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 17/31] drm/i915/slpc: Enable SLPC in GuC if supported Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-21 13:14   ` Michal Wajdeczko
  2017-09-19 17:41 ` [PATCH 19/31] drm/i915/slpc: Allocate/Release/Initialize SLPC shared data Sagar Arun Kamble
                   ` (12 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

Communication with SLPC is via Host to GuC interrupt through
shared data and parameters. This patch defines the structure of
shared data, parameters, data structure to be passed as input and
received as output from SLPC. This patch also defines the events
to be sent as input and status values output by GuC on processing
SLPC events. SLPC shared data has details of SKU type, Slice count,
IA Perf MSR values, SLPC state, Power source/plan, SLPC tasks status.
Parameters allow overriding task control, frequency range etc.

v1: fix whitespace (Sagar)

v2-v3: Rebase.

v4: Updated with GuC firmware v9.

v5: Added definition of input and output data structures for SLPC
events. Updated commit message.

v6: Removed definition of host2guc_slpc. Will be added in the next
patch that uses it. Commit subject update. Rebase.

v7: Added definition of SLPC_RESET_FLAG_TDR_OCCURRED to be sent
throgh SLPC reset in case of engine reset. Moved all Host/SLPC
interfaces from later patches to this patch. Commit message update.

v8: Updated value of SLPC_RESET_FLAG_TDR_OCCURRED.

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/intel_slpc.c |  39 +++++++
 drivers/gpu/drm/i915/intel_slpc.h | 207 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 246 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index 06abda5..a3db63c 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -25,6 +25,45 @@
 #include "i915_drv.h"
 #include "intel_uc.h"
 
+struct slpc_param slpc_paramlist[SLPC_MAX_PARAM] = {
+	{SLPC_PARAM_TASK_ENABLE_GTPERF, "Enable task GTPERF"},
+	{SLPC_PARAM_TASK_DISABLE_GTPERF, "Disable task GTPERF"},
+	{SLPC_PARAM_TASK_ENABLE_BALANCER, "Enable task BALANCER"},
+	{SLPC_PARAM_TASK_DISABLE_BALANCER, "Disable task BALANCER"},
+	{SLPC_PARAM_TASK_ENABLE_DCC, "Enable task DCC"},
+	{SLPC_PARAM_TASK_DISABLE_DCC, "Disable task DCC"},
+	{SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
+				"Minimum GT frequency request for unslice"},
+	{SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ,
+				"Maximum GT frequency request for unslice"},
+	{SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ,
+				"Minimum GT frequency request for slice"},
+	{SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ,
+				"Maximum GT frequency request for slice"},
+	{SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS,
+				"If non-zero, algorithm will slow down "
+				"frame-based applications to this frame-rate"},
+	{SLPC_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT,
+				"Lock GT frequency request to RPe"},
+	{SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING,
+				"Set to TRUE to enable slowing framerate"},
+	{SLPC_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE,
+				"Prevent from changing the RC mode"},
+	{SLPC_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ,
+				"Override fused value of unslice RP0"},
+	{SLPC_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ,
+				"Override fused value of slice RP0"},
+	{SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING,
+				"TRUE means enable Intelligent Bias Control"},
+	{SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO,
+				"TRUE = enable eval mode when transitioning "
+				"from idle to active."},
+	{SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE,
+				"FALSE = disable eval mode completely"},
+	{SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE,
+				"Enable IBC when non-Gaming Mode is enabled"}
+};
+
 void intel_slpc_init(struct intel_slpc *slpc)
 {
 }
diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h
index f68671f..ac4cb65 100644
--- a/drivers/gpu/drm/i915/intel_slpc.h
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -38,6 +38,213 @@ static inline bool intel_slpc_active(struct intel_slpc *slpc)
 	return slpc->active;
 }
 
+enum slpc_status {
+	SLPC_STATUS_OK = 0,
+	SLPC_STATUS_ERROR = 1,
+	SLPC_STATUS_ILLEGAL_COMMAND = 2,
+	SLPC_STATUS_INVALID_ARGS = 3,
+	SLPC_STATUS_INVALID_PARAMS = 4,
+	SLPC_STATUS_INVALID_DATA = 5,
+	SLPC_STATUS_OUT_OF_RANGE = 6,
+	SLPC_STATUS_NOT_SUPPORTED = 7,
+	SLPC_STATUS_NOT_IMPLEMENTED = 8,
+	SLPC_STATUS_NO_DATA = 9,
+	SLPC_STATUS_EVENT_NOT_REGISTERED = 10,
+	SLPC_STATUS_REGISTER_LOCKED = 11,
+	SLPC_STATUS_TEMPORARILY_UNAVAILABLE = 12,
+	SLPC_STATUS_VALUE_ALREADY_SET = 13,
+	SLPC_STATUS_VALUE_ALREADY_UNSET = 14,
+	SLPC_STATUS_VALUE_NOT_CHANGED = 15,
+	SLPC_STATUS_MEMIO_ERROR = 16,
+	SLPC_STATUS_EVENT_QUEUED_REQ_DPC = 17,
+	SLPC_STATUS_EVENT_QUEUED_NOREQ_DPC = 18,
+	SLPC_STATUS_NO_EVENT_QUEUED = 19,
+	SLPC_STATUS_OUT_OF_SPACE = 20,
+	SLPC_STATUS_TIMEOUT = 21,
+	SLPC_STATUS_NO_LOCK = 22,
+};
+
+enum slpc_event_id {
+	SLPC_EVENT_RESET = 0,
+	SLPC_EVENT_SHUTDOWN = 1,
+	SLPC_EVENT_PLATFORM_INFO_CHANGE = 2,
+	SLPC_EVENT_DISPLAY_MODE_CHANGE = 3,
+	SLPC_EVENT_FLIP_COMPLETE = 4,
+	SLPC_EVENT_QUERY_TASK_STATE = 5,
+	SLPC_EVENT_PARAMETER_SET = 6,
+	SLPC_EVENT_PARAMETER_UNSET = 7,
+};
+
+enum slpc_param_id {
+	SLPC_PARAM_TASK_ENABLE_GTPERF = 0,
+	SLPC_PARAM_TASK_DISABLE_GTPERF = 1,
+	SLPC_PARAM_TASK_ENABLE_BALANCER = 2,
+	SLPC_PARAM_TASK_DISABLE_BALANCER = 3,
+	SLPC_PARAM_TASK_ENABLE_DCC = 4,
+	SLPC_PARAM_TASK_DISABLE_DCC = 5,
+	SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ = 6,
+	SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ = 7,
+	SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ = 8,
+	SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ = 9,
+	SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS = 10,
+	SLPC_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT = 11,
+	SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING = 12,
+	SLPC_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE = 13,
+	SLPC_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ = 14,
+	SLPC_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ = 15,
+	SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING = 16,
+	SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO = 17,
+	SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE = 18,
+	SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE = 19,
+	SLPC_MAX_PARAM,
+	SLPC_KMD_MAX_PARAM = 32,
+};
+
+enum slpc_platform_sku {
+	SLPC_PLATFORM_SKU_UNDEFINED = 0,
+	SLPC_PLATFORM_SKU_ULX = 1,
+	SLPC_PLATFORM_SKU_ULT = 2,
+	SLPC_PLATFORM_SKU_T = 3,
+	SLPC_PLATFORM_SKU_MOBL = 4,
+	SLPC_PLATFORM_SKU_DT = 5,
+	SLPC_PLATFORM_SKU_UNKNOWN = 6,
+};
+
+enum slpc_power_source {
+	SLPC_POWER_SOURCE_UNDEFINED = 0,
+	SLPC_POWER_SOURCE_AC = 1,
+	SLPC_POWER_SOURCE_DC = 2,
+	SLPC_POWER_SOURCE_UNKNOWN = 3,
+};
+
+enum slpc_power_plan {
+	SLPC_POWER_PLAN_UNDEFINED = 0,
+	SLPC_POWER_PLAN_BATTERY_SAVER = 1,
+	SLPC_POWER_PLAN_BALANCED = 2,
+	SLPC_POWER_PLAN_PERFORMANCE = 3,
+	SLPC_POWER_PLAN_UNKNOWN = 4,
+};
+
+struct slpc_platform_info {
+	u8 platform_sku;
+	u8 slice_count;
+	u8 reserved;
+	u8 power_plan_source;
+	u8 P0_freq;
+	u8 P1_freq;
+	u8 Pe_freq;
+	u8 Pn_freq;
+	u32 reserved1;
+	u32 reserved2;
+} __packed;
+
+enum slpc_global_state {
+	SLPC_GLOBAL_STATE_NOT_RUNNING = 0,
+	SLPC_GLOBAL_STATE_INITIALIZING = 1,
+	SLPC_GLOBAL_STATE_RESETTING = 2,
+	SLPC_GLOBAL_STATE_RUNNING = 3,
+	SLPC_GLOBAL_STATE_SHUTTING_DOWN = 4,
+	SLPC_GLOBAL_STATE_ERROR = 5
+};
+
+struct slpc_task_state_data {
+	union {
+		u32 bitfield1;
+		struct {
+			u32 gtperf_task_active:1;
+			u32 gtperf_stall_possible:1;
+			u32 gtperf_gaming_mode:1;
+			u32 gtperf_target_fps:8;
+			u32 dcc_task_active:1;
+			u32 in_dcc:1;
+			u32 in_dct:1;
+			u32 freq_switch_active:1;
+			u32 ibc_enabled:1;
+			u32 ibc_active:1;
+			u32 pg1_enabled:1;
+			u32 pg1_active:1;
+			u32 reserved:13;
+		};
+	};
+	union {
+		u32 bitfield2;
+		struct {
+			u32 max_unslice_freq:8;
+			u32 min_unslice_freq:8;
+			u32 max_slice_freq:8;
+			u32 min_slice_freq:8;
+		};
+	};
+} __packed;
+
+#define SLPC_MAX_OVERRIDE_PARAMETERS 192
+#define SLPC_OVERRIDE_BITFIELD_SIZE ((SLPC_MAX_OVERRIDE_PARAMETERS + 31) / 32)
+
+struct slpc_shared_data {
+	u32 reserved;
+	u32 shared_data_size;
+	u32 global_state;
+	struct slpc_platform_info platform_info;
+	struct slpc_task_state_data task_state_data;
+	u32 override_parameters_set_bits[SLPC_OVERRIDE_BITFIELD_SIZE];
+	u32 override_parameters_values[SLPC_MAX_OVERRIDE_PARAMETERS];
+} __packed;
+
+enum slpc_reset_flags {
+	SLPC_RESET_FLAG_TDR_OCCURRED = (1 << 0)
+};
+
+#define SLPC_EVENT_MAX_INPUT_ARGS  7
+#define SLPC_EVENT_MAX_OUTPUT_ARGS 1
+
+union slpc_event_input_header {
+	u32 value;
+	struct {
+		u32 num_args:8;
+		u32 event_id:8;
+	};
+};
+
+struct slpc_event_input {
+	u32 h2g_action_id;
+	union slpc_event_input_header header;
+	u32 args[SLPC_EVENT_MAX_INPUT_ARGS];
+} __packed;
+
+union slpc_event_output_header {
+	u32 value;
+	struct {
+		u32 num_args:8;
+		u32 event_id:8;
+		u32 status:16;
+	};
+};
+
+struct slpc_event_output {
+	u32 reserved;
+	union slpc_event_output_header header;
+	u32 args[SLPC_EVENT_MAX_OUTPUT_ARGS];
+} __packed;
+
+#define SLPC_EVENT(id, argc)	((u32) (id) << 8 | (argc))
+#define SLPC_POWER_PLAN_SOURCE(plan, source) ((plan) | ((source) << 6))
+#define SLPC_POWER_PLAN(plan_source) ((plan_source) & 0x3F)
+#define SLPC_POWER_SOURCE(plan_source) ((plan_source) >> 6)
+
+/* Structures for exposing parameter details to user. */
+#define MAX_PARAM_DESCRIPTION_SIZE	160
+struct slpc_param {
+	enum slpc_param_id id;
+	char description[MAX_PARAM_DESCRIPTION_SIZE];
+};
+
+extern struct slpc_param slpc_paramlist[];
+
+#define SLPC_PARAM_TASK_DEFAULT  0
+#define SLPC_PARAM_TASK_ENABLED  1
+#define SLPC_PARAM_TASK_DISABLED 2
+#define SLPC_PARAM_TASK_UNKNOWN  3
+
 /* intel_slpc.c */
 void intel_slpc_init(struct intel_slpc *slpc);
 void intel_slpc_cleanup(struct intel_slpc *slpc);
-- 
1.9.1

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

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

* [PATCH 19/31] drm/i915/slpc: Allocate/Release/Initialize SLPC shared data
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (17 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 18/31] drm/i915/slpc: Add SLPC communication interfaces Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 20/31] drm/i915/slpc: Add parameter set/unset/get, task control/status functions Sagar Arun Kamble
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

Populate SLPC shared data with required default values for
Slice count, Power source/plan, IA Perf MSRs.

v1: Update for SLPC interface version 2015.2.4
    intel_slpc_active() returns 1 if slpc initialized (Paulo)
    change default host_os to "Windows"
    Spelling fixes (Sagar Kamble and Nick Hoath)
    Added WARN for checking if upper 32bits of GTT offset
    of shared object are zero. (ChrisW)
    Changed function call from gem_allocate/release_guc_obj to
    i915_guc_allocate/release_gem_obj. (Sagar)
    Updated commit message and moved POWER_PLAN and POWER_SOURCE
    definition from later patch. (Akash)
    Add struct_mutex locking while allocating/releasing slpc shared
    object. This was caught by CI BAT. Adding SLPC state variable
    to determine if it is active as it not just dependent on shared
    data setup.
    Rebase with guc_allocate_vma related changes.

v2: WARN_ON for platform_sku validity and space changes.(David)
    Checkpatch update.

v3: Fixing WARNING in igt@drv_module_reload_basic found in trybot BAT
    with SLPC Enabled.

v4: Updated support for GuC v9. s/slice_total/hweight8(slice_mask)/(Dave).

v5: SLPC vma mapping changes and removed explicit type conversions.(Chris).
    s/freq_unslice_max|min/unslice__max|min_freq.

v6: Commit message update. s/msr_value/val for reuse later.

v7: Set default values for tasks and min frequency parameters.
    Moved initialization with allocation of data so that post GuC load
    earlier parameters persist.

v8: Added check for SLPC status during cleanup of shared data. SLPC
    disabling is asynchronous and should complete within 10us.

v9: Enabling Balancer task in SLPC.

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h  |   1 +
 drivers/gpu/drm/i915/intel_pm.c   |   2 +-
 drivers/gpu/drm/i915/intel_slpc.c | 167 ++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h |   1 +
 4 files changed, 170 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0cf04eb..df3d544 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1876,6 +1876,7 @@ bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
 void gen6_rps_idle(struct drm_i915_private *dev_priv);
 void gen6_rps_boost(struct drm_i915_gem_request *rq,
 		    struct intel_rps_client *rps);
+void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv);
 void g4x_wm_get_hw_state(struct drm_device *dev);
 void vlv_wm_get_hw_state(struct drm_device *dev);
 void ilk_wm_get_hw_state(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index e5607e5..6b2b7f8 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6486,7 +6486,7 @@ int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6)
 	return INTEL_RC6_ENABLE;
 }
 
-static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
+void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
 {
 	/* All of these values are in units of 50MHz */
 
diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index a3db63c..73e7bf5 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -22,6 +22,7 @@
  *
  */
 #include <linux/firmware.h>
+#include <asm/msr-index.h>
 #include "i915_drv.h"
 #include "intel_uc.h"
 
@@ -64,12 +65,178 @@ struct slpc_param slpc_paramlist[SLPC_MAX_PARAM] = {
 				"Enable IBC when non-Gaming Mode is enabled"}
 };
 
+static unsigned int slpc_get_platform_sku(struct drm_i915_private *dev_priv)
+{
+	enum slpc_platform_sku platform_sku;
+
+	if (IS_SKL_ULX(dev_priv))
+		platform_sku = SLPC_PLATFORM_SKU_ULX;
+	else if (IS_SKL_ULT(dev_priv))
+		platform_sku = SLPC_PLATFORM_SKU_ULT;
+	else
+		platform_sku = SLPC_PLATFORM_SKU_DT;
+
+	WARN_ON(platform_sku > 0xFF);
+
+	return platform_sku;
+}
+
+static unsigned int slpc_get_slice_count(struct drm_i915_private *dev_priv)
+{
+	unsigned int slice_count = 1;
+
+	if (IS_SKYLAKE(dev_priv))
+		slice_count = hweight8(INTEL_INFO(dev_priv)->sseu.slice_mask);
+
+	return slice_count;
+}
+
+void slpc_mem_set_param(struct slpc_shared_data *data,
+			      u32 id,
+			      u32 value)
+{
+	data->override_parameters_set_bits[id >> 5]
+						|= (1 << (id % 32));
+	data->override_parameters_values[id] = value;
+}
+
+void slpc_mem_unset_param(struct slpc_shared_data *data,
+				u32 id)
+{
+	data->override_parameters_set_bits[id >> 5]
+						&= (~(1 << (id % 32)));
+	data->override_parameters_values[id] = 0;
+}
+
+int slpc_mem_task_control(struct slpc_shared_data *data, u64 val,
+			  u32 enable_id, u32 disable_id)
+{
+	int ret = 0;
+
+	if (val == SLPC_PARAM_TASK_DEFAULT) {
+		/* set default */
+		slpc_mem_unset_param(data, enable_id);
+		slpc_mem_unset_param(data, disable_id);
+	} else if (val == SLPC_PARAM_TASK_ENABLED) {
+		/* set enable */
+		slpc_mem_set_param(data, enable_id, 1);
+		slpc_mem_unset_param(data, disable_id);
+	} else if (val == SLPC_PARAM_TASK_DISABLED) {
+		/* set disable */
+		slpc_mem_set_param(data, disable_id, 1);
+		slpc_mem_unset_param(data, enable_id);
+	} else {
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void slpc_shared_data_init(struct intel_slpc *slpc)
+{
+	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
+	struct page *page;
+	struct slpc_shared_data *data;
+	u64 val;
+
+	page = i915_vma_first_page(slpc->vma);
+	data = kmap_atomic(page);
+
+	memset(data, 0, sizeof(struct slpc_shared_data));
+
+	data->shared_data_size = sizeof(struct slpc_shared_data);
+	data->global_state = SLPC_GLOBAL_STATE_NOT_RUNNING;
+	data->platform_info.platform_sku =
+				slpc_get_platform_sku(dev_priv);
+	data->platform_info.slice_count =
+				slpc_get_slice_count(dev_priv);
+	data->platform_info.power_plan_source =
+		SLPC_POWER_PLAN_SOURCE(SLPC_POWER_PLAN_BALANCED,
+					    SLPC_POWER_SOURCE_AC);
+	rdmsrl(MSR_TURBO_RATIO_LIMIT, val);
+	data->platform_info.P0_freq = val;
+	rdmsrl(MSR_PLATFORM_INFO, val);
+	data->platform_info.P1_freq = val >> 8;
+	data->platform_info.Pe_freq = val >> 40;
+	data->platform_info.Pn_freq = val >> 48;
+
+	/* Enable only GTPERF task, Disable others */
+	val = SLPC_PARAM_TASK_ENABLED;
+	slpc_mem_task_control(data, val,
+			      SLPC_PARAM_TASK_ENABLE_GTPERF,
+			      SLPC_PARAM_TASK_DISABLE_GTPERF);
+
+	slpc_mem_task_control(data, val,
+			      SLPC_PARAM_TASK_ENABLE_BALANCER,
+			      SLPC_PARAM_TASK_DISABLE_BALANCER);
+
+	val = SLPC_PARAM_TASK_DISABLED;
+	slpc_mem_task_control(data, val,
+			      SLPC_PARAM_TASK_ENABLE_DCC,
+			      SLPC_PARAM_TASK_DISABLE_DCC);
+
+	slpc_mem_set_param(data, SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS, 0);
+
+	slpc_mem_set_param(data, SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING,
+			   0);
+
+	slpc_mem_set_param(data, SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING,
+			   1);
+
+	slpc_mem_set_param(data,
+			   SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO,
+			   0);
+
+	slpc_mem_set_param(data, SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE, 0);
+
+	slpc_mem_set_param(data,
+			   SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE,
+			   1);
+
+	slpc_mem_set_param(data,
+			   SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
+			   intel_gpu_freq(dev_priv,
+				dev_priv->pm.rps.efficient_freq));
+	slpc_mem_set_param(data,
+			   SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ,
+			   intel_gpu_freq(dev_priv,
+				dev_priv->pm.rps.efficient_freq));
+
+	kunmap_atomic(data);
+}
+
 void intel_slpc_init(struct intel_slpc *slpc)
 {
+	struct intel_guc *guc = slpc_to_guc(slpc);
+	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
+	struct i915_vma *vma;
+
+	slpc->active = false;
+
+	mutex_lock(&dev_priv->pm.pcu_lock);
+	gen6_init_rps_frequencies(dev_priv);
+	mutex_unlock(&dev_priv->pm.pcu_lock);
+
+	/* Allocate shared data structure */
+	vma = slpc->vma;
+	if (!vma) {
+		vma = intel_guc_allocate_vma(guc,
+			       PAGE_ALIGN(sizeof(struct slpc_shared_data)));
+		if (IS_ERR(vma)) {
+			DRM_ERROR("slpc_shared_data allocation failed\n");
+			i915.enable_slpc = 0;
+			return;
+		}
+
+		slpc->vma = vma;
+		slpc_shared_data_init(slpc);
+	}
 }
 
 void intel_slpc_cleanup(struct intel_slpc *slpc)
 {
+	/* Release shared data structure */
+	i915_vma_unpin_and_release(&slpc->vma);
 }
 
 void intel_slpc_enable(struct intel_slpc *slpc)
diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h
index ac4cb65..9312b2f 100644
--- a/drivers/gpu/drm/i915/intel_slpc.h
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -26,6 +26,7 @@
 
 struct intel_slpc {
 	bool active;
+	struct i915_vma *vma;
 };
 
 static inline int intel_slpc_enabled(void)
-- 
1.9.1

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

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

* [PATCH 20/31] drm/i915/slpc: Add parameter set/unset/get, task control/status functions
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (18 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 19/31] drm/i915/slpc: Allocate/Release/Initialize SLPC shared data Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-21 13:47   ` Michal Wajdeczko
  2017-09-19 17:41 ` [PATCH 21/31] drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR Sagar Arun Kamble
                   ` (10 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

SLPC behavior can be changed through set of parameters.
These parameters can be updated and queried from i915 though
Host to GuC SLPC events. This patch adds parameter update
events for setting/unsetting/getting parameters. SLPC has
various tasks for controlling different controls. This patch
adds functions to control and query the task status.

v1: Use host2guc_slpc
    update slcp_param_id enum values for SLPC 2015.2.4
    return void instead of ignored error code (Paulo)

v2: Checkpatch update.

v3: Rebase.

v4: Updated with GuC firmware v9.

v5: Updated input structure to host2guc_slpc. Added functions
    to update only parameters in the SLPC shared memory. This
    will allow to setup shared data with all parameters and send
    single event to SLPC take them into effect. Commit message
    update. (Sagar)

v6: Rearranged helpers to use them in slpc_shared_data_init.
    Added definition of SLPC_KMD_MAX_PARAM.

v7: Added definition of host2guc_slpc with rearrangement of patches.
    Added task control/status functions.

v8: Rebase w.r.t s/intel_guc_send/intel_guc_send_mmio.

Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/intel_guc.c  |  21 ++++-
 drivers/gpu/drm/i915/intel_guc.h  |   2 +
 drivers/gpu/drm/i915/intel_slpc.c | 185 ++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h |   8 ++
 4 files changed, 215 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
index a92c7e8..656bae9 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -67,9 +67,11 @@ void intel_guc_init_send_regs(struct intel_guc *guc)
 /*
  * This function implements the MMIO based host to GuC interface.
  */
-int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len)
+int __intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len,
+			  u32 *output)
 {
 	struct drm_i915_private *dev_priv = guc_to_i915(guc);
+	union slpc_event_output_header header;
 	u32 status;
 	int i;
 	int ret;
@@ -115,12 +117,29 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len)
 			 action[0], ret, status, I915_READ(SOFT_SCRATCH(15)));
 	}
 
+	/*
+	 * Output data from Host to GuC SLPC actions is populated in scratch
+	 * registers SOFT_SCRATCH(1) to SOFT_SCRATCH(14) based on event.
+	 * Currently only SLPC action status in GuC is meaningful as Host
+	 * can query only overridden parameters and that are fetched from
+	 * Host-GuC SLPC shared data.
+	 */
+	if (output && !ret) {
+		output[0] = header.value = I915_READ(SOFT_SCRATCH(1));
+		ret = header.status;
+	}
+
 	intel_uncore_forcewake_put(dev_priv, guc->send_regs.fw_domains);
 	mutex_unlock(&guc->send_mutex);
 
 	return ret;
 }
 
+int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len)
+{
+	return __intel_guc_send_mmio(guc, action, len, NULL);
+}
+
 int intel_guc_sample_forcewake(struct intel_guc *guc)
 {
 	struct drm_i915_private *dev_priv = guc_to_i915(guc);
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index b835d30..c27d2dd 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -132,6 +132,8 @@ struct intel_guc {
 int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 len);
 void gen8_guc_raise_irq(struct intel_guc *guc);
 void intel_guc_init_send_regs(struct intel_guc *guc);
+int __intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len,
+			  u32 *output);
 int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32 len);
 int intel_guc_sample_forcewake(struct intel_guc *guc);
 int intel_guc_runtime_suspend(struct intel_guc *guc);
diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index 73e7bf5..f47d81e 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -132,6 +132,191 @@ int slpc_mem_task_control(struct slpc_shared_data *data, u64 val,
 	return ret;
 }
 
+static void host2guc_slpc(struct intel_slpc *slpc,
+			  struct slpc_event_input *input, u32 len)
+{
+	struct intel_guc *guc = slpc_to_guc(slpc);
+	u32 *data;
+	u32 output[SLPC_EVENT_MAX_OUTPUT_ARGS];
+	int ret = 0;
+
+	/*
+	 * We have only 15 scratch registers for communication.
+	 * the first we will use for the event ID in input and
+	 * output data. Event processing status will be present
+	 * in SOFT_SCRATCH(1) register.
+	 */
+	BUILD_BUG_ON(SLPC_EVENT_MAX_INPUT_ARGS > 14);
+	BUILD_BUG_ON(SLPC_EVENT_MAX_OUTPUT_ARGS < 1);
+	BUILD_BUG_ON(SLPC_EVENT_MAX_OUTPUT_ARGS > 14);
+
+	data = (u32 *) input;
+	data[0] = INTEL_GUC_ACTION_SLPC_REQUEST;
+	ret = __intel_guc_send_mmio(guc, data, len, output);
+
+	if (ret)
+		DRM_ERROR("event 0x%x status %d\n",
+			  ((output[0] & 0xFF00) >> 8), ret);
+}
+
+static void host2guc_slpc_set_param(struct intel_slpc *slpc,
+				    u32 id, u32 value)
+{
+	struct slpc_event_input data = {0};
+
+	data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2);
+	data.args[0] = id;
+	data.args[1] = value;
+
+	host2guc_slpc(slpc, &data, 4);
+}
+
+static void host2guc_slpc_unset_param(struct intel_slpc *slpc,
+				      u32 id)
+{
+	struct slpc_event_input data = {0};
+
+	data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1);
+	data.args[0] = id;
+
+	host2guc_slpc(slpc, &data, 3);
+}
+
+void intel_slpc_set_param(struct intel_slpc *slpc,
+			  u32 id,
+			  u32 value)
+{
+	struct page *page;
+	struct slpc_shared_data *data = NULL;
+
+	WARN_ON(id >= SLPC_MAX_PARAM);
+
+	if (!slpc->vma)
+		return;
+
+	page = i915_vma_first_page(slpc->vma);
+	data = kmap_atomic(page);
+	slpc_mem_set_param(data, id, value);
+	kunmap_atomic(data);
+
+	host2guc_slpc_set_param(slpc, id, value);
+}
+
+void intel_slpc_unset_param(struct intel_slpc *slpc,
+			    u32 id)
+{
+	struct page *page;
+	struct slpc_shared_data *data = NULL;
+
+	WARN_ON(id >= SLPC_MAX_PARAM);
+
+	if (!slpc->vma)
+		return;
+
+	page = i915_vma_first_page(slpc->vma);
+	data = kmap_atomic(page);
+	slpc_mem_unset_param(data, id);
+	kunmap_atomic(data);
+
+	host2guc_slpc_unset_param(slpc, id);
+}
+
+void intel_slpc_get_param(struct intel_slpc *slpc,
+			  u32 id,
+			  int *overriding, u32 *value)
+{
+	struct page *page;
+	struct slpc_shared_data *data = NULL;
+	u32 bits;
+
+	WARN_ON(id >= SLPC_MAX_PARAM);
+
+	if (!slpc->vma)
+		return;
+
+	page = i915_vma_first_page(slpc->vma);
+	data = kmap_atomic(page);
+	if (overriding) {
+		bits = data->override_parameters_set_bits[id >> 5];
+		*overriding = (0 != (bits & (1 << (id % 32))));
+	}
+	if (value)
+		*value = data->override_parameters_values[id];
+
+	kunmap_atomic(data);
+}
+
+int intel_slpc_task_control(struct intel_slpc *slpc, u64 val,
+			    u32 enable_id, u32 disable_id)
+{
+	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
+	int ret = 0;
+
+	if (!slpc->active)
+		return -ENODEV;
+
+	intel_runtime_pm_get(dev_priv);
+
+	if (val == SLPC_PARAM_TASK_DEFAULT) {
+		/* set default */
+		intel_slpc_unset_param(slpc, enable_id);
+		intel_slpc_unset_param(slpc, disable_id);
+	} else if (val == SLPC_PARAM_TASK_ENABLED) {
+		/* set enable */
+		intel_slpc_set_param(slpc, enable_id, 1);
+		intel_slpc_unset_param(slpc, disable_id);
+	} else if (val == SLPC_PARAM_TASK_DISABLED) {
+		/* set disable */
+		intel_slpc_set_param(slpc, disable_id, 1);
+		intel_slpc_unset_param(slpc, enable_id);
+	} else {
+		ret = -EINVAL;
+	}
+
+	intel_slpc_enable(slpc);
+	intel_runtime_pm_put(dev_priv);
+
+	return ret;
+}
+
+int intel_slpc_task_status(struct intel_slpc *slpc, u64 *val,
+			   u32 enable_id, u32 disable_id)
+{
+	int override_enable, override_disable;
+	u32 value_enable, value_disable;
+	int ret = 0;
+
+	if (!slpc->active) {
+		ret = -ENODEV;
+	} else if (val) {
+		intel_slpc_get_param(slpc, enable_id, &override_enable,
+				     &value_enable);
+		intel_slpc_get_param(slpc, disable_id, &override_disable,
+				     &value_disable);
+
+		/*
+		 * Set the output value:
+		 * 0: default
+		 * 1: enabled
+		 * 2: disabled
+		 * 3: unknown (should not happen)
+		 */
+		if (override_disable && (value_disable == 1))
+			*val = SLPC_PARAM_TASK_DISABLED;
+		else if (override_enable && (value_enable == 1))
+			*val = SLPC_PARAM_TASK_ENABLED;
+		else if (!override_enable && !override_disable)
+			*val = SLPC_PARAM_TASK_DEFAULT;
+		else
+			*val = SLPC_PARAM_TASK_UNKNOWN;
+
+	} else {
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
 static void slpc_shared_data_init(struct intel_slpc *slpc)
 {
 	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h
index 9312b2f..0ff17f0 100644
--- a/drivers/gpu/drm/i915/intel_slpc.h
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -247,6 +247,14 @@ struct slpc_param {
 #define SLPC_PARAM_TASK_UNKNOWN  3
 
 /* intel_slpc.c */
+void intel_slpc_set_param(struct intel_slpc *slpc, u32 id, u32 value);
+void intel_slpc_unset_param(struct intel_slpc *slpc, u32 id);
+void intel_slpc_get_param(struct intel_slpc *slpc, u32 id,
+			  int *overriding, u32 *value);
+int intel_slpc_task_control(struct intel_slpc *slpc, u64 val,
+			    u32 enable_id, u32 disable_id);
+int intel_slpc_task_status(struct intel_slpc *slpc, u64 *val,
+			   u32 enable_id, u32 disable_id);
 void intel_slpc_init(struct intel_slpc *slpc);
 void intel_slpc_cleanup(struct intel_slpc *slpc);
 void intel_slpc_enable(struct intel_slpc *slpc);
-- 
1.9.1

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

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

* [PATCH 21/31] drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (19 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 20/31] drm/i915/slpc: Add parameter set/unset/get, task control/status functions Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-21 14:06   ` Michal Wajdeczko
  2017-09-19 17:41 ` [PATCH 22/31] drm/i915/slpc: Send SHUTDOWN event Sagar Arun Kamble
                   ` (9 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

Send host2guc SLPC reset event to GuC post GuC load.
Post this, i915 can ascertain if SLPC has started running successfully
through shared data. This check is done during intel_init_gt_powersave.
This allows to get initial configuration setup by SLPC and if needed
move to Host RPS if SLPC runs into issues.
On TDR/Engine reset i915 should send extra flag
SLPC_RESET_FLAG_TDR_OCCURREDto clear SLPC state as appropriate.

v1: Extract host2guc_slpc to handle slpc status code
    coding style changes (Paulo)
    Removed WARN_ON for checking msb of gtt address of
    shared gem obj. (ChrisW)
    host2guc_action to i915_guc_action change.(Sagar)
    Updating SLPC enabled status. (Sagar)

v2: Commit message update. (David)

v3: Rebase.

v4: Added DRM_INFO message when SLPC is enabled.

v5: Updated patch as host2guc_slpc is moved to earlier patch.
    SLPC activation status message put after checking the
    state from shared data during intel_init_gt_powersave.

v6: Added definition of host2guc_slpc and clflush the shared data only
    for required size. Setting state to NOT_RUNNING before sending RESET
    event. Output data for SLPC actions is to be retrieved during
    intel_guc_send with lock protection so created wrapper
    __intel_guc_send that outputs GuC output data if needed. Clearing
    pm_rps_events on confirming SLPC RUNNING status so that even if
    host touches any of the PM registers by mistake it should not have
    any effect. (Sagar)

v7: Added save/restore_default_rps as Uncore sanitize will clear the
    RP_CONTROL setup by BIOS. s/i915_ggtt_offset/guc_ggtt_offset.

v8: Added support for handling TDR based SLPC reset. Added functions
    host2guc_slpc_tdr_reset, intel_slpc_reset_prepare and
    intel_slpc_tdr_reset to handle TDR based SLPC reset.

Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c   |   2 +
 drivers/gpu/drm/i915/i915_irq.c   |   7 +-
 drivers/gpu/drm/i915/intel_pm.c   |  10 +++
 drivers/gpu/drm/i915/intel_slpc.c | 170 ++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h |   9 ++
 drivers/gpu/drm/i915/intel_uc.c   |   1 +
 6 files changed, 198 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index f13a3de..932f9ef 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1074,6 +1074,8 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 
 	intel_sanitize_options(dev_priv);
 
+	intel_slpc_save_default_rps(&dev_priv->guc.slpc);
+
 	ret = i915_ggtt_probe_hw(dev_priv);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4a1554c..2d5ad13 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2838,8 +2838,13 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
 		}
 	}
 
-	if (!engine_mask)
+	if (!engine_mask) {
+		if (intel_slpc_active(&dev_priv->guc.slpc)) {
+			intel_slpc_reset_prepare(&dev_priv->guc.slpc);
+			intel_slpc_tdr_reset(&dev_priv->guc.slpc);
+		}
 		goto out;
+	}
 
 	/* Full reset needs the mutex, stop any other user trying to do so. */
 	if (test_and_set_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags)) {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6b2b7f8..c2065f2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7918,6 +7918,16 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 		intel_runtime_pm_get(dev_priv);
 	}
 
+	if (intel_slpc_enabled()) {
+		dev_priv->guc.slpc.active =
+			intel_slpc_get_status(&dev_priv->guc.slpc);
+		if (!intel_slpc_active(&dev_priv->guc.slpc)) {
+			i915.enable_slpc = 0;
+			intel_sanitize_gt_powersave(dev_priv);
+		} else
+			dev_priv->pm_rps_events = 0;
+	}
+
 	mutex_lock(&dev_priv->drm.struct_mutex);
 	mutex_lock(&dev_priv->pm.pcu_lock);
 
diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index f47d81e..57e69d4 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -390,6 +390,140 @@ static void slpc_shared_data_init(struct intel_slpc *slpc)
 	kunmap_atomic(data);
 }
 
+static void host2guc_slpc_reset(struct intel_slpc *slpc)
+{
+	struct slpc_event_input data = {0};
+	u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
+
+	data.header.value = SLPC_EVENT(SLPC_EVENT_RESET, 2);
+	data.args[0] = shared_data_gtt_offset;
+	data.args[1] = 0;
+
+	host2guc_slpc(slpc, &data, 4);
+}
+
+static void host2guc_slpc_tdr_reset(struct intel_slpc *slpc)
+{
+	struct slpc_event_input data = {0};
+	u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
+
+	data.header.value = SLPC_EVENT(SLPC_EVENT_RESET, 3);
+	data.args[0] = shared_data_gtt_offset;
+	data.args[1] = 0;
+	data.args[2] = SLPC_RESET_FLAG_TDR_OCCURRED;
+
+	host2guc_slpc(slpc, &data, 5);
+}
+
+static void host2guc_slpc_query_task_state(struct intel_slpc *slpc)
+{
+	struct slpc_event_input data = {0};
+	u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
+
+	data.header.value = SLPC_EVENT(SLPC_EVENT_QUERY_TASK_STATE, 2);
+	data.args[0] = shared_data_gtt_offset;
+	data.args[1] = 0;
+
+	host2guc_slpc(slpc, &data, 4);
+}
+
+void intel_slpc_query_task_state(struct intel_slpc *slpc)
+{
+	if (slpc->active)
+		host2guc_slpc_query_task_state(slpc);
+}
+
+/*
+ * This function will reads the state updates from GuC SLPC into shared data
+ * by invoking H2G action. Returns current state of GuC SLPC.
+ */
+void intel_slpc_read_shared_data(struct intel_slpc *slpc,
+				 struct slpc_shared_data *data)
+{
+	struct page *page;
+	void *pv = NULL;
+
+	intel_slpc_query_task_state(slpc);
+
+	page = i915_vma_first_page(slpc->vma);
+	pv = kmap_atomic(page);
+
+	drm_clflush_virt_range(pv, sizeof(struct slpc_shared_data));
+	memcpy(data, pv, sizeof(struct slpc_shared_data));
+
+	kunmap_atomic(pv);
+}
+
+const char *intel_slpc_get_state_str(enum slpc_global_state state)
+{
+	if (state == SLPC_GLOBAL_STATE_NOT_RUNNING)
+		return "not running";
+	else if (state == SLPC_GLOBAL_STATE_INITIALIZING)
+		return "initializing";
+	else if (state == SLPC_GLOBAL_STATE_RESETTING)
+		return "resetting";
+	else if (state == SLPC_GLOBAL_STATE_RUNNING)
+		return "running";
+	else if (state == SLPC_GLOBAL_STATE_SHUTTING_DOWN)
+		return "shutting down";
+	else if (state == SLPC_GLOBAL_STATE_ERROR)
+		return "error";
+	else
+		return "unknown";
+}
+
+bool intel_slpc_get_status(struct intel_slpc *slpc)
+{
+	struct slpc_shared_data data;
+	bool ret = false;
+
+	intel_slpc_read_shared_data(slpc, &data);
+	DRM_INFO("SLPC state: %s\n",
+		 intel_slpc_get_state_str(data.global_state));
+
+	switch (data.global_state) {
+	case SLPC_GLOBAL_STATE_RUNNING:
+		/* Capture required state from SLPC here */
+		ret = true;
+		break;
+	case SLPC_GLOBAL_STATE_ERROR:
+		DRM_ERROR("SLPC in error state.\n");
+		break;
+	case SLPC_GLOBAL_STATE_RESETTING:
+		/*
+		 * SLPC enabling in GuC should be completing fast.
+		 * If SLPC is taking time to initialize (unlikely as we are
+		 * sending reset event during GuC load itself).
+		 * TODO: Need to wait till state changes to RUNNING.
+		 */
+		ret = true;
+		DRM_ERROR("SLPC not running yet.!!!");
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+/*
+ * Uncore sanitize clears RPS state in Host GTPM flows set by BIOS, Save the
+ * initial BIOS programmed RPS state that is needed by SLPC and not set by SLPC.
+ * Set this state while enabling SLPC.
+ */
+void intel_slpc_save_default_rps(struct intel_slpc *slpc)
+{
+	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
+
+	slpc->rp_control = I915_READ(GEN6_RP_CONTROL);
+}
+
+static void intel_slpc_restore_default_rps(struct intel_slpc *slpc)
+{
+	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
+
+	I915_WRITE(GEN6_RP_CONTROL, slpc->rp_control);
+}
+
 void intel_slpc_init(struct intel_slpc *slpc)
 {
 	struct intel_guc *guc = slpc_to_guc(slpc);
@@ -426,6 +560,42 @@ void intel_slpc_cleanup(struct intel_slpc *slpc)
 
 void intel_slpc_enable(struct intel_slpc *slpc)
 {
+	struct page *page;
+	struct slpc_shared_data *data;
+
+	intel_slpc_restore_default_rps(slpc);
+
+	page = i915_vma_first_page(slpc->vma);
+	data = kmap_atomic(page);
+	data->global_state = SLPC_GLOBAL_STATE_NOT_RUNNING;
+	kunmap_atomic(data);
+
+	if (slpc->tdr_reset) {
+		host2guc_slpc_tdr_reset(slpc);
+		slpc->tdr_reset = false;
+	} else {
+		host2guc_slpc_reset(slpc);
+	}
+
+	slpc->active = true;
+}
+
+void intel_slpc_reset_prepare(struct intel_slpc *slpc)
+{
+	if (intel_slpc_active(slpc)) {
+		intel_slpc_disable(slpc);
+		slpc->tdr_reset = true;
+	}
+}
+
+void intel_slpc_tdr_reset(struct intel_slpc *slpc)
+{
+	intel_slpc_restore_default_rps(slpc);
+	slpc_shared_data_init(slpc);
+
+	host2guc_slpc_tdr_reset(slpc);
+	slpc->active = true;
+	slpc->tdr_reset = false;
 }
 
 void intel_slpc_disable(struct intel_slpc *slpc)
diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h
index 0ff17f0..20c342b 100644
--- a/drivers/gpu/drm/i915/intel_slpc.h
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -26,7 +26,9 @@
 
 struct intel_slpc {
 	bool active;
+	bool tdr_reset;
 	struct i915_vma *vma;
+	u32 rp_control;
 };
 
 static inline int intel_slpc_enabled(void)
@@ -255,9 +257,16 @@ int intel_slpc_task_control(struct intel_slpc *slpc, u64 val,
 			    u32 enable_id, u32 disable_id);
 int intel_slpc_task_status(struct intel_slpc *slpc, u64 *val,
 			   u32 enable_id, u32 disable_id);
+void intel_slpc_read_shared_data(struct intel_slpc *slpc,
+				 struct slpc_shared_data *data);
+const char *intel_slpc_get_state_str(enum slpc_global_state state);
+bool intel_slpc_get_status(struct intel_slpc *slpc);
+void intel_slpc_save_default_rps(struct intel_slpc *slpc);
 void intel_slpc_init(struct intel_slpc *slpc);
 void intel_slpc_cleanup(struct intel_slpc *slpc);
 void intel_slpc_enable(struct intel_slpc *slpc);
 void intel_slpc_disable(struct intel_slpc *slpc);
+void intel_slpc_reset_prepare(struct intel_slpc *slpc);
+void intel_slpc_tdr_reset(struct intel_slpc *slpc);
 
 #endif
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index 990d84a..d8582b8 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -502,5 +502,6 @@ int intel_uc_resume(struct drm_i915_private *dev_priv)
 
 int intel_uc_reset_prepare(struct drm_i915_private *dev_priv)
 {
+	intel_slpc_reset_prepare(&dev_priv->guc.slpc);
 	return intel_uc_suspend(dev_priv);
 }
-- 
1.9.1

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

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

* [PATCH 22/31] drm/i915/slpc: Send SHUTDOWN event
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (20 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 21/31] drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-19 17:41 ` [PATCH 23/31] drm/i915/slpc: Add support for min/max frequency control Sagar Arun Kamble
                   ` (8 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

From: Tom O'Rourke <Tom.O'Rourke@intel.com>

Send SLPC shutdown event during disable, suspend, and reset
operations. Sending shutdown event while already shutdown
is OK.

v1: Return void instead of ignored error code (Paulo)
    Removed WARN_ON for checking msb of gtt address of
    shared gem obj. (ChrisW)
    Added SLPC state update during disable, suspend and reset.
    Changed semantics of reset. It is supposed to just disable. (Sagar)

v2-v4: Rebase.

v5: Updated the input data structure. (Sagar)

v6: Rebase.

v7: s/i915_ggtt_offset/guc_ggtt_offset.

v8: Updated the status check post disabling to wait for 20us. (Sagar)

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/intel_slpc.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index 57e69d4..b0a17ef 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -427,6 +427,18 @@ static void host2guc_slpc_query_task_state(struct intel_slpc *slpc)
 	host2guc_slpc(slpc, &data, 4);
 }
 
+static void host2guc_slpc_shutdown(struct intel_slpc *slpc)
+{
+	struct slpc_event_input data = {0};
+	u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
+
+	data.header.value = SLPC_EVENT(SLPC_EVENT_SHUTDOWN, 2);
+	data.args[0] = shared_data_gtt_offset;
+	data.args[1] = 0;
+
+	host2guc_slpc(slpc, &data, 4);
+}
+
 void intel_slpc_query_task_state(struct intel_slpc *slpc)
 {
 	if (slpc->active)
@@ -598,6 +610,21 @@ void intel_slpc_tdr_reset(struct intel_slpc *slpc)
 	slpc->tdr_reset = false;
 }
 
+static bool intel_slpc_disabled(struct intel_slpc *slpc)
+{
+	struct slpc_shared_data data;
+
+	intel_slpc_read_shared_data(slpc, &data);
+	return (data.global_state == SLPC_GLOBAL_STATE_NOT_RUNNING);
+}
+
 void intel_slpc_disable(struct intel_slpc *slpc)
 {
+	host2guc_slpc_shutdown(slpc);
+
+	/* Ensure SLPC is not running prior to releasing Shared data */
+	if (wait_for_us(intel_slpc_disabled(slpc), 20))
+		WARN_ONCE(true, "SLPC shutdown failed\n");
+
+	slpc->active = false;
 }
-- 
1.9.1

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

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

* [PATCH 23/31] drm/i915/slpc: Add support for min/max frequency control
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (21 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 22/31] drm/i915/slpc: Send SHUTDOWN event Sagar Arun Kamble
@ 2017-09-19 17:41 ` Sagar Arun Kamble
  2017-09-19 17:42 ` [PATCH 24/31] drm/i915/slpc: Add debugfs support to read/write/revert the parameters Sagar Arun Kamble
                   ` (7 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

Update sysfs and debugfs functions to set SLPC
parameters when setting max/min frequency.

v1: Update for SLPC 2015.2.4 (params for both slice and unslice)
    Replace HAS_SLPC with intel_slpc_active() (Paulo)

v2-v4: Rebase.

v5: Removed typecasting the frequency values to u32. (Chris)
    Changed intel_slpc_active to guc.slpc.enabled. Carved out
    SLPC helpers to set min and max frequencies.

v6: Rebase. Doing explicit SLPC reset on setting frequency to start sane
    and covered with RPM get/put. Caching SLPC limits post enabling first.

v7: Rebase due to change in the dev_priv->pm.rps structure.

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 48 ++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/i915_sysfs.c   | 36 ++++++++++++++++++++----
 drivers/gpu/drm/i915/intel_slpc.c   | 56 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h   |  5 ++++
 4 files changed, 135 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 9356a69..dbfe185 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -4381,7 +4381,13 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 	if (INTEL_GEN(dev_priv) < 6)
 		return -ENODEV;
 
-	*val = intel_gpu_freq(dev_priv, dev_priv->pm.rps.max_freq_softlimit);
+	if (intel_slpc_active(&dev_priv->guc.slpc))
+		*val = intel_gpu_freq(dev_priv,
+				      dev_priv->guc.slpc.max_unslice_freq);
+	else
+		*val = intel_gpu_freq(dev_priv,
+				      dev_priv->pm.rps.max_freq_softlimit);
+
 	return 0;
 }
 
@@ -4398,20 +4404,32 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 
 	DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val);
 
+	intel_runtime_pm_get(dev_priv);
+
 	ret = mutex_lock_interruptible(&dev_priv->pm.pcu_lock);
-	if (ret)
+	if (ret) {
+		intel_runtime_pm_put(dev_priv);
 		return ret;
+	}
 
 	/*
 	 * Turbo will still be enabled, but won't go above the set value.
 	 */
 	val = intel_freq_opcode(dev_priv, val);
 
+	if (intel_slpc_active(&dev_priv->guc.slpc)) {
+		ret = intel_slpc_max_freq_set(&dev_priv->guc.slpc, val);
+		mutex_unlock(&dev_priv->pm.pcu_lock);
+		intel_runtime_pm_put(dev_priv);
+		return ret;
+	}
+
 	hw_max = rps->max_freq;
 	hw_min = rps->min_freq;
 
 	if (val < hw_min || val > hw_max || val < rps->min_freq_softlimit) {
 		mutex_unlock(&dev_priv->pm.pcu_lock);
+		intel_runtime_pm_put(dev_priv);
 		return -EINVAL;
 	}
 
@@ -4422,6 +4440,8 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 
 	mutex_unlock(&dev_priv->pm.pcu_lock);
 
+	intel_runtime_pm_put(dev_priv);
+
 	return 0;
 }
 
@@ -4437,7 +4457,13 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 	if (INTEL_GEN(dev_priv) < 6)
 		return -ENODEV;
 
-	*val = intel_gpu_freq(dev_priv, dev_priv->pm.rps.min_freq_softlimit);
+	if (intel_slpc_active(&dev_priv->guc.slpc))
+		*val = intel_gpu_freq(dev_priv,
+				      dev_priv->guc.slpc.min_unslice_freq);
+	else
+		*val = intel_gpu_freq(dev_priv,
+				      dev_priv->pm.rps.min_freq_softlimit);
+
 	return 0;
 }
 
@@ -4453,21 +4479,33 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 
 	DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val);
 
+	intel_runtime_pm_get(dev_priv);
+
 	ret = mutex_lock_interruptible(&dev_priv->pm.pcu_lock);
-	if (ret)
+	if (ret) {
+		intel_runtime_pm_put(dev_priv);
 		return ret;
+	}
 
 	/*
 	 * Turbo will still be enabled, but won't go below the set value.
 	 */
 	val = intel_freq_opcode(dev_priv, val);
 
+	if (intel_slpc_active(&dev_priv->guc.slpc)) {
+		ret = intel_slpc_min_freq_set(&dev_priv->guc.slpc, val);
+		mutex_unlock(&dev_priv->pm.pcu_lock);
+		intel_runtime_pm_put(dev_priv);
+		return ret;
+	}
+
 	hw_max = dev_priv->pm.rps.max_freq;
 	hw_min = dev_priv->pm.rps.min_freq;
 
 	if (val < hw_min ||
 	    val > hw_max || val > dev_priv->pm.rps.max_freq_softlimit) {
 		mutex_unlock(&dev_priv->pm.pcu_lock);
+		intel_runtime_pm_put(dev_priv);
 		return -EINVAL;
 	}
 
@@ -4478,6 +4516,8 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
 
 	mutex_unlock(&dev_priv->pm.pcu_lock);
 
+	intel_runtime_pm_put(dev_priv);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 8add849..a2470f0 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -325,9 +325,14 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute
 {
 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
 
-	return snprintf(buf, PAGE_SIZE, "%d\n",
-			intel_gpu_freq(dev_priv,
-				       dev_priv->pm.rps.max_freq_softlimit));
+	if (intel_slpc_active(&dev_priv->guc.slpc))
+		return snprintf(buf, PAGE_SIZE, "%d\n",
+				intel_gpu_freq(dev_priv,
+					dev_priv->guc.slpc.max_unslice_freq));
+	else
+		return snprintf(buf, PAGE_SIZE, "%d\n",
+				intel_gpu_freq(dev_priv,
+					dev_priv->pm.rps.max_freq_softlimit));
 }
 
 static ssize_t gt_max_freq_mhz_store(struct device *kdev,
@@ -348,6 +353,13 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
 
 	val = intel_freq_opcode(dev_priv, val);
 
+	if (intel_slpc_active(&dev_priv->guc.slpc)) {
+		ret = intel_slpc_max_freq_set(&dev_priv->guc.slpc, val);
+		mutex_unlock(&dev_priv->pm.pcu_lock);
+		intel_runtime_pm_put(dev_priv);
+		return ret ? ret : count;
+	}
+
 	if (val < dev_priv->pm.rps.min_freq ||
 	    val > dev_priv->pm.rps.max_freq ||
 	    val < dev_priv->pm.rps.min_freq_softlimit) {
@@ -382,9 +394,14 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute
 {
 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
 
-	return snprintf(buf, PAGE_SIZE, "%d\n",
-			intel_gpu_freq(dev_priv,
-				       dev_priv->pm.rps.min_freq_softlimit));
+	if (intel_slpc_active(&dev_priv->guc.slpc))
+		return snprintf(buf, PAGE_SIZE, "%d\n",
+				intel_gpu_freq(dev_priv,
+					dev_priv->guc.slpc.min_unslice_freq));
+	else
+		return snprintf(buf, PAGE_SIZE, "%d\n",
+				intel_gpu_freq(dev_priv,
+					dev_priv->pm.rps.min_freq_softlimit));
 }
 
 static ssize_t gt_min_freq_mhz_store(struct device *kdev,
@@ -405,6 +422,13 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
 
 	val = intel_freq_opcode(dev_priv, val);
 
+	if (intel_slpc_active(&dev_priv->guc.slpc)) {
+		ret = intel_slpc_min_freq_set(&dev_priv->guc.slpc, val);
+		mutex_unlock(&dev_priv->pm.pcu_lock);
+		intel_runtime_pm_put(dev_priv);
+		return ret ? ret : count;
+	}
+
 	if (val < dev_priv->pm.rps.min_freq ||
 	    val > dev_priv->pm.rps.max_freq ||
 	    val > dev_priv->pm.rps.max_freq_softlimit) {
diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index b0a17ef..d0fd402 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -496,6 +496,10 @@ bool intel_slpc_get_status(struct intel_slpc *slpc)
 	switch (data.global_state) {
 	case SLPC_GLOBAL_STATE_RUNNING:
 		/* Capture required state from SLPC here */
+		slpc->max_unslice_freq = data.task_state_data.max_unslice_freq *
+					 GEN9_FREQ_SCALER;
+		slpc->min_unslice_freq = data.task_state_data.min_unslice_freq *
+					 GEN9_FREQ_SCALER;
 		ret = true;
 		break;
 	case SLPC_GLOBAL_STATE_ERROR:
@@ -536,6 +540,58 @@ static void intel_slpc_restore_default_rps(struct intel_slpc *slpc)
 	I915_WRITE(GEN6_RP_CONTROL, slpc->rp_control);
 }
 
+/*
+ * TODO: Add separate interfaces to set Max/Min Slice frequency.
+ * Since currently both slice and unslice are configured to same
+ * frequencies these unified interface relying on Unslice frequencies
+ * should be sufficient. These functions take frequency opcode as input.
+ */
+int intel_slpc_max_freq_set(struct intel_slpc *slpc, u32 val)
+{
+	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
+
+	if (val < dev_priv->pm.rps.min_freq ||
+	    val > dev_priv->pm.rps.max_freq ||
+	    val < slpc->min_unslice_freq)
+		return -EINVAL;
+
+	intel_slpc_set_param(slpc,
+			     SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ,
+			     intel_gpu_freq(dev_priv, val));
+	intel_slpc_set_param(slpc,
+			     SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ,
+			     intel_gpu_freq(dev_priv, val));
+
+	intel_slpc_enable(slpc);
+
+	slpc->max_unslice_freq = val;
+
+	return 0;
+}
+
+int intel_slpc_min_freq_set(struct intel_slpc *slpc, u32 val)
+{
+	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
+
+	if (val < dev_priv->pm.rps.min_freq ||
+	    val > dev_priv->pm.rps.max_freq ||
+	    val > slpc->max_unslice_freq)
+		return -EINVAL;
+
+	intel_slpc_set_param(slpc,
+			     SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
+			     intel_gpu_freq(dev_priv, val));
+	intel_slpc_set_param(slpc,
+			     SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ,
+			     intel_gpu_freq(dev_priv, val));
+
+	intel_slpc_enable(slpc);
+
+	slpc->min_unslice_freq = val;
+
+	return 0;
+}
+
 void intel_slpc_init(struct intel_slpc *slpc)
 {
 	struct intel_guc *guc = slpc_to_guc(slpc);
diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h
index 20c342b..ae857d3 100644
--- a/drivers/gpu/drm/i915/intel_slpc.h
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -29,6 +29,9 @@ struct intel_slpc {
 	bool tdr_reset;
 	struct i915_vma *vma;
 	u32 rp_control;
+	/* i915 cached SLPC frequency limits */
+	u32 min_unslice_freq;
+	u32 max_unslice_freq;
 };
 
 static inline int intel_slpc_enabled(void)
@@ -262,6 +265,8 @@ void intel_slpc_read_shared_data(struct intel_slpc *slpc,
 const char *intel_slpc_get_state_str(enum slpc_global_state state);
 bool intel_slpc_get_status(struct intel_slpc *slpc);
 void intel_slpc_save_default_rps(struct intel_slpc *slpc);
+int intel_slpc_max_freq_set(struct intel_slpc *slpc, u32 val);
+int intel_slpc_min_freq_set(struct intel_slpc *slpc, u32 val);
 void intel_slpc_init(struct intel_slpc *slpc);
 void intel_slpc_cleanup(struct intel_slpc *slpc);
 void intel_slpc_enable(struct intel_slpc *slpc);
-- 
1.9.1

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

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

* [PATCH 24/31] drm/i915/slpc: Add debugfs support to read/write/revert the parameters
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (22 preceding siblings ...)
  2017-09-19 17:41 ` [PATCH 23/31] drm/i915/slpc: Add support for min/max frequency control Sagar Arun Kamble
@ 2017-09-19 17:42 ` Sagar Arun Kamble
  2017-09-21 15:07   ` Michal Wajdeczko
  2017-09-19 17:42 ` [PATCH 25/31] drm/i915/slpc: Add enable/disable controls for SLPC tasks Sagar Arun Kamble
                   ` (6 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:42 UTC (permalink / raw)
  To: intel-gfx

This patch adds two debugfs interfaces:
1. i915_slpc_paramlist: List of all parameters that Host can configure.
   Currently listing id and description of each.
2. i915_slpc_param_ctl: This allows to change the parameters. Syntax is:
   echo "write <id> <value>" > i915_slpc_param_ctl.
   echo "read <id>" > i915_slpc_param_ctl; cat i915_slpc_param_ctl
   revert allows to set to default SLPC internal values. Syntax is:
   echo "revert <id>" > i915_slpc_param_ctl.

Added support to set/read parameters and unset the parameters which will
revert them to default SLPC internal values. Also added RPM ref. cover
around set/unset calls. Explicit SLPC reset is needed on setting/unsetting
some of the parameters.

Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c |  19 +++++
 drivers/gpu/drm/i915/intel_slpc.c   | 158 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h   |   6 ++
 3 files changed, 183 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index dbfe185..0a04f3d 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2352,6 +2352,23 @@ static int i915_huc_load_status_info(struct seq_file *m, void *data)
 	return 0;
 }
 
+static int i915_slpc_paramlist_info(struct seq_file *m, void *data)
+{
+	struct drm_i915_private *dev_priv = node_to_i915(m->private);
+	int i;
+
+	if (!dev_priv->guc.slpc.active) {
+		seq_puts(m, "SLPC not active\n");
+		return 0;
+	}
+
+	seq_puts(m, "Param id\tParam description\n");
+	for (i = 0; i < SLPC_MAX_PARAM; i++)
+		seq_printf(m, "%8d\t%s\n", slpc_paramlist[i].id,
+					   slpc_paramlist[i].description);
+	return 0;
+}
+
 static int i915_guc_load_status_info(struct seq_file *m, void *data)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -4881,6 +4898,7 @@ static int i915_hpd_storm_ctl_open(struct inode *inode, struct file *file)
 	{"i915_guc_load_err_log_dump", i915_guc_log_dump, 0, (void *)1},
 	{"i915_guc_stage_pool", i915_guc_stage_pool, 0},
 	{"i915_huc_load_status", i915_huc_load_status_info, 0},
+	{"i915_slpc_paramlist", i915_slpc_paramlist_info, 0},
 	{"i915_frequency_info", i915_frequency_info, 0},
 	{"i915_hangcheck_info", i915_hangcheck_info, 0},
 	{"i915_reset_info", i915_reset_info, 0},
@@ -4944,6 +4962,7 @@ static int i915_hpd_storm_ctl_open(struct inode *inode, struct file *file)
 	{"i915_dp_test_type", &i915_displayport_test_type_fops},
 	{"i915_dp_test_active", &i915_displayport_test_active_fops},
 	{"i915_guc_log_control", &i915_guc_log_control_fops},
+	{"i915_slpc_param_ctl", &i915_slpc_param_ctl_fops},
 	{"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
 	{"i915_ipc_status", &i915_ipc_status_fops}
 };
diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index d0fd402..0c094f0 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -25,6 +25,8 @@
 #include <asm/msr-index.h>
 #include "i915_drv.h"
 #include "intel_uc.h"
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
 
 struct slpc_param slpc_paramlist[SLPC_MAX_PARAM] = {
 	{SLPC_PARAM_TASK_ENABLE_GTPERF, "Enable task GTPERF"},
@@ -684,3 +686,159 @@ void intel_slpc_disable(struct intel_slpc *slpc)
 
 	slpc->active = false;
 }
+
+static int slpc_param_ctl_show(struct seq_file *m, void *data)
+{
+	struct drm_i915_private *dev_priv = m->private;
+	struct intel_slpc *slpc = &dev_priv->guc.slpc;
+
+	if (!slpc->active) {
+		seq_puts(m, "SLPC not active\n");
+		return 0;
+	}
+
+	seq_printf(m, "%s=%u, override=%s\n",
+			slpc_paramlist[slpc->debug_param_id].description,
+			slpc->debug_param_value,
+			yesno(!!slpc->debug_param_override));
+
+	return 0;
+}
+
+static int slpc_param_ctl_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, slpc_param_ctl_show, inode->i_private);
+}
+
+static const char *read_token = "read", *write_token = "write",
+		  *revert_token = "revert";
+
+/*
+ * Parse SLPC parameter control strings: (Similar to Pipe CRC handling)
+ *   command: wsp* op wsp+ param id wsp+ [value] wsp*
+ *   op: "read"/"write"/"revert"
+ *   param id: slpc_param_id
+ *   value: u32 value
+ *   wsp: (#0x20 | #0x9 | #0xA)+
+ *
+ * eg.:
+ *  "read 0"		-> read SLPC_PARAM_TASK_ENABLE_GTPERF
+ *  "write 7 500"	-> set SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ to 500MHz
+ *  "revert 7"		-> revert SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ to
+ *			   default value.
+ */
+static int slpc_param_ctl_parse(char *buf, size_t len, char **op,
+				u32 *id, u32 *value)
+{
+#define MAX_WORDS 3
+	int n_words;
+	char *words[MAX_WORDS];
+	ssize_t ret;
+
+	n_words = buffer_tokenize(buf, words, MAX_WORDS);
+	if (!(n_words == 3) && !(n_words == 2)) {
+		DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n",
+				 MAX_WORDS);
+		return -EINVAL;
+	}
+
+	if (strcmp(words[0], read_token) && strcmp(words[0], write_token) &&
+	    strcmp(words[0], revert_token)) {
+		DRM_DEBUG_DRIVER("unknown operation\n");
+		return -EINVAL;
+	}
+
+	*op = words[0];
+
+	ret = kstrtou32(words[1], 0, id);
+	if (ret)
+		return ret;
+
+	if (n_words == 3) {
+		ret = kstrtou32(words[2], 0, value);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static ssize_t slpc_param_ctl_write(struct file *file, const char __user *ubuf,
+				     size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	struct drm_i915_private *dev_priv = m->private;
+	struct intel_slpc *slpc = &dev_priv->guc.slpc;
+	char *tmpbuf, *op = NULL;
+	u32 id, value;
+	int ret;
+
+	if (len == 0)
+		return 0;
+
+	if (len > 40) {
+		DRM_DEBUG_DRIVER("expected <40 chars into slpc_param_ctl\n");
+		return -E2BIG;
+	}
+
+	tmpbuf = kmalloc(len + 1, GFP_KERNEL);
+	if (!tmpbuf)
+		return -ENOMEM;
+
+	if (copy_from_user(tmpbuf, ubuf, len)) {
+		ret = -EFAULT;
+		goto out;
+	}
+	tmpbuf[len] = '\0';
+
+	ret = slpc_param_ctl_parse(tmpbuf, len, &op, &id, &value);
+
+	if (id >= SLPC_MAX_PARAM) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!strcmp(op, read_token)) {
+		intel_slpc_get_param(slpc, id,
+				     &slpc->debug_param_override,
+				     &slpc->debug_param_value);
+		slpc->debug_param_id = id;
+	} else if (!strcmp(op, write_token) || !strcmp(op, revert_token)) {
+		if ((id >= SLPC_PARAM_TASK_ENABLE_GTPERF) &&
+		    (id <= SLPC_PARAM_TASK_DISABLE_DCC)) {
+			DRM_DEBUG_DRIVER("Tasks are not controlled by "
+					 "this interface\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/*
+		 * After updating parameters, RESET event has to be sent to GuC
+		 * SLPC for ensuring parameters take effect.
+		 */
+		intel_runtime_pm_get(dev_priv);
+		if (!strcmp(op, write_token))
+			intel_slpc_set_param(slpc, id, value);
+		else if (!strcmp(op, revert_token))
+			intel_slpc_unset_param(slpc, id);
+		intel_slpc_enable(slpc);
+		intel_runtime_pm_put(dev_priv);
+	}
+
+out:
+	kfree(tmpbuf);
+	if (ret < 0)
+		return ret;
+
+	*offp += len;
+	return len;
+}
+
+const struct file_operations i915_slpc_param_ctl_fops = {
+	.owner = THIS_MODULE,
+	.open = slpc_param_ctl_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.write = slpc_param_ctl_write
+};
diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h
index ae857d3..e49c513 100644
--- a/drivers/gpu/drm/i915/intel_slpc.h
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -32,6 +32,10 @@ struct intel_slpc {
 	/* i915 cached SLPC frequency limits */
 	u32 min_unslice_freq;
 	u32 max_unslice_freq;
+
+	u32 debug_param_id;
+	u32 debug_param_value;
+	u32 debug_param_override;
 };
 
 static inline int intel_slpc_enabled(void)
@@ -251,6 +255,8 @@ struct slpc_param {
 #define SLPC_PARAM_TASK_DISABLED 2
 #define SLPC_PARAM_TASK_UNKNOWN  3
 
+extern const struct file_operations i915_slpc_param_ctl_fops;
+
 /* intel_slpc.c */
 void intel_slpc_set_param(struct intel_slpc *slpc, u32 id, u32 value);
 void intel_slpc_unset_param(struct intel_slpc *slpc, u32 id);
-- 
1.9.1

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

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

* [PATCH 25/31] drm/i915/slpc: Add enable/disable controls for SLPC tasks
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (23 preceding siblings ...)
  2017-09-19 17:42 ` [PATCH 24/31] drm/i915/slpc: Add debugfs support to read/write/revert the parameters Sagar Arun Kamble
@ 2017-09-19 17:42 ` Sagar Arun Kamble
  2017-09-19 17:42 ` [PATCH 26/31] drm/i915/slpc: Add i915_slpc_info to debugfs Sagar Arun Kamble
                   ` (5 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:42 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

From: Tom O'Rourke <Tom.O'Rourke@intel.com>

Adds debugfs hooks for enabling/disabling each SLPC task.

The enable/disable debugfs files are
i915_slpc_gtperf, i915_slpc_balancer, and i915_slpc_dcc.

Each of these can take the values:
"default", "enabled", or "disabled"

v1: update for SLPC v2015.2.4
    dfps and turbo merged and renamed "gtperf"
    ibc split out and renamed "balancer"
    Avoid magic numbers (Jon Bloomfield)

v2-v3: Rebase.

v5: Moved slpc_enable_disable_set and slpc_enable_disable_get to
    intel_slpc.c. s/slpc_enable_disable_get/intel_slpc_task_status
    and s/slpc_enable_disable_set/intel_slpc_task_control. Prepared
    separate functions to update the task status only in the SLPC
    shared memory. Passing dev_priv as parameter.

v6: Rebase. s/slpc_param_show|write/slpc_task_param_show|write.
    Moved functions to intel_slpc.c. RPM Get/Put added before setting
    parameters and sending RESET event explicitly. (Sagar)

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c |   3 +
 drivers/gpu/drm/i915/intel_slpc.c   | 184 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h   |   3 +
 3 files changed, 190 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 0a04f3d..e6fd63f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -4942,6 +4942,9 @@ static int i915_hpd_storm_ctl_open(struct inode *inode, struct file *file)
 	const struct file_operations *fops;
 } i915_debugfs_files[] = {
 	{"i915_wedged", &i915_wedged_fops},
+	{"i915_slpc_gtperf", &i915_slpc_gtperf_fops},
+	{"i915_slpc_balancer", &i915_slpc_balancer_fops},
+	{"i915_slpc_dcc", &i915_slpc_dcc_fops},
 	{"i915_max_freq", &i915_max_freq_fops},
 	{"i915_min_freq", &i915_min_freq_fops},
 	{"i915_cache_sharing", &i915_cache_sharing_fops},
diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index 0c094f0..512d88b 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -842,3 +842,187 @@ static ssize_t slpc_param_ctl_write(struct file *file, const char __user *ubuf,
 	.release = single_release,
 	.write = slpc_param_ctl_write
 };
+
+static void slpc_task_param_show(struct seq_file *m, u32 enable_id,
+				 u32 disable_id)
+{
+	struct drm_i915_private *dev_priv = m->private;
+	const char *status;
+	u64 val;
+	int ret;
+
+	ret = intel_slpc_task_status(&dev_priv->guc.slpc, &val,
+				     enable_id, disable_id);
+
+	if (ret) {
+		seq_printf(m, "error %d\n", ret);
+	} else {
+		switch (val) {
+		case SLPC_PARAM_TASK_DEFAULT:
+			status = "default\n";
+			break;
+
+		case SLPC_PARAM_TASK_ENABLED:
+			status = "enabled\n";
+			break;
+
+		case SLPC_PARAM_TASK_DISABLED:
+			status = "disabled\n";
+			break;
+
+		default:
+			status = "unknown\n";
+			break;
+		}
+
+		seq_puts(m, status);
+	}
+}
+
+static int slpc_task_param_write(struct seq_file *m, const char __user *ubuf,
+			    size_t len, u32 enable_id, u32 disable_id)
+{
+	struct drm_i915_private *dev_priv = m->private;
+	u64 val;
+	int ret = 0;
+	char buf[10];
+
+	if (len >= sizeof(buf))
+		ret = -EINVAL;
+	else if (copy_from_user(buf, ubuf, len))
+		ret = -EFAULT;
+	else
+		buf[len] = '\0';
+
+	if (!ret) {
+		if (!strncmp(buf, "default", 7))
+			val = SLPC_PARAM_TASK_DEFAULT;
+		else if (!strncmp(buf, "enabled", 7))
+			val = SLPC_PARAM_TASK_ENABLED;
+		else if (!strncmp(buf, "disabled", 8))
+			val = SLPC_PARAM_TASK_DISABLED;
+		else
+			ret = -EINVAL;
+	}
+
+	if (!ret)
+		ret = intel_slpc_task_control(&dev_priv->guc.slpc, val,
+					      enable_id, disable_id);
+
+	return ret;
+}
+
+static int slpc_gtperf_show(struct seq_file *m, void *data)
+{
+	slpc_task_param_show(m, SLPC_PARAM_TASK_ENABLE_GTPERF,
+			SLPC_PARAM_TASK_DISABLE_GTPERF);
+
+	return 0;
+}
+
+static int slpc_gtperf_open(struct inode *inode, struct file *file)
+{
+	struct drm_i915_private *dev_priv = inode->i_private;
+
+	return single_open(file, slpc_gtperf_show, dev_priv);
+}
+
+static ssize_t slpc_gtperf_write(struct file *file, const char __user *ubuf,
+			      size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	int ret = 0;
+
+	ret = slpc_task_param_write(m, ubuf, len, SLPC_PARAM_TASK_ENABLE_GTPERF,
+			       SLPC_PARAM_TASK_DISABLE_GTPERF);
+	if (ret)
+		return ret;
+
+	return len;
+}
+
+const struct file_operations i915_slpc_gtperf_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = slpc_gtperf_open,
+	.release = single_release,
+	.read	 = seq_read,
+	.write	 = slpc_gtperf_write,
+	.llseek	 = seq_lseek
+};
+
+static int slpc_balancer_show(struct seq_file *m, void *data)
+{
+	slpc_task_param_show(m, SLPC_PARAM_TASK_ENABLE_BALANCER,
+			SLPC_PARAM_TASK_DISABLE_BALANCER);
+
+	return 0;
+}
+
+static int slpc_balancer_open(struct inode *inode, struct file *file)
+{
+	struct drm_i915_private *dev_priv = inode->i_private;
+
+	return single_open(file, slpc_balancer_show, dev_priv);
+}
+
+static ssize_t slpc_balancer_write(struct file *file, const char __user *ubuf,
+			      size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	int ret = 0;
+
+	ret = slpc_task_param_write(m, ubuf, len,
+				SLPC_PARAM_TASK_ENABLE_BALANCER,
+				SLPC_PARAM_TASK_DISABLE_BALANCER);
+	if (ret)
+		return ret;
+
+	return len;
+}
+
+const struct file_operations i915_slpc_balancer_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = slpc_balancer_open,
+	.release = single_release,
+	.read	 = seq_read,
+	.write	 = slpc_balancer_write,
+	.llseek	 = seq_lseek
+};
+
+static int slpc_dcc_show(struct seq_file *m, void *data)
+{
+	slpc_task_param_show(m, SLPC_PARAM_TASK_ENABLE_DCC,
+			SLPC_PARAM_TASK_DISABLE_DCC);
+
+	return 0;
+}
+
+static int slpc_dcc_open(struct inode *inode, struct file *file)
+{
+	struct drm_i915_private *dev_priv = inode->i_private;
+
+	return single_open(file, slpc_dcc_show, dev_priv);
+}
+
+static ssize_t slpc_dcc_write(struct file *file, const char __user *ubuf,
+			      size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	int ret = 0;
+
+	ret = slpc_task_param_write(m, ubuf, len, SLPC_PARAM_TASK_ENABLE_DCC,
+			       SLPC_PARAM_TASK_DISABLE_DCC);
+	if (ret)
+		return ret;
+
+	return len;
+}
+
+const struct file_operations i915_slpc_dcc_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = slpc_dcc_open,
+	.release = single_release,
+	.read	 = seq_read,
+	.write	 = slpc_dcc_write,
+	.llseek	 = seq_lseek
+};
diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h
index e49c513..6006bf5 100644
--- a/drivers/gpu/drm/i915/intel_slpc.h
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -256,6 +256,9 @@ struct slpc_param {
 #define SLPC_PARAM_TASK_UNKNOWN  3
 
 extern const struct file_operations i915_slpc_param_ctl_fops;
+extern const struct file_operations i915_slpc_gtperf_fops;
+extern const struct file_operations i915_slpc_balancer_fops;
+extern const struct file_operations i915_slpc_dcc_fops;
 
 /* intel_slpc.c */
 void intel_slpc_set_param(struct intel_slpc *slpc, u32 id, u32 value);
-- 
1.9.1

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

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

* [PATCH 26/31] drm/i915/slpc: Add i915_slpc_info to debugfs
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (24 preceding siblings ...)
  2017-09-19 17:42 ` [PATCH 25/31] drm/i915/slpc: Add enable/disable controls for SLPC tasks Sagar Arun Kamble
@ 2017-09-19 17:42 ` Sagar Arun Kamble
  2017-09-21 15:13   ` Michal Wajdeczko
  2017-09-19 17:42 ` [PATCH 27/31] drm/i915/slpc: Add SLPC banner to RPS debugfs interfaces Sagar Arun Kamble
                   ` (4 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:42 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

From: Tom O'Rourke <Tom.O'Rourke@intel.com>

i915_slpc_info shows the contents of SLPC shared data
parsed into text format.

v1: Reformat slpc info (Radek)
    squashed query task state info
    in slpc info, kunmap before seq_print (Paulo)
    return void instead of ignored return value (Paulo)
    Avoid magic numbers and use local variables (Jon Bloomfield)
    Removed WARN_ON for checking msb of gtt address of
    shared gem obj. (ChrisW)
    Moved definition of power plan and power source to earlier
    patch in the series.
    drm/i915/slpc: Allocate/Release/Initialize SLPC shared data
    (Akash)

v2-v3: Rebase.

v4: Updated with GuC firmware v9.

v5: Updated host2guc_slpc_query_task_state with struct slpc_input_event
    structure. Removed unnecessary checks of vma from i915_slpc_info.
    Created helpers for reading the SLPC shared data and string form of
    SLPC state. (Sagar)

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 165 ++++++++++++++++++++++++++++++++++++
 1 file changed, 165 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index e6fd63f..7a0838f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1023,6 +1023,170 @@ static int i915_error_state_open(struct inode *inode, struct file *file)
 			NULL, i915_next_seqno_set,
 			"0x%llx\n");
 
+static int i915_slpc_info(struct seq_file *m, void *unused)
+{
+	struct drm_i915_private *dev_priv = node_to_i915(m->private);
+	int i, value;
+	struct slpc_shared_data data;
+	enum slpc_global_state global_state;
+	enum slpc_platform_sku platform_sku;
+	struct slpc_task_state_data *task_data;
+	enum slpc_power_plan power_plan;
+	enum slpc_power_source power_source;
+
+	if (!dev_priv->guc.slpc.active)
+		return -ENODEV;
+
+	intel_runtime_pm_get(dev_priv);
+	mutex_lock(&dev_priv->pm.pcu_lock);
+
+	intel_slpc_read_shared_data(&dev_priv->guc.slpc, &data);
+
+	mutex_unlock(&dev_priv->pm.pcu_lock);
+	intel_runtime_pm_put(dev_priv);
+
+	seq_printf(m, "shared data size: %d\n", data.shared_data_size);
+
+	global_state = (enum slpc_global_state) data.global_state;
+	seq_printf(m, "global state: %d (", global_state);
+	seq_printf(m, "%s)\n", intel_slpc_get_state_str(global_state));
+
+	platform_sku = (enum slpc_platform_sku)
+			data.platform_info.platform_sku;
+	seq_printf(m, "sku: %d (", platform_sku);
+	switch (platform_sku) {
+	case SLPC_PLATFORM_SKU_UNDEFINED:
+		seq_puts(m, "undefined)\n");
+		break;
+	case SLPC_PLATFORM_SKU_ULX:
+		seq_puts(m, "ULX)\n");
+		break;
+	case SLPC_PLATFORM_SKU_ULT:
+		seq_puts(m, "ULT)\n");
+		break;
+	case SLPC_PLATFORM_SKU_T:
+		seq_puts(m, "T)\n");
+		break;
+	case SLPC_PLATFORM_SKU_MOBL:
+		seq_puts(m, "Mobile)\n");
+		break;
+	case SLPC_PLATFORM_SKU_DT:
+		seq_puts(m, "DT)\n");
+		break;
+	case SLPC_PLATFORM_SKU_UNKNOWN:
+	default:
+		seq_puts(m, "unknown)\n");
+		break;
+	}
+	seq_printf(m, "slice count: %d\n",
+		   data.platform_info.slice_count);
+
+	seq_printf(m, "power plan/source: 0x%x\n\tplan:\t",
+		   data.platform_info.power_plan_source);
+	power_plan = (enum slpc_power_plan) SLPC_POWER_PLAN(
+				data.platform_info.power_plan_source);
+	power_source = (enum slpc_power_source) SLPC_POWER_SOURCE(
+				data.platform_info.power_plan_source);
+	switch (power_plan) {
+	case SLPC_POWER_PLAN_UNDEFINED:
+		seq_puts(m, "undefined");
+		break;
+	case SLPC_POWER_PLAN_BATTERY_SAVER:
+		seq_puts(m, "battery saver");
+		break;
+	case SLPC_POWER_PLAN_BALANCED:
+		seq_puts(m, "balanced");
+		break;
+	case SLPC_POWER_PLAN_PERFORMANCE:
+		seq_puts(m, "performance");
+		break;
+	case SLPC_POWER_PLAN_UNKNOWN:
+	default:
+		seq_puts(m, "unknown");
+		break;
+	}
+	seq_puts(m, "\n\tsource:\t");
+	switch (power_source) {
+	case SLPC_POWER_SOURCE_UNDEFINED:
+		seq_puts(m, "undefined\n");
+		break;
+	case SLPC_POWER_SOURCE_AC:
+		seq_puts(m, "AC\n");
+		break;
+	case SLPC_POWER_SOURCE_DC:
+		seq_puts(m, "DC\n");
+		break;
+	case SLPC_POWER_SOURCE_UNKNOWN:
+	default:
+		seq_puts(m, "unknown\n");
+		break;
+	}
+
+	seq_printf(m, "IA frequency (MHz):\n\tP0: %d\n\tP1: %d\n\tPe: %d\n\tPn: %d\n",
+		   data.platform_info.P0_freq * 50,
+		   data.platform_info.P1_freq * 50,
+		   data.platform_info.Pe_freq * 50,
+		   data.platform_info.Pn_freq * 50);
+
+	task_data = &data.task_state_data;
+	seq_printf(m, "task state data: 0x%08x 0x%08x\n",
+		   task_data->bitfield1, task_data->bitfield2);
+
+	seq_printf(m, "\tgtperf task active: %s\n",
+		   yesno(task_data->gtperf_task_active));
+	seq_printf(m, "\tgtperf stall possible: %s\n",
+		   yesno(task_data->gtperf_stall_possible));
+	seq_printf(m, "\tgtperf gaming mode: %s\n",
+		   yesno(task_data->gtperf_gaming_mode));
+	seq_printf(m, "\tgtperf target fps: %d\n",
+		   task_data->gtperf_target_fps);
+
+	seq_printf(m, "\tdcc task active: %s\n",
+		   yesno(task_data->dcc_task_active));
+	seq_printf(m, "\tin dcc: %s\n",
+		   yesno(task_data->in_dcc));
+	seq_printf(m, "\tin dct: %s\n",
+		   yesno(task_data->in_dct));
+	seq_printf(m, "\tfreq switch active: %s\n",
+		   yesno(task_data->freq_switch_active));
+
+	seq_printf(m, "\tibc enabled: %s\n",
+		   yesno(task_data->ibc_enabled));
+	seq_printf(m, "\tibc active: %s\n",
+		   yesno(task_data->ibc_active));
+	seq_printf(m, "\tpg1 enabled: %s\n",
+		   yesno(task_data->pg1_enabled));
+	seq_printf(m, "\tpg1 active: %s\n",
+		   yesno(task_data->pg1_active));
+
+	seq_printf(m, "\tunslice max freq: %dMHz\n",
+		   intel_gpu_freq(dev_priv,
+			task_data->max_unslice_freq * GEN9_FREQ_SCALER));
+	seq_printf(m, "\tunslice min freq: %dMHz\n",
+		   intel_gpu_freq(dev_priv,
+			task_data->min_unslice_freq * GEN9_FREQ_SCALER));
+	seq_printf(m, "\tslice max freq: %dMHz\n",
+		   intel_gpu_freq(dev_priv,
+			task_data->max_slice_freq * GEN9_FREQ_SCALER));
+	seq_printf(m, "\tslice min freq: %dMHz\n",
+		   intel_gpu_freq(dev_priv,
+			task_data->min_slice_freq * GEN9_FREQ_SCALER));
+
+	seq_puts(m, "override parameter bitfield\n");
+	for (i = 0; i < SLPC_OVERRIDE_BITFIELD_SIZE; i++)
+		seq_printf(m, "%d: 0x%08x\n", i,
+			   data.override_parameters_set_bits[i]);
+
+	seq_puts(m, "override parameters (only non-zero shown)\n");
+	for (i = 0; i < SLPC_MAX_OVERRIDE_PARAMETERS; i++) {
+		value = data.override_parameters_values[i];
+		if (value)
+			seq_printf(m, "%d: 0x%8x\n", i, value);
+	}
+
+	return 0;
+}
+
 static int i915_frequency_info(struct seq_file *m, void *unused)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -4899,6 +5063,7 @@ static int i915_hpd_storm_ctl_open(struct inode *inode, struct file *file)
 	{"i915_guc_stage_pool", i915_guc_stage_pool, 0},
 	{"i915_huc_load_status", i915_huc_load_status_info, 0},
 	{"i915_slpc_paramlist", i915_slpc_paramlist_info, 0},
+	{"i915_slpc_info", i915_slpc_info, 0},
 	{"i915_frequency_info", i915_frequency_info, 0},
 	{"i915_hangcheck_info", i915_hangcheck_info, 0},
 	{"i915_reset_info", i915_reset_info, 0},
-- 
1.9.1

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

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

* [PATCH 27/31] drm/i915/slpc: Add SLPC banner to RPS debugfs interfaces.
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (25 preceding siblings ...)
  2017-09-19 17:42 ` [PATCH 26/31] drm/i915/slpc: Add i915_slpc_info to debugfs Sagar Arun Kamble
@ 2017-09-19 17:42 ` Sagar Arun Kamble
  2017-09-19 17:42 ` [PATCH 28/31] drm/i915/slpc: Add SKL SLPC Support Sagar Arun Kamble
                   ` (3 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:42 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

When SLPC is controlling frequency requests, RPS state related to
autotuning is no longer valid. Make user aware through banner
upfront. Value read from register RPNSWREQ likely has the frequency
requested last by GuC SLPC.

v1: Replace HAS_SLPC with intel_slpc_active (Paulo)
    Avoid magic numbers (Nick)
    Use a function for repeated code (Jon)

v2: Add "SLPC Active" to i915_frequency_info output and
    don't update cur_freq as it is driver internal request. (Chris)

v3: Removing sysfs interface gt_req_freq_mhz out of this patch
    for proper division of functionality. (Sagar)

v4: idle_freq, boost_freq are also not used with SLPC.

v5: Added SLPC banner to i915_rps_boost_info and keep printing
    driver internal values. (Chris)

v6: Commit message update.

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 7a0838f..a873565 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1195,6 +1195,9 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 
 	intel_runtime_pm_get(dev_priv);
 
+	if (intel_slpc_active(&dev_priv->guc.slpc))
+		seq_puts(m, "SLPC Active\n");
+
 	if (IS_GEN5(dev_priv)) {
 		u16 rgvswctl = I915_READ16(MEMSWCTL);
 		u16 rgvstat = I915_READ16(MEMSTAT_ILK);
@@ -2409,6 +2412,9 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
 	struct intel_rps *rps = &dev_priv->pm.rps;
 	struct drm_file *file;
 
+	if (intel_slpc_active(&dev_priv->guc.slpc))
+		seq_puts(m, "SLPC Active\n");
+
 	seq_printf(m, "RPS enabled? %d\n", rps->enabled);
 	seq_printf(m, "GPU busy? %s [%d requests]\n",
 		   yesno(dev_priv->gt.awake), dev_priv->gt.active_requests);
-- 
1.9.1

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

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

* [PATCH 28/31] drm/i915/slpc: Add SKL SLPC Support
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (26 preceding siblings ...)
  2017-09-19 17:42 ` [PATCH 27/31] drm/i915/slpc: Add SLPC banner to RPS debugfs interfaces Sagar Arun Kamble
@ 2017-09-19 17:42 ` Sagar Arun Kamble
  2017-09-19 17:42 ` [PATCH 29/31] drm/i915/slpc: Add Broxton SLPC support Sagar Arun Kamble
                   ` (2 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:42 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

From: Tom O'Rourke <Tom.O'Rourke@intel.com>

This patch adds has_slpc to skylake info.

The SLPC interface has changed and could continue to
change. Only GuC versions known to be compatible are
supported here.

v1: Move slpc_version_check to intel_guc_ucode_init.
    fix whitespace (Sagar)
    Moved version check to different patch as has_slpc
    should not be updated based on it. Instead module parameter
    should be updated based on version check. (Sagar)
    Added support to skylake_gt3 as well. (Sagar)

Reviewed-by: David Weinehall <david.weinehall@linux.intel.com>
Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_pci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 853002f..26eb673 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -426,6 +426,7 @@
 	.platform = INTEL_SKYLAKE, \
 	.has_csr = 1, \
 	.has_guc = 1, \
+	.has_slpc = 1, \
 	.ddb_size = 896
 
 static const struct intel_device_info intel_skylake_gt1_info __initconst = {
-- 
1.9.1

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

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

* [PATCH 29/31] drm/i915/slpc: Add Broxton SLPC support
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (27 preceding siblings ...)
  2017-09-19 17:42 ` [PATCH 28/31] drm/i915/slpc: Add SKL SLPC Support Sagar Arun Kamble
@ 2017-09-19 17:42 ` Sagar Arun Kamble
  2017-09-19 17:42 ` [PATCH 30/31] drm/i915/slpc: Add Kabylake " Sagar Arun Kamble
  2017-09-19 17:42 ` [PATCH 31/31] drm/i915/slpc: Add Geminilake " Sagar Arun Kamble
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:42 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tom O'Rourke

From: Tom O'Rourke <Tom.O'Rourke@intel.com>

Adds has_slpc to broxton info.

v1: Adjusted slpc version check for major version 8.
    Added message if version mismatch happens for easier debug. (Sagar)

v2-v3: Rebase.

v4: Commit message update.

v5: Rebase. Updated check in sanitize_slpc_option.

Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_pci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 26eb673..026dc0c 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -484,6 +484,7 @@
 
 static const struct intel_device_info intel_broxton_info __initconst = {
 	GEN9_LP_FEATURES,
+	.has_slpc = 1,
 	.platform = INTEL_BROXTON,
 	.ddb_size = 512,
 };
-- 
1.9.1

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

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

* [PATCH 30/31] drm/i915/slpc: Add Kabylake SLPC support
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (28 preceding siblings ...)
  2017-09-19 17:42 ` [PATCH 29/31] drm/i915/slpc: Add Broxton SLPC support Sagar Arun Kamble
@ 2017-09-19 17:42 ` Sagar Arun Kamble
  2017-09-19 17:42 ` [PATCH 31/31] drm/i915/slpc: Add Geminilake " Sagar Arun Kamble
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:42 UTC (permalink / raw)
  To: intel-gfx

Adds has_slpc to kabylake info.

Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_pci.c   | 1 +
 drivers/gpu/drm/i915/intel_slpc.c | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 026dc0c..d89d6fc 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -502,6 +502,7 @@
 	.platform = INTEL_KABYLAKE, \
 	.has_csr = 1, \
 	.has_guc = 1, \
+	.has_slpc = 1, \
 	.has_ipc = 1, \
 	.ddb_size = 896
 
diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index 512d88b..b723b46 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -71,9 +71,9 @@ static unsigned int slpc_get_platform_sku(struct drm_i915_private *dev_priv)
 {
 	enum slpc_platform_sku platform_sku;
 
-	if (IS_SKL_ULX(dev_priv))
+	if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv))
 		platform_sku = SLPC_PLATFORM_SKU_ULX;
-	else if (IS_SKL_ULT(dev_priv))
+	else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv))
 		platform_sku = SLPC_PLATFORM_SKU_ULT;
 	else
 		platform_sku = SLPC_PLATFORM_SKU_DT;
-- 
1.9.1

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

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

* [PATCH 31/31] drm/i915/slpc: Add Geminilake SLPC support
  2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
                   ` (29 preceding siblings ...)
  2017-09-19 17:42 ` [PATCH 30/31] drm/i915/slpc: Add Kabylake " Sagar Arun Kamble
@ 2017-09-19 17:42 ` Sagar Arun Kamble
  30 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-19 17:42 UTC (permalink / raw)
  To: intel-gfx

Adds has_slpc to geminilake info.

Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
 drivers/gpu/drm/i915/i915_pci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index d89d6fc..738e214 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -491,6 +491,7 @@
 
 static const struct intel_device_info intel_geminilake_info __initconst = {
 	GEN9_LP_FEATURES,
+	.has_slpc = 1,
 	.platform = INTEL_GEMINILAKE,
 	.ddb_size = 1024,
 	.color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 }
-- 
1.9.1

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

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

* Re: [PATCH 03/31] drm/i915: Separate RPS and RC6 handling for BDW
  2017-09-19 17:41 ` [PATCH 03/31] drm/i915: Separate RPS and RC6 handling for BDW Sagar Arun Kamble
@ 2017-09-20 11:14   ` Szwichtenberg, Radoslaw
  2017-09-20 12:31     ` Szwichtenberg, Radoslaw
  0 siblings, 1 reply; 58+ messages in thread
From: Szwichtenberg, Radoslaw @ 2017-09-20 11:14 UTC (permalink / raw)
  To: intel-gfx, Kamble, Sagar A

On Tue, 2017-09-19 at 23:11 +0530, Sagar Arun Kamble wrote:
> This patch separates RC6 and RPS enabling for BDW.
> RC6/RPS Disabling are handled through gen6 functions.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 27 +++++++++++++++------------
>  1 file changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index f78a1e8..6de69ae 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -6613,7 +6613,7 @@ static void gen9_enable_rc6(struct drm_i915_private
> *dev_priv)
>  	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>  }
>  
> -static void gen8_enable_rps(struct drm_i915_private *dev_priv)
> +static void gen8_enable_rc6(struct drm_i915_private *dev_priv)
>  {
>  	struct intel_engine_cs *engine;
>  	enum intel_engine_id id;
> @@ -6645,16 +6645,18 @@ static void gen8_enable_rps(struct drm_i915_private
> *dev_priv)
>  	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
>  		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
>  	intel_print_rc6_info(dev_priv, rc6_mask);
> -	if (IS_BROADWELL(dev_priv))
> -		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
> -				GEN7_RC_CTL_TO_MODE |
> -				rc6_mask);
> -	else
> -		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
> -				GEN6_RC_CTL_EI_MODE(1) |
> -				rc6_mask);
> +	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
> +			GEN7_RC_CTL_TO_MODE |
> +			rc6_mask);
>  
> -	/* 4 Program defaults and thresholds for RPS*/
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
> +}
> +
> +static void gen8_enable_rps(struct drm_i915_private *dev_priv)
> +{
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
> +
> +	/* 1 Program defaults and thresholds for RPS*/
>  	I915_WRITE(GEN6_RPNSWREQ,
>  		   HSW_FREQUENCY(dev_priv->rps.rp1_freq));
>  	I915_WRITE(GEN6_RC_VIDEO_FREQ,
> @@ -6674,7 +6676,7 @@ static void gen8_enable_rps(struct drm_i915_private
> *dev_priv)
>  
>  	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
>  
> -	/* 5: Enable RPS */
> +	/* 2: Enable RPS */
>  	I915_WRITE(GEN6_RP_CONTROL,
>  		   GEN6_RP_MEDIA_TURBO |
>  		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
> @@ -6683,7 +6685,7 @@ static void gen8_enable_rps(struct drm_i915_private
> *dev_priv)
>  		   GEN6_RP_UP_BUSY_AVG |
>  		   GEN6_RP_DOWN_IDLE_AVG);
>  
> -	/* 6: Ring frequency + overclocking (our driver does this later */
> +	/* 3: Ring frequency + overclocking (our driver does this later */
This comment looks invalid (no overclocking done here). Also closing bracket
missing and maybe one white line to be removed :)

-Radek
>  
>  	reset_rps(dev_priv, gen6_set_rps);
>  
> @@ -7976,6 +7978,7 @@ void intel_enable_gt_powersave(struct drm_i915_private
> *dev_priv)
>  		if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv))
>  			gen6_update_ring_freq(dev_priv);
>  	} else if (IS_BROADWELL(dev_priv)) {
> +		gen8_enable_rc6(dev_priv);
>  		gen8_enable_rps(dev_priv);
>  		gen6_update_ring_freq(dev_priv);
>  	} else if (INTEL_GEN(dev_priv) >= 6) {
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 02/31] drm/i915: Separate RPS and RC6 handling for gen6+
  2017-09-19 17:41 ` [PATCH 02/31] drm/i915: Separate RPS and RC6 handling for gen6+ Sagar Arun Kamble
@ 2017-09-20 12:29   ` Szwichtenberg, Radoslaw
  0 siblings, 0 replies; 58+ messages in thread
From: Szwichtenberg, Radoslaw @ 2017-09-20 12:29 UTC (permalink / raw)
  To: intel-gfx, Kamble, Sagar A

On Tue, 2017-09-19 at 23:11 +0530, Sagar Arun Kamble wrote:
> This patch separates enable/disable of RC6 and RPS for gen6+
> platforms prior to VLV.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>

Reviewed-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/31] drm/i915: Separate RPS and RC6 handling for VLV
  2017-09-19 17:41 ` [PATCH 04/31] drm/i915: Separate RPS and RC6 handling for VLV Sagar Arun Kamble
@ 2017-09-20 12:30   ` Szwichtenberg, Radoslaw
  0 siblings, 0 replies; 58+ messages in thread
From: Szwichtenberg, Radoslaw @ 2017-09-20 12:30 UTC (permalink / raw)
  To: intel-gfx, Kamble, Sagar A

On Tue, 2017-09-19 at 23:11 +0530, Sagar Arun Kamble wrote:
> This patch separates enable/disable of RC6 and RPS for VLV.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/31] drm/i915: Separate RPS and RC6 handling for BDW
  2017-09-20 11:14   ` Szwichtenberg, Radoslaw
@ 2017-09-20 12:31     ` Szwichtenberg, Radoslaw
  0 siblings, 0 replies; 58+ messages in thread
From: Szwichtenberg, Radoslaw @ 2017-09-20 12:31 UTC (permalink / raw)
  To: intel-gfx, Kamble, Sagar A

On Wed, 2017-09-20 at 11:14 +0000, Szwichtenberg, Radoslaw wrote:
> On Tue, 2017-09-19 at 23:11 +0530, Sagar Arun Kamble wrote:
> > This patch separates RC6 and RPS enabling for BDW.
> > RC6/RPS Disabling are handled through gen6 functions.
> > 
> > Cc: Imre Deak <imre.deak@intel.com>
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 27 +++++++++++++++------------
> >  1 file changed, 15 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c
> > b/drivers/gpu/drm/i915/intel_pm.c
> > index f78a1e8..6de69ae 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -6613,7 +6613,7 @@ static void gen9_enable_rc6(struct drm_i915_private
> > *dev_priv)
> >  	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
> >  }
> >  
> > -static void gen8_enable_rps(struct drm_i915_private *dev_priv)
> > +static void gen8_enable_rc6(struct drm_i915_private *dev_priv)
> >  {
> >  	struct intel_engine_cs *engine;
> >  	enum intel_engine_id id;
> > @@ -6645,16 +6645,18 @@ static void gen8_enable_rps(struct drm_i915_private
> > *dev_priv)
> >  	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
> >  		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
> >  	intel_print_rc6_info(dev_priv, rc6_mask);
> > -	if (IS_BROADWELL(dev_priv))
> > -		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
> > -				GEN7_RC_CTL_TO_MODE |
> > -				rc6_mask);
> > -	else
> > -		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
> > -				GEN6_RC_CTL_EI_MODE(1) |
> > -				rc6_mask);
> > +	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
> > +			GEN7_RC_CTL_TO_MODE |
> > +			rc6_mask);
> >  
> > -	/* 4 Program defaults and thresholds for RPS*/
> > +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
> > +}
> > +
> > +static void gen8_enable_rps(struct drm_i915_private *dev_priv)
> > +{
> > +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
> > +
> > +	/* 1 Program defaults and thresholds for RPS*/
> >  	I915_WRITE(GEN6_RPNSWREQ,
> >  		   HSW_FREQUENCY(dev_priv->rps.rp1_freq));
> >  	I915_WRITE(GEN6_RC_VIDEO_FREQ,
> > @@ -6674,7 +6676,7 @@ static void gen8_enable_rps(struct drm_i915_private
> > *dev_priv)
> >  
> >  	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
> >  
> > -	/* 5: Enable RPS */
> > +	/* 2: Enable RPS */
> >  	I915_WRITE(GEN6_RP_CONTROL,
> >  		   GEN6_RP_MEDIA_TURBO |
> >  		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
> > @@ -6683,7 +6685,7 @@ static void gen8_enable_rps(struct drm_i915_private
> > *dev_priv)
> >  		   GEN6_RP_UP_BUSY_AVG |
> >  		   GEN6_RP_DOWN_IDLE_AVG);
> >  
> > -	/* 6: Ring frequency + overclocking (our driver does this later */
> > +	/* 3: Ring frequency + overclocking (our driver does this later */
> 
> This comment looks invalid (no overclocking done here). Also closing bracket
> missing and maybe one white line to be removed :)
> 
> -Radek
Forgot to mention - beside this comment all changes look good to me (you can
have my r-b after this is fixed).
> >  
> >  	reset_rps(dev_priv, gen6_set_rps);
> >  
> > @@ -7976,6 +7978,7 @@ void intel_enable_gt_powersave(struct drm_i915_private
> > *dev_priv)
> >  		if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv))
> >  			gen6_update_ring_freq(dev_priv);
> >  	} else if (IS_BROADWELL(dev_priv)) {
> > +		gen8_enable_rc6(dev_priv);
> >  		gen8_enable_rps(dev_priv);
> >  		gen6_update_ring_freq(dev_priv);
> >  	} else if (INTEL_GEN(dev_priv) >= 6) {
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/31] drm/i915: Separate RPS and RC6 handling for CHV
  2017-09-19 17:41 ` [PATCH 05/31] drm/i915: Separate RPS and RC6 handling for CHV Sagar Arun Kamble
@ 2017-09-20 12:32   ` Szwichtenberg, Radoslaw
  0 siblings, 0 replies; 58+ messages in thread
From: Szwichtenberg, Radoslaw @ 2017-09-20 12:32 UTC (permalink / raw)
  To: intel-gfx, Kamble, Sagar A

On Tue, 2017-09-19 at 23:11 +0530, Sagar Arun Kamble wrote:
> This patch separates enable/disable of RC6 and RPS for CHV.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 06/31] drm/i915: Name i915_runtime_pm structure in dev_priv as "rpm"
  2017-09-19 17:41 ` [PATCH 06/31] drm/i915: Name i915_runtime_pm structure in dev_priv as "rpm" Sagar Arun Kamble
@ 2017-09-20 12:34   ` Szwichtenberg, Radoslaw
  0 siblings, 0 replies; 58+ messages in thread
From: Szwichtenberg, Radoslaw @ 2017-09-20 12:34 UTC (permalink / raw)
  To: intel-gfx, Kamble, Sagar A

On Tue, 2017-09-19 at 23:11 +0530, Sagar Arun Kamble wrote:
> Will be using pm for state containing RPS/RC6 state in the next patch.
> 
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 07/31] drm/i915: Name structure in dev_priv that contains RPS/RC6 state as "pm"
  2017-09-19 17:41 ` [PATCH 07/31] drm/i915: Name structure in dev_priv that contains RPS/RC6 state as "pm" Sagar Arun Kamble
@ 2017-09-21  8:23   ` Szwichtenberg, Radoslaw
  0 siblings, 0 replies; 58+ messages in thread
From: Szwichtenberg, Radoslaw @ 2017-09-21  8:23 UTC (permalink / raw)
  To: intel-gfx, Kamble, Sagar A

On Tue, 2017-09-19 at 23:11 +0530, Sagar Arun Kamble wrote:
> Prepared substructure rps for RPS related state. autoenable_work and
> pcu_lock are used for RC6 hence they are defined outside rps structure.
> Renamed the RPS lock as pcu_lock.
> 
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Imre Deak <imre.deak@intel.com>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/31] drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled
  2017-09-19 17:41 ` [PATCH 08/31] drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled Sagar Arun Kamble
@ 2017-09-21  8:26   ` Szwichtenberg, Radoslaw
  2017-09-26  7:41   ` Ewelina Musial
  1 sibling, 0 replies; 58+ messages in thread
From: Szwichtenberg, Radoslaw @ 2017-09-21  8:26 UTC (permalink / raw)
  To: intel-gfx, Kamble, Sagar A

On Tue, 2017-09-19 at 23:11 +0530, Sagar Arun Kamble wrote:
> This function gives the status of RC6, whether disabled or if
> enabled then which state. intel_enable_rc6 will be used for
> enabling RC6 in the next patch.
> 
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Imre Deak <imre.deak@intel.com>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 15/31] drm/i915/slpc: Sanitize GuC version
  2017-09-19 17:41 ` [PATCH 15/31] drm/i915/slpc: Sanitize GuC version Sagar Arun Kamble
@ 2017-09-21 12:52   ` Michal Wajdeczko
  2017-09-28  9:20     ` Sagar Arun Kamble
  0 siblings, 1 reply; 58+ messages in thread
From: Michal Wajdeczko @ 2017-09-21 12:52 UTC (permalink / raw)
  To: intel-gfx, Sagar Arun Kamble; +Cc: Tom O'Rourke

On Tue, 19 Sep 2017 19:41:51 +0200, Sagar Arun Kamble  
<sagar.a.kamble@intel.com> wrote:

> From: Tom O'Rourke <Tom.O'Rourke@intel.com>
>
> The SLPC interface is dependent on GuC version.
> Only GuC versions known to be compatible are supported here.
>
> SLPC with GuC firmware v9 is supported with this series.
>
> v1: Updated with modified sanitize_slpc_option in earlier patch.
>
> v2-v3: Rebase.
>
> v4: Updated support for GuC firmware v9.
>
> v5: Commit subject updated.
>
> v6: Commit subject and message update. Add support condition as >=v9.
>
> v7: Sanitizing GuC version in intel_uc_init_fw for SLPC compatibility.
>     Added info. print for needed version and pointer to 01.org.
>
> v8: s/FIRMWARE_URL/I915_FIRMWARE_URL, Macro added for SLPC required GuC
>     Major version and rearrangement for sanitization. (MichalW, Joonas)
>
> v9: Checking major_ver_found to sanitize SLPC option enable_slpc post
>     fetching the firmware as with Custom firmware loaded through
>     guc_firmware_path parameter, major_ver_wanted are cleared. (Lukasz)
>
> v10: Moved the I915_FIRMWARE_URL macro to intel_uc_common.h.
>
> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_csr.c        | 15 ++++++---------
>  drivers/gpu/drm/i915/intel_guc.h        |  1 +
>  drivers/gpu/drm/i915/intel_guc_loader.c | 15 +++++++++++++++
>  drivers/gpu/drm/i915/intel_uc.c         |  1 +
>  drivers/gpu/drm/i915/intel_uc_common.h  |  2 ++
>  5 files changed, 25 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_csr.c  
> b/drivers/gpu/drm/i915/intel_csr.c
> index 965988f..56c56f5 100644
> --- a/drivers/gpu/drm/i915/intel_csr.c
> +++ b/drivers/gpu/drm/i915/intel_csr.c
> @@ -52,11 +52,6 @@
>  MODULE_FIRMWARE(I915_CSR_BXT);
>  #define BXT_CSR_VERSION_REQUIRED	CSR_VERSION(1, 7)
> -#define FIRMWARE_URL  "https://01.org/linuxgraphics/downloads/firmware"
> -
> -
> -
> -
>  #define CSR_MAX_FW_SIZE			0x2FFF
>  #define CSR_DEFAULT_FW_OFFSET		0xFFFFFFFF
> @@ -309,11 +304,12 @@ static uint32_t *parse_csr_fw(struct  
> drm_i915_private *dev_priv,
> 	if (csr->version != required_version) {
>  		DRM_INFO("Refusing to load DMC firmware v%u.%u,"
> -			 " please use v%u.%u [" FIRMWARE_URL "].\n",
> +			 " please use v%u.%u [%s].\n",
>  			 CSR_VERSION_MAJOR(csr->version),
>  			 CSR_VERSION_MINOR(csr->version),
>  			 CSR_VERSION_MAJOR(required_version),
> -			 CSR_VERSION_MINOR(required_version));
> +			 CSR_VERSION_MINOR(required_version),
> +			 I915_FIRMWARE_URL);

Hmm, I'm not sure that including URL here is useful.
URL will be repeated in csr_load_work_fn() where we can explain
its purpose ;)


>  		return NULL;
>  	}
> @@ -420,8 +416,9 @@ static void csr_load_work_fn(struct work_struct  
> *work)
>  	} else {
>  		dev_notice(dev_priv->drm.dev,
>  			   "Failed to load DMC firmware"
> -			   " [" FIRMWARE_URL "],"
> -			   " disabling runtime power management.\n");
> +			   " [%s],"
> +			   " disabling runtime power management.\n",
> +			   I915_FIRMWARE_URL);

Maybe more user friendly message should looks like:

"Failed to load DMC firmware, disabling runtime power management."
"DMC firmware can be downloaded from  
https://01.org/linuxgraphics/downloads/firmware"

>  	}
> 	release_firmware(fw);
> diff --git a/drivers/gpu/drm/i915/intel_guc.h  
> b/drivers/gpu/drm/i915/intel_guc.h
> index a894991..3821bf2 100644
> --- a/drivers/gpu/drm/i915/intel_guc.h
> +++ b/drivers/gpu/drm/i915/intel_guc.h
> @@ -159,6 +159,7 @@ static inline void intel_guc_init_early(struct  
> intel_guc *guc)
>  int intel_guc_select_fw(struct intel_guc *guc);
>  int intel_guc_init_hw(struct intel_guc *guc);
>  u32 intel_guc_wopcm_size(struct intel_guc *guc);
> +void intel_guc_fetch_sanitize_options(struct intel_guc *guc);
> /* i915_guc_submission.c */
>  int i915_guc_submission_init(struct drm_i915_private *dev_priv);
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c  
> b/drivers/gpu/drm/i915/intel_guc_loader.c
> index 6ee7c16..4550620 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -64,6 +64,8 @@
>  #define GLK_FW_MAJOR 10
>  #define GLK_FW_MINOR 56
> +#define I915_SLPC_REQUIRED_GUC_MAJOR 9
> +
>  #define GUC_FW_PATH(platform, major, minor) \
>         "i915/" __stringify(platform) "_guc_ver" __stringify(major) "_"  
> __stringify(minor) ".bin"
> @@ -418,3 +420,16 @@ int intel_guc_select_fw(struct intel_guc *guc)
> 	return 0;
>  }
> +
> +void intel_guc_fetch_sanitize_options(struct intel_guc *guc)
> +{
> +	if (guc->fw.major_ver_found <
> +			I915_SLPC_REQUIRED_GUC_MAJOR) {

Generally we do not allow Guc fw major "found" to be different than  
"wanted"
so this check could be also done against "wanted".

> +		DRM_INFO("SLPC not supported with GuC firmware"
> +			 " v%u, please use v%u+ [%s].\n",
> +			 guc->fw.major_ver_found,
> +			 I915_SLPC_REQUIRED_GUC_MAJOR,
> +			 I915_FIRMWARE_URL);

Not sure that URL in this message is helpful.

> +		i915.enable_slpc = 0;
> +	}
> +}
> diff --git a/drivers/gpu/drm/i915/intel_uc.c  
> b/drivers/gpu/drm/i915/intel_uc.c
> index eeec986..350027f 100644
> --- a/drivers/gpu/drm/i915/intel_uc.c
> +++ b/drivers/gpu/drm/i915/intel_uc.c
> @@ -194,6 +194,7 @@ static void fetch_uc_fw(struct drm_i915_private  
> *dev_priv,
>  		}
>  		uc_fw->major_ver_found = css->guc.sw_version >> 16;
>  		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
> +		intel_guc_fetch_sanitize_options(&dev_priv->guc);

This should be done as part of intel_uc_sanitize_options()

>  		break;
> 	case INTEL_UC_FW_TYPE_HUC:
> diff --git a/drivers/gpu/drm/i915/intel_uc_common.h  
> b/drivers/gpu/drm/i915/intel_uc_common.h
> index 3de6823..4726511 100644
> --- a/drivers/gpu/drm/i915/intel_uc_common.h
> +++ b/drivers/gpu/drm/i915/intel_uc_common.h
> @@ -27,6 +27,8 @@
>  #include "intel_ringbuffer.h"
>  #include "i915_vma.h"

Add separation line

> +#define I915_FIRMWARE_URL   
> "https://01.org/linuxgraphics/intel-linux-graphics-firmwares"
> +
>  enum intel_uc_fw_status {
>  	INTEL_UC_FIRMWARE_FAIL = -1,
>  	INTEL_UC_FIRMWARE_NONE = 0,

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

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

* Re: [PATCH 16/31] drm/i915/slpc: Lay out SLPC init/enable/disable/cleanup helpers
  2017-09-19 17:41 ` [PATCH 16/31] drm/i915/slpc: Lay out SLPC init/enable/disable/cleanup helpers Sagar Arun Kamble
@ 2017-09-21 13:00   ` Michal Wajdeczko
  2017-09-28  9:29     ` Sagar Arun Kamble
  0 siblings, 1 reply; 58+ messages in thread
From: Michal Wajdeczko @ 2017-09-21 13:00 UTC (permalink / raw)
  To: intel-gfx, Sagar Arun Kamble; +Cc: Tom O'Rourke

On Tue, 19 Sep 2017 19:41:52 +0200, Sagar Arun Kamble  
<sagar.a.kamble@intel.com> wrote:

> SLPC operates based on parameters setup in shared data between
> i915 and GuC SLPC. This is to be created/initialized in intel_slpc_init.
> From there onwards i915 can control the SLPC operations by Enabling,
> Disabling complete SLPC or changing SLPC parameters. During cleanup
> SLPC shared data has to be freed.
> With this patch on platforms with SLPC support we call intel_slpc_*()
> functions from GuC setup functions and do not use Host rps functions.
> With SLPC, intel_enable_gt_powersave will only handle RC6. In the later
> patch intel_init_gt_powersave will check if SLPC has started running
> through shared data and update initial state that i915 needs like
> frequency limits if needed.
>
> v1: Return void instead of ignored error code (Paulo)
>     enable/disable RC6 in SLPC flows (Sagar)
>     replace HAS_SLPC() use with intel_slpc_enabled()
> 	or intel_slpc_active() (Paulo)
>     Fix for renaming gen9_disable_rps to gen9_disable_rc6 in
>     "drm/i915/bxt: Explicitly clear the Turbo control register"
>     Defer RC6 and SLPC enabling to intel_gen6_powersave_work. (Sagar)
>     Performance drop with SLPC was happening as ring frequency table
>     was not programmed when SLPC was enabled. This patch programs ring
>     frequency table with SLPC. Initial reset of SLPC is based on kernel
>     parameter as planning to add slpc state in intel_slpc_active. Cleanup
>     is also based on kernel parameter as SLPC gets disabled in
>     disable/suspend.(Sagar)
>
> v2: Usage of INTEL_GEN instead of INTEL_INFO->gen (David)
>     Checkpatch update.
>
> v3: Rebase
>
> v4: Removed reset functions to comply with *_gt_powersave routines.
>     (Sagar)
>
> v5: Removed intel_slpc_active. Relying on slpc.active for control flows
>     that are based on SLPC active status in GuC. State setup/cleanup  
> needed
>     for SLPC is handled using kernel parameter i915.enable_slpc. Moved  
> SLPC
>     init and enabling to GuC enable path as SLPC in GuC can start doing  
> the
>     setup post GuC init. Commit message update. (Sagar)
>
> v6: Rearranged function definitions.
>
> v7: Makefile rearrangement. Reducing usage of i915.enable_slpc and  
> relying
>     mostly on rps.rps_enabled to bypass Host RPS flows. Commit message
>     update.
>
> v8: Changed parameters for SLPC functions to struct intel_slpc*.
>
> v9: Reinstated intel_slpc_active and intel_slpc_enabled as they are more
>     meaningful.
>
> v10: Rebase changes due to creation of intel_guc.h. Updates in
>      intel_guc_cleanup w.r.t slpc cleanup.
>
> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> ---
>  drivers/gpu/drm/i915/Makefile     |  1 +
>  drivers/gpu/drm/i915/i915_drv.h   | 12 ++++++++++
>  drivers/gpu/drm/i915/intel_guc.c  |  3 +++
>  drivers/gpu/drm/i915/intel_guc.h  |  3 +++

Hmm, this looks like cross dependency on other pending series

>  drivers/gpu/drm/i915/intel_pm.c   | 19 +++++++++++-----
>  drivers/gpu/drm/i915/intel_slpc.c | 42

It looks that SLPC is tight with Guc so maybe better names would be:

	intel_guc_slpc.c and struct intel_guc_slpc

ie. the same pattern as with Guc log.	

> ++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_slpc.h | 47  
> +++++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_uc.c   | 20 +++++++++++++++++
>  8 files changed, 142 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/intel_slpc.c
>  create mode 100644 drivers/gpu/drm/i915/intel_slpc.h
>
> diff --git a/drivers/gpu/drm/i915/Makefile  
> b/drivers/gpu/drm/i915/Makefile
> index d1327f6..62bf4f6e 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -64,6 +64,7 @@ i915-y += intel_uc.o \
>  	  intel_guc_log.o \
>  	  intel_guc_loader.o \
>  	  intel_huc.o \
> +	  intel_slpc.o \
>  	  i915_guc_submission.o
> # autogenerated null render state
> diff --git a/drivers/gpu/drm/i915/i915_drv.h  
> b/drivers/gpu/drm/i915/i915_drv.h
> index 428cb1c..af633c6 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2748,6 +2748,18 @@ static inline struct drm_i915_private  
> *guc_to_i915(struct intel_guc *guc)
>  	return container_of(guc, struct drm_i915_private, guc);
>  }
> +static inline struct intel_guc *slpc_to_guc(struct intel_slpc *slpc)
> +{
> +	return container_of(slpc, struct intel_guc, slpc);
> +}
> +
> +static inline struct drm_i915_private *slpc_to_i915(struct intel_slpc  
> *slpc)
> +{
> +	struct intel_guc *guc = slpc_to_guc(slpc);
> +
> +	return guc_to_i915(guc);
> +}
> +
>  static inline struct drm_i915_private *huc_to_i915(struct intel_huc  
> *huc)
>  {
>  	return container_of(huc, struct drm_i915_private, huc);
> diff --git a/drivers/gpu/drm/i915/intel_guc.c  
> b/drivers/gpu/drm/i915/intel_guc.c
> index f4dc708..a92c7e8 100644
> --- a/drivers/gpu/drm/i915/intel_guc.c
> +++ b/drivers/gpu/drm/i915/intel_guc.c
> @@ -226,6 +226,9 @@ void intel_guc_cleanup(struct intel_guc *guc)
> 	if (i915.enable_guc_submission)
>  		i915_guc_submission_cleanup(dev_priv);
> +
> +	if (intel_slpc_enabled())
> +		intel_slpc_cleanup(&guc->slpc);
>  }
> /**
> diff --git a/drivers/gpu/drm/i915/intel_guc.h  
> b/drivers/gpu/drm/i915/intel_guc.h
> index 3821bf2..b835d30 100644
> --- a/drivers/gpu/drm/i915/intel_guc.h
> +++ b/drivers/gpu/drm/i915/intel_guc.h
> @@ -28,6 +28,7 @@
>  #include "intel_guc_fwif.h"
>  #include "i915_guc_reg.h"
>  #include "intel_guc_ct.h"
> +#include "intel_slpc.h"
> /*
>   * This structure primarily describes the GEM object shared with the  
> GuC.
> @@ -115,6 +116,8 @@ struct intel_guc {
>  		enum forcewake_domains fw_domains;
>  	} send_regs;
> +	struct intel_slpc slpc;
> +

Pick better place - now you're inside 'send' related members.

>  	/* To serialize the intel_guc_send actions */
>  	struct mutex send_mutex;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c  
> b/drivers/gpu/drm/i915/intel_pm.c
> index 20ec8f4..e5607e5 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -7995,6 +7995,12 @@ void intel_suspend_gt_powersave(struct  
> drm_i915_private *dev_priv)
>  		intel_runtime_pm_put(dev_priv);
> 	/* gen6_rps_idle() will be called later to disable interrupts */
> +
> +	if (intel_slpc_active(&dev_priv->guc.slpc)) {
> +		intel_runtime_pm_get(dev_priv);
> +		intel_slpc_disable(&dev_priv->guc.slpc);
> +		intel_runtime_pm_put(dev_priv);
> +	}
>  }
> void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
> @@ -8121,7 +8127,8 @@ void intel_enable_gt_powersave(struct  
> drm_i915_private *dev_priv)
>  	mutex_lock(&dev_priv->pm.pcu_lock);
> 	intel_enable_rc6(dev_priv);
> -	intel_enable_rps(dev_priv);
> +	if (!intel_slpc_active(&dev_priv->guc.slpc))
> +		intel_enable_rps(dev_priv);
>  	intel_update_ring_freq(dev_priv);
> 	mutex_unlock(&dev_priv->pm.pcu_lock);
> @@ -8134,8 +8141,9 @@ static void __intel_autoenable_gt_powersave(struct  
> work_struct *work)
>  	struct intel_engine_cs *rcs;
>  	struct drm_i915_gem_request *req;
> -	if (READ_ONCE(dev_priv->pm.rps.enabled) &&
> -	    READ_ONCE(dev_priv->pm.rc6.enabled) &&
> +	if (READ_ONCE(dev_priv->pm.rc6.enabled) &&
> +	    !(!(intel_slpc_active(&dev_priv->guc.slpc)) ^
> +	      READ_ONCE(dev_priv->pm.rps.enabled)) &&
>  	    !(NEEDS_RING_FREQ_UPDATE(dev_priv) ^
>  	      READ_ONCE(dev_priv->pm.ring_pstate.configured)))
>  		goto out;
> @@ -8167,8 +8175,9 @@ static void __intel_autoenable_gt_powersave(struct  
> work_struct *work)
> void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv)
>  {
> -	if (READ_ONCE(dev_priv->pm.rps.enabled) &&
> -	    READ_ONCE(dev_priv->pm.rc6.enabled) &&
> +	if (READ_ONCE(dev_priv->pm.rc6.enabled) &&
> +	    !(!(intel_slpc_active(&dev_priv->guc.slpc)) ^
> +	      READ_ONCE(dev_priv->pm.rps.enabled)) &&
>  	    !(NEEDS_RING_FREQ_UPDATE(dev_priv) ^
>  	      READ_ONCE(dev_priv->pm.ring_pstate.configured)))
>  		return;
> diff --git a/drivers/gpu/drm/i915/intel_slpc.c  
> b/drivers/gpu/drm/i915/intel_slpc.c
> new file mode 100644
> index 0000000..06abda5
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_slpc.c
> @@ -0,0 +1,42 @@
> +/*
> + * Copyright © 2017 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person  
> obtaining a
> + * copy of this software and associated documentation files (the  
> "Software"),
> + * to deal in the Software without restriction, including without  
> limitation
> + * the rights to use, copy, modify, merge, publish, distribute,  
> sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the  
> next
> + * paragraph) shall be included in all copies or substantial portions  
> of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
> EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
> MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  
> SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR  
> OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,  
> ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER  
> DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +#include <linux/firmware.h>
> +#include "i915_drv.h"
> +#include "intel_uc.h"
> +
> +void intel_slpc_init(struct intel_slpc *slpc)
> +{
> +}
> +
> +void intel_slpc_cleanup(struct intel_slpc *slpc)
> +{
> +}
> +
> +void intel_slpc_enable(struct intel_slpc *slpc)
> +{
> +}
> +
> +void intel_slpc_disable(struct intel_slpc *slpc)
> +{
> +}
> diff --git a/drivers/gpu/drm/i915/intel_slpc.h  
> b/drivers/gpu/drm/i915/intel_slpc.h
> new file mode 100644
> index 0000000..f68671f
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_slpc.h
> @@ -0,0 +1,47 @@
> +/*
> + * Copyright © 2017 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person  
> obtaining a
> + * copy of this software and associated documentation files (the  
> "Software"),
> + * to deal in the Software without restriction, including without  
> limitation
> + * the rights to use, copy, modify, merge, publish, distribute,  
> sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the  
> next
> + * paragraph) shall be included in all copies or substantial portions  
> of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
> EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
> MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  
> SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR  
> OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,  
> ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER  
> DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +#ifndef _INTEL_SLPC_H_
> +#define _INTEL_SLPC_H_
> +
> +struct intel_slpc {
> +	bool active;
> +};
> +
> +static inline int intel_slpc_enabled(void)
> +{
> +	return i915.enable_slpc;
> +}
> +
> +static inline bool intel_slpc_active(struct intel_slpc *slpc)
> +{
> +	return slpc->active;
> +}
> +
> +/* intel_slpc.c */
> +void intel_slpc_init(struct intel_slpc *slpc);
> +void intel_slpc_cleanup(struct intel_slpc *slpc);
> +void intel_slpc_enable(struct intel_slpc *slpc);
> +void intel_slpc_disable(struct intel_slpc *slpc);
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/intel_uc.c  
> b/drivers/gpu/drm/i915/intel_uc.c
> index 350027f..990d84a 100644
> --- a/drivers/gpu/drm/i915/intel_uc.c
> +++ b/drivers/gpu/drm/i915/intel_uc.c
> @@ -328,6 +328,9 @@ int intel_uc_init_hw(struct drm_i915_private  
> *dev_priv)
>  		ret = i915_guc_submission_init(dev_priv);
>  		if (ret)
>  			goto err_guc;
> +
> +		if (intel_slpc_enabled())
> +			intel_slpc_init(&dev_priv->guc.slpc);
>  	}
> 	/* init WOPCM */
> @@ -369,6 +372,17 @@ int intel_uc_init_hw(struct drm_i915_private  
> *dev_priv)
>  		goto err_log_capture;
> 	intel_huc_auth(&dev_priv->huc);
> +
> +	/*
> +	 * SLPC is enabled by setting up the shared data structure and
> +	 * sending reset event to GuC SLPC. Initial data is setup in
> +	 * intel_slpc_init. Here we send the reset event. SLPC enabling
> +	 * in GuC can happen in parallel in GuC with other initialization
> +	 * being done in i915.
> +	 */
> +	if (intel_slpc_enabled())
> +		intel_slpc_enable(&dev_priv->guc.slpc);
> +
>  	if (i915.enable_guc_submission) {
>  		if (i915.guc_log_level >= 0)
>  			gen9_enable_guc_interrupts(dev_priv);
> @@ -398,6 +412,12 @@ int intel_uc_init_hw(struct drm_i915_private  
> *dev_priv)
>  	if (i915.enable_guc_submission)
>  		i915_guc_submission_cleanup(dev_priv);
>  err_guc:
> +	if (intel_slpc_enabled()) {
> +		if (intel_slpc_active(&dev_priv->guc.slpc))
> +			intel_slpc_disable(&dev_priv->guc.slpc);
> +		intel_slpc_cleanup(&dev_priv->guc.slpc);
> +	}
> +
>  	i915_ggtt_disable_guc(dev_priv);
> 	DRM_ERROR("GuC init failed\n");
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 18/31] drm/i915/slpc: Add SLPC communication interfaces
  2017-09-19 17:41 ` [PATCH 18/31] drm/i915/slpc: Add SLPC communication interfaces Sagar Arun Kamble
@ 2017-09-21 13:14   ` Michal Wajdeczko
  2017-09-28  9:48     ` Sagar Arun Kamble
  0 siblings, 1 reply; 58+ messages in thread
From: Michal Wajdeczko @ 2017-09-21 13:14 UTC (permalink / raw)
  To: intel-gfx, Sagar Arun Kamble; +Cc: Tom O'Rourke

On Tue, 19 Sep 2017 19:41:54 +0200, Sagar Arun Kamble  
<sagar.a.kamble@intel.com> wrote:

> Communication with SLPC is via Host to GuC interrupt through
> shared data and parameters. This patch defines the structure of
> shared data, parameters, data structure to be passed as input and
> received as output from SLPC. This patch also defines the events
> to be sent as input and status values output by GuC on processing
> SLPC events. SLPC shared data has details of SKU type, Slice count,
> IA Perf MSR values, SLPC state, Power source/plan, SLPC tasks status.
> Parameters allow overriding task control, frequency range etc.
>
> v1: fix whitespace (Sagar)
>
> v2-v3: Rebase.
>
> v4: Updated with GuC firmware v9.
>
> v5: Added definition of input and output data structures for SLPC
> events. Updated commit message.
>
> v6: Removed definition of host2guc_slpc. Will be added in the next
> patch that uses it. Commit subject update. Rebase.
>
> v7: Added definition of SLPC_RESET_FLAG_TDR_OCCURRED to be sent
> throgh SLPC reset in case of engine reset. Moved all Host/SLPC
> interfaces from later patches to this patch. Commit message update.
>
> v8: Updated value of SLPC_RESET_FLAG_TDR_OCCURRED.
>
> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_slpc.c |  39 +++++++
>  drivers/gpu/drm/i915/intel_slpc.h | 207  
> ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 246 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_slpc.c  
> b/drivers/gpu/drm/i915/intel_slpc.c
> index 06abda5..a3db63c 100644
> --- a/drivers/gpu/drm/i915/intel_slpc.c
> +++ b/drivers/gpu/drm/i915/intel_slpc.c
> @@ -25,6 +25,45 @@
>  #include "i915_drv.h"
>  #include "intel_uc.h"
> +struct slpc_param slpc_paramlist[SLPC_MAX_PARAM] = {
> +	{SLPC_PARAM_TASK_ENABLE_GTPERF, "Enable task GTPERF"},
> +	{SLPC_PARAM_TASK_DISABLE_GTPERF, "Disable task GTPERF"},
> +	{SLPC_PARAM_TASK_ENABLE_BALANCER, "Enable task BALANCER"},
> +	{SLPC_PARAM_TASK_DISABLE_BALANCER, "Disable task BALANCER"},
> +	{SLPC_PARAM_TASK_ENABLE_DCC, "Enable task DCC"},
> +	{SLPC_PARAM_TASK_DISABLE_DCC, "Disable task DCC"},
> +	{SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
> +				"Minimum GT frequency request for unslice"},
> +	{SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ,
> +				"Maximum GT frequency request for unslice"},
> +	{SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ,
> +				"Minimum GT frequency request for slice"},
> +	{SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ,
> +				"Maximum GT frequency request for slice"},
> +	{SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS,
> +				"If non-zero, algorithm will slow down "
> +				"frame-based applications to this frame-rate"},
> +	{SLPC_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT,
> +				"Lock GT frequency request to RPe"},
> +	{SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING,
> +				"Set to TRUE to enable slowing framerate"},
> +	{SLPC_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE,
> +				"Prevent from changing the RC mode"},
> +	{SLPC_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ,
> +				"Override fused value of unslice RP0"},
> +	{SLPC_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ,
> +				"Override fused value of slice RP0"},
> +	{SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING,
> +				"TRUE means enable Intelligent Bias Control"},
> +	{SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO,
> +				"TRUE = enable eval mode when transitioning "
> +				"from idle to active."},
> +	{SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE,
> +				"FALSE = disable eval mode completely"},
> +	{SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE,
> +				"Enable IBC when non-Gaming Mode is enabled"}
> +};
> +
>  void intel_slpc_init(struct intel_slpc *slpc)
>  {
>  }
> diff --git a/drivers/gpu/drm/i915/intel_slpc.h  
> b/drivers/gpu/drm/i915/intel_slpc.h
> index f68671f..ac4cb65 100644
> --- a/drivers/gpu/drm/i915/intel_slpc.h
> +++ b/drivers/gpu/drm/i915/intel_slpc.h
> @@ -38,6 +38,213 @@ static inline bool intel_slpc_active(struct  
> intel_slpc *slpc)
>  	return slpc->active;
>  }
> +enum slpc_status {
> +	SLPC_STATUS_OK = 0,
> +	SLPC_STATUS_ERROR = 1,
> +	SLPC_STATUS_ILLEGAL_COMMAND = 2,
> +	SLPC_STATUS_INVALID_ARGS = 3,
> +	SLPC_STATUS_INVALID_PARAMS = 4,
> +	SLPC_STATUS_INVALID_DATA = 5,
> +	SLPC_STATUS_OUT_OF_RANGE = 6,
> +	SLPC_STATUS_NOT_SUPPORTED = 7,
> +	SLPC_STATUS_NOT_IMPLEMENTED = 8,
> +	SLPC_STATUS_NO_DATA = 9,
> +	SLPC_STATUS_EVENT_NOT_REGISTERED = 10,
> +	SLPC_STATUS_REGISTER_LOCKED = 11,
> +	SLPC_STATUS_TEMPORARILY_UNAVAILABLE = 12,
> +	SLPC_STATUS_VALUE_ALREADY_SET = 13,
> +	SLPC_STATUS_VALUE_ALREADY_UNSET = 14,
> +	SLPC_STATUS_VALUE_NOT_CHANGED = 15,
> +	SLPC_STATUS_MEMIO_ERROR = 16,
> +	SLPC_STATUS_EVENT_QUEUED_REQ_DPC = 17,
> +	SLPC_STATUS_EVENT_QUEUED_NOREQ_DPC = 18,
> +	SLPC_STATUS_NO_EVENT_QUEUED = 19,
> +	SLPC_STATUS_OUT_OF_SPACE = 20,
> +	SLPC_STATUS_TIMEOUT = 21,
> +	SLPC_STATUS_NO_LOCK = 22,
> +};

I'm always wondering why everyone wants to design its own errno codes ...
But seriously, do we need to define and use all of them ?

> +
> +enum slpc_event_id {
> +	SLPC_EVENT_RESET = 0,
> +	SLPC_EVENT_SHUTDOWN = 1,
> +	SLPC_EVENT_PLATFORM_INFO_CHANGE = 2,
> +	SLPC_EVENT_DISPLAY_MODE_CHANGE = 3,
> +	SLPC_EVENT_FLIP_COMPLETE = 4,
> +	SLPC_EVENT_QUERY_TASK_STATE = 5,
> +	SLPC_EVENT_PARAMETER_SET = 6,
> +	SLPC_EVENT_PARAMETER_UNSET = 7,
> +};
> +
> +enum slpc_param_id {
> +	SLPC_PARAM_TASK_ENABLE_GTPERF = 0,
> +	SLPC_PARAM_TASK_DISABLE_GTPERF = 1,
> +	SLPC_PARAM_TASK_ENABLE_BALANCER = 2,
> +	SLPC_PARAM_TASK_DISABLE_BALANCER = 3,
> +	SLPC_PARAM_TASK_ENABLE_DCC = 4,
> +	SLPC_PARAM_TASK_DISABLE_DCC = 5,
> +	SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ = 6,
> +	SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ = 7,
> +	SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ = 8,
> +	SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ = 9,
> +	SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS = 10,
> +	SLPC_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT = 11,
> +	SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING = 12,
> +	SLPC_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE = 13,
> +	SLPC_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ = 14,
> +	SLPC_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ = 15,
> +	SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING = 16,
> +	SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO = 17,
> +	SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE = 18,
> +	SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE = 19,
> +	SLPC_MAX_PARAM,
> +	SLPC_KMD_MAX_PARAM = 32,
> +};
> +
> +enum slpc_platform_sku {
> +	SLPC_PLATFORM_SKU_UNDEFINED = 0,
> +	SLPC_PLATFORM_SKU_ULX = 1,
> +	SLPC_PLATFORM_SKU_ULT = 2,
> +	SLPC_PLATFORM_SKU_T = 3,
> +	SLPC_PLATFORM_SKU_MOBL = 4,
> +	SLPC_PLATFORM_SKU_DT = 5,
> +	SLPC_PLATFORM_SKU_UNKNOWN = 6,
> +};
> +
> +enum slpc_power_source {
> +	SLPC_POWER_SOURCE_UNDEFINED = 0,
> +	SLPC_POWER_SOURCE_AC = 1,
> +	SLPC_POWER_SOURCE_DC = 2,
> +	SLPC_POWER_SOURCE_UNKNOWN = 3,
> +};
> +
> +enum slpc_power_plan {
> +	SLPC_POWER_PLAN_UNDEFINED = 0,
> +	SLPC_POWER_PLAN_BATTERY_SAVER = 1,
> +	SLPC_POWER_PLAN_BALANCED = 2,
> +	SLPC_POWER_PLAN_PERFORMANCE = 3,
> +	SLPC_POWER_PLAN_UNKNOWN = 4,
> +};
> +
> +struct slpc_platform_info {
> +	u8 platform_sku;
> +	u8 slice_count;
> +	u8 reserved;
> +	u8 power_plan_source;
> +	u8 P0_freq;
> +	u8 P1_freq;
> +	u8 Pe_freq;
> +	u8 Pn_freq;
> +	u32 reserved1;
> +	u32 reserved2;
> +} __packed;
> +
> +enum slpc_global_state {
> +	SLPC_GLOBAL_STATE_NOT_RUNNING = 0,
> +	SLPC_GLOBAL_STATE_INITIALIZING = 1,
> +	SLPC_GLOBAL_STATE_RESETTING = 2,
> +	SLPC_GLOBAL_STATE_RUNNING = 3,
> +	SLPC_GLOBAL_STATE_SHUTTING_DOWN = 4,
> +	SLPC_GLOBAL_STATE_ERROR = 5
> +};
> +
> +struct slpc_task_state_data {
> +	union {
> +		u32 bitfield1;
> +		struct {
> +			u32 gtperf_task_active:1;
> +			u32 gtperf_stall_possible:1;
> +			u32 gtperf_gaming_mode:1;
> +			u32 gtperf_target_fps:8;
> +			u32 dcc_task_active:1;
> +			u32 in_dcc:1;
> +			u32 in_dct:1;
> +			u32 freq_switch_active:1;
> +			u32 ibc_enabled:1;
> +			u32 ibc_active:1;
> +			u32 pg1_enabled:1;
> +			u32 pg1_active:1;
> +			u32 reserved:13;
> +		};
> +	};
> +	union {
> +		u32 bitfield2;
> +		struct {
> +			u32 max_unslice_freq:8;
> +			u32 min_unslice_freq:8;
> +			u32 max_slice_freq:8;
> +			u32 min_slice_freq:8;
> +		};
> +	};
> +} __packed;
> +
> +#define SLPC_MAX_OVERRIDE_PARAMETERS 192
> +#define SLPC_OVERRIDE_BITFIELD_SIZE ((SLPC_MAX_OVERRIDE_PARAMETERS +  
> 31) / 32)
> +
> +struct slpc_shared_data {
> +	u32 reserved;
> +	u32 shared_data_size;
> +	u32 global_state;
> +	struct slpc_platform_info platform_info;
> +	struct slpc_task_state_data task_state_data;
> +	u32 override_parameters_set_bits[SLPC_OVERRIDE_BITFIELD_SIZE];
> +	u32 override_parameters_values[SLPC_MAX_OVERRIDE_PARAMETERS];
> +} __packed;
> +
> +enum slpc_reset_flags {
> +	SLPC_RESET_FLAG_TDR_OCCURRED = (1 << 0)
> +};
> +
> +#define SLPC_EVENT_MAX_INPUT_ARGS  7
> +#define SLPC_EVENT_MAX_OUTPUT_ARGS 1
> +
> +union slpc_event_input_header {
> +	u32 value;
> +	struct {
> +		u32 num_args:8;
> +		u32 event_id:8;
> +	};
> +};
> +
> +struct slpc_event_input {
> +	u32 h2g_action_id;
> +	union slpc_event_input_header header;
> +	u32 args[SLPC_EVENT_MAX_INPUT_ARGS];
> +} __packed;
> +
> +union slpc_event_output_header {
> +	u32 value;
> +	struct {
> +		u32 num_args:8;
> +		u32 event_id:8;
> +		u32 status:16;
> +	};
> +};
> +
> +struct slpc_event_output {
> +	u32 reserved;
> +	union slpc_event_output_header header;
> +	u32 args[SLPC_EVENT_MAX_OUTPUT_ARGS];
> +} __packed;
> +
> +#define SLPC_EVENT(id, argc)	((u32) (id) << 8 | (argc))
> +#define SLPC_POWER_PLAN_SOURCE(plan, source) ((plan) | ((source) << 6))
> +#define SLPC_POWER_PLAN(plan_source) ((plan_source) & 0x3F)
> +#define SLPC_POWER_SOURCE(plan_source) ((plan_source) >> 6)
> +
> +/* Structures for exposing parameter details to user. */
> +#define MAX_PARAM_DESCRIPTION_SIZE	160
> +struct slpc_param {
> +	enum slpc_param_id id;
> +	char description[MAX_PARAM_DESCRIPTION_SIZE];

Hmm, 160 bytes for description is big.

As "id" starts from 0 maybe we can use simpler variant (in .c file)

	static struct slpc_param_names {
		const char *description;
	} params[] = { ... };

> +};
> +
> +extern struct slpc_param slpc_paramlist[];
> +
> +#define SLPC_PARAM_TASK_DEFAULT  0
> +#define SLPC_PARAM_TASK_ENABLED  1
> +#define SLPC_PARAM_TASK_DISABLED 2
> +#define SLPC_PARAM_TASK_UNKNOWN  3
> +
>  /* intel_slpc.c */
>  void intel_slpc_init(struct intel_slpc *slpc);
>  void intel_slpc_cleanup(struct intel_slpc *slpc);
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 20/31] drm/i915/slpc: Add parameter set/unset/get, task control/status functions
  2017-09-19 17:41 ` [PATCH 20/31] drm/i915/slpc: Add parameter set/unset/get, task control/status functions Sagar Arun Kamble
@ 2017-09-21 13:47   ` Michal Wajdeczko
  2017-09-28  9:55     ` Sagar Arun Kamble
  0 siblings, 1 reply; 58+ messages in thread
From: Michal Wajdeczko @ 2017-09-21 13:47 UTC (permalink / raw)
  To: intel-gfx, Sagar Arun Kamble; +Cc: Tom O'Rourke

On Tue, 19 Sep 2017 19:41:56 +0200, Sagar Arun Kamble  
<sagar.a.kamble@intel.com> wrote:

> SLPC behavior can be changed through set of parameters.
> These parameters can be updated and queried from i915 though
> Host to GuC SLPC events. This patch adds parameter update
> events for setting/unsetting/getting parameters. SLPC has
> various tasks for controlling different controls. This patch
> adds functions to control and query the task status.
>
> v1: Use host2guc_slpc
>     update slcp_param_id enum values for SLPC 2015.2.4
>     return void instead of ignored error code (Paulo)
>
> v2: Checkpatch update.
>
> v3: Rebase.
>
> v4: Updated with GuC firmware v9.
>
> v5: Updated input structure to host2guc_slpc. Added functions
>     to update only parameters in the SLPC shared memory. This
>     will allow to setup shared data with all parameters and send
>     single event to SLPC take them into effect. Commit message
>     update. (Sagar)
>
> v6: Rearranged helpers to use them in slpc_shared_data_init.
>     Added definition of SLPC_KMD_MAX_PARAM.
>
> v7: Added definition of host2guc_slpc with rearrangement of patches.
>     Added task control/status functions.
>
> v8: Rebase w.r.t s/intel_guc_send/intel_guc_send_mmio.
>
> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_guc.c  |  21 ++++-
>  drivers/gpu/drm/i915/intel_guc.h  |   2 +
>  drivers/gpu/drm/i915/intel_slpc.c | 185  
> ++++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_slpc.h |   8 ++
>  4 files changed, 215 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_guc.c  
> b/drivers/gpu/drm/i915/intel_guc.c
> index a92c7e8..656bae9 100644
> --- a/drivers/gpu/drm/i915/intel_guc.c
> +++ b/drivers/gpu/drm/i915/intel_guc.c
> @@ -67,9 +67,11 @@ void intel_guc_init_send_regs(struct intel_guc *guc)
>  /*
>   * This function implements the MMIO based host to GuC interface.
>   */
> -int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32  
> len)
> +int __intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32  
> len,
> +			  u32 *output)
>  {
>  	struct drm_i915_private *dev_priv = guc_to_i915(guc);
> +	union slpc_event_output_header header;

Don't pollute generic send function with slpc specific code.


>  	u32 status;
>  	int i;
>  	int ret;
> @@ -115,12 +117,29 @@ int intel_guc_send_mmio(struct intel_guc *guc,  
> const u32 *action, u32 len)
>  			 action[0], ret, status, I915_READ(SOFT_SCRATCH(15)));
>  	}
> +	/*
> +	 * Output data from Host to GuC SLPC actions is populated in scratch
> +	 * registers SOFT_SCRATCH(1) to SOFT_SCRATCH(14) based on event.

Note that receiving more data over MMIO will be handled by these pending  
patches
	https://patchwork.freedesktop.org/patch/170667/
	https://patchwork.freedesktop.org/patch/170669/

The same series will also add support for responses over CT so stay tuned!

> +	 * Currently only SLPC action status in GuC is meaningful as Host
> +	 * can query only overridden parameters and that are fetched from
> +	 * Host-GuC SLPC shared data.
> +	 */
> +	if (output && !ret) {
> +		output[0] = header.value = I915_READ(SOFT_SCRATCH(1));
> +		ret = header.status;
> +	}
> +
>  	intel_uncore_forcewake_put(dev_priv, guc->send_regs.fw_domains);
>  	mutex_unlock(&guc->send_mutex);
> 	return ret;
>  }
> +int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32  
> len)
> +{
> +	return __intel_guc_send_mmio(guc, action, len, NULL);
> +}
> +
>  int intel_guc_sample_forcewake(struct intel_guc *guc)
>  {
>  	struct drm_i915_private *dev_priv = guc_to_i915(guc);
> diff --git a/drivers/gpu/drm/i915/intel_guc.h  
> b/drivers/gpu/drm/i915/intel_guc.h
> index b835d30..c27d2dd 100644
> --- a/drivers/gpu/drm/i915/intel_guc.h
> +++ b/drivers/gpu/drm/i915/intel_guc.h
> @@ -132,6 +132,8 @@ struct intel_guc {
>  int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32  
> len);
>  void gen8_guc_raise_irq(struct intel_guc *guc);
>  void intel_guc_init_send_regs(struct intel_guc *guc);
> +int __intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32  
> len,
> +			  u32 *output);
>  int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, u32  
> len);
>  int intel_guc_sample_forcewake(struct intel_guc *guc);
>  int intel_guc_runtime_suspend(struct intel_guc *guc);
> diff --git a/drivers/gpu/drm/i915/intel_slpc.c  
> b/drivers/gpu/drm/i915/intel_slpc.c
> index 73e7bf5..f47d81e 100644
> --- a/drivers/gpu/drm/i915/intel_slpc.c
> +++ b/drivers/gpu/drm/i915/intel_slpc.c
> @@ -132,6 +132,191 @@ int slpc_mem_task_control(struct slpc_shared_data  
> *data, u64 val,
>  	return ret;
>  }
> +static void host2guc_slpc(struct intel_slpc *slpc,
> +			  struct slpc_event_input *input, u32 len)
> +{
> +	struct intel_guc *guc = slpc_to_guc(slpc);
> +	u32 *data;
> +	u32 output[SLPC_EVENT_MAX_OUTPUT_ARGS];
> +	int ret = 0;
> +
> +	/*
> +	 * We have only 15 scratch registers for communication.
> +	 * the first we will use for the event ID in input and
> +	 * output data. Event processing status will be present
> +	 * in SOFT_SCRATCH(1) register.
> +	 */
> +	BUILD_BUG_ON(SLPC_EVENT_MAX_INPUT_ARGS > 14);
> +	BUILD_BUG_ON(SLPC_EVENT_MAX_OUTPUT_ARGS < 1);
> +	BUILD_BUG_ON(SLPC_EVENT_MAX_OUTPUT_ARGS > 14);
> +
> +	data = (u32 *) input;
> +	data[0] = INTEL_GUC_ACTION_SLPC_REQUEST;
> +	ret = __intel_guc_send_mmio(guc, data, len, output);
> +
> +	if (ret)
> +		DRM_ERROR("event 0x%x status %d\n",
> +			  ((output[0] & 0xFF00) >> 8), ret);
> +}
> +
> +static void host2guc_slpc_set_param(struct intel_slpc *slpc,
> +				    u32 id, u32 value)
> +{
> +	struct slpc_event_input data = {0};
> +
> +	data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2);
> +	data.args[0] = id;
> +	data.args[1] = value;
> +
> +	host2guc_slpc(slpc, &data, 4);
> +}
> +
> +static void host2guc_slpc_unset_param(struct intel_slpc *slpc,
> +				      u32 id)
> +{
> +	struct slpc_event_input data = {0};
> +
> +	data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1);
> +	data.args[0] = id;
> +
> +	host2guc_slpc(slpc, &data, 3);
> +}
> +
> +void intel_slpc_set_param(struct intel_slpc *slpc,
> +			  u32 id,
> +			  u32 value)
> +{
> +	struct page *page;
> +	struct slpc_shared_data *data = NULL;
> +
> +	WARN_ON(id >= SLPC_MAX_PARAM);
> +
> +	if (!slpc->vma)
> +		return;
> +
> +	page = i915_vma_first_page(slpc->vma);
> +	data = kmap_atomic(page);
> +	slpc_mem_set_param(data, id, value);
> +	kunmap_atomic(data);
> +
> +	host2guc_slpc_set_param(slpc, id, value);
> +}
> +
> +void intel_slpc_unset_param(struct intel_slpc *slpc,
> +			    u32 id)
> +{
> +	struct page *page;
> +	struct slpc_shared_data *data = NULL;
> +
> +	WARN_ON(id >= SLPC_MAX_PARAM);
> +
> +	if (!slpc->vma)
> +		return;
> +
> +	page = i915_vma_first_page(slpc->vma);
> +	data = kmap_atomic(page);
> +	slpc_mem_unset_param(data, id);
> +	kunmap_atomic(data);
> +
> +	host2guc_slpc_unset_param(slpc, id);
> +}
> +
> +void intel_slpc_get_param(struct intel_slpc *slpc,
> +			  u32 id,
> +			  int *overriding, u32 *value)
> +{
> +	struct page *page;
> +	struct slpc_shared_data *data = NULL;
> +	u32 bits;
> +
> +	WARN_ON(id >= SLPC_MAX_PARAM);
> +
> +	if (!slpc->vma)
> +		return;
> +
> +	page = i915_vma_first_page(slpc->vma);
> +	data = kmap_atomic(page);
> +	if (overriding) {
> +		bits = data->override_parameters_set_bits[id >> 5];
> +		*overriding = (0 != (bits & (1 << (id % 32))));
> +	}
> +	if (value)
> +		*value = data->override_parameters_values[id];
> +
> +	kunmap_atomic(data);
> +}
> +
> +int intel_slpc_task_control(struct intel_slpc *slpc, u64 val,
> +			    u32 enable_id, u32 disable_id)
> +{
> +	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
> +	int ret = 0;
> +
> +	if (!slpc->active)
> +		return -ENODEV;
> +
> +	intel_runtime_pm_get(dev_priv);
> +
> +	if (val == SLPC_PARAM_TASK_DEFAULT) {
> +		/* set default */
> +		intel_slpc_unset_param(slpc, enable_id);
> +		intel_slpc_unset_param(slpc, disable_id);
> +	} else if (val == SLPC_PARAM_TASK_ENABLED) {
> +		/* set enable */
> +		intel_slpc_set_param(slpc, enable_id, 1);
> +		intel_slpc_unset_param(slpc, disable_id);
> +	} else if (val == SLPC_PARAM_TASK_DISABLED) {
> +		/* set disable */
> +		intel_slpc_set_param(slpc, disable_id, 1);
> +		intel_slpc_unset_param(slpc, enable_id);
> +	} else {
> +		ret = -EINVAL;
> +	}
> +
> +	intel_slpc_enable(slpc);
> +	intel_runtime_pm_put(dev_priv);
> +
> +	return ret;
> +}
> +
> +int intel_slpc_task_status(struct intel_slpc *slpc, u64 *val,
> +			   u32 enable_id, u32 disable_id)
> +{
> +	int override_enable, override_disable;
> +	u32 value_enable, value_disable;
> +	int ret = 0;
> +
> +	if (!slpc->active) {
> +		ret = -ENODEV;
> +	} else if (val) {
> +		intel_slpc_get_param(slpc, enable_id, &override_enable,
> +				     &value_enable);
> +		intel_slpc_get_param(slpc, disable_id, &override_disable,
> +				     &value_disable);
> +
> +		/*
> +		 * Set the output value:
> +		 * 0: default
> +		 * 1: enabled
> +		 * 2: disabled
> +		 * 3: unknown (should not happen)
> +		 */
> +		if (override_disable && (value_disable == 1))
> +			*val = SLPC_PARAM_TASK_DISABLED;
> +		else if (override_enable && (value_enable == 1))
> +			*val = SLPC_PARAM_TASK_ENABLED;
> +		else if (!override_enable && !override_disable)
> +			*val = SLPC_PARAM_TASK_DEFAULT;
> +		else
> +			*val = SLPC_PARAM_TASK_UNKNOWN;
> +
> +	} else {
> +		ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
>  static void slpc_shared_data_init(struct intel_slpc *slpc)
>  {
>  	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
> diff --git a/drivers/gpu/drm/i915/intel_slpc.h  
> b/drivers/gpu/drm/i915/intel_slpc.h
> index 9312b2f..0ff17f0 100644
> --- a/drivers/gpu/drm/i915/intel_slpc.h
> +++ b/drivers/gpu/drm/i915/intel_slpc.h
> @@ -247,6 +247,14 @@ struct slpc_param {
>  #define SLPC_PARAM_TASK_UNKNOWN  3
> /* intel_slpc.c */
> +void intel_slpc_set_param(struct intel_slpc *slpc, u32 id, u32 value);
> +void intel_slpc_unset_param(struct intel_slpc *slpc, u32 id);
> +void intel_slpc_get_param(struct intel_slpc *slpc, u32 id,
> +			  int *overriding, u32 *value);
> +int intel_slpc_task_control(struct intel_slpc *slpc, u64 val,
> +			    u32 enable_id, u32 disable_id);
> +int intel_slpc_task_status(struct intel_slpc *slpc, u64 *val,
> +			   u32 enable_id, u32 disable_id);
>  void intel_slpc_init(struct intel_slpc *slpc);
>  void intel_slpc_cleanup(struct intel_slpc *slpc);
>  void intel_slpc_enable(struct intel_slpc *slpc);
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 21/31] drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR
  2017-09-19 17:41 ` [PATCH 21/31] drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR Sagar Arun Kamble
@ 2017-09-21 14:06   ` Michal Wajdeczko
  2017-09-28 10:10     ` Sagar Arun Kamble
  0 siblings, 1 reply; 58+ messages in thread
From: Michal Wajdeczko @ 2017-09-21 14:06 UTC (permalink / raw)
  To: intel-gfx, Sagar Arun Kamble; +Cc: Tom O'Rourke

On Tue, 19 Sep 2017 19:41:57 +0200, Sagar Arun Kamble  
<sagar.a.kamble@intel.com> wrote:

> Send host2guc SLPC reset event to GuC post GuC load.
> Post this, i915 can ascertain if SLPC has started running successfully
> through shared data. This check is done during intel_init_gt_powersave.
> This allows to get initial configuration setup by SLPC and if needed
> move to Host RPS if SLPC runs into issues.
> On TDR/Engine reset i915 should send extra flag
> SLPC_RESET_FLAG_TDR_OCCURREDto clear SLPC state as appropriate.
>
> v1: Extract host2guc_slpc to handle slpc status code
>     coding style changes (Paulo)
>     Removed WARN_ON for checking msb of gtt address of
>     shared gem obj. (ChrisW)
>     host2guc_action to i915_guc_action change.(Sagar)
>     Updating SLPC enabled status. (Sagar)
>
> v2: Commit message update. (David)
>
> v3: Rebase.
>
> v4: Added DRM_INFO message when SLPC is enabled.
>
> v5: Updated patch as host2guc_slpc is moved to earlier patch.
>     SLPC activation status message put after checking the
>     state from shared data during intel_init_gt_powersave.
>
> v6: Added definition of host2guc_slpc and clflush the shared data only
>     for required size. Setting state to NOT_RUNNING before sending RESET
>     event. Output data for SLPC actions is to be retrieved during
>     intel_guc_send with lock protection so created wrapper
>     __intel_guc_send that outputs GuC output data if needed. Clearing
>     pm_rps_events on confirming SLPC RUNNING status so that even if
>     host touches any of the PM registers by mistake it should not have
>     any effect. (Sagar)
>
> v7: Added save/restore_default_rps as Uncore sanitize will clear the
>     RP_CONTROL setup by BIOS. s/i915_ggtt_offset/guc_ggtt_offset.
>
> v8: Added support for handling TDR based SLPC reset. Added functions
>     host2guc_slpc_tdr_reset, intel_slpc_reset_prepare and
>     intel_slpc_tdr_reset to handle TDR based SLPC reset.
>
> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.c   |   2 +
>  drivers/gpu/drm/i915/i915_irq.c   |   7 +-
>  drivers/gpu/drm/i915/intel_pm.c   |  10 +++
>  drivers/gpu/drm/i915/intel_slpc.c | 170  
> ++++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_slpc.h |   9 ++
>  drivers/gpu/drm/i915/intel_uc.c   |   1 +
>  6 files changed, 198 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c  
> b/drivers/gpu/drm/i915/i915_drv.c
> index f13a3de..932f9ef 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1074,6 +1074,8 @@ static int i915_driver_init_hw(struct  
> drm_i915_private *dev_priv)
> 	intel_sanitize_options(dev_priv);
> +	intel_slpc_save_default_rps(&dev_priv->guc.slpc);
> +
>  	ret = i915_ggtt_probe_hw(dev_priv);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/gpu/drm/i915/i915_irq.c  
> b/drivers/gpu/drm/i915/i915_irq.c
> index 4a1554c..2d5ad13 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -2838,8 +2838,13 @@ void i915_handle_error(struct drm_i915_private  
> *dev_priv,
>  		}
>  	}
> -	if (!engine_mask)
> +	if (!engine_mask) {
> +		if (intel_slpc_active(&dev_priv->guc.slpc)) {
> +			intel_slpc_reset_prepare(&dev_priv->guc.slpc);
> +			intel_slpc_tdr_reset(&dev_priv->guc.slpc);
> +		}

Can you just jump to single slpc function that will hide slpc internals ?

>  		goto out;
> +	}
> 	/* Full reset needs the mutex, stop any other user trying to do so. */
>  	if (test_and_set_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags)) {
> diff --git a/drivers/gpu/drm/i915/intel_pm.c  
> b/drivers/gpu/drm/i915/intel_pm.c
> index 6b2b7f8..c2065f2 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -7918,6 +7918,16 @@ void intel_init_gt_powersave(struct  
> drm_i915_private *dev_priv)
>  		intel_runtime_pm_get(dev_priv);
>  	}
> +	if (intel_slpc_enabled()) {
> +		dev_priv->guc.slpc.active =
> +			intel_slpc_get_status(&dev_priv->guc.slpc);
> +		if (!intel_slpc_active(&dev_priv->guc.slpc)) {
> +			i915.enable_slpc = 0;
> +			intel_sanitize_gt_powersave(dev_priv);
> +		} else
> +			dev_priv->pm_rps_events = 0;
> +	}
> +

Hmm, on one hand you're trying to use friendly wrappers like
enabled() active() but at the same time you're modifying data
which these helpers were trying to hide ...

>  	mutex_lock(&dev_priv->drm.struct_mutex);
>  	mutex_lock(&dev_priv->pm.pcu_lock);
> diff --git a/drivers/gpu/drm/i915/intel_slpc.c  
> b/drivers/gpu/drm/i915/intel_slpc.c
> index f47d81e..57e69d4 100644
> --- a/drivers/gpu/drm/i915/intel_slpc.c
> +++ b/drivers/gpu/drm/i915/intel_slpc.c
> @@ -390,6 +390,140 @@ static void slpc_shared_data_init(struct  
> intel_slpc *slpc)
>  	kunmap_atomic(data);
>  }
> +static void host2guc_slpc_reset(struct intel_slpc *slpc)
> +{
> +	struct slpc_event_input data = {0};
> +	u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
> +
> +	data.header.value = SLPC_EVENT(SLPC_EVENT_RESET, 2);
> +	data.args[0] = shared_data_gtt_offset;
> +	data.args[1] = 0;
> +
> +	host2guc_slpc(slpc, &data, 4);
> +}
> +
> +static void host2guc_slpc_tdr_reset(struct intel_slpc *slpc)
> +{
> +	struct slpc_event_input data = {0};
> +	u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
> +
> +	data.header.value = SLPC_EVENT(SLPC_EVENT_RESET, 3);
> +	data.args[0] = shared_data_gtt_offset;
> +	data.args[1] = 0;
> +	data.args[2] = SLPC_RESET_FLAG_TDR_OCCURRED;
> +
> +	host2guc_slpc(slpc, &data, 5);
> +}
> +
> +static void host2guc_slpc_query_task_state(struct intel_slpc *slpc)
> +{
> +	struct slpc_event_input data = {0};
> +	u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
> +
> +	data.header.value = SLPC_EVENT(SLPC_EVENT_QUERY_TASK_STATE, 2);
> +	data.args[0] = shared_data_gtt_offset;
> +	data.args[1] = 0;
> +
> +	host2guc_slpc(slpc, &data, 4);
> +}
> +
> +void intel_slpc_query_task_state(struct intel_slpc *slpc)
> +{
> +	if (slpc->active)
> +		host2guc_slpc_query_task_state(slpc);
> +}
> +
> +/*
> + * This function will reads the state updates from GuC SLPC into shared  
> data
> + * by invoking H2G action. Returns current state of GuC SLPC.
> + */
> +void intel_slpc_read_shared_data(struct intel_slpc *slpc,
> +				 struct slpc_shared_data *data)
> +{
> +	struct page *page;
> +	void *pv = NULL;
> +
> +	intel_slpc_query_task_state(slpc);
> +
> +	page = i915_vma_first_page(slpc->vma);
> +	pv = kmap_atomic(page);
> +
> +	drm_clflush_virt_range(pv, sizeof(struct slpc_shared_data));
> +	memcpy(data, pv, sizeof(struct slpc_shared_data));
> +
> +	kunmap_atomic(pv);
> +}
> +
> +const char *intel_slpc_get_state_str(enum slpc_global_state state)
> +{
> +	if (state == SLPC_GLOBAL_STATE_NOT_RUNNING)
> +		return "not running";
> +	else if (state == SLPC_GLOBAL_STATE_INITIALIZING)
> +		return "initializing";
> +	else if (state == SLPC_GLOBAL_STATE_RESETTING)
> +		return "resetting";
> +	else if (state == SLPC_GLOBAL_STATE_RUNNING)
> +		return "running";
> +	else if (state == SLPC_GLOBAL_STATE_SHUTTING_DOWN)
> +		return "shutting down";
> +	else if (state == SLPC_GLOBAL_STATE_ERROR)
> +		return "error";
> +	else
> +		return "unknown";

s/if..else/switch..case

> +}
> +
> +bool intel_slpc_get_status(struct intel_slpc *slpc)
> +{
> +	struct slpc_shared_data data;
> +	bool ret = false;
> +
> +	intel_slpc_read_shared_data(slpc, &data);
> +	DRM_INFO("SLPC state: %s\n",
> +		 intel_slpc_get_state_str(data.global_state));
> +
> +	switch (data.global_state) {
> +	case SLPC_GLOBAL_STATE_RUNNING:
> +		/* Capture required state from SLPC here */
> +		ret = true;
> +		break;
> +	case SLPC_GLOBAL_STATE_ERROR:
> +		DRM_ERROR("SLPC in error state.\n");
> +		break;
> +	case SLPC_GLOBAL_STATE_RESETTING:
> +		/*
> +		 * SLPC enabling in GuC should be completing fast.
> +		 * If SLPC is taking time to initialize (unlikely as we are
> +		 * sending reset event during GuC load itself).
> +		 * TODO: Need to wait till state changes to RUNNING.
> +		 */
> +		ret = true;
> +		DRM_ERROR("SLPC not running yet.!!!");
> +		break;
> +	default:
> +		break;
> +	}
> +	return ret;
> +}

Hmm, this function is trying to do much more than simple 'get' status.
Is this necessary to print that many messages here ?

> +
> +/*
> + * Uncore sanitize clears RPS state in Host GTPM flows set by BIOS,  
> Save the
> + * initial BIOS programmed RPS state that is needed by SLPC and not set  
> by SLPC.
> + * Set this state while enabling SLPC.
> + */
> +void intel_slpc_save_default_rps(struct intel_slpc *slpc)
> +{
> +	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
> +
> +	slpc->rp_control = I915_READ(GEN6_RP_CONTROL);
> +}
> +
> +static void intel_slpc_restore_default_rps(struct intel_slpc *slpc)
> +{
> +	struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
> +
> +	I915_WRITE(GEN6_RP_CONTROL, slpc->rp_control);
> +}
> +
>  void intel_slpc_init(struct intel_slpc *slpc)
>  {
>  	struct intel_guc *guc = slpc_to_guc(slpc);
> @@ -426,6 +560,42 @@ void intel_slpc_cleanup(struct intel_slpc *slpc)
> void intel_slpc_enable(struct intel_slpc *slpc)
>  {
> +	struct page *page;
> +	struct slpc_shared_data *data;
> +
> +	intel_slpc_restore_default_rps(slpc);
> +
> +	page = i915_vma_first_page(slpc->vma);
> +	data = kmap_atomic(page);
> +	data->global_state = SLPC_GLOBAL_STATE_NOT_RUNNING;
> +	kunmap_atomic(data);
> +
> +	if (slpc->tdr_reset) {
> +		host2guc_slpc_tdr_reset(slpc);
> +		slpc->tdr_reset = false;
> +	} else {
> +		host2guc_slpc_reset(slpc);
> +	}
> +
> +	slpc->active = true;
> +}
> +
> +void intel_slpc_reset_prepare(struct intel_slpc *slpc)
> +{
> +	if (intel_slpc_active(slpc)) {
> +		intel_slpc_disable(slpc);
> +		slpc->tdr_reset = true;
> +	}
> +}
> +
> +void intel_slpc_tdr_reset(struct intel_slpc *slpc)
> +{
> +	intel_slpc_restore_default_rps(slpc);
> +	slpc_shared_data_init(slpc);
> +
> +	host2guc_slpc_tdr_reset(slpc);
> +	slpc->active = true;
> +	slpc->tdr_reset = false;
>  }
> void intel_slpc_disable(struct intel_slpc *slpc)
> diff --git a/drivers/gpu/drm/i915/intel_slpc.h  
> b/drivers/gpu/drm/i915/intel_slpc.h
> index 0ff17f0..20c342b 100644
> --- a/drivers/gpu/drm/i915/intel_slpc.h
> +++ b/drivers/gpu/drm/i915/intel_slpc.h
> @@ -26,7 +26,9 @@
> struct intel_slpc {
>  	bool active;
> +	bool tdr_reset;
>  	struct i915_vma *vma;
> +	u32 rp_control;
>  };
> static inline int intel_slpc_enabled(void)
> @@ -255,9 +257,16 @@ int intel_slpc_task_control(struct intel_slpc  
> *slpc, u64 val,
>  			    u32 enable_id, u32 disable_id);
>  int intel_slpc_task_status(struct intel_slpc *slpc, u64 *val,
>  			   u32 enable_id, u32 disable_id);
> +void intel_slpc_read_shared_data(struct intel_slpc *slpc,
> +				 struct slpc_shared_data *data);
> +const char *intel_slpc_get_state_str(enum slpc_global_state state);
> +bool intel_slpc_get_status(struct intel_slpc *slpc);
> +void intel_slpc_save_default_rps(struct intel_slpc *slpc);
>  void intel_slpc_init(struct intel_slpc *slpc);
>  void intel_slpc_cleanup(struct intel_slpc *slpc);
>  void intel_slpc_enable(struct intel_slpc *slpc);
>  void intel_slpc_disable(struct intel_slpc *slpc);
> +void intel_slpc_reset_prepare(struct intel_slpc *slpc);
> +void intel_slpc_tdr_reset(struct intel_slpc *slpc);
> #endif
> diff --git a/drivers/gpu/drm/i915/intel_uc.c  
> b/drivers/gpu/drm/i915/intel_uc.c
> index 990d84a..d8582b8 100644
> --- a/drivers/gpu/drm/i915/intel_uc.c
> +++ b/drivers/gpu/drm/i915/intel_uc.c
> @@ -502,5 +502,6 @@ int intel_uc_resume(struct drm_i915_private  
> *dev_priv)
> int intel_uc_reset_prepare(struct drm_i915_private *dev_priv)
>  {
> +	intel_slpc_reset_prepare(&dev_priv->guc.slpc);
>  	return intel_uc_suspend(dev_priv);
>  }
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 24/31] drm/i915/slpc: Add debugfs support to read/write/revert the parameters
  2017-09-19 17:42 ` [PATCH 24/31] drm/i915/slpc: Add debugfs support to read/write/revert the parameters Sagar Arun Kamble
@ 2017-09-21 15:07   ` Michal Wajdeczko
  2017-09-28 10:18     ` Sagar Arun Kamble
  0 siblings, 1 reply; 58+ messages in thread
From: Michal Wajdeczko @ 2017-09-21 15:07 UTC (permalink / raw)
  To: intel-gfx, Sagar Arun Kamble

On Tue, 19 Sep 2017 19:42:00 +0200, Sagar Arun Kamble  
<sagar.a.kamble@intel.com> wrote:

> This patch adds two debugfs interfaces:
> 1. i915_slpc_paramlist: List of all parameters that Host can configure.
>    Currently listing id and description of each.
> 2. i915_slpc_param_ctl: This allows to change the parameters. Syntax is:
>    echo "write <id> <value>" > i915_slpc_param_ctl.
>    echo "read <id>" > i915_slpc_param_ctl; cat i915_slpc_param_ctl
>    revert allows to set to default SLPC internal values. Syntax is:
>    echo "revert <id>" > i915_slpc_param_ctl.
>
> Added support to set/read parameters and unset the parameters which will
> revert them to default SLPC internal values. Also added RPM ref. cover
> around set/unset calls. Explicit SLPC reset is needed on  
> setting/unsetting
> some of the parameters.
>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c |  19 +++++
>  drivers/gpu/drm/i915/intel_slpc.c   | 158  
> ++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_slpc.h   |   6 ++
>  3 files changed, 183 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c  
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index dbfe185..0a04f3d 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2352,6 +2352,23 @@ static int i915_huc_load_status_info(struct  
> seq_file *m, void *data)
>  	return 0;
>  }
> +static int i915_slpc_paramlist_info(struct seq_file *m, void *data)

I'm little confused that part of the debugfs functionality is done here
while other part in slpc.c

> +{
> +	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> +	int i;
> +
> +	if (!dev_priv->guc.slpc.active) {

intel_slpc_active() ?

> +		seq_puts(m, "SLPC not active\n");
> +		return 0;
> +	}
> +
> +	seq_puts(m, "Param id\tParam description\n");
> +	for (i = 0; i < SLPC_MAX_PARAM; i++)
> +		seq_printf(m, "%8d\t%s\n", slpc_paramlist[i].id,
> +					   slpc_paramlist[i].description);

What if size of slpc_paramlist[] will be smaller than i ?

> +	return 0;
> +}
> +
>  static int i915_guc_load_status_info(struct seq_file *m, void *data)
>  {
>  	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> @@ -4881,6 +4898,7 @@ static int i915_hpd_storm_ctl_open(struct inode  
> *inode, struct file *file)
>  	{"i915_guc_load_err_log_dump", i915_guc_log_dump, 0, (void *)1},
>  	{"i915_guc_stage_pool", i915_guc_stage_pool, 0},
>  	{"i915_huc_load_status", i915_huc_load_status_info, 0},
> +	{"i915_slpc_paramlist", i915_slpc_paramlist_info, 0},
>  	{"i915_frequency_info", i915_frequency_info, 0},
>  	{"i915_hangcheck_info", i915_hangcheck_info, 0},
>  	{"i915_reset_info", i915_reset_info, 0},
> @@ -4944,6 +4962,7 @@ static int i915_hpd_storm_ctl_open(struct inode  
> *inode, struct file *file)
>  	{"i915_dp_test_type", &i915_displayport_test_type_fops},
>  	{"i915_dp_test_active", &i915_displayport_test_active_fops},
>  	{"i915_guc_log_control", &i915_guc_log_control_fops},
> +	{"i915_slpc_param_ctl", &i915_slpc_param_ctl_fops},
>  	{"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
>  	{"i915_ipc_status", &i915_ipc_status_fops}
>  };
> diff --git a/drivers/gpu/drm/i915/intel_slpc.c  
> b/drivers/gpu/drm/i915/intel_slpc.c
> index d0fd402..0c094f0 100644
> --- a/drivers/gpu/drm/i915/intel_slpc.c
> +++ b/drivers/gpu/drm/i915/intel_slpc.c
> @@ -25,6 +25,8 @@
>  #include <asm/msr-index.h>
>  #include "i915_drv.h"
>  #include "intel_uc.h"
> +#include <linux/seq_file.h>
> +#include <linux/debugfs.h>
> struct slpc_param slpc_paramlist[SLPC_MAX_PARAM] = {
>  	{SLPC_PARAM_TASK_ENABLE_GTPERF, "Enable task GTPERF"},
> @@ -684,3 +686,159 @@ void intel_slpc_disable(struct intel_slpc *slpc)
> 	slpc->active = false;
>  }
> +
> +static int slpc_param_ctl_show(struct seq_file *m, void *data)
> +{
> +	struct drm_i915_private *dev_priv = m->private;
> +	struct intel_slpc *slpc = &dev_priv->guc.slpc;
> +
> +	if (!slpc->active) {

intel_slpc_active() ?

> +		seq_puts(m, "SLPC not active\n");
> +		return 0;
> +	}
> +
> +	seq_printf(m, "%s=%u, override=%s\n",
> +			slpc_paramlist[slpc->debug_param_id].description,
> +			slpc->debug_param_value,
> +			yesno(!!slpc->debug_param_override));
> +

What if slpc->debug_param_id >= SLPC_MAX_PARAM or sizeof paramlist ?

> +	return 0;
> +}
> +
> +static int slpc_param_ctl_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, slpc_param_ctl_show, inode->i_private);
> +}
> +
> +static const char *read_token = "read", *write_token = "write",
> +		  *revert_token = "revert";
> +
> +/*
> + * Parse SLPC parameter control strings: (Similar to Pipe CRC handling)
> + *   command: wsp* op wsp+ param id wsp+ [value] wsp*
> + *   op: "read"/"write"/"revert"
> + *   param id: slpc_param_id
> + *   value: u32 value
> + *   wsp: (#0x20 | #0x9 | #0xA)+
> + *
> + * eg.:
> + *  "read 0"		-> read SLPC_PARAM_TASK_ENABLE_GTPERF
> + *  "write 7 500"	-> set SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ to  
> 500MHz
> + *  "revert 7"		-> revert SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ to
> + *			   default value.
> + */
> +static int slpc_param_ctl_parse(char *buf, size_t len, char **op,
> +				u32 *id, u32 *value)
> +{
> +#define MAX_WORDS 3
> +	int n_words;
> +	char *words[MAX_WORDS];
> +	ssize_t ret;
> +
> +	n_words = buffer_tokenize(buf, words, MAX_WORDS);

Ha! finally found the purpose of the patch 001
Please try to keep them closer.

> +	if (!(n_words == 3) && !(n_words == 2)) {
> +		DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n",
> +				 MAX_WORDS);
> +		return -EINVAL;
> +	}
> +
> +	if (strcmp(words[0], read_token) && strcmp(words[0], write_token) &&
> +	    strcmp(words[0], revert_token)) {
> +		DRM_DEBUG_DRIVER("unknown operation\n");

Please add operation word into message for easier debug

> +		return -EINVAL;
> +	}
> +
> +	*op = words[0];

Hmm, this will cause yet another strcmp - try to convert into OP code.

> +
> +	ret = kstrtou32(words[1], 0, id);
> +	if (ret)
> +		return ret;
> +
> +	if (n_words == 3) {
> +		ret = kstrtou32(words[2], 0, value);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;

Shouldn't we return n_words-1 to easier catch any missing params?

> +}
> +
> +static ssize_t slpc_param_ctl_write(struct file *file, const char  
> __user *ubuf,
> +				     size_t len, loff_t *offp)
> +{
> +	struct seq_file *m = file->private_data;
> +	struct drm_i915_private *dev_priv = m->private;
> +	struct intel_slpc *slpc = &dev_priv->guc.slpc;
> +	char *tmpbuf, *op = NULL;
> +	u32 id, value;
> +	int ret;
> +
> +	if (len == 0)
> +		return 0;
> +
> +	if (len > 40) {
> +		DRM_DEBUG_DRIVER("expected <40 chars into slpc_param_ctl\n");
> +		return -E2BIG;
> +	}
> +
> +	tmpbuf = kmalloc(len + 1, GFP_KERNEL);
> +	if (!tmpbuf)
> +		return -ENOMEM;
> +
> +	if (copy_from_user(tmpbuf, ubuf, len)) {
> +		ret = -EFAULT;
> +		goto out;
> +	}
> +	tmpbuf[len] = '\0';
> +
> +	ret = slpc_param_ctl_parse(tmpbuf, len, &op, &id, &value);

'ret' is not checked for errors

> +
> +	if (id >= SLPC_MAX_PARAM) {
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	if (!strcmp(op, read_token)) {
> +		intel_slpc_get_param(slpc, id,
> +				     &slpc->debug_param_override,
> +				     &slpc->debug_param_value);
> +		slpc->debug_param_id = id;
> +	} else if (!strcmp(op, write_token) || !strcmp(op, revert_token)) {
> +		if ((id >= SLPC_PARAM_TASK_ENABLE_GTPERF) &&
> +		    (id <= SLPC_PARAM_TASK_DISABLE_DCC)) {
> +			DRM_DEBUG_DRIVER("Tasks are not controlled by "
> +					 "this interface\n");
> +			ret = -EINVAL;
> +			goto out;
> +		}
> +
> +		/*
> +		 * After updating parameters, RESET event has to be sent to GuC
> +		 * SLPC for ensuring parameters take effect.
> +		 */
> +		intel_runtime_pm_get(dev_priv);
> +		if (!strcmp(op, write_token))
> +			intel_slpc_set_param(slpc, id, value);
> +		else if (!strcmp(op, revert_token))
> +			intel_slpc_unset_param(slpc, id);
> +		intel_slpc_enable(slpc);
> +		intel_runtime_pm_put(dev_priv);
> +	}
> +
> +out:
> +	kfree(tmpbuf);
> +	if (ret < 0)
> +		return ret;
> +
> +	*offp += len;
> +	return len;
> +}
> +
> +const struct file_operations i915_slpc_param_ctl_fops = {
> +	.owner = THIS_MODULE,
> +	.open = slpc_param_ctl_open,
> +	.read = seq_read,
> +	.llseek = seq_lseek,
> +	.release = single_release,
> +	.write = slpc_param_ctl_write
> +};
> diff --git a/drivers/gpu/drm/i915/intel_slpc.h  
> b/drivers/gpu/drm/i915/intel_slpc.h
> index ae857d3..e49c513 100644
> --- a/drivers/gpu/drm/i915/intel_slpc.h
> +++ b/drivers/gpu/drm/i915/intel_slpc.h
> @@ -32,6 +32,10 @@ struct intel_slpc {
>  	/* i915 cached SLPC frequency limits */
>  	u32 min_unslice_freq;
>  	u32 max_unslice_freq;
> +
> +	u32 debug_param_id;
> +	u32 debug_param_value;
> +	u32 debug_param_override;

Group above under 'debug' sub-struct

>  };
> static inline int intel_slpc_enabled(void)
> @@ -251,6 +255,8 @@ struct slpc_param {
>  #define SLPC_PARAM_TASK_DISABLED 2
>  #define SLPC_PARAM_TASK_UNKNOWN  3
> +extern const struct file_operations i915_slpc_param_ctl_fops;
> +
>  /* intel_slpc.c */
>  void intel_slpc_set_param(struct intel_slpc *slpc, u32 id, u32 value);
>  void intel_slpc_unset_param(struct intel_slpc *slpc, u32 id);
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 01/31] drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing
  2017-09-19 17:41 ` [PATCH 01/31] drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing Sagar Arun Kamble
@ 2017-09-21 15:12   ` Michal Wajdeczko
  2017-09-28  9:10     ` Sagar Arun Kamble
  0 siblings, 1 reply; 58+ messages in thread
From: Michal Wajdeczko @ 2017-09-21 15:12 UTC (permalink / raw)
  To: intel-gfx, Sagar Arun Kamble; +Cc: Tomeu Vizoso

On Tue, 19 Sep 2017 19:41:37 +0200, Sagar Arun Kamble  
<sagar.a.kamble@intel.com> wrote:

> Input string parsing used in CRC control parameter parsing is generic
> and can be reused for other debugfs interfaces. Hence name it as
> buffer_tokenize instead of tieing to display_crc. Also fix the function
> desciption for CRC control parsing that was misplaced at tokenize  
> function.
>
> Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> Acked-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h       |  1 +
>  drivers/gpu/drm/i915/intel_pipe_crc.c | 88  
> +++++++++++++++++------------------
>  2 files changed, 45 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h  
> b/drivers/gpu/drm/i915/i915_drv.h
> index 6d7d871..4d5ffde 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3847,6 +3847,7 @@ u32 i915_gem_fence_alignment(struct  
> drm_i915_private *dev_priv, u32 size,
>  int i915_debugfs_register(struct drm_i915_private *dev_priv);
>  int i915_debugfs_connector_add(struct drm_connector *connector);
>  void intel_display_crc_init(struct drm_i915_private *dev_priv);
> +int buffer_tokenize(char *buf, char *words[], int max_words);
>  #else
>  static inline int i915_debugfs_register(struct drm_i915_private  
> *dev_priv) {return 0;}
>  static inline int i915_debugfs_connector_add(struct drm_connector  
> *connector)
> diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c  
> b/drivers/gpu/drm/i915/intel_pipe_crc.c
> index 96043a5..2e312b8 100644
> --- a/drivers/gpu/drm/i915/intel_pipe_crc.c
> +++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
> @@ -710,49 +710,6 @@ static int pipe_crc_set_source(struct  
> drm_i915_private *dev_priv,
>  	return ret;
>  }
> -/*
> - * Parse pipe CRC command strings:
> - *   command: wsp* object wsp+ name wsp+ source wsp*
> - *   object: 'pipe'
> - *   name: (A | B | C)
> - *   source: (none | plane1 | plane2 | pf)
> - *   wsp: (#0x20 | #0x9 | #0xA)+
> - *
> - * eg.:
> - *  "pipe A plane1"  ->  Start CRC computations on plane1 of pipe A
> - *  "pipe A none"    ->  Stop CRC
> - */
> -static int display_crc_ctl_tokenize(char *buf, char *words[], int  
> max_words)
> -{
> -	int n_words = 0;
> -
> -	while (*buf) {
> -		char *end;
> -
> -		/* skip leading white space */
> -		buf = skip_spaces(buf);
> -		if (!*buf)
> -			break;	/* end of buffer */
> -
> -		/* find end of word */
> -		for (end = buf; *end && !isspace(*end); end++)
> -			;
> -
> -		if (n_words == max_words) {
> -			DRM_DEBUG_DRIVER("too many words, allowed <= %d\n",
> -					 max_words);
> -			return -EINVAL;	/* ran out of words[] before bytes */
> -		}
> -
> -		if (*end)
> -			*end++ = '\0';
> -		words[n_words++] = buf;
> -		buf = end;
> -	}
> -
> -	return n_words;
> -}
> -
>  enum intel_pipe_crc_object {
>  	PIPE_CRC_OBJECT_PIPE,
>  };
> @@ -806,6 +763,49 @@ static int display_crc_ctl_parse_pipe(const char  
> *buf, enum pipe *pipe)
>  	return -EINVAL;
>  }
> +int buffer_tokenize(char *buf, char *words[], int max_words)
> +{
> +	int n_words = 0;
> +
> +	while (*buf) {
> +		char *end;
> +
> +		/* skip leading white space */
> +		buf = skip_spaces(buf);
> +		if (!*buf)
> +			break;	/* end of buffer */
> +
> +		/* find end of word */
> +		for (end = buf; *end && !isspace(*end); end++)
> +			;
> +
> +		if (n_words == max_words) {
> +			DRM_DEBUG_DRIVER("too many words, allowed <= %d\n",
> +					 max_words);
> +			return -EINVAL;	/* ran out of words[] before bytes */
> +		}
> +
> +		if (*end)
> +			*end++ = '\0';
> +		words[n_words++] = buf;
> +		buf = end;
> +	}
> +
> +	return n_words;
> +}

You should move this function to i915_debugfs.c

> +
> +/*
> + * Parse pipe CRC command strings:
> + *   command: wsp* object wsp+ name wsp+ source wsp*
> + *   object: 'pipe'
> + *   name: (A | B | C)
> + *   source: (none | plane1 | plane2 | pf)
> + *   wsp: (#0x20 | #0x9 | #0xA)+
> + *
> + * eg.:
> + *  "pipe A plane1"  ->  Start CRC computations on plane1 of pipe A
> + *  "pipe A none"    ->  Stop CRC
> + */
>  static int display_crc_ctl_parse(struct drm_i915_private *dev_priv,
>  				 char *buf, size_t len)
>  {
> @@ -816,7 +816,7 @@ static int display_crc_ctl_parse(struct  
> drm_i915_private *dev_priv,
>  	enum intel_pipe_crc_object object;
>  	enum intel_pipe_crc_source source;
> -	n_words = display_crc_ctl_tokenize(buf, words, N_WORDS);
> +	n_words = buffer_tokenize(buf, words, N_WORDS);
>  	if (n_words != N_WORDS) {
>  		DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n",
>  				 N_WORDS);
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 26/31] drm/i915/slpc: Add i915_slpc_info to debugfs
  2017-09-19 17:42 ` [PATCH 26/31] drm/i915/slpc: Add i915_slpc_info to debugfs Sagar Arun Kamble
@ 2017-09-21 15:13   ` Michal Wajdeczko
  2017-09-28 10:20     ` Sagar Arun Kamble
  0 siblings, 1 reply; 58+ messages in thread
From: Michal Wajdeczko @ 2017-09-21 15:13 UTC (permalink / raw)
  To: intel-gfx, Sagar Arun Kamble; +Cc: Tom O'Rourke

On Tue, 19 Sep 2017 19:42:02 +0200, Sagar Arun Kamble  
<sagar.a.kamble@intel.com> wrote:

> From: Tom O'Rourke <Tom.O'Rourke@intel.com>
>
> i915_slpc_info shows the contents of SLPC shared data
> parsed into text format.
>
> v1: Reformat slpc info (Radek)
>     squashed query task state info
>     in slpc info, kunmap before seq_print (Paulo)
>     return void instead of ignored return value (Paulo)
>     Avoid magic numbers and use local variables (Jon Bloomfield)
>     Removed WARN_ON for checking msb of gtt address of
>     shared gem obj. (ChrisW)
>     Moved definition of power plan and power source to earlier
>     patch in the series.
>     drm/i915/slpc: Allocate/Release/Initialize SLPC shared data
>     (Akash)
>
> v2-v3: Rebase.
>
> v4: Updated with GuC firmware v9.
>
> v5: Updated host2guc_slpc_query_task_state with struct slpc_input_event
>     structure. Removed unnecessary checks of vma from i915_slpc_info.
>     Created helpers for reading the SLPC shared data and string form of
>     SLPC state. (Sagar)
>
> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c | 165  
> ++++++++++++++++++++++++++++++++++++
>  1 file changed, 165 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c  
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index e6fd63f..7a0838f 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1023,6 +1023,170 @@ static int i915_error_state_open(struct inode  
> *inode, struct file *file)
>  			NULL, i915_next_seqno_set,
>  			"0x%llx\n");
> +static int i915_slpc_info(struct seq_file *m, void *unused)
> +{
> +	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> +	int i, value;
> +	struct slpc_shared_data data;
> +	enum slpc_global_state global_state;
> +	enum slpc_platform_sku platform_sku;
> +	struct slpc_task_state_data *task_data;
> +	enum slpc_power_plan power_plan;
> +	enum slpc_power_source power_source;
> +
> +	if (!dev_priv->guc.slpc.active)
> +		return -ENODEV;
> +
> +	intel_runtime_pm_get(dev_priv);
> +	mutex_lock(&dev_priv->pm.pcu_lock);
> +
> +	intel_slpc_read_shared_data(&dev_priv->guc.slpc, &data);
> +
> +	mutex_unlock(&dev_priv->pm.pcu_lock);
> +	intel_runtime_pm_put(dev_priv);
> +
> +	seq_printf(m, "shared data size: %d\n", data.shared_data_size);
> +
> +	global_state = (enum slpc_global_state) data.global_state;
> +	seq_printf(m, "global state: %d (", global_state);
> +	seq_printf(m, "%s)\n", intel_slpc_get_state_str(global_state));
> +
> +	platform_sku = (enum slpc_platform_sku)
> +			data.platform_info.platform_sku;
> +	seq_printf(m, "sku: %d (", platform_sku);
> +	switch (platform_sku) {
> +	case SLPC_PLATFORM_SKU_UNDEFINED:
> +		seq_puts(m, "undefined)\n");
> +		break;
> +	case SLPC_PLATFORM_SKU_ULX:
> +		seq_puts(m, "ULX)\n");
> +		break;
> +	case SLPC_PLATFORM_SKU_ULT:
> +		seq_puts(m, "ULT)\n");
> +		break;
> +	case SLPC_PLATFORM_SKU_T:
> +		seq_puts(m, "T)\n");
> +		break;
> +	case SLPC_PLATFORM_SKU_MOBL:
> +		seq_puts(m, "Mobile)\n");
> +		break;
> +	case SLPC_PLATFORM_SKU_DT:
> +		seq_puts(m, "DT)\n");
> +		break;
> +	case SLPC_PLATFORM_SKU_UNKNOWN:
> +	default:
> +		seq_puts(m, "unknown)\n");
> +		break;
> +	}

Define platform_to_string() followed by single seq_puts()

> +	seq_printf(m, "slice count: %d\n",
> +		   data.platform_info.slice_count);
> +
> +	seq_printf(m, "power plan/source: 0x%x\n\tplan:\t",
> +		   data.platform_info.power_plan_source);
> +	power_plan = (enum slpc_power_plan) SLPC_POWER_PLAN(
> +				data.platform_info.power_plan_source);
> +	power_source = (enum slpc_power_source) SLPC_POWER_SOURCE(
> +				data.platform_info.power_plan_source);
> +	switch (power_plan) {
> +	case SLPC_POWER_PLAN_UNDEFINED:
> +		seq_puts(m, "undefined");
> +		break;
> +	case SLPC_POWER_PLAN_BATTERY_SAVER:
> +		seq_puts(m, "battery saver");
> +		break;
> +	case SLPC_POWER_PLAN_BALANCED:
> +		seq_puts(m, "balanced");
> +		break;
> +	case SLPC_POWER_PLAN_PERFORMANCE:
> +		seq_puts(m, "performance");
> +		break;
> +	case SLPC_POWER_PLAN_UNKNOWN:
> +	default:
> +		seq_puts(m, "unknown");
> +		break;
> +	}

Define power_plan_to_string() followed by single seq_puts()

> +	seq_puts(m, "\n\tsource:\t");
> +	switch (power_source) {
> +	case SLPC_POWER_SOURCE_UNDEFINED:
> +		seq_puts(m, "undefined\n");
> +		break;
> +	case SLPC_POWER_SOURCE_AC:
> +		seq_puts(m, "AC\n");
> +		break;
> +	case SLPC_POWER_SOURCE_DC:
> +		seq_puts(m, "DC\n");
> +		break;
> +	case SLPC_POWER_SOURCE_UNKNOWN:
> +	default:
> +		seq_puts(m, "unknown\n");
> +		break;
> +	}
> +
> +	seq_printf(m, "IA frequency (MHz):\n\tP0: %d\n\tP1: %d\n\tPe:  
> %d\n\tPn: %d\n",
> +		   data.platform_info.P0_freq * 50,
> +		   data.platform_info.P1_freq * 50,
> +		   data.platform_info.Pe_freq * 50,
> +		   data.platform_info.Pn_freq * 50);
> +
> +	task_data = &data.task_state_data;
> +	seq_printf(m, "task state data: 0x%08x 0x%08x\n",
> +		   task_data->bitfield1, task_data->bitfield2);
> +
> +	seq_printf(m, "\tgtperf task active: %s\n",
> +		   yesno(task_data->gtperf_task_active));
> +	seq_printf(m, "\tgtperf stall possible: %s\n",
> +		   yesno(task_data->gtperf_stall_possible));
> +	seq_printf(m, "\tgtperf gaming mode: %s\n",
> +		   yesno(task_data->gtperf_gaming_mode));
> +	seq_printf(m, "\tgtperf target fps: %d\n",
> +		   task_data->gtperf_target_fps);
> +
> +	seq_printf(m, "\tdcc task active: %s\n",
> +		   yesno(task_data->dcc_task_active));
> +	seq_printf(m, "\tin dcc: %s\n",
> +		   yesno(task_data->in_dcc));
> +	seq_printf(m, "\tin dct: %s\n",
> +		   yesno(task_data->in_dct));
> +	seq_printf(m, "\tfreq switch active: %s\n",
> +		   yesno(task_data->freq_switch_active));
> +
> +	seq_printf(m, "\tibc enabled: %s\n",
> +		   yesno(task_data->ibc_enabled));
> +	seq_printf(m, "\tibc active: %s\n",
> +		   yesno(task_data->ibc_active));
> +	seq_printf(m, "\tpg1 enabled: %s\n",
> +		   yesno(task_data->pg1_enabled));
> +	seq_printf(m, "\tpg1 active: %s\n",
> +		   yesno(task_data->pg1_active));
> +
> +	seq_printf(m, "\tunslice max freq: %dMHz\n",
> +		   intel_gpu_freq(dev_priv,
> +			task_data->max_unslice_freq * GEN9_FREQ_SCALER));
> +	seq_printf(m, "\tunslice min freq: %dMHz\n",
> +		   intel_gpu_freq(dev_priv,
> +			task_data->min_unslice_freq * GEN9_FREQ_SCALER));
> +	seq_printf(m, "\tslice max freq: %dMHz\n",
> +		   intel_gpu_freq(dev_priv,
> +			task_data->max_slice_freq * GEN9_FREQ_SCALER));
> +	seq_printf(m, "\tslice min freq: %dMHz\n",
> +		   intel_gpu_freq(dev_priv,
> +			task_data->min_slice_freq * GEN9_FREQ_SCALER));
> +
> +	seq_puts(m, "override parameter bitfield\n");
> +	for (i = 0; i < SLPC_OVERRIDE_BITFIELD_SIZE; i++)
> +		seq_printf(m, "%d: 0x%08x\n", i,
> +			   data.override_parameters_set_bits[i]);
> +
> +	seq_puts(m, "override parameters (only non-zero shown)\n");
> +	for (i = 0; i < SLPC_MAX_OVERRIDE_PARAMETERS; i++) {
> +		value = data.override_parameters_values[i];
> +		if (value)
> +			seq_printf(m, "%d: 0x%8x\n", i, value);
> +	}
> +
> +	return 0;
> +}
> +
>  static int i915_frequency_info(struct seq_file *m, void *unused)
>  {
>  	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> @@ -4899,6 +5063,7 @@ static int i915_hpd_storm_ctl_open(struct inode  
> *inode, struct file *file)
>  	{"i915_guc_stage_pool", i915_guc_stage_pool, 0},
>  	{"i915_huc_load_status", i915_huc_load_status_info, 0},
>  	{"i915_slpc_paramlist", i915_slpc_paramlist_info, 0},
> +	{"i915_slpc_info", i915_slpc_info, 0},
>  	{"i915_frequency_info", i915_frequency_info, 0},
>  	{"i915_hangcheck_info", i915_hangcheck_info, 0},
>  	{"i915_reset_info", i915_reset_info, 0},
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/31] drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled
  2017-09-19 17:41 ` [PATCH 08/31] drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled Sagar Arun Kamble
  2017-09-21  8:26   ` Szwichtenberg, Radoslaw
@ 2017-09-26  7:41   ` Ewelina Musial
  2017-09-28  9:11     ` Sagar Arun Kamble
  1 sibling, 1 reply; 58+ messages in thread
From: Ewelina Musial @ 2017-09-26  7:41 UTC (permalink / raw)
  To: Sagar Arun Kamble; +Cc: intel-gfx

On Tue, Sep 19, 2017 at 11:11:44PM +0530, Sagar Arun Kamble wrote:
> This function gives the status of RC6, whether disabled or if
> enabled then which state. intel_enable_rc6 will be used for
> enabling RC6 in the next patch.
> 
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Imre Deak <imre.deak@intel.com>
> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Ewelina Musial <ewelina.musial@intel.com>

- Ewelina
> ---
>  drivers/gpu/drm/i915/i915_drv.c   |  2 +-
>  drivers/gpu/drm/i915/i915_sysfs.c |  2 +-
>  drivers/gpu/drm/i915/intel_drv.h  |  2 +-
>  drivers/gpu/drm/i915/intel_guc.c  |  3 ++-
>  drivers/gpu/drm/i915/intel_pm.c   | 12 ++++++------
>  5 files changed, 11 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 6cc1162..a6dbad3 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -2486,7 +2486,7 @@ static int intel_runtime_suspend(struct device *kdev)
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	int ret;
>  
> -	if (WARN_ON_ONCE(!(dev_priv->pm.rps.enabled && intel_enable_rc6())))
> +	if (WARN_ON_ONCE(!(dev_priv->pm.rps.enabled && intel_rc6_enabled())))
>  		return -ENODEV;
>  
>  	if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv)))
> diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
> index c16e907..8add849 100644
> --- a/drivers/gpu/drm/i915/i915_sysfs.c
> +++ b/drivers/gpu/drm/i915/i915_sysfs.c
> @@ -49,7 +49,7 @@ static u32 calc_residency(struct drm_i915_private *dev_priv,
>  static ssize_t
>  show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf)
>  {
> -	return snprintf(buf, PAGE_SIZE, "%x\n", intel_enable_rc6());
> +	return snprintf(buf, PAGE_SIZE, "%x\n", intel_rc6_enabled());
>  }
>  
>  static ssize_t
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index f7db720..0cf04eb 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1900,7 +1900,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>  				  struct intel_crtc_state *cstate);
>  void intel_init_ipc(struct drm_i915_private *dev_priv);
>  void intel_enable_ipc(struct drm_i915_private *dev_priv);
> -static inline int intel_enable_rc6(void)
> +static inline int intel_rc6_enabled(void)
>  {
>  	return i915.enable_rc6;
>  }
> diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
> index c731cff..f4dc708 100644
> --- a/drivers/gpu/drm/i915/intel_guc.c
> +++ b/drivers/gpu/drm/i915/intel_guc.c
> @@ -128,7 +128,8 @@ int intel_guc_sample_forcewake(struct intel_guc *guc)
>  
>  	action[0] = INTEL_GUC_ACTION_SAMPLE_FORCEWAKE;
>  	/* WaRsDisableCoarsePowerGating:skl,bxt */
> -	if (!intel_enable_rc6() || NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
> +	if (!intel_rc6_enabled() ||
> +	    NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
>  		action[1] = 0;
>  	else
>  		/* bit 0 and 1 are for Render and Media domain separately */
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index b89677a..b83751e 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -6606,7 +6606,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
>  	I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 25);
>  
>  	/* 3a: Enable RC6 */
> -	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
> +	if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
>  		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
>  	DRM_INFO("RC6 %s\n", onoff(rc6_mask & GEN6_RC_CTL_RC6_ENABLE));
>  	I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
> @@ -6655,7 +6655,7 @@ static void gen8_enable_rc6(struct drm_i915_private *dev_priv)
>  		I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
>  
>  	/* 3: Enable RC6 */
> -	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
> +	if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
>  		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
>  	intel_print_rc6_info(dev_priv, rc6_mask);
>  	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
> @@ -6749,7 +6749,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv)
>  	I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
>  
>  	/* Check if we are enabling RC6 */
> -	rc6_mode = intel_enable_rc6();
> +	rc6_mode = intel_rc6_enabled();
>  	if (rc6_mode & INTEL_RC6_ENABLE)
>  		rc6_mask |= GEN6_RC_CTL_RC6_ENABLE;
>  
> @@ -7251,7 +7251,7 @@ static void cherryview_enable_rc6(struct drm_i915_private *dev_priv)
>  	pcbr = I915_READ(VLV_PCBR);
>  
>  	/* 3: Enable RC6 */
> -	if ((intel_enable_rc6() & INTEL_RC6_ENABLE) &&
> +	if ((intel_rc6_enabled() & INTEL_RC6_ENABLE) &&
>  	    (pcbr >> VLV_PCBR_ADDR_SHIFT))
>  		rc6_mode = GEN7_RC_CTL_TO_MODE;
>  
> @@ -7345,7 +7345,7 @@ static void valleyview_enable_rc6(struct drm_i915_private *dev_priv)
>  				      VLV_MEDIA_RC6_COUNT_EN |
>  				      VLV_RENDER_RC6_COUNT_EN));
>  
> -	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
> +	if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
>  		rc6_mode = GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
>  
>  	intel_print_rc6_info(dev_priv, rc6_mode);
> @@ -9418,7 +9418,7 @@ u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv,
>  {
>  	u64 time_hw, units, div;
>  
> -	if (!intel_enable_rc6())
> +	if (!intel_rc6_enabled())
>  		return 0;
>  
>  	intel_runtime_pm_get(dev_priv);
> -- 
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 01/31] drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing
  2017-09-21 15:12   ` Michal Wajdeczko
@ 2017-09-28  9:10     ` Sagar Arun Kamble
  0 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-28  9:10 UTC (permalink / raw)
  To: Michal Wajdeczko, intel-gfx; +Cc: Tomeu Vizoso

Thanks for the review Michal. Will update as suggested.

On 9/21/2017 8:42 PM, Michal Wajdeczko wrote:
> On Tue, 19 Sep 2017 19:41:37 +0200, Sagar Arun Kamble 
> <sagar.a.kamble@intel.com> wrote:
>
>> Input string parsing used in CRC control parameter parsing is generic
>> and can be reused for other debugfs interfaces. Hence name it as
>> buffer_tokenize instead of tieing to display_crc. Also fix the function
>> desciption for CRC control parsing that was misplaced at tokenize 
>> function.
>>
>> Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
>> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
>> Acked-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_drv.h       |  1 +
>>  drivers/gpu/drm/i915/intel_pipe_crc.c | 88 
>> +++++++++++++++++------------------
>>  2 files changed, 45 insertions(+), 44 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h 
>> b/drivers/gpu/drm/i915/i915_drv.h
>> index 6d7d871..4d5ffde 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -3847,6 +3847,7 @@ u32 i915_gem_fence_alignment(struct 
>> drm_i915_private *dev_priv, u32 size,
>>  int i915_debugfs_register(struct drm_i915_private *dev_priv);
>>  int i915_debugfs_connector_add(struct drm_connector *connector);
>>  void intel_display_crc_init(struct drm_i915_private *dev_priv);
>> +int buffer_tokenize(char *buf, char *words[], int max_words);
>>  #else
>>  static inline int i915_debugfs_register(struct drm_i915_private 
>> *dev_priv) {return 0;}
>>  static inline int i915_debugfs_connector_add(struct drm_connector 
>> *connector)
>> diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c 
>> b/drivers/gpu/drm/i915/intel_pipe_crc.c
>> index 96043a5..2e312b8 100644
>> --- a/drivers/gpu/drm/i915/intel_pipe_crc.c
>> +++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
>> @@ -710,49 +710,6 @@ static int pipe_crc_set_source(struct 
>> drm_i915_private *dev_priv,
>>      return ret;
>>  }
>> -/*
>> - * Parse pipe CRC command strings:
>> - *   command: wsp* object wsp+ name wsp+ source wsp*
>> - *   object: 'pipe'
>> - *   name: (A | B | C)
>> - *   source: (none | plane1 | plane2 | pf)
>> - *   wsp: (#0x20 | #0x9 | #0xA)+
>> - *
>> - * eg.:
>> - *  "pipe A plane1"  ->  Start CRC computations on plane1 of pipe A
>> - *  "pipe A none"    ->  Stop CRC
>> - */
>> -static int display_crc_ctl_tokenize(char *buf, char *words[], int 
>> max_words)
>> -{
>> -    int n_words = 0;
>> -
>> -    while (*buf) {
>> -        char *end;
>> -
>> -        /* skip leading white space */
>> -        buf = skip_spaces(buf);
>> -        if (!*buf)
>> -            break;    /* end of buffer */
>> -
>> -        /* find end of word */
>> -        for (end = buf; *end && !isspace(*end); end++)
>> -            ;
>> -
>> -        if (n_words == max_words) {
>> -            DRM_DEBUG_DRIVER("too many words, allowed <= %d\n",
>> -                     max_words);
>> -            return -EINVAL;    /* ran out of words[] before bytes */
>> -        }
>> -
>> -        if (*end)
>> -            *end++ = '\0';
>> -        words[n_words++] = buf;
>> -        buf = end;
>> -    }
>> -
>> -    return n_words;
>> -}
>> -
>>  enum intel_pipe_crc_object {
>>      PIPE_CRC_OBJECT_PIPE,
>>  };
>> @@ -806,6 +763,49 @@ static int display_crc_ctl_parse_pipe(const char 
>> *buf, enum pipe *pipe)
>>      return -EINVAL;
>>  }
>> +int buffer_tokenize(char *buf, char *words[], int max_words)
>> +{
>> +    int n_words = 0;
>> +
>> +    while (*buf) {
>> +        char *end;
>> +
>> +        /* skip leading white space */
>> +        buf = skip_spaces(buf);
>> +        if (!*buf)
>> +            break;    /* end of buffer */
>> +
>> +        /* find end of word */
>> +        for (end = buf; *end && !isspace(*end); end++)
>> +            ;
>> +
>> +        if (n_words == max_words) {
>> +            DRM_DEBUG_DRIVER("too many words, allowed <= %d\n",
>> +                     max_words);
>> +            return -EINVAL;    /* ran out of words[] before bytes */
>> +        }
>> +
>> +        if (*end)
>> +            *end++ = '\0';
>> +        words[n_words++] = buf;
>> +        buf = end;
>> +    }
>> +
>> +    return n_words;
>> +}
>
> You should move this function to i915_debugfs.c
>
>> +
>> +/*
>> + * Parse pipe CRC command strings:
>> + *   command: wsp* object wsp+ name wsp+ source wsp*
>> + *   object: 'pipe'
>> + *   name: (A | B | C)
>> + *   source: (none | plane1 | plane2 | pf)
>> + *   wsp: (#0x20 | #0x9 | #0xA)+
>> + *
>> + * eg.:
>> + *  "pipe A plane1"  ->  Start CRC computations on plane1 of pipe A
>> + *  "pipe A none"    ->  Stop CRC
>> + */
>>  static int display_crc_ctl_parse(struct drm_i915_private *dev_priv,
>>                   char *buf, size_t len)
>>  {
>> @@ -816,7 +816,7 @@ static int display_crc_ctl_parse(struct 
>> drm_i915_private *dev_priv,
>>      enum intel_pipe_crc_object object;
>>      enum intel_pipe_crc_source source;
>> -    n_words = display_crc_ctl_tokenize(buf, words, N_WORDS);
>> +    n_words = buffer_tokenize(buf, words, N_WORDS);
>>      if (n_words != N_WORDS) {
>>          DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n",
>>                   N_WORDS);

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

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

* Re: [PATCH 08/31] drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled
  2017-09-26  7:41   ` Ewelina Musial
@ 2017-09-28  9:11     ` Sagar Arun Kamble
  0 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-28  9:11 UTC (permalink / raw)
  To: Ewelina Musial; +Cc: intel-gfx

Thank you Radek, Ewelina for the reviews.

On 9/26/2017 1:11 PM, Ewelina Musial wrote:
> On Tue, Sep 19, 2017 at 11:11:44PM +0530, Sagar Arun Kamble wrote:
>> This function gives the status of RC6, whether disabled or if
>> enabled then which state. intel_enable_rc6 will be used for
>> enabling RC6 in the next patch.
>>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> Cc: Imre Deak <imre.deak@intel.com>
>> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
> Reviewed-by: Ewelina Musial <ewelina.musial@intel.com>
>
> - Ewelina
>> ---
>>   drivers/gpu/drm/i915/i915_drv.c   |  2 +-
>>   drivers/gpu/drm/i915/i915_sysfs.c |  2 +-
>>   drivers/gpu/drm/i915/intel_drv.h  |  2 +-
>>   drivers/gpu/drm/i915/intel_guc.c  |  3 ++-
>>   drivers/gpu/drm/i915/intel_pm.c   | 12 ++++++------
>>   5 files changed, 11 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
>> index 6cc1162..a6dbad3 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.c
>> +++ b/drivers/gpu/drm/i915/i915_drv.c
>> @@ -2486,7 +2486,7 @@ static int intel_runtime_suspend(struct device *kdev)
>>   	struct drm_i915_private *dev_priv = to_i915(dev);
>>   	int ret;
>>   
>> -	if (WARN_ON_ONCE(!(dev_priv->pm.rps.enabled && intel_enable_rc6())))
>> +	if (WARN_ON_ONCE(!(dev_priv->pm.rps.enabled && intel_rc6_enabled())))
>>   		return -ENODEV;
>>   
>>   	if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv)))
>> diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
>> index c16e907..8add849 100644
>> --- a/drivers/gpu/drm/i915/i915_sysfs.c
>> +++ b/drivers/gpu/drm/i915/i915_sysfs.c
>> @@ -49,7 +49,7 @@ static u32 calc_residency(struct drm_i915_private *dev_priv,
>>   static ssize_t
>>   show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf)
>>   {
>> -	return snprintf(buf, PAGE_SIZE, "%x\n", intel_enable_rc6());
>> +	return snprintf(buf, PAGE_SIZE, "%x\n", intel_rc6_enabled());
>>   }
>>   
>>   static ssize_t
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index f7db720..0cf04eb 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -1900,7 +1900,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>>   				  struct intel_crtc_state *cstate);
>>   void intel_init_ipc(struct drm_i915_private *dev_priv);
>>   void intel_enable_ipc(struct drm_i915_private *dev_priv);
>> -static inline int intel_enable_rc6(void)
>> +static inline int intel_rc6_enabled(void)
>>   {
>>   	return i915.enable_rc6;
>>   }
>> diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c
>> index c731cff..f4dc708 100644
>> --- a/drivers/gpu/drm/i915/intel_guc.c
>> +++ b/drivers/gpu/drm/i915/intel_guc.c
>> @@ -128,7 +128,8 @@ int intel_guc_sample_forcewake(struct intel_guc *guc)
>>   
>>   	action[0] = INTEL_GUC_ACTION_SAMPLE_FORCEWAKE;
>>   	/* WaRsDisableCoarsePowerGating:skl,bxt */
>> -	if (!intel_enable_rc6() || NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
>> +	if (!intel_rc6_enabled() ||
>> +	    NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
>>   		action[1] = 0;
>>   	else
>>   		/* bit 0 and 1 are for Render and Media domain separately */
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>> index b89677a..b83751e 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -6606,7 +6606,7 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
>>   	I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 25);
>>   
>>   	/* 3a: Enable RC6 */
>> -	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
>> +	if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
>>   		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
>>   	DRM_INFO("RC6 %s\n", onoff(rc6_mask & GEN6_RC_CTL_RC6_ENABLE));
>>   	I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
>> @@ -6655,7 +6655,7 @@ static void gen8_enable_rc6(struct drm_i915_private *dev_priv)
>>   		I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
>>   
>>   	/* 3: Enable RC6 */
>> -	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
>> +	if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
>>   		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
>>   	intel_print_rc6_info(dev_priv, rc6_mask);
>>   	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
>> @@ -6749,7 +6749,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv)
>>   	I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
>>   
>>   	/* Check if we are enabling RC6 */
>> -	rc6_mode = intel_enable_rc6();
>> +	rc6_mode = intel_rc6_enabled();
>>   	if (rc6_mode & INTEL_RC6_ENABLE)
>>   		rc6_mask |= GEN6_RC_CTL_RC6_ENABLE;
>>   
>> @@ -7251,7 +7251,7 @@ static void cherryview_enable_rc6(struct drm_i915_private *dev_priv)
>>   	pcbr = I915_READ(VLV_PCBR);
>>   
>>   	/* 3: Enable RC6 */
>> -	if ((intel_enable_rc6() & INTEL_RC6_ENABLE) &&
>> +	if ((intel_rc6_enabled() & INTEL_RC6_ENABLE) &&
>>   	    (pcbr >> VLV_PCBR_ADDR_SHIFT))
>>   		rc6_mode = GEN7_RC_CTL_TO_MODE;
>>   
>> @@ -7345,7 +7345,7 @@ static void valleyview_enable_rc6(struct drm_i915_private *dev_priv)
>>   				      VLV_MEDIA_RC6_COUNT_EN |
>>   				      VLV_RENDER_RC6_COUNT_EN));
>>   
>> -	if (intel_enable_rc6() & INTEL_RC6_ENABLE)
>> +	if (intel_rc6_enabled() & INTEL_RC6_ENABLE)
>>   		rc6_mode = GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
>>   
>>   	intel_print_rc6_info(dev_priv, rc6_mode);
>> @@ -9418,7 +9418,7 @@ u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv,
>>   {
>>   	u64 time_hw, units, div;
>>   
>> -	if (!intel_enable_rc6())
>> +	if (!intel_rc6_enabled())
>>   		return 0;
>>   
>>   	intel_runtime_pm_get(dev_priv);
>> -- 
>> 1.9.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 15/31] drm/i915/slpc: Sanitize GuC version
  2017-09-21 12:52   ` Michal Wajdeczko
@ 2017-09-28  9:20     ` Sagar Arun Kamble
  0 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-28  9:20 UTC (permalink / raw)
  To: Michal Wajdeczko, intel-gfx; +Cc: Tom O'Rourke



On 9/21/2017 6:22 PM, Michal Wajdeczko wrote:
> On Tue, 19 Sep 2017 19:41:51 +0200, Sagar Arun Kamble 
> <sagar.a.kamble@intel.com> wrote:
>
>> From: Tom O'Rourke <Tom.O'Rourke@intel.com>
>>
>> The SLPC interface is dependent on GuC version.
>> Only GuC versions known to be compatible are supported here.
>>
>> SLPC with GuC firmware v9 is supported with this series.
>>
>> v1: Updated with modified sanitize_slpc_option in earlier patch.
>>
>> v2-v3: Rebase.
>>
>> v4: Updated support for GuC firmware v9.
>>
>> v5: Commit subject updated.
>>
>> v6: Commit subject and message update. Add support condition as >=v9.
>>
>> v7: Sanitizing GuC version in intel_uc_init_fw for SLPC compatibility.
>>     Added info. print for needed version and pointer to 01.org.
>>
>> v8: s/FIRMWARE_URL/I915_FIRMWARE_URL, Macro added for SLPC required GuC
>>     Major version and rearrangement for sanitization. (MichalW, Joonas)
>>
>> v9: Checking major_ver_found to sanitize SLPC option enable_slpc post
>>     fetching the firmware as with Custom firmware loaded through
>>     guc_firmware_path parameter, major_ver_wanted are cleared. (Lukasz)
>>
>> v10: Moved the I915_FIRMWARE_URL macro to intel_uc_common.h.
>>
>> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
>> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_csr.c        | 15 ++++++---------
>>  drivers/gpu/drm/i915/intel_guc.h        |  1 +
>>  drivers/gpu/drm/i915/intel_guc_loader.c | 15 +++++++++++++++
>>  drivers/gpu/drm/i915/intel_uc.c         |  1 +
>>  drivers/gpu/drm/i915/intel_uc_common.h  |  2 ++
>>  5 files changed, 25 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_csr.c 
>> b/drivers/gpu/drm/i915/intel_csr.c
>> index 965988f..56c56f5 100644
>> --- a/drivers/gpu/drm/i915/intel_csr.c
>> +++ b/drivers/gpu/drm/i915/intel_csr.c
>> @@ -52,11 +52,6 @@
>>  MODULE_FIRMWARE(I915_CSR_BXT);
>>  #define BXT_CSR_VERSION_REQUIRED    CSR_VERSION(1, 7)
>> -#define FIRMWARE_URL "https://01.org/linuxgraphics/downloads/firmware"
>> -
>> -
>> -
>> -
>>  #define CSR_MAX_FW_SIZE            0x2FFF
>>  #define CSR_DEFAULT_FW_OFFSET        0xFFFFFFFF
>> @@ -309,11 +304,12 @@ static uint32_t *parse_csr_fw(struct 
>> drm_i915_private *dev_priv,
>>     if (csr->version != required_version) {
>>          DRM_INFO("Refusing to load DMC firmware v%u.%u,"
>> -             " please use v%u.%u [" FIRMWARE_URL "].\n",
>> +             " please use v%u.%u [%s].\n",
>>               CSR_VERSION_MAJOR(csr->version),
>>               CSR_VERSION_MINOR(csr->version),
>>               CSR_VERSION_MAJOR(required_version),
>> -             CSR_VERSION_MINOR(required_version));
>> +             CSR_VERSION_MINOR(required_version),
>> +             I915_FIRMWARE_URL);
>
> Hmm, I'm not sure that including URL here is useful.
> URL will be repeated in csr_load_work_fn() where we can explain
> its purpose ;)
Sure. Will remove from here.
>
>
>>          return NULL;
>>      }
>> @@ -420,8 +416,9 @@ static void csr_load_work_fn(struct work_struct 
>> *work)
>>      } else {
>>          dev_notice(dev_priv->drm.dev,
>>                 "Failed to load DMC firmware"
>> -               " [" FIRMWARE_URL "],"
>> -               " disabling runtime power management.\n");
>> +               " [%s],"
>> +               " disabling runtime power management.\n",
>> +               I915_FIRMWARE_URL);
>
> Maybe more user friendly message should looks like:
>
> "Failed to load DMC firmware, disabling runtime power management."
> "DMC firmware can be downloaded from 
> https://01.org/linuxgraphics/downloads/firmware"
Yes. Will update like this.
>
>>      }
>>     release_firmware(fw);
>> diff --git a/drivers/gpu/drm/i915/intel_guc.h 
>> b/drivers/gpu/drm/i915/intel_guc.h
>> index a894991..3821bf2 100644
>> --- a/drivers/gpu/drm/i915/intel_guc.h
>> +++ b/drivers/gpu/drm/i915/intel_guc.h
>> @@ -159,6 +159,7 @@ static inline void intel_guc_init_early(struct 
>> intel_guc *guc)
>>  int intel_guc_select_fw(struct intel_guc *guc);
>>  int intel_guc_init_hw(struct intel_guc *guc);
>>  u32 intel_guc_wopcm_size(struct intel_guc *guc);
>> +void intel_guc_fetch_sanitize_options(struct intel_guc *guc);
>> /* i915_guc_submission.c */
>>  int i915_guc_submission_init(struct drm_i915_private *dev_priv);
>> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c 
>> b/drivers/gpu/drm/i915/intel_guc_loader.c
>> index 6ee7c16..4550620 100644
>> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
>> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
>> @@ -64,6 +64,8 @@
>>  #define GLK_FW_MAJOR 10
>>  #define GLK_FW_MINOR 56
>> +#define I915_SLPC_REQUIRED_GUC_MAJOR 9
>> +
>>  #define GUC_FW_PATH(platform, major, minor) \
>>         "i915/" __stringify(platform) "_guc_ver" __stringify(major) 
>> "_" __stringify(minor) ".bin"
>> @@ -418,3 +420,16 @@ int intel_guc_select_fw(struct intel_guc *guc)
>>     return 0;
>>  }
>> +
>> +void intel_guc_fetch_sanitize_options(struct intel_guc *guc)
>> +{
>> +    if (guc->fw.major_ver_found <
>> +            I915_SLPC_REQUIRED_GUC_MAJOR) {
>
> Generally we do not allow Guc fw major "found" to be different than 
> "wanted"
> so this check could be also done against "wanted".
With Custom firmware loaded through  guc_firmware_path parameter, 
major_ver_wanted is cleared. And
then check fails. Lukasz verified this.
>
>> +        DRM_INFO("SLPC not supported with GuC firmware"
>> +             " v%u, please use v%u+ [%s].\n",
>> +             guc->fw.major_ver_found,
>> +             I915_SLPC_REQUIRED_GUC_MAJOR,
>> +             I915_FIRMWARE_URL);
>
> Not sure that URL in this message is helpful.
Will reword the message like for DMC.
>
>> +        i915.enable_slpc = 0;
>> +    }
>> +}
>> diff --git a/drivers/gpu/drm/i915/intel_uc.c 
>> b/drivers/gpu/drm/i915/intel_uc.c
>> index eeec986..350027f 100644
>> --- a/drivers/gpu/drm/i915/intel_uc.c
>> +++ b/drivers/gpu/drm/i915/intel_uc.c
>> @@ -194,6 +194,7 @@ static void fetch_uc_fw(struct drm_i915_private 
>> *dev_priv,
>>          }
>>          uc_fw->major_ver_found = css->guc.sw_version >> 16;
>>          uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
>> + intel_guc_fetch_sanitize_options(&dev_priv->guc);
>
> This should be done as part of intel_uc_sanitize_options()
During fetch we know what is found hence doing check there helps for 
case when GuC firmware is supplied through guc_firmware_path parameter.
>
>>          break;
>>     case INTEL_UC_FW_TYPE_HUC:
>> diff --git a/drivers/gpu/drm/i915/intel_uc_common.h 
>> b/drivers/gpu/drm/i915/intel_uc_common.h
>> index 3de6823..4726511 100644
>> --- a/drivers/gpu/drm/i915/intel_uc_common.h
>> +++ b/drivers/gpu/drm/i915/intel_uc_common.h
>> @@ -27,6 +27,8 @@
>>  #include "intel_ringbuffer.h"
>>  #include "i915_vma.h"
>
> Add separation line
Ok. Will update.
>
>> +#define I915_FIRMWARE_URL 
>> "https://01.org/linuxgraphics/intel-linux-graphics-firmwares"
>> +
>>  enum intel_uc_fw_status {
>>      INTEL_UC_FIRMWARE_FAIL = -1,
>>      INTEL_UC_FIRMWARE_NONE = 0,
>
> Michal

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

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

* Re: [PATCH 16/31] drm/i915/slpc: Lay out SLPC init/enable/disable/cleanup helpers
  2017-09-21 13:00   ` Michal Wajdeczko
@ 2017-09-28  9:29     ` Sagar Arun Kamble
  0 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-28  9:29 UTC (permalink / raw)
  To: Michal Wajdeczko, intel-gfx; +Cc: Tom O'Rourke



On 9/21/2017 6:30 PM, Michal Wajdeczko wrote:
> On Tue, 19 Sep 2017 19:41:52 +0200, Sagar Arun Kamble 
> <sagar.a.kamble@intel.com> wrote:
>
>> SLPC operates based on parameters setup in shared data between
>> i915 and GuC SLPC. This is to be created/initialized in intel_slpc_init.
>> From there onwards i915 can control the SLPC operations by Enabling,
>> Disabling complete SLPC or changing SLPC parameters. During cleanup
>> SLPC shared data has to be freed.
>> With this patch on platforms with SLPC support we call intel_slpc_*()
>> functions from GuC setup functions and do not use Host rps functions.
>> With SLPC, intel_enable_gt_powersave will only handle RC6. In the later
>> patch intel_init_gt_powersave will check if SLPC has started running
>> through shared data and update initial state that i915 needs like
>> frequency limits if needed.
>>
>> v1: Return void instead of ignored error code (Paulo)
>>     enable/disable RC6 in SLPC flows (Sagar)
>>     replace HAS_SLPC() use with intel_slpc_enabled()
>>     or intel_slpc_active() (Paulo)
>>     Fix for renaming gen9_disable_rps to gen9_disable_rc6 in
>>     "drm/i915/bxt: Explicitly clear the Turbo control register"
>>     Defer RC6 and SLPC enabling to intel_gen6_powersave_work. (Sagar)
>>     Performance drop with SLPC was happening as ring frequency table
>>     was not programmed when SLPC was enabled. This patch programs ring
>>     frequency table with SLPC. Initial reset of SLPC is based on kernel
>>     parameter as planning to add slpc state in intel_slpc_active. 
>> Cleanup
>>     is also based on kernel parameter as SLPC gets disabled in
>>     disable/suspend.(Sagar)
>>
>> v2: Usage of INTEL_GEN instead of INTEL_INFO->gen (David)
>>     Checkpatch update.
>>
>> v3: Rebase
>>
>> v4: Removed reset functions to comply with *_gt_powersave routines.
>>     (Sagar)
>>
>> v5: Removed intel_slpc_active. Relying on slpc.active for control flows
>>     that are based on SLPC active status in GuC. State setup/cleanup 
>> needed
>>     for SLPC is handled using kernel parameter i915.enable_slpc. 
>> Moved SLPC
>>     init and enabling to GuC enable path as SLPC in GuC can start 
>> doing the
>>     setup post GuC init. Commit message update. (Sagar)
>>
>> v6: Rearranged function definitions.
>>
>> v7: Makefile rearrangement. Reducing usage of i915.enable_slpc and 
>> relying
>>     mostly on rps.rps_enabled to bypass Host RPS flows. Commit message
>>     update.
>>
>> v8: Changed parameters for SLPC functions to struct intel_slpc*.
>>
>> v9: Reinstated intel_slpc_active and intel_slpc_enabled as they are more
>>     meaningful.
>>
>> v10: Rebase changes due to creation of intel_guc.h. Updates in
>>      intel_guc_cleanup w.r.t slpc cleanup.
>>
>> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
>> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
>> ---
>>  drivers/gpu/drm/i915/Makefile     |  1 +
>>  drivers/gpu/drm/i915/i915_drv.h   | 12 ++++++++++
>>  drivers/gpu/drm/i915/intel_guc.c  |  3 +++
>>  drivers/gpu/drm/i915/intel_guc.h  |  3 +++
>
> Hmm, this looks like cross dependency on other pending series
Yes. Will make this independent series.
>
>>  drivers/gpu/drm/i915/intel_pm.c   | 19 +++++++++++-----
>>  drivers/gpu/drm/i915/intel_slpc.c | 42
>
> It looks that SLPC is tight with Guc so maybe better names would be:
>
>     intel_guc_slpc.c and struct intel_guc_slpc
>
> ie. the same pattern as with Guc log.
Sure. Will update.
>
>
>> ++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_slpc.h | 47 
>> +++++++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_uc.c   | 20 +++++++++++++++++
>>  8 files changed, 142 insertions(+), 5 deletions(-)
>>  create mode 100644 drivers/gpu/drm/i915/intel_slpc.c
>>  create mode 100644 drivers/gpu/drm/i915/intel_slpc.h
>>
>> diff --git a/drivers/gpu/drm/i915/Makefile 
>> b/drivers/gpu/drm/i915/Makefile
>> index d1327f6..62bf4f6e 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -64,6 +64,7 @@ i915-y += intel_uc.o \
>>        intel_guc_log.o \
>>        intel_guc_loader.o \
>>        intel_huc.o \
>> +      intel_slpc.o \
>>        i915_guc_submission.o
>> # autogenerated null render state
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h 
>> b/drivers/gpu/drm/i915/i915_drv.h
>> index 428cb1c..af633c6 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -2748,6 +2748,18 @@ static inline struct drm_i915_private 
>> *guc_to_i915(struct intel_guc *guc)
>>      return container_of(guc, struct drm_i915_private, guc);
>>  }
>> +static inline struct intel_guc *slpc_to_guc(struct intel_slpc *slpc)
>> +{
>> +    return container_of(slpc, struct intel_guc, slpc);
>> +}
>> +
>> +static inline struct drm_i915_private *slpc_to_i915(struct 
>> intel_slpc *slpc)
>> +{
>> +    struct intel_guc *guc = slpc_to_guc(slpc);
>> +
>> +    return guc_to_i915(guc);
>> +}
>> +
>>  static inline struct drm_i915_private *huc_to_i915(struct intel_huc 
>> *huc)
>>  {
>>      return container_of(huc, struct drm_i915_private, huc);
>> diff --git a/drivers/gpu/drm/i915/intel_guc.c 
>> b/drivers/gpu/drm/i915/intel_guc.c
>> index f4dc708..a92c7e8 100644
>> --- a/drivers/gpu/drm/i915/intel_guc.c
>> +++ b/drivers/gpu/drm/i915/intel_guc.c
>> @@ -226,6 +226,9 @@ void intel_guc_cleanup(struct intel_guc *guc)
>>     if (i915.enable_guc_submission)
>>          i915_guc_submission_cleanup(dev_priv);
>> +
>> +    if (intel_slpc_enabled())
>> +        intel_slpc_cleanup(&guc->slpc);
>>  }
>> /**
>> diff --git a/drivers/gpu/drm/i915/intel_guc.h 
>> b/drivers/gpu/drm/i915/intel_guc.h
>> index 3821bf2..b835d30 100644
>> --- a/drivers/gpu/drm/i915/intel_guc.h
>> +++ b/drivers/gpu/drm/i915/intel_guc.h
>> @@ -28,6 +28,7 @@
>>  #include "intel_guc_fwif.h"
>>  #include "i915_guc_reg.h"
>>  #include "intel_guc_ct.h"
>> +#include "intel_slpc.h"
>> /*
>>   * This structure primarily describes the GEM object shared with the 
>> GuC.
>> @@ -115,6 +116,8 @@ struct intel_guc {
>>          enum forcewake_domains fw_domains;
>>      } send_regs;
>> +    struct intel_slpc slpc;
>> +
>
> Pick better place - now you're inside 'send' related members.
Ok. Will update.
>
>>      /* To serialize the intel_guc_send actions */
>>      struct mutex send_mutex;
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c 
>> b/drivers/gpu/drm/i915/intel_pm.c
>> index 20ec8f4..e5607e5 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -7995,6 +7995,12 @@ void intel_suspend_gt_powersave(struct 
>> drm_i915_private *dev_priv)
>>          intel_runtime_pm_put(dev_priv);
>>     /* gen6_rps_idle() will be called later to disable interrupts */
>> +
>> +    if (intel_slpc_active(&dev_priv->guc.slpc)) {
>> +        intel_runtime_pm_get(dev_priv);
>> +        intel_slpc_disable(&dev_priv->guc.slpc);
>> +        intel_runtime_pm_put(dev_priv);
>> +    }
>>  }
>> void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
>> @@ -8121,7 +8127,8 @@ void intel_enable_gt_powersave(struct 
>> drm_i915_private *dev_priv)
>>      mutex_lock(&dev_priv->pm.pcu_lock);
>>     intel_enable_rc6(dev_priv);
>> -    intel_enable_rps(dev_priv);
>> +    if (!intel_slpc_active(&dev_priv->guc.slpc))
>> +        intel_enable_rps(dev_priv);
>>      intel_update_ring_freq(dev_priv);
>>     mutex_unlock(&dev_priv->pm.pcu_lock);
>> @@ -8134,8 +8141,9 @@ static void 
>> __intel_autoenable_gt_powersave(struct work_struct *work)
>>      struct intel_engine_cs *rcs;
>>      struct drm_i915_gem_request *req;
>> -    if (READ_ONCE(dev_priv->pm.rps.enabled) &&
>> -        READ_ONCE(dev_priv->pm.rc6.enabled) &&
>> +    if (READ_ONCE(dev_priv->pm.rc6.enabled) &&
>> +        !(!(intel_slpc_active(&dev_priv->guc.slpc)) ^
>> +          READ_ONCE(dev_priv->pm.rps.enabled)) &&
>>          !(NEEDS_RING_FREQ_UPDATE(dev_priv) ^
>>            READ_ONCE(dev_priv->pm.ring_pstate.configured)))
>>          goto out;
>> @@ -8167,8 +8175,9 @@ static void 
>> __intel_autoenable_gt_powersave(struct work_struct *work)
>> void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv)
>>  {
>> -    if (READ_ONCE(dev_priv->pm.rps.enabled) &&
>> -        READ_ONCE(dev_priv->pm.rc6.enabled) &&
>> +    if (READ_ONCE(dev_priv->pm.rc6.enabled) &&
>> +        !(!(intel_slpc_active(&dev_priv->guc.slpc)) ^
>> +          READ_ONCE(dev_priv->pm.rps.enabled)) &&
>>          !(NEEDS_RING_FREQ_UPDATE(dev_priv) ^
>>            READ_ONCE(dev_priv->pm.ring_pstate.configured)))
>>          return;
>> diff --git a/drivers/gpu/drm/i915/intel_slpc.c 
>> b/drivers/gpu/drm/i915/intel_slpc.c
>> new file mode 100644
>> index 0000000..06abda5
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/intel_slpc.c
>> @@ -0,0 +1,42 @@
>> +/*
>> + * Copyright © 2017 Intel Corporation
>> + *
>> + * Permission is hereby granted, free of charge, to any person 
>> obtaining a
>> + * copy of this software and associated documentation files (the 
>> "Software"),
>> + * to deal in the Software without restriction, including without 
>> limitation
>> + * the rights to use, copy, modify, merge, publish, distribute, 
>> sublicense,
>> + * and/or sell copies of the Software, and to permit persons to whom 
>> the
>> + * Software is furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice (including 
>> the next
>> + * paragraph) shall be included in all copies or substantial 
>> portions of the
>> + * Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
>> EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
>> MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO 
>> EVENT SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 
>> OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
>> ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
>> OTHER DEALINGS
>> + * IN THE SOFTWARE.
>> + *
>> + */
>> +#include <linux/firmware.h>
>> +#include "i915_drv.h"
>> +#include "intel_uc.h"
>> +
>> +void intel_slpc_init(struct intel_slpc *slpc)
>> +{
>> +}
>> +
>> +void intel_slpc_cleanup(struct intel_slpc *slpc)
>> +{
>> +}
>> +
>> +void intel_slpc_enable(struct intel_slpc *slpc)
>> +{
>> +}
>> +
>> +void intel_slpc_disable(struct intel_slpc *slpc)
>> +{
>> +}
>> diff --git a/drivers/gpu/drm/i915/intel_slpc.h 
>> b/drivers/gpu/drm/i915/intel_slpc.h
>> new file mode 100644
>> index 0000000..f68671f
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/intel_slpc.h
>> @@ -0,0 +1,47 @@
>> +/*
>> + * Copyright © 2017 Intel Corporation
>> + *
>> + * Permission is hereby granted, free of charge, to any person 
>> obtaining a
>> + * copy of this software and associated documentation files (the 
>> "Software"),
>> + * to deal in the Software without restriction, including without 
>> limitation
>> + * the rights to use, copy, modify, merge, publish, distribute, 
>> sublicense,
>> + * and/or sell copies of the Software, and to permit persons to whom 
>> the
>> + * Software is furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice (including 
>> the next
>> + * paragraph) shall be included in all copies or substantial 
>> portions of the
>> + * Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
>> EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
>> MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO 
>> EVENT SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 
>> OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
>> ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
>> OTHER DEALINGS
>> + * IN THE SOFTWARE.
>> + *
>> + */
>> +#ifndef _INTEL_SLPC_H_
>> +#define _INTEL_SLPC_H_
>> +
>> +struct intel_slpc {
>> +    bool active;
>> +};
>> +
>> +static inline int intel_slpc_enabled(void)
>> +{
>> +    return i915.enable_slpc;
>> +}
>> +
>> +static inline bool intel_slpc_active(struct intel_slpc *slpc)
>> +{
>> +    return slpc->active;
>> +}
>> +
>> +/* intel_slpc.c */
>> +void intel_slpc_init(struct intel_slpc *slpc);
>> +void intel_slpc_cleanup(struct intel_slpc *slpc);
>> +void intel_slpc_enable(struct intel_slpc *slpc);
>> +void intel_slpc_disable(struct intel_slpc *slpc);
>> +
>> +#endif
>> diff --git a/drivers/gpu/drm/i915/intel_uc.c 
>> b/drivers/gpu/drm/i915/intel_uc.c
>> index 350027f..990d84a 100644
>> --- a/drivers/gpu/drm/i915/intel_uc.c
>> +++ b/drivers/gpu/drm/i915/intel_uc.c
>> @@ -328,6 +328,9 @@ int intel_uc_init_hw(struct drm_i915_private 
>> *dev_priv)
>>          ret = i915_guc_submission_init(dev_priv);
>>          if (ret)
>>              goto err_guc;
>> +
>> +        if (intel_slpc_enabled())
>> +            intel_slpc_init(&dev_priv->guc.slpc);
>>      }
>>     /* init WOPCM */
>> @@ -369,6 +372,17 @@ int intel_uc_init_hw(struct drm_i915_private 
>> *dev_priv)
>>          goto err_log_capture;
>>     intel_huc_auth(&dev_priv->huc);
>> +
>> +    /*
>> +     * SLPC is enabled by setting up the shared data structure and
>> +     * sending reset event to GuC SLPC. Initial data is setup in
>> +     * intel_slpc_init. Here we send the reset event. SLPC enabling
>> +     * in GuC can happen in parallel in GuC with other initialization
>> +     * being done in i915.
>> +     */
>> +    if (intel_slpc_enabled())
>> +        intel_slpc_enable(&dev_priv->guc.slpc);
>> +
>>      if (i915.enable_guc_submission) {
>>          if (i915.guc_log_level >= 0)
>>              gen9_enable_guc_interrupts(dev_priv);
>> @@ -398,6 +412,12 @@ int intel_uc_init_hw(struct drm_i915_private 
>> *dev_priv)
>>      if (i915.enable_guc_submission)
>>          i915_guc_submission_cleanup(dev_priv);
>>  err_guc:
>> +    if (intel_slpc_enabled()) {
>> +        if (intel_slpc_active(&dev_priv->guc.slpc))
>> +            intel_slpc_disable(&dev_priv->guc.slpc);
>> +        intel_slpc_cleanup(&dev_priv->guc.slpc);
>> +    }
>> +
>>      i915_ggtt_disable_guc(dev_priv);
>>     DRM_ERROR("GuC init failed\n");

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

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

* Re: [PATCH 18/31] drm/i915/slpc: Add SLPC communication interfaces
  2017-09-21 13:14   ` Michal Wajdeczko
@ 2017-09-28  9:48     ` Sagar Arun Kamble
  0 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-28  9:48 UTC (permalink / raw)
  To: Michal Wajdeczko, intel-gfx; +Cc: Tom O'Rourke



On 9/21/2017 6:44 PM, Michal Wajdeczko wrote:
> On Tue, 19 Sep 2017 19:41:54 +0200, Sagar Arun Kamble 
> <sagar.a.kamble@intel.com> wrote:
>
>> Communication with SLPC is via Host to GuC interrupt through
>> shared data and parameters. This patch defines the structure of
>> shared data, parameters, data structure to be passed as input and
>> received as output from SLPC. This patch also defines the events
>> to be sent as input and status values output by GuC on processing
>> SLPC events. SLPC shared data has details of SKU type, Slice count,
>> IA Perf MSR values, SLPC state, Power source/plan, SLPC tasks status.
>> Parameters allow overriding task control, frequency range etc.
>>
>> v1: fix whitespace (Sagar)
>>
>> v2-v3: Rebase.
>>
>> v4: Updated with GuC firmware v9.
>>
>> v5: Added definition of input and output data structures for SLPC
>> events. Updated commit message.
>>
>> v6: Removed definition of host2guc_slpc. Will be added in the next
>> patch that uses it. Commit subject update. Rebase.
>>
>> v7: Added definition of SLPC_RESET_FLAG_TDR_OCCURRED to be sent
>> throgh SLPC reset in case of engine reset. Moved all Host/SLPC
>> interfaces from later patches to this patch. Commit message update.
>>
>> v8: Updated value of SLPC_RESET_FLAG_TDR_OCCURRED.
>>
>> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
>> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_slpc.c |  39 +++++++
>>  drivers/gpu/drm/i915/intel_slpc.h | 207 
>> ++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 246 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_slpc.c 
>> b/drivers/gpu/drm/i915/intel_slpc.c
>> index 06abda5..a3db63c 100644
>> --- a/drivers/gpu/drm/i915/intel_slpc.c
>> +++ b/drivers/gpu/drm/i915/intel_slpc.c
>> @@ -25,6 +25,45 @@
>>  #include "i915_drv.h"
>>  #include "intel_uc.h"
>> +struct slpc_param slpc_paramlist[SLPC_MAX_PARAM] = {
>> +    {SLPC_PARAM_TASK_ENABLE_GTPERF, "Enable task GTPERF"},
>> +    {SLPC_PARAM_TASK_DISABLE_GTPERF, "Disable task GTPERF"},
>> +    {SLPC_PARAM_TASK_ENABLE_BALANCER, "Enable task BALANCER"},
>> +    {SLPC_PARAM_TASK_DISABLE_BALANCER, "Disable task BALANCER"},
>> +    {SLPC_PARAM_TASK_ENABLE_DCC, "Enable task DCC"},
>> +    {SLPC_PARAM_TASK_DISABLE_DCC, "Disable task DCC"},
>> +    {SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
>> +                "Minimum GT frequency request for unslice"},
>> +    {SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ,
>> +                "Maximum GT frequency request for unslice"},
>> +    {SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ,
>> +                "Minimum GT frequency request for slice"},
>> +    {SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ,
>> +                "Maximum GT frequency request for slice"},
>> +    {SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS,
>> +                "If non-zero, algorithm will slow down "
>> +                "frame-based applications to this frame-rate"},
>> +    {SLPC_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT,
>> +                "Lock GT frequency request to RPe"},
>> +    {SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING,
>> +                "Set to TRUE to enable slowing framerate"},
>> +    {SLPC_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE,
>> +                "Prevent from changing the RC mode"},
>> +    {SLPC_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ,
>> +                "Override fused value of unslice RP0"},
>> +    {SLPC_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ,
>> +                "Override fused value of slice RP0"},
>> +    {SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING,
>> +                "TRUE means enable Intelligent Bias Control"},
>> +    {SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO,
>> +                "TRUE = enable eval mode when transitioning "
>> +                "from idle to active."},
>> +    {SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE,
>> +                "FALSE = disable eval mode completely"},
>> +    {SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE,
>> +                "Enable IBC when non-Gaming Mode is enabled"}
>> +};
>> +
>>  void intel_slpc_init(struct intel_slpc *slpc)
>>  {
>>  }
>> diff --git a/drivers/gpu/drm/i915/intel_slpc.h 
>> b/drivers/gpu/drm/i915/intel_slpc.h
>> index f68671f..ac4cb65 100644
>> --- a/drivers/gpu/drm/i915/intel_slpc.h
>> +++ b/drivers/gpu/drm/i915/intel_slpc.h
>> @@ -38,6 +38,213 @@ static inline bool intel_slpc_active(struct 
>> intel_slpc *slpc)
>>      return slpc->active;
>>  }
>> +enum slpc_status {
>> +    SLPC_STATUS_OK = 0,
>> +    SLPC_STATUS_ERROR = 1,
>> +    SLPC_STATUS_ILLEGAL_COMMAND = 2,
>> +    SLPC_STATUS_INVALID_ARGS = 3,
>> +    SLPC_STATUS_INVALID_PARAMS = 4,
>> +    SLPC_STATUS_INVALID_DATA = 5,
>> +    SLPC_STATUS_OUT_OF_RANGE = 6,
>> +    SLPC_STATUS_NOT_SUPPORTED = 7,
>> +    SLPC_STATUS_NOT_IMPLEMENTED = 8,
>> +    SLPC_STATUS_NO_DATA = 9,
>> +    SLPC_STATUS_EVENT_NOT_REGISTERED = 10,
>> +    SLPC_STATUS_REGISTER_LOCKED = 11,
>> +    SLPC_STATUS_TEMPORARILY_UNAVAILABLE = 12,
>> +    SLPC_STATUS_VALUE_ALREADY_SET = 13,
>> +    SLPC_STATUS_VALUE_ALREADY_UNSET = 14,
>> +    SLPC_STATUS_VALUE_NOT_CHANGED = 15,
>> +    SLPC_STATUS_MEMIO_ERROR = 16,
>> +    SLPC_STATUS_EVENT_QUEUED_REQ_DPC = 17,
>> +    SLPC_STATUS_EVENT_QUEUED_NOREQ_DPC = 18,
>> +    SLPC_STATUS_NO_EVENT_QUEUED = 19,
>> +    SLPC_STATUS_OUT_OF_SPACE = 20,
>> +    SLPC_STATUS_TIMEOUT = 21,
>> +    SLPC_STATUS_NO_LOCK = 22,
>> +};
>
> I'm always wondering why everyone wants to design its own errno codes ...
> But seriously, do we need to define and use all of them ?
It will be needed to decode the SLPC error state. In my series I haven't 
used these all.
But I think it would be good to describe the error based on these enums 
so that user knows what was the error like in parameter description.
Or should we remove these error codes all together and refer the GuC-KMD 
interface header separately to know what happened?
>
>> +
>> +enum slpc_event_id {
>> +    SLPC_EVENT_RESET = 0,
>> +    SLPC_EVENT_SHUTDOWN = 1,
>> +    SLPC_EVENT_PLATFORM_INFO_CHANGE = 2,
>> +    SLPC_EVENT_DISPLAY_MODE_CHANGE = 3,
>> +    SLPC_EVENT_FLIP_COMPLETE = 4,
>> +    SLPC_EVENT_QUERY_TASK_STATE = 5,
>> +    SLPC_EVENT_PARAMETER_SET = 6,
>> +    SLPC_EVENT_PARAMETER_UNSET = 7,
>> +};
>> +
>> +enum slpc_param_id {
>> +    SLPC_PARAM_TASK_ENABLE_GTPERF = 0,
>> +    SLPC_PARAM_TASK_DISABLE_GTPERF = 1,
>> +    SLPC_PARAM_TASK_ENABLE_BALANCER = 2,
>> +    SLPC_PARAM_TASK_DISABLE_BALANCER = 3,
>> +    SLPC_PARAM_TASK_ENABLE_DCC = 4,
>> +    SLPC_PARAM_TASK_DISABLE_DCC = 5,
>> +    SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ = 6,
>> +    SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ = 7,
>> +    SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ = 8,
>> +    SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ = 9,
>> +    SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS = 10,
>> +    SLPC_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT = 11,
>> +    SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING = 12,
>> +    SLPC_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE = 13,
>> +    SLPC_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ = 14,
>> +    SLPC_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ = 15,
>> +    SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING = 16,
>> +    SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO = 17,
>> +    SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE = 18,
>> +    SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE = 19,
>> +    SLPC_MAX_PARAM,
>> +    SLPC_KMD_MAX_PARAM = 32,
>> +};
>> +
>> +enum slpc_platform_sku {
>> +    SLPC_PLATFORM_SKU_UNDEFINED = 0,
>> +    SLPC_PLATFORM_SKU_ULX = 1,
>> +    SLPC_PLATFORM_SKU_ULT = 2,
>> +    SLPC_PLATFORM_SKU_T = 3,
>> +    SLPC_PLATFORM_SKU_MOBL = 4,
>> +    SLPC_PLATFORM_SKU_DT = 5,
>> +    SLPC_PLATFORM_SKU_UNKNOWN = 6,
>> +};
>> +
>> +enum slpc_power_source {
>> +    SLPC_POWER_SOURCE_UNDEFINED = 0,
>> +    SLPC_POWER_SOURCE_AC = 1,
>> +    SLPC_POWER_SOURCE_DC = 2,
>> +    SLPC_POWER_SOURCE_UNKNOWN = 3,
>> +};
>> +
>> +enum slpc_power_plan {
>> +    SLPC_POWER_PLAN_UNDEFINED = 0,
>> +    SLPC_POWER_PLAN_BATTERY_SAVER = 1,
>> +    SLPC_POWER_PLAN_BALANCED = 2,
>> +    SLPC_POWER_PLAN_PERFORMANCE = 3,
>> +    SLPC_POWER_PLAN_UNKNOWN = 4,
>> +};
>> +
>> +struct slpc_platform_info {
>> +    u8 platform_sku;
>> +    u8 slice_count;
>> +    u8 reserved;
>> +    u8 power_plan_source;
>> +    u8 P0_freq;
>> +    u8 P1_freq;
>> +    u8 Pe_freq;
>> +    u8 Pn_freq;
>> +    u32 reserved1;
>> +    u32 reserved2;
>> +} __packed;
>> +
>> +enum slpc_global_state {
>> +    SLPC_GLOBAL_STATE_NOT_RUNNING = 0,
>> +    SLPC_GLOBAL_STATE_INITIALIZING = 1,
>> +    SLPC_GLOBAL_STATE_RESETTING = 2,
>> +    SLPC_GLOBAL_STATE_RUNNING = 3,
>> +    SLPC_GLOBAL_STATE_SHUTTING_DOWN = 4,
>> +    SLPC_GLOBAL_STATE_ERROR = 5
>> +};
>> +
>> +struct slpc_task_state_data {
>> +    union {
>> +        u32 bitfield1;
>> +        struct {
>> +            u32 gtperf_task_active:1;
>> +            u32 gtperf_stall_possible:1;
>> +            u32 gtperf_gaming_mode:1;
>> +            u32 gtperf_target_fps:8;
>> +            u32 dcc_task_active:1;
>> +            u32 in_dcc:1;
>> +            u32 in_dct:1;
>> +            u32 freq_switch_active:1;
>> +            u32 ibc_enabled:1;
>> +            u32 ibc_active:1;
>> +            u32 pg1_enabled:1;
>> +            u32 pg1_active:1;
>> +            u32 reserved:13;
>> +        };
>> +    };
>> +    union {
>> +        u32 bitfield2;
>> +        struct {
>> +            u32 max_unslice_freq:8;
>> +            u32 min_unslice_freq:8;
>> +            u32 max_slice_freq:8;
>> +            u32 min_slice_freq:8;
>> +        };
>> +    };
>> +} __packed;
>> +
>> +#define SLPC_MAX_OVERRIDE_PARAMETERS 192
>> +#define SLPC_OVERRIDE_BITFIELD_SIZE ((SLPC_MAX_OVERRIDE_PARAMETERS + 
>> 31) / 32)
>> +
>> +struct slpc_shared_data {
>> +    u32 reserved;
>> +    u32 shared_data_size;
>> +    u32 global_state;
>> +    struct slpc_platform_info platform_info;
>> +    struct slpc_task_state_data task_state_data;
>> +    u32 override_parameters_set_bits[SLPC_OVERRIDE_BITFIELD_SIZE];
>> +    u32 override_parameters_values[SLPC_MAX_OVERRIDE_PARAMETERS];
>> +} __packed;
>> +
>> +enum slpc_reset_flags {
>> +    SLPC_RESET_FLAG_TDR_OCCURRED = (1 << 0)
>> +};
>> +
>> +#define SLPC_EVENT_MAX_INPUT_ARGS  7
>> +#define SLPC_EVENT_MAX_OUTPUT_ARGS 1
>> +
>> +union slpc_event_input_header {
>> +    u32 value;
>> +    struct {
>> +        u32 num_args:8;
>> +        u32 event_id:8;
>> +    };
>> +};
>> +
>> +struct slpc_event_input {
>> +    u32 h2g_action_id;
>> +    union slpc_event_input_header header;
>> +    u32 args[SLPC_EVENT_MAX_INPUT_ARGS];
>> +} __packed;
>> +
>> +union slpc_event_output_header {
>> +    u32 value;
>> +    struct {
>> +        u32 num_args:8;
>> +        u32 event_id:8;
>> +        u32 status:16;
>> +    };
>> +};
>> +
>> +struct slpc_event_output {
>> +    u32 reserved;
>> +    union slpc_event_output_header header;
>> +    u32 args[SLPC_EVENT_MAX_OUTPUT_ARGS];
>> +} __packed;
>> +
>> +#define SLPC_EVENT(id, argc)    ((u32) (id) << 8 | (argc))
>> +#define SLPC_POWER_PLAN_SOURCE(plan, source) ((plan) | ((source) << 6))
>> +#define SLPC_POWER_PLAN(plan_source) ((plan_source) & 0x3F)
>> +#define SLPC_POWER_SOURCE(plan_source) ((plan_source) >> 6)
>> +
>> +/* Structures for exposing parameter details to user. */
>> +#define MAX_PARAM_DESCRIPTION_SIZE    160
>> +struct slpc_param {
>> +    enum slpc_param_id id;
>> +    char description[MAX_PARAM_DESCRIPTION_SIZE];
>
> Hmm, 160 bytes for description is big.
>
> As "id" starts from 0 maybe we can use simpler variant (in .c file)
>
>     static struct slpc_param_names {
>         const char *description;
>     } params[] = { ... };
Sure. Will update.
>
>> +};
>> +
>> +extern struct slpc_param slpc_paramlist[];
>> +
>> +#define SLPC_PARAM_TASK_DEFAULT  0
>> +#define SLPC_PARAM_TASK_ENABLED  1
>> +#define SLPC_PARAM_TASK_DISABLED 2
>> +#define SLPC_PARAM_TASK_UNKNOWN  3
>> +
>>  /* intel_slpc.c */
>>  void intel_slpc_init(struct intel_slpc *slpc);
>>  void intel_slpc_cleanup(struct intel_slpc *slpc);

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

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

* Re: [PATCH 20/31] drm/i915/slpc: Add parameter set/unset/get, task control/status functions
  2017-09-21 13:47   ` Michal Wajdeczko
@ 2017-09-28  9:55     ` Sagar Arun Kamble
  0 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-28  9:55 UTC (permalink / raw)
  To: Michal Wajdeczko, intel-gfx; +Cc: Tom O'Rourke



On 9/21/2017 7:17 PM, Michal Wajdeczko wrote:
> On Tue, 19 Sep 2017 19:41:56 +0200, Sagar Arun Kamble 
> <sagar.a.kamble@intel.com> wrote:
>
>> SLPC behavior can be changed through set of parameters.
>> These parameters can be updated and queried from i915 though
>> Host to GuC SLPC events. This patch adds parameter update
>> events for setting/unsetting/getting parameters. SLPC has
>> various tasks for controlling different controls. This patch
>> adds functions to control and query the task status.
>>
>> v1: Use host2guc_slpc
>>     update slcp_param_id enum values for SLPC 2015.2.4
>>     return void instead of ignored error code (Paulo)
>>
>> v2: Checkpatch update.
>>
>> v3: Rebase.
>>
>> v4: Updated with GuC firmware v9.
>>
>> v5: Updated input structure to host2guc_slpc. Added functions
>>     to update only parameters in the SLPC shared memory. This
>>     will allow to setup shared data with all parameters and send
>>     single event to SLPC take them into effect. Commit message
>>     update. (Sagar)
>>
>> v6: Rearranged helpers to use them in slpc_shared_data_init.
>>     Added definition of SLPC_KMD_MAX_PARAM.
>>
>> v7: Added definition of host2guc_slpc with rearrangement of patches.
>>     Added task control/status functions.
>>
>> v8: Rebase w.r.t s/intel_guc_send/intel_guc_send_mmio.
>>
>> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
>> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
>> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_guc.c  |  21 ++++-
>>  drivers/gpu/drm/i915/intel_guc.h  |   2 +
>>  drivers/gpu/drm/i915/intel_slpc.c | 185 
>> ++++++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_slpc.h |   8 ++
>>  4 files changed, 215 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_guc.c 
>> b/drivers/gpu/drm/i915/intel_guc.c
>> index a92c7e8..656bae9 100644
>> --- a/drivers/gpu/drm/i915/intel_guc.c
>> +++ b/drivers/gpu/drm/i915/intel_guc.c
>> @@ -67,9 +67,11 @@ void intel_guc_init_send_regs(struct intel_guc *guc)
>>  /*
>>   * This function implements the MMIO based host to GuC interface.
>>   */
>> -int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, 
>> u32 len)
>> +int __intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, 
>> u32 len,
>> +              u32 *output)
>>  {
>>      struct drm_i915_private *dev_priv = guc_to_i915(guc);
>> +    union slpc_event_output_header header;
>
> Don't pollute generic send function with slpc specific code.
Ok. Will prepare new SLPC specific send function built on top of GUC CT 
based send.
>
>
>>      u32 status;
>>      int i;
>>      int ret;
>> @@ -115,12 +117,29 @@ int intel_guc_send_mmio(struct intel_guc *guc, 
>> const u32 *action, u32 len)
>>               action[0], ret, status, I915_READ(SOFT_SCRATCH(15)));
>>      }
>> +    /*
>> +     * Output data from Host to GuC SLPC actions is populated in 
>> scratch
>> +     * registers SOFT_SCRATCH(1) to SOFT_SCRATCH(14) based on event.
>
> Note that receiving more data over MMIO will be handled by these 
> pending patches
>     https://patchwork.freedesktop.org/patch/170667/
>     https://patchwork.freedesktop.org/patch/170669/
>
> The same series will also add support for responses over CT so stay 
> tuned!
Yes. Will base SLPC changes on top of these.
>
>> +     * Currently only SLPC action status in GuC is meaningful as Host
>> +     * can query only overridden parameters and that are fetched from
>> +     * Host-GuC SLPC shared data.
>> +     */
>> +    if (output && !ret) {
>> +        output[0] = header.value = I915_READ(SOFT_SCRATCH(1));
>> +        ret = header.status;
>> +    }
>> +
>>      intel_uncore_forcewake_put(dev_priv, guc->send_regs.fw_domains);
>>      mutex_unlock(&guc->send_mutex);
>>     return ret;
>>  }
>> +int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, 
>> u32 len)
>> +{
>> +    return __intel_guc_send_mmio(guc, action, len, NULL);
>> +}
>> +
>>  int intel_guc_sample_forcewake(struct intel_guc *guc)
>>  {
>>      struct drm_i915_private *dev_priv = guc_to_i915(guc);
>> diff --git a/drivers/gpu/drm/i915/intel_guc.h 
>> b/drivers/gpu/drm/i915/intel_guc.h
>> index b835d30..c27d2dd 100644
>> --- a/drivers/gpu/drm/i915/intel_guc.h
>> +++ b/drivers/gpu/drm/i915/intel_guc.h
>> @@ -132,6 +132,8 @@ struct intel_guc {
>>  int intel_guc_send_nop(struct intel_guc *guc, const u32 *action, u32 
>> len);
>>  void gen8_guc_raise_irq(struct intel_guc *guc);
>>  void intel_guc_init_send_regs(struct intel_guc *guc);
>> +int __intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, 
>> u32 len,
>> +              u32 *output);
>>  int intel_guc_send_mmio(struct intel_guc *guc, const u32 *action, 
>> u32 len);
>>  int intel_guc_sample_forcewake(struct intel_guc *guc);
>>  int intel_guc_runtime_suspend(struct intel_guc *guc);
>> diff --git a/drivers/gpu/drm/i915/intel_slpc.c 
>> b/drivers/gpu/drm/i915/intel_slpc.c
>> index 73e7bf5..f47d81e 100644
>> --- a/drivers/gpu/drm/i915/intel_slpc.c
>> +++ b/drivers/gpu/drm/i915/intel_slpc.c
>> @@ -132,6 +132,191 @@ int slpc_mem_task_control(struct 
>> slpc_shared_data *data, u64 val,
>>      return ret;
>>  }
>> +static void host2guc_slpc(struct intel_slpc *slpc,
>> +              struct slpc_event_input *input, u32 len)
>> +{
>> +    struct intel_guc *guc = slpc_to_guc(slpc);
>> +    u32 *data;
>> +    u32 output[SLPC_EVENT_MAX_OUTPUT_ARGS];
>> +    int ret = 0;
>> +
>> +    /*
>> +     * We have only 15 scratch registers for communication.
>> +     * the first we will use for the event ID in input and
>> +     * output data. Event processing status will be present
>> +     * in SOFT_SCRATCH(1) register.
>> +     */
>> +    BUILD_BUG_ON(SLPC_EVENT_MAX_INPUT_ARGS > 14);
>> +    BUILD_BUG_ON(SLPC_EVENT_MAX_OUTPUT_ARGS < 1);
>> +    BUILD_BUG_ON(SLPC_EVENT_MAX_OUTPUT_ARGS > 14);
>> +
>> +    data = (u32 *) input;
>> +    data[0] = INTEL_GUC_ACTION_SLPC_REQUEST;
>> +    ret = __intel_guc_send_mmio(guc, data, len, output);
>> +
>> +    if (ret)
>> +        DRM_ERROR("event 0x%x status %d\n",
>> +              ((output[0] & 0xFF00) >> 8), ret);
>> +}
>> +
>> +static void host2guc_slpc_set_param(struct intel_slpc *slpc,
>> +                    u32 id, u32 value)
>> +{
>> +    struct slpc_event_input data = {0};
>> +
>> +    data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2);
>> +    data.args[0] = id;
>> +    data.args[1] = value;
>> +
>> +    host2guc_slpc(slpc, &data, 4);
>> +}
>> +
>> +static void host2guc_slpc_unset_param(struct intel_slpc *slpc,
>> +                      u32 id)
>> +{
>> +    struct slpc_event_input data = {0};
>> +
>> +    data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1);
>> +    data.args[0] = id;
>> +
>> +    host2guc_slpc(slpc, &data, 3);
>> +}
>> +
>> +void intel_slpc_set_param(struct intel_slpc *slpc,
>> +              u32 id,
>> +              u32 value)
>> +{
>> +    struct page *page;
>> +    struct slpc_shared_data *data = NULL;
>> +
>> +    WARN_ON(id >= SLPC_MAX_PARAM);
>> +
>> +    if (!slpc->vma)
>> +        return;
>> +
>> +    page = i915_vma_first_page(slpc->vma);
>> +    data = kmap_atomic(page);
>> +    slpc_mem_set_param(data, id, value);
>> +    kunmap_atomic(data);
>> +
>> +    host2guc_slpc_set_param(slpc, id, value);
>> +}
>> +
>> +void intel_slpc_unset_param(struct intel_slpc *slpc,
>> +                u32 id)
>> +{
>> +    struct page *page;
>> +    struct slpc_shared_data *data = NULL;
>> +
>> +    WARN_ON(id >= SLPC_MAX_PARAM);
>> +
>> +    if (!slpc->vma)
>> +        return;
>> +
>> +    page = i915_vma_first_page(slpc->vma);
>> +    data = kmap_atomic(page);
>> +    slpc_mem_unset_param(data, id);
>> +    kunmap_atomic(data);
>> +
>> +    host2guc_slpc_unset_param(slpc, id);
>> +}
>> +
>> +void intel_slpc_get_param(struct intel_slpc *slpc,
>> +              u32 id,
>> +              int *overriding, u32 *value)
>> +{
>> +    struct page *page;
>> +    struct slpc_shared_data *data = NULL;
>> +    u32 bits;
>> +
>> +    WARN_ON(id >= SLPC_MAX_PARAM);
>> +
>> +    if (!slpc->vma)
>> +        return;
>> +
>> +    page = i915_vma_first_page(slpc->vma);
>> +    data = kmap_atomic(page);
>> +    if (overriding) {
>> +        bits = data->override_parameters_set_bits[id >> 5];
>> +        *overriding = (0 != (bits & (1 << (id % 32))));
>> +    }
>> +    if (value)
>> +        *value = data->override_parameters_values[id];
>> +
>> +    kunmap_atomic(data);
>> +}
>> +
>> +int intel_slpc_task_control(struct intel_slpc *slpc, u64 val,
>> +                u32 enable_id, u32 disable_id)
>> +{
>> +    struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
>> +    int ret = 0;
>> +
>> +    if (!slpc->active)
>> +        return -ENODEV;
>> +
>> +    intel_runtime_pm_get(dev_priv);
>> +
>> +    if (val == SLPC_PARAM_TASK_DEFAULT) {
>> +        /* set default */
>> +        intel_slpc_unset_param(slpc, enable_id);
>> +        intel_slpc_unset_param(slpc, disable_id);
>> +    } else if (val == SLPC_PARAM_TASK_ENABLED) {
>> +        /* set enable */
>> +        intel_slpc_set_param(slpc, enable_id, 1);
>> +        intel_slpc_unset_param(slpc, disable_id);
>> +    } else if (val == SLPC_PARAM_TASK_DISABLED) {
>> +        /* set disable */
>> +        intel_slpc_set_param(slpc, disable_id, 1);
>> +        intel_slpc_unset_param(slpc, enable_id);
>> +    } else {
>> +        ret = -EINVAL;
>> +    }
>> +
>> +    intel_slpc_enable(slpc);
>> +    intel_runtime_pm_put(dev_priv);
>> +
>> +    return ret;
>> +}
>> +
>> +int intel_slpc_task_status(struct intel_slpc *slpc, u64 *val,
>> +               u32 enable_id, u32 disable_id)
>> +{
>> +    int override_enable, override_disable;
>> +    u32 value_enable, value_disable;
>> +    int ret = 0;
>> +
>> +    if (!slpc->active) {
>> +        ret = -ENODEV;
>> +    } else if (val) {
>> +        intel_slpc_get_param(slpc, enable_id, &override_enable,
>> +                     &value_enable);
>> +        intel_slpc_get_param(slpc, disable_id, &override_disable,
>> +                     &value_disable);
>> +
>> +        /*
>> +         * Set the output value:
>> +         * 0: default
>> +         * 1: enabled
>> +         * 2: disabled
>> +         * 3: unknown (should not happen)
>> +         */
>> +        if (override_disable && (value_disable == 1))
>> +            *val = SLPC_PARAM_TASK_DISABLED;
>> +        else if (override_enable && (value_enable == 1))
>> +            *val = SLPC_PARAM_TASK_ENABLED;
>> +        else if (!override_enable && !override_disable)
>> +            *val = SLPC_PARAM_TASK_DEFAULT;
>> +        else
>> +            *val = SLPC_PARAM_TASK_UNKNOWN;
>> +
>> +    } else {
>> +        ret = -EINVAL;
>> +    }
>> +
>> +    return ret;
>> +}
>> +
>>  static void slpc_shared_data_init(struct intel_slpc *slpc)
>>  {
>>      struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
>> diff --git a/drivers/gpu/drm/i915/intel_slpc.h 
>> b/drivers/gpu/drm/i915/intel_slpc.h
>> index 9312b2f..0ff17f0 100644
>> --- a/drivers/gpu/drm/i915/intel_slpc.h
>> +++ b/drivers/gpu/drm/i915/intel_slpc.h
>> @@ -247,6 +247,14 @@ struct slpc_param {
>>  #define SLPC_PARAM_TASK_UNKNOWN  3
>> /* intel_slpc.c */
>> +void intel_slpc_set_param(struct intel_slpc *slpc, u32 id, u32 value);
>> +void intel_slpc_unset_param(struct intel_slpc *slpc, u32 id);
>> +void intel_slpc_get_param(struct intel_slpc *slpc, u32 id,
>> +              int *overriding, u32 *value);
>> +int intel_slpc_task_control(struct intel_slpc *slpc, u64 val,
>> +                u32 enable_id, u32 disable_id);
>> +int intel_slpc_task_status(struct intel_slpc *slpc, u64 *val,
>> +               u32 enable_id, u32 disable_id);
>>  void intel_slpc_init(struct intel_slpc *slpc);
>>  void intel_slpc_cleanup(struct intel_slpc *slpc);
>>  void intel_slpc_enable(struct intel_slpc *slpc);

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

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

* Re: [PATCH 21/31] drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR
  2017-09-21 14:06   ` Michal Wajdeczko
@ 2017-09-28 10:10     ` Sagar Arun Kamble
  0 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-28 10:10 UTC (permalink / raw)
  To: Michal Wajdeczko, intel-gfx; +Cc: Tom O'Rourke



On 9/21/2017 7:36 PM, Michal Wajdeczko wrote:
> On Tue, 19 Sep 2017 19:41:57 +0200, Sagar Arun Kamble 
> <sagar.a.kamble@intel.com> wrote:
>
>> Send host2guc SLPC reset event to GuC post GuC load.
>> Post this, i915 can ascertain if SLPC has started running successfully
>> through shared data. This check is done during intel_init_gt_powersave.
>> This allows to get initial configuration setup by SLPC and if needed
>> move to Host RPS if SLPC runs into issues.
>> On TDR/Engine reset i915 should send extra flag
>> SLPC_RESET_FLAG_TDR_OCCURREDto clear SLPC state as appropriate.
>>
>> v1: Extract host2guc_slpc to handle slpc status code
>>     coding style changes (Paulo)
>>     Removed WARN_ON for checking msb of gtt address of
>>     shared gem obj. (ChrisW)
>>     host2guc_action to i915_guc_action change.(Sagar)
>>     Updating SLPC enabled status. (Sagar)
>>
>> v2: Commit message update. (David)
>>
>> v3: Rebase.
>>
>> v4: Added DRM_INFO message when SLPC is enabled.
>>
>> v5: Updated patch as host2guc_slpc is moved to earlier patch.
>>     SLPC activation status message put after checking the
>>     state from shared data during intel_init_gt_powersave.
>>
>> v6: Added definition of host2guc_slpc and clflush the shared data only
>>     for required size. Setting state to NOT_RUNNING before sending RESET
>>     event. Output data for SLPC actions is to be retrieved during
>>     intel_guc_send with lock protection so created wrapper
>>     __intel_guc_send that outputs GuC output data if needed. Clearing
>>     pm_rps_events on confirming SLPC RUNNING status so that even if
>>     host touches any of the PM registers by mistake it should not have
>>     any effect. (Sagar)
>>
>> v7: Added save/restore_default_rps as Uncore sanitize will clear the
>>     RP_CONTROL setup by BIOS. s/i915_ggtt_offset/guc_ggtt_offset.
>>
>> v8: Added support for handling TDR based SLPC reset. Added functions
>>     host2guc_slpc_tdr_reset, intel_slpc_reset_prepare and
>>     intel_slpc_tdr_reset to handle TDR based SLPC reset.
>>
>> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
>> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
>> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_drv.c   |   2 +
>>  drivers/gpu/drm/i915/i915_irq.c   |   7 +-
>>  drivers/gpu/drm/i915/intel_pm.c   |  10 +++
>>  drivers/gpu/drm/i915/intel_slpc.c | 170 
>> ++++++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_slpc.h |   9 ++
>>  drivers/gpu/drm/i915/intel_uc.c   |   1 +
>>  6 files changed, 198 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.c 
>> b/drivers/gpu/drm/i915/i915_drv.c
>> index f13a3de..932f9ef 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.c
>> +++ b/drivers/gpu/drm/i915/i915_drv.c
>> @@ -1074,6 +1074,8 @@ static int i915_driver_init_hw(struct 
>> drm_i915_private *dev_priv)
>>     intel_sanitize_options(dev_priv);
>> +    intel_slpc_save_default_rps(&dev_priv->guc.slpc);
>> +
>>      ret = i915_ggtt_probe_hw(dev_priv);
>>      if (ret)
>>          return ret;
>> diff --git a/drivers/gpu/drm/i915/i915_irq.c 
>> b/drivers/gpu/drm/i915/i915_irq.c
>> index 4a1554c..2d5ad13 100644
>> --- a/drivers/gpu/drm/i915/i915_irq.c
>> +++ b/drivers/gpu/drm/i915/i915_irq.c
>> @@ -2838,8 +2838,13 @@ void i915_handle_error(struct drm_i915_private 
>> *dev_priv,
>>          }
>>      }
>> -    if (!engine_mask)
>> +    if (!engine_mask) {
>> +        if (intel_slpc_active(&dev_priv->guc.slpc)) {
>> + intel_slpc_reset_prepare(&dev_priv->guc.slpc);
>> +            intel_slpc_tdr_reset(&dev_priv->guc.slpc);
>> +        }
>
> Can you just jump to single slpc function that will hide slpc internals ?
we need to have these two calls as currently SLPC gets enabled during 
intel_uc_init_hw and we can reset from two places.
1. engine reset 2. full gpu reset
In 1st case we want to disable SLPC and reset it
In 2nd case we just want to disable SLPC and let it get enabled through 
intel_slpc_enable based on flag tdr_reset.
I will remove intel_slpc_active check here and probably create two 
functions now to handle these different types of resets.
>>          goto out;
>> +    }
>>     /* Full reset needs the mutex, stop any other user trying to do 
>> so. */
>>      if (test_and_set_bit(I915_RESET_BACKOFF, 
>> &dev_priv->gpu_error.flags)) {
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c 
>> b/drivers/gpu/drm/i915/intel_pm.c
>> index 6b2b7f8..c2065f2 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -7918,6 +7918,16 @@ void intel_init_gt_powersave(struct 
>> drm_i915_private *dev_priv)
>>          intel_runtime_pm_get(dev_priv);
>>      }
>> +    if (intel_slpc_enabled()) {
>> +        dev_priv->guc.slpc.active =
>> +            intel_slpc_get_status(&dev_priv->guc.slpc);
>> +        if (!intel_slpc_active(&dev_priv->guc.slpc)) {
>> +            i915.enable_slpc = 0;
>> +            intel_sanitize_gt_powersave(dev_priv);
>> +        } else
>> +            dev_priv->pm_rps_events = 0;
>> +    }
>> +
>
> Hmm, on one hand you're trying to use friendly wrappers like
> enabled() active() but at the same time you're modifying data
> which these helpers were trying to hide ...
This actually is point from where on intel_slpc_active() is determined.
SLPC enabling is asynchronous and we would need to poll on the shared 
memory status to know the status like in HuC case.
I wanted to hide that latency by pushing out the check for SLPC status 
to intel_init_gt_powersave and not hold the gem_init for long.
But it seems this mechanism is unreliable and it is better to poll. 
Ideally SLPC should have just returned ACK immediately.
Will update this to include poll similar to the one done in SLPC disabling.
current flow is, 
i915_gem_init->intel_init_gt_powersave->intel_enable_gt_powersave (later 
during workload submission)
>
>> mutex_lock(&dev_priv->drm.struct_mutex);
>>      mutex_lock(&dev_priv->pm.pcu_lock);
>> diff --git a/drivers/gpu/drm/i915/intel_slpc.c 
>> b/drivers/gpu/drm/i915/intel_slpc.c
>> index f47d81e..57e69d4 100644
>> --- a/drivers/gpu/drm/i915/intel_slpc.c
>> +++ b/drivers/gpu/drm/i915/intel_slpc.c
>> @@ -390,6 +390,140 @@ static void slpc_shared_data_init(struct 
>> intel_slpc *slpc)
>>      kunmap_atomic(data);
>>  }
>> +static void host2guc_slpc_reset(struct intel_slpc *slpc)
>> +{
>> +    struct slpc_event_input data = {0};
>> +    u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
>> +
>> +    data.header.value = SLPC_EVENT(SLPC_EVENT_RESET, 2);
>> +    data.args[0] = shared_data_gtt_offset;
>> +    data.args[1] = 0;
>> +
>> +    host2guc_slpc(slpc, &data, 4);
>> +}
>> +
>> +static void host2guc_slpc_tdr_reset(struct intel_slpc *slpc)
>> +{
>> +    struct slpc_event_input data = {0};
>> +    u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
>> +
>> +    data.header.value = SLPC_EVENT(SLPC_EVENT_RESET, 3);
>> +    data.args[0] = shared_data_gtt_offset;
>> +    data.args[1] = 0;
>> +    data.args[2] = SLPC_RESET_FLAG_TDR_OCCURRED;
>> +
>> +    host2guc_slpc(slpc, &data, 5);
>> +}
>> +
>> +static void host2guc_slpc_query_task_state(struct intel_slpc *slpc)
>> +{
>> +    struct slpc_event_input data = {0};
>> +    u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
>> +
>> +    data.header.value = SLPC_EVENT(SLPC_EVENT_QUERY_TASK_STATE, 2);
>> +    data.args[0] = shared_data_gtt_offset;
>> +    data.args[1] = 0;
>> +
>> +    host2guc_slpc(slpc, &data, 4);
>> +}
>> +
>> +void intel_slpc_query_task_state(struct intel_slpc *slpc)
>> +{
>> +    if (slpc->active)
>> +        host2guc_slpc_query_task_state(slpc);
>> +}
>> +
>> +/*
>> + * This function will reads the state updates from GuC SLPC into 
>> shared data
>> + * by invoking H2G action. Returns current state of GuC SLPC.
>> + */
>> +void intel_slpc_read_shared_data(struct intel_slpc *slpc,
>> +                 struct slpc_shared_data *data)
>> +{
>> +    struct page *page;
>> +    void *pv = NULL;
>> +
>> +    intel_slpc_query_task_state(slpc);
>> +
>> +    page = i915_vma_first_page(slpc->vma);
>> +    pv = kmap_atomic(page);
>> +
>> +    drm_clflush_virt_range(pv, sizeof(struct slpc_shared_data));
>> +    memcpy(data, pv, sizeof(struct slpc_shared_data));
>> +
>> +    kunmap_atomic(pv);
>> +}
>> +
>> +const char *intel_slpc_get_state_str(enum slpc_global_state state)
>> +{
>> +    if (state == SLPC_GLOBAL_STATE_NOT_RUNNING)
>> +        return "not running";
>> +    else if (state == SLPC_GLOBAL_STATE_INITIALIZING)
>> +        return "initializing";
>> +    else if (state == SLPC_GLOBAL_STATE_RESETTING)
>> +        return "resetting";
>> +    else if (state == SLPC_GLOBAL_STATE_RUNNING)
>> +        return "running";
>> +    else if (state == SLPC_GLOBAL_STATE_SHUTTING_DOWN)
>> +        return "shutting down";
>> +    else if (state == SLPC_GLOBAL_STATE_ERROR)
>> +        return "error";
>> +    else
>> +        return "unknown";
>
> s/if..else/switch..case
Ok. will update.
>
>> +}
>> +
>> +bool intel_slpc_get_status(struct intel_slpc *slpc)
>> +{
>> +    struct slpc_shared_data data;
>> +    bool ret = false;
>> +
>> +    intel_slpc_read_shared_data(slpc, &data);
>> +    DRM_INFO("SLPC state: %s\n",
>> +         intel_slpc_get_state_str(data.global_state));
>> +
>> +    switch (data.global_state) {
>> +    case SLPC_GLOBAL_STATE_RUNNING:
>> +        /* Capture required state from SLPC here */
>> +        ret = true;
>> +        break;
>> +    case SLPC_GLOBAL_STATE_ERROR:
>> +        DRM_ERROR("SLPC in error state.\n");
>> +        break;
>> +    case SLPC_GLOBAL_STATE_RESETTING:
>> +        /*
>> +         * SLPC enabling in GuC should be completing fast.
>> +         * If SLPC is taking time to initialize (unlikely as we are
>> +         * sending reset event during GuC load itself).
>> +         * TODO: Need to wait till state changes to RUNNING.
>> +         */
>> +        ret = true;
>> +        DRM_ERROR("SLPC not running yet.!!!");
>> +        break;
>> +    default:
>> +        break;
>> +    }
>> +    return ret;
>> +}
>
> Hmm, this function is trying to do much more than simple 'get' status.
> Is this necessary to print that many messages here ?
These are for debug purpose. will split the functionality here.
>
>> +
>> +/*
>> + * Uncore sanitize clears RPS state in Host GTPM flows set by BIOS, 
>> Save the
>> + * initial BIOS programmed RPS state that is needed by SLPC and not 
>> set by SLPC.
>> + * Set this state while enabling SLPC.
>> + */
>> +void intel_slpc_save_default_rps(struct intel_slpc *slpc)
>> +{
>> +    struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
>> +
>> +    slpc->rp_control = I915_READ(GEN6_RP_CONTROL);
>> +}
>> +
>> +static void intel_slpc_restore_default_rps(struct intel_slpc *slpc)
>> +{
>> +    struct drm_i915_private *dev_priv = slpc_to_i915(slpc);
>> +
>> +    I915_WRITE(GEN6_RP_CONTROL, slpc->rp_control);
>> +}
>> +
>>  void intel_slpc_init(struct intel_slpc *slpc)
>>  {
>>      struct intel_guc *guc = slpc_to_guc(slpc);
>> @@ -426,6 +560,42 @@ void intel_slpc_cleanup(struct intel_slpc *slpc)
>> void intel_slpc_enable(struct intel_slpc *slpc)
>>  {
>> +    struct page *page;
>> +    struct slpc_shared_data *data;
>> +
>> +    intel_slpc_restore_default_rps(slpc);
>> +
>> +    page = i915_vma_first_page(slpc->vma);
>> +    data = kmap_atomic(page);
>> +    data->global_state = SLPC_GLOBAL_STATE_NOT_RUNNING;
>> +    kunmap_atomic(data);
>> +
>> +    if (slpc->tdr_reset) {
>> +        host2guc_slpc_tdr_reset(slpc);
>> +        slpc->tdr_reset = false;
>> +    } else {
>> +        host2guc_slpc_reset(slpc);
>> +    }
>> +
>> +    slpc->active = true;
>> +}
>> +
>> +void intel_slpc_reset_prepare(struct intel_slpc *slpc)
>> +{
>> +    if (intel_slpc_active(slpc)) {
>> +        intel_slpc_disable(slpc);
>> +        slpc->tdr_reset = true;
>> +    }
>> +}
>> +
>> +void intel_slpc_tdr_reset(struct intel_slpc *slpc)
>> +{
>> +    intel_slpc_restore_default_rps(slpc);
>> +    slpc_shared_data_init(slpc);
>> +
>> +    host2guc_slpc_tdr_reset(slpc);
>> +    slpc->active = true;
>> +    slpc->tdr_reset = false;
>>  }
>> void intel_slpc_disable(struct intel_slpc *slpc)
>> diff --git a/drivers/gpu/drm/i915/intel_slpc.h 
>> b/drivers/gpu/drm/i915/intel_slpc.h
>> index 0ff17f0..20c342b 100644
>> --- a/drivers/gpu/drm/i915/intel_slpc.h
>> +++ b/drivers/gpu/drm/i915/intel_slpc.h
>> @@ -26,7 +26,9 @@
>> struct intel_slpc {
>>      bool active;
>> +    bool tdr_reset;
>>      struct i915_vma *vma;
>> +    u32 rp_control;
>>  };
>> static inline int intel_slpc_enabled(void)
>> @@ -255,9 +257,16 @@ int intel_slpc_task_control(struct intel_slpc 
>> *slpc, u64 val,
>>                  u32 enable_id, u32 disable_id);
>>  int intel_slpc_task_status(struct intel_slpc *slpc, u64 *val,
>>                 u32 enable_id, u32 disable_id);
>> +void intel_slpc_read_shared_data(struct intel_slpc *slpc,
>> +                 struct slpc_shared_data *data);
>> +const char *intel_slpc_get_state_str(enum slpc_global_state state);
>> +bool intel_slpc_get_status(struct intel_slpc *slpc);
>> +void intel_slpc_save_default_rps(struct intel_slpc *slpc);
>>  void intel_slpc_init(struct intel_slpc *slpc);
>>  void intel_slpc_cleanup(struct intel_slpc *slpc);
>>  void intel_slpc_enable(struct intel_slpc *slpc);
>>  void intel_slpc_disable(struct intel_slpc *slpc);
>> +void intel_slpc_reset_prepare(struct intel_slpc *slpc);
>> +void intel_slpc_tdr_reset(struct intel_slpc *slpc);
>> #endif
>> diff --git a/drivers/gpu/drm/i915/intel_uc.c 
>> b/drivers/gpu/drm/i915/intel_uc.c
>> index 990d84a..d8582b8 100644
>> --- a/drivers/gpu/drm/i915/intel_uc.c
>> +++ b/drivers/gpu/drm/i915/intel_uc.c
>> @@ -502,5 +502,6 @@ int intel_uc_resume(struct drm_i915_private 
>> *dev_priv)
>> int intel_uc_reset_prepare(struct drm_i915_private *dev_priv)
>>  {
>> +    intel_slpc_reset_prepare(&dev_priv->guc.slpc);
>>      return intel_uc_suspend(dev_priv);
>>  }

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

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

* Re: [PATCH 24/31] drm/i915/slpc: Add debugfs support to read/write/revert the parameters
  2017-09-21 15:07   ` Michal Wajdeczko
@ 2017-09-28 10:18     ` Sagar Arun Kamble
  0 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-28 10:18 UTC (permalink / raw)
  To: Michal Wajdeczko, intel-gfx



On 9/21/2017 8:37 PM, Michal Wajdeczko wrote:
> On Tue, 19 Sep 2017 19:42:00 +0200, Sagar Arun Kamble 
> <sagar.a.kamble@intel.com> wrote:
>
>> This patch adds two debugfs interfaces:
>> 1. i915_slpc_paramlist: List of all parameters that Host can configure.
>>    Currently listing id and description of each.
>> 2. i915_slpc_param_ctl: This allows to change the parameters. Syntax is:
>>    echo "write <id> <value>" > i915_slpc_param_ctl.
>>    echo "read <id>" > i915_slpc_param_ctl; cat i915_slpc_param_ctl
>>    revert allows to set to default SLPC internal values. Syntax is:
>>    echo "revert <id>" > i915_slpc_param_ctl.
>>
>> Added support to set/read parameters and unset the parameters which will
>> revert them to default SLPC internal values. Also added RPM ref. cover
>> around set/unset calls. Explicit SLPC reset is needed on 
>> setting/unsetting
>> some of the parameters.
>>
>> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_debugfs.c |  19 +++++
>>  drivers/gpu/drm/i915/intel_slpc.c   | 158 
>> ++++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_slpc.h   |   6 ++
>>  3 files changed, 183 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
>> b/drivers/gpu/drm/i915/i915_debugfs.c
>> index dbfe185..0a04f3d 100644
>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>> @@ -2352,6 +2352,23 @@ static int i915_huc_load_status_info(struct 
>> seq_file *m, void *data)
>>      return 0;
>>  }
>> +static int i915_slpc_paramlist_info(struct seq_file *m, void *data)
>
> I'm little confused that part of the debugfs functionality is done here
> while other part in slpc.c
Will pull them together. It was to allow new interfaces to make use of 
the functionality in slpc.c.
>
>> +{
>> +    struct drm_i915_private *dev_priv = node_to_i915(m->private);
>> +    int i;
>> +
>> +    if (!dev_priv->guc.slpc.active) {
>
> intel_slpc_active() ?
yes. will update.
>
>> +        seq_puts(m, "SLPC not active\n");
>> +        return 0;
>> +    }
>> +
>> +    seq_puts(m, "Param id\tParam description\n");
>> +    for (i = 0; i < SLPC_MAX_PARAM; i++)
>> +        seq_printf(m, "%8d\t%s\n", slpc_paramlist[i].id,
>> +                       slpc_paramlist[i].description);
>
> What if size of slpc_paramlist[] will be smaller than i ?
will add the size checks.
>
>> +    return 0;
>> +}
>> +
>>  static int i915_guc_load_status_info(struct seq_file *m, void *data)
>>  {
>>      struct drm_i915_private *dev_priv = node_to_i915(m->private);
>> @@ -4881,6 +4898,7 @@ static int i915_hpd_storm_ctl_open(struct inode 
>> *inode, struct file *file)
>>      {"i915_guc_load_err_log_dump", i915_guc_log_dump, 0, (void *)1},
>>      {"i915_guc_stage_pool", i915_guc_stage_pool, 0},
>>      {"i915_huc_load_status", i915_huc_load_status_info, 0},
>> +    {"i915_slpc_paramlist", i915_slpc_paramlist_info, 0},
>>      {"i915_frequency_info", i915_frequency_info, 0},
>>      {"i915_hangcheck_info", i915_hangcheck_info, 0},
>>      {"i915_reset_info", i915_reset_info, 0},
>> @@ -4944,6 +4962,7 @@ static int i915_hpd_storm_ctl_open(struct inode 
>> *inode, struct file *file)
>>      {"i915_dp_test_type", &i915_displayport_test_type_fops},
>>      {"i915_dp_test_active", &i915_displayport_test_active_fops},
>>      {"i915_guc_log_control", &i915_guc_log_control_fops},
>> +    {"i915_slpc_param_ctl", &i915_slpc_param_ctl_fops},
>>      {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
>>      {"i915_ipc_status", &i915_ipc_status_fops}
>>  };
>> diff --git a/drivers/gpu/drm/i915/intel_slpc.c 
>> b/drivers/gpu/drm/i915/intel_slpc.c
>> index d0fd402..0c094f0 100644
>> --- a/drivers/gpu/drm/i915/intel_slpc.c
>> +++ b/drivers/gpu/drm/i915/intel_slpc.c
>> @@ -25,6 +25,8 @@
>>  #include <asm/msr-index.h>
>>  #include "i915_drv.h"
>>  #include "intel_uc.h"
>> +#include <linux/seq_file.h>
>> +#include <linux/debugfs.h>
>> struct slpc_param slpc_paramlist[SLPC_MAX_PARAM] = {
>>      {SLPC_PARAM_TASK_ENABLE_GTPERF, "Enable task GTPERF"},
>> @@ -684,3 +686,159 @@ void intel_slpc_disable(struct intel_slpc *slpc)
>>     slpc->active = false;
>>  }
>> +
>> +static int slpc_param_ctl_show(struct seq_file *m, void *data)
>> +{
>> +    struct drm_i915_private *dev_priv = m->private;
>> +    struct intel_slpc *slpc = &dev_priv->guc.slpc;
>> +
>> +    if (!slpc->active) {
>
> intel_slpc_active() ?
yes. will update.
>
>> +        seq_puts(m, "SLPC not active\n");
>> +        return 0;
>> +    }
>> +
>> +    seq_printf(m, "%s=%u, override=%s\n",
>> + slpc_paramlist[slpc->debug_param_id].description,
>> +            slpc->debug_param_value,
>> +            yesno(!!slpc->debug_param_override));
>> +
>
> What if slpc->debug_param_id >= SLPC_MAX_PARAM or sizeof paramlist ?
will add the check.
>
>> +    return 0;
>> +}
>> +
>> +static int slpc_param_ctl_open(struct inode *inode, struct file *file)
>> +{
>> +    return single_open(file, slpc_param_ctl_show, inode->i_private);
>> +}
>> +
>> +static const char *read_token = "read", *write_token = "write",
>> +          *revert_token = "revert";
>> +
>> +/*
>> + * Parse SLPC parameter control strings: (Similar to Pipe CRC handling)
>> + *   command: wsp* op wsp+ param id wsp+ [value] wsp*
>> + *   op: "read"/"write"/"revert"
>> + *   param id: slpc_param_id
>> + *   value: u32 value
>> + *   wsp: (#0x20 | #0x9 | #0xA)+
>> + *
>> + * eg.:
>> + *  "read 0"        -> read SLPC_PARAM_TASK_ENABLE_GTPERF
>> + *  "write 7 500"    -> set SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ 
>> to 500MHz
>> + *  "revert 7"        -> revert 
>> SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ to
>> + *               default value.
>> + */
>> +static int slpc_param_ctl_parse(char *buf, size_t len, char **op,
>> +                u32 *id, u32 *value)
>> +{
>> +#define MAX_WORDS 3
>> +    int n_words;
>> +    char *words[MAX_WORDS];
>> +    ssize_t ret;
>> +
>> +    n_words = buffer_tokenize(buf, words, MAX_WORDS);
>
> Ha! finally found the purpose of the patch 001
> Please try to keep them closer.
ok. will bring that closer. Thinking was to keep all drm/i915/slpc 
patches together.
>
>> +    if (!(n_words == 3) && !(n_words == 2)) {
>> +        DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n",
>> +                 MAX_WORDS);
>> +        return -EINVAL;
>> +    }
>> +
>> +    if (strcmp(words[0], read_token) && strcmp(words[0], 
>> write_token) &&
>> +        strcmp(words[0], revert_token)) {
>> +        DRM_DEBUG_DRIVER("unknown operation\n");
>
> Please add operation word into message for easier debug
It is there. :) Did you mean "unknown operation word" ?
>
>> +        return -EINVAL;
>> +    }
>> +
>> +    *op = words[0];
>
> Hmm, this will cause yet another strcmp - try to convert into OP code.
Ok. will update.
>
>> +
>> +    ret = kstrtou32(words[1], 0, id);
>> +    if (ret)
>> +        return ret;
>> +
>> +    if (n_words == 3) {
>> +        ret = kstrtou32(words[2], 0, value);
>> +        if (ret)
>> +            return ret;
>> +    }
>> +
>> +    return 0;
>
> Shouldn't we return n_words-1 to easier catch any missing params?
Yes. Will add this.
>
>> +}
>> +
>> +static ssize_t slpc_param_ctl_write(struct file *file, const char 
>> __user *ubuf,
>> +                     size_t len, loff_t *offp)
>> +{
>> +    struct seq_file *m = file->private_data;
>> +    struct drm_i915_private *dev_priv = m->private;
>> +    struct intel_slpc *slpc = &dev_priv->guc.slpc;
>> +    char *tmpbuf, *op = NULL;
>> +    u32 id, value;
>> +    int ret;
>> +
>> +    if (len == 0)
>> +        return 0;
>> +
>> +    if (len > 40) {
>> +        DRM_DEBUG_DRIVER("expected <40 chars into slpc_param_ctl\n");
>> +        return -E2BIG;
>> +    }
>> +
>> +    tmpbuf = kmalloc(len + 1, GFP_KERNEL);
>> +    if (!tmpbuf)
>> +        return -ENOMEM;
>> +
>> +    if (copy_from_user(tmpbuf, ubuf, len)) {
>> +        ret = -EFAULT;
>> +        goto out;
>> +    }
>> +    tmpbuf[len] = '\0';
>> +
>> +    ret = slpc_param_ctl_parse(tmpbuf, len, &op, &id, &value);
>
> 'ret' is not checked for errors
Will check now with above return fixed.
>
>> +
>> +    if (id >= SLPC_MAX_PARAM) {
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +
>> +    if (!strcmp(op, read_token)) {
>> +        intel_slpc_get_param(slpc, id,
>> +                     &slpc->debug_param_override,
>> +                     &slpc->debug_param_value);
>> +        slpc->debug_param_id = id;
>> +    } else if (!strcmp(op, write_token) || !strcmp(op, revert_token)) {
>> +        if ((id >= SLPC_PARAM_TASK_ENABLE_GTPERF) &&
>> +            (id <= SLPC_PARAM_TASK_DISABLE_DCC)) {
>> +            DRM_DEBUG_DRIVER("Tasks are not controlled by "
>> +                     "this interface\n");
>> +            ret = -EINVAL;
>> +            goto out;
>> +        }
>> +
>> +        /*
>> +         * After updating parameters, RESET event has to be sent to GuC
>> +         * SLPC for ensuring parameters take effect.
>> +         */
>> +        intel_runtime_pm_get(dev_priv);
>> +        if (!strcmp(op, write_token))
>> +            intel_slpc_set_param(slpc, id, value);
>> +        else if (!strcmp(op, revert_token))
>> +            intel_slpc_unset_param(slpc, id);
>> +        intel_slpc_enable(slpc);
>> +        intel_runtime_pm_put(dev_priv);
>> +    }
>> +
>> +out:
>> +    kfree(tmpbuf);
>> +    if (ret < 0)
>> +        return ret;
>> +
>> +    *offp += len;
>> +    return len;
>> +}
>> +
>> +const struct file_operations i915_slpc_param_ctl_fops = {
>> +    .owner = THIS_MODULE,
>> +    .open = slpc_param_ctl_open,
>> +    .read = seq_read,
>> +    .llseek = seq_lseek,
>> +    .release = single_release,
>> +    .write = slpc_param_ctl_write
>> +};
>> diff --git a/drivers/gpu/drm/i915/intel_slpc.h 
>> b/drivers/gpu/drm/i915/intel_slpc.h
>> index ae857d3..e49c513 100644
>> --- a/drivers/gpu/drm/i915/intel_slpc.h
>> +++ b/drivers/gpu/drm/i915/intel_slpc.h
>> @@ -32,6 +32,10 @@ struct intel_slpc {
>>      /* i915 cached SLPC frequency limits */
>>      u32 min_unslice_freq;
>>      u32 max_unslice_freq;
>> +
>> +    u32 debug_param_id;
>> +    u32 debug_param_value;
>> +    u32 debug_param_override;
>
> Group above under 'debug' sub-struct
Sure.
>
>>  };
>> static inline int intel_slpc_enabled(void)
>> @@ -251,6 +255,8 @@ struct slpc_param {
>>  #define SLPC_PARAM_TASK_DISABLED 2
>>  #define SLPC_PARAM_TASK_UNKNOWN  3
>> +extern const struct file_operations i915_slpc_param_ctl_fops;
>> +
>>  /* intel_slpc.c */
>>  void intel_slpc_set_param(struct intel_slpc *slpc, u32 id, u32 value);
>>  void intel_slpc_unset_param(struct intel_slpc *slpc, u32 id);

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

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

* Re: [PATCH 26/31] drm/i915/slpc: Add i915_slpc_info to debugfs
  2017-09-21 15:13   ` Michal Wajdeczko
@ 2017-09-28 10:20     ` Sagar Arun Kamble
  0 siblings, 0 replies; 58+ messages in thread
From: Sagar Arun Kamble @ 2017-09-28 10:20 UTC (permalink / raw)
  To: Michal Wajdeczko, intel-gfx; +Cc: Tom O'Rourke



On 9/21/2017 8:43 PM, Michal Wajdeczko wrote:
> On Tue, 19 Sep 2017 19:42:02 +0200, Sagar Arun Kamble 
> <sagar.a.kamble@intel.com> wrote:
>
>> From: Tom O'Rourke <Tom.O'Rourke@intel.com>
>>
>> i915_slpc_info shows the contents of SLPC shared data
>> parsed into text format.
>>
>> v1: Reformat slpc info (Radek)
>>     squashed query task state info
>>     in slpc info, kunmap before seq_print (Paulo)
>>     return void instead of ignored return value (Paulo)
>>     Avoid magic numbers and use local variables (Jon Bloomfield)
>>     Removed WARN_ON for checking msb of gtt address of
>>     shared gem obj. (ChrisW)
>>     Moved definition of power plan and power source to earlier
>>     patch in the series.
>>     drm/i915/slpc: Allocate/Release/Initialize SLPC shared data
>>     (Akash)
>>
>> v2-v3: Rebase.
>>
>> v4: Updated with GuC firmware v9.
>>
>> v5: Updated host2guc_slpc_query_task_state with struct slpc_input_event
>>     structure. Removed unnecessary checks of vma from i915_slpc_info.
>>     Created helpers for reading the SLPC shared data and string form of
>>     SLPC state. (Sagar)
>>
>> Signed-off-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
>> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_debugfs.c | 165 
>> ++++++++++++++++++++++++++++++++++++
>>  1 file changed, 165 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
>> b/drivers/gpu/drm/i915/i915_debugfs.c
>> index e6fd63f..7a0838f 100644
>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>> @@ -1023,6 +1023,170 @@ static int i915_error_state_open(struct inode 
>> *inode, struct file *file)
>>              NULL, i915_next_seqno_set,
>>              "0x%llx\n");
>> +static int i915_slpc_info(struct seq_file *m, void *unused)
>> +{
>> +    struct drm_i915_private *dev_priv = node_to_i915(m->private);
>> +    int i, value;
>> +    struct slpc_shared_data data;
>> +    enum slpc_global_state global_state;
>> +    enum slpc_platform_sku platform_sku;
>> +    struct slpc_task_state_data *task_data;
>> +    enum slpc_power_plan power_plan;
>> +    enum slpc_power_source power_source;
>> +
>> +    if (!dev_priv->guc.slpc.active)
>> +        return -ENODEV;
>> +
>> +    intel_runtime_pm_get(dev_priv);
>> +    mutex_lock(&dev_priv->pm.pcu_lock);
>> +
>> +    intel_slpc_read_shared_data(&dev_priv->guc.slpc, &data);
>> +
>> +    mutex_unlock(&dev_priv->pm.pcu_lock);
>> +    intel_runtime_pm_put(dev_priv);
>> +
>> +    seq_printf(m, "shared data size: %d\n", data.shared_data_size);
>> +
>> +    global_state = (enum slpc_global_state) data.global_state;
>> +    seq_printf(m, "global state: %d (", global_state);
>> +    seq_printf(m, "%s)\n", intel_slpc_get_state_str(global_state));
>> +
>> +    platform_sku = (enum slpc_platform_sku)
>> +            data.platform_info.platform_sku;
>> +    seq_printf(m, "sku: %d (", platform_sku);
>> +    switch (platform_sku) {
>> +    case SLPC_PLATFORM_SKU_UNDEFINED:
>> +        seq_puts(m, "undefined)\n");
>> +        break;
>> +    case SLPC_PLATFORM_SKU_ULX:
>> +        seq_puts(m, "ULX)\n");
>> +        break;
>> +    case SLPC_PLATFORM_SKU_ULT:
>> +        seq_puts(m, "ULT)\n");
>> +        break;
>> +    case SLPC_PLATFORM_SKU_T:
>> +        seq_puts(m, "T)\n");
>> +        break;
>> +    case SLPC_PLATFORM_SKU_MOBL:
>> +        seq_puts(m, "Mobile)\n");
>> +        break;
>> +    case SLPC_PLATFORM_SKU_DT:
>> +        seq_puts(m, "DT)\n");
>> +        break;
>> +    case SLPC_PLATFORM_SKU_UNKNOWN:
>> +    default:
>> +        seq_puts(m, "unknown)\n");
>> +        break;
>> +    }
>
> Define platform_to_string() followed by single seq_puts()
Sure. Will update.
>
>> +    seq_printf(m, "slice count: %d\n",
>> +           data.platform_info.slice_count);
>> +
>> +    seq_printf(m, "power plan/source: 0x%x\n\tplan:\t",
>> +           data.platform_info.power_plan_source);
>> +    power_plan = (enum slpc_power_plan) SLPC_POWER_PLAN(
>> +                data.platform_info.power_plan_source);
>> +    power_source = (enum slpc_power_source) SLPC_POWER_SOURCE(
>> +                data.platform_info.power_plan_source);
>> +    switch (power_plan) {
>> +    case SLPC_POWER_PLAN_UNDEFINED:
>> +        seq_puts(m, "undefined");
>> +        break;
>> +    case SLPC_POWER_PLAN_BATTERY_SAVER:
>> +        seq_puts(m, "battery saver");
>> +        break;
>> +    case SLPC_POWER_PLAN_BALANCED:
>> +        seq_puts(m, "balanced");
>> +        break;
>> +    case SLPC_POWER_PLAN_PERFORMANCE:
>> +        seq_puts(m, "performance");
>> +        break;
>> +    case SLPC_POWER_PLAN_UNKNOWN:
>> +    default:
>> +        seq_puts(m, "unknown");
>> +        break;
>> +    }
>
> Define power_plan_to_string() followed by single seq_puts()
Sure. Will update.
>
>> +    seq_puts(m, "\n\tsource:\t");
>> +    switch (power_source) {
>> +    case SLPC_POWER_SOURCE_UNDEFINED:
>> +        seq_puts(m, "undefined\n");
>> +        break;
>> +    case SLPC_POWER_SOURCE_AC:
>> +        seq_puts(m, "AC\n");
>> +        break;
>> +    case SLPC_POWER_SOURCE_DC:
>> +        seq_puts(m, "DC\n");
>> +        break;
>> +    case SLPC_POWER_SOURCE_UNKNOWN:
>> +    default:
>> +        seq_puts(m, "unknown\n");
>> +        break;
>> +    }
>> +
>> +    seq_printf(m, "IA frequency (MHz):\n\tP0: %d\n\tP1: %d\n\tPe: 
>> %d\n\tPn: %d\n",
>> +           data.platform_info.P0_freq * 50,
>> +           data.platform_info.P1_freq * 50,
>> +           data.platform_info.Pe_freq * 50,
>> +           data.platform_info.Pn_freq * 50);
>> +
>> +    task_data = &data.task_state_data;
>> +    seq_printf(m, "task state data: 0x%08x 0x%08x\n",
>> +           task_data->bitfield1, task_data->bitfield2);
>> +
>> +    seq_printf(m, "\tgtperf task active: %s\n",
>> +           yesno(task_data->gtperf_task_active));
>> +    seq_printf(m, "\tgtperf stall possible: %s\n",
>> +           yesno(task_data->gtperf_stall_possible));
>> +    seq_printf(m, "\tgtperf gaming mode: %s\n",
>> +           yesno(task_data->gtperf_gaming_mode));
>> +    seq_printf(m, "\tgtperf target fps: %d\n",
>> +           task_data->gtperf_target_fps);
>> +
>> +    seq_printf(m, "\tdcc task active: %s\n",
>> +           yesno(task_data->dcc_task_active));
>> +    seq_printf(m, "\tin dcc: %s\n",
>> +           yesno(task_data->in_dcc));
>> +    seq_printf(m, "\tin dct: %s\n",
>> +           yesno(task_data->in_dct));
>> +    seq_printf(m, "\tfreq switch active: %s\n",
>> +           yesno(task_data->freq_switch_active));
>> +
>> +    seq_printf(m, "\tibc enabled: %s\n",
>> +           yesno(task_data->ibc_enabled));
>> +    seq_printf(m, "\tibc active: %s\n",
>> +           yesno(task_data->ibc_active));
>> +    seq_printf(m, "\tpg1 enabled: %s\n",
>> +           yesno(task_data->pg1_enabled));
>> +    seq_printf(m, "\tpg1 active: %s\n",
>> +           yesno(task_data->pg1_active));
>> +
>> +    seq_printf(m, "\tunslice max freq: %dMHz\n",
>> +           intel_gpu_freq(dev_priv,
>> +            task_data->max_unslice_freq * GEN9_FREQ_SCALER));
>> +    seq_printf(m, "\tunslice min freq: %dMHz\n",
>> +           intel_gpu_freq(dev_priv,
>> +            task_data->min_unslice_freq * GEN9_FREQ_SCALER));
>> +    seq_printf(m, "\tslice max freq: %dMHz\n",
>> +           intel_gpu_freq(dev_priv,
>> +            task_data->max_slice_freq * GEN9_FREQ_SCALER));
>> +    seq_printf(m, "\tslice min freq: %dMHz\n",
>> +           intel_gpu_freq(dev_priv,
>> +            task_data->min_slice_freq * GEN9_FREQ_SCALER));
>> +
>> +    seq_puts(m, "override parameter bitfield\n");
>> +    for (i = 0; i < SLPC_OVERRIDE_BITFIELD_SIZE; i++)
>> +        seq_printf(m, "%d: 0x%08x\n", i,
>> +               data.override_parameters_set_bits[i]);
>> +
>> +    seq_puts(m, "override parameters (only non-zero shown)\n");
>> +    for (i = 0; i < SLPC_MAX_OVERRIDE_PARAMETERS; i++) {
>> +        value = data.override_parameters_values[i];
>> +        if (value)
>> +            seq_printf(m, "%d: 0x%8x\n", i, value);
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>  static int i915_frequency_info(struct seq_file *m, void *unused)
>>  {
>>      struct drm_i915_private *dev_priv = node_to_i915(m->private);
>> @@ -4899,6 +5063,7 @@ static int i915_hpd_storm_ctl_open(struct inode 
>> *inode, struct file *file)
>>      {"i915_guc_stage_pool", i915_guc_stage_pool, 0},
>>      {"i915_huc_load_status", i915_huc_load_status_info, 0},
>>      {"i915_slpc_paramlist", i915_slpc_paramlist_info, 0},
>> +    {"i915_slpc_info", i915_slpc_info, 0},
>>      {"i915_frequency_info", i915_frequency_info, 0},
>>      {"i915_hangcheck_info", i915_hangcheck_info, 0},
>>      {"i915_reset_info", i915_reset_info, 0},

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

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

end of thread, other threads:[~2017-09-28 10:20 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-19 17:41 [PATCH 00/31] Add support for GuC-based SLPC Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 01/31] drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing Sagar Arun Kamble
2017-09-21 15:12   ` Michal Wajdeczko
2017-09-28  9:10     ` Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 02/31] drm/i915: Separate RPS and RC6 handling for gen6+ Sagar Arun Kamble
2017-09-20 12:29   ` Szwichtenberg, Radoslaw
2017-09-19 17:41 ` [PATCH 03/31] drm/i915: Separate RPS and RC6 handling for BDW Sagar Arun Kamble
2017-09-20 11:14   ` Szwichtenberg, Radoslaw
2017-09-20 12:31     ` Szwichtenberg, Radoslaw
2017-09-19 17:41 ` [PATCH 04/31] drm/i915: Separate RPS and RC6 handling for VLV Sagar Arun Kamble
2017-09-20 12:30   ` Szwichtenberg, Radoslaw
2017-09-19 17:41 ` [PATCH 05/31] drm/i915: Separate RPS and RC6 handling for CHV Sagar Arun Kamble
2017-09-20 12:32   ` Szwichtenberg, Radoslaw
2017-09-19 17:41 ` [PATCH 06/31] drm/i915: Name i915_runtime_pm structure in dev_priv as "rpm" Sagar Arun Kamble
2017-09-20 12:34   ` Szwichtenberg, Radoslaw
2017-09-19 17:41 ` [PATCH 07/31] drm/i915: Name structure in dev_priv that contains RPS/RC6 state as "pm" Sagar Arun Kamble
2017-09-21  8:23   ` Szwichtenberg, Radoslaw
2017-09-19 17:41 ` [PATCH 08/31] drm/i915: Rename intel_enable_rc6 to intel_rc6_enabled Sagar Arun Kamble
2017-09-21  8:26   ` Szwichtenberg, Radoslaw
2017-09-26  7:41   ` Ewelina Musial
2017-09-28  9:11     ` Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 09/31] drm/i915: Create generic function to setup ring frequency table Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 10/31] drm/i915: Create generic functions to control RC6, RPS Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 11/31] drm/i915: Introduce separate status variable for RC6 and Ring frequency setup Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 12/31] drm/i915: Define RPS idle, busy, boost function pointers Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 13/31] drm/i915/slpc: Add has_slpc capability flag Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 14/31] drm/i915/slpc: Add enable_slpc module parameter Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 15/31] drm/i915/slpc: Sanitize GuC version Sagar Arun Kamble
2017-09-21 12:52   ` Michal Wajdeczko
2017-09-28  9:20     ` Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 16/31] drm/i915/slpc: Lay out SLPC init/enable/disable/cleanup helpers Sagar Arun Kamble
2017-09-21 13:00   ` Michal Wajdeczko
2017-09-28  9:29     ` Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 17/31] drm/i915/slpc: Enable SLPC in GuC if supported Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 18/31] drm/i915/slpc: Add SLPC communication interfaces Sagar Arun Kamble
2017-09-21 13:14   ` Michal Wajdeczko
2017-09-28  9:48     ` Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 19/31] drm/i915/slpc: Allocate/Release/Initialize SLPC shared data Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 20/31] drm/i915/slpc: Add parameter set/unset/get, task control/status functions Sagar Arun Kamble
2017-09-21 13:47   ` Michal Wajdeczko
2017-09-28  9:55     ` Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 21/31] drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR Sagar Arun Kamble
2017-09-21 14:06   ` Michal Wajdeczko
2017-09-28 10:10     ` Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 22/31] drm/i915/slpc: Send SHUTDOWN event Sagar Arun Kamble
2017-09-19 17:41 ` [PATCH 23/31] drm/i915/slpc: Add support for min/max frequency control Sagar Arun Kamble
2017-09-19 17:42 ` [PATCH 24/31] drm/i915/slpc: Add debugfs support to read/write/revert the parameters Sagar Arun Kamble
2017-09-21 15:07   ` Michal Wajdeczko
2017-09-28 10:18     ` Sagar Arun Kamble
2017-09-19 17:42 ` [PATCH 25/31] drm/i915/slpc: Add enable/disable controls for SLPC tasks Sagar Arun Kamble
2017-09-19 17:42 ` [PATCH 26/31] drm/i915/slpc: Add i915_slpc_info to debugfs Sagar Arun Kamble
2017-09-21 15:13   ` Michal Wajdeczko
2017-09-28 10:20     ` Sagar Arun Kamble
2017-09-19 17:42 ` [PATCH 27/31] drm/i915/slpc: Add SLPC banner to RPS debugfs interfaces Sagar Arun Kamble
2017-09-19 17:42 ` [PATCH 28/31] drm/i915/slpc: Add SKL SLPC Support Sagar Arun Kamble
2017-09-19 17:42 ` [PATCH 29/31] drm/i915/slpc: Add Broxton SLPC support Sagar Arun Kamble
2017-09-19 17:42 ` [PATCH 30/31] drm/i915/slpc: Add Kabylake " Sagar Arun Kamble
2017-09-19 17:42 ` [PATCH 31/31] drm/i915/slpc: Add Geminilake " Sagar Arun Kamble

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.