[PATCH i-g-t] pm_rps: Extended testcases with checking PMINTRMSK register value

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In addition to checking whether the frequency is in correct range
for certain scenario, we can also verify whether PM interrupts are
masked correctly. Few test cases were extended with such checks.
While I'm here, let'a apply some minor coding style cleanup to the rest
of the code. We can also become DRM master, to make sure that the test
isn't ran along Xorg (which will interfere with our mesurements)

Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Cc: Jeff Mcgee <jeff.mcgee@xxxxxxxxx>
Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@xxxxxxxxx>
Signed-off-by: Katarzyna Dec <katarzyna.dec@xxxxxxxxx>
---
 tests/pm_rps.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 83 insertions(+), 9 deletions(-)

diff --git a/tests/pm_rps.c b/tests/pm_rps.c
index f0455e78..a4d525f0 100644
--- a/tests/pm_rps.c
+++ b/tests/pm_rps.c
@@ -23,6 +23,7 @@
  * Authors:
  *    Ben Widawsky <ben@xxxxxxxxxxxx>
  *    Jeff McGee <jeff.mcgee@xxxxxxxxx>
+ *    Katarzyna Dec <katarzyna.dec@xxxxxxxxx>
  *
  */
 
@@ -39,6 +40,7 @@
 #include <sys/wait.h>
 
 #include "intel_bufmgr.h"
+#include "i915_reg.h"
 
 static int drm_fd;
 
@@ -50,6 +52,7 @@ enum {
 	RP0,
 	RP1,
 	RPn,
+	BOOST,
 	NUMFREQ
 };
 
@@ -60,7 +63,9 @@ struct junk {
 	const char *mode;
 	FILE *filp;
 } stuff[] = {
-	{ "cur", "r", NULL }, { "min", "rb+", NULL }, { "max", "rb+", NULL }, { "RP0", "r", NULL }, { "RP1", "r", NULL }, { "RPn", "r", NULL }, { NULL, NULL, NULL }
+	{ "cur", "r", NULL }, { "min", "rb+", NULL }, { "max", "rb+", NULL },
+	{ "RP0", "r", NULL }, { "RP1", "r", NULL }, { "RPn", "r", NULL },
+	{ "boost", "r", NULL }, { NULL, NULL, NULL }
 };
 
 static int readval(FILE *filp)
@@ -276,13 +281,14 @@ static void load_helper_run(enum load load)
 
 			emit_store_dword_imm(val);
 			intel_batchbuffer_flush_on_ring(lh.batch,
-                                                        I915_EXEC_BLT);
+							I915_EXEC_BLT);
 			val++;
 
 			gem_execbuf(drm_fd, &execbuf);
 
 			/* Lower the load by pausing after every submitted
-			 * write. */
+			 * write.
+			 */
 			if (lh.load == LOW)
 				usleep(LOAD_HELPER_PAUSE_USEC);
 		}
@@ -312,7 +318,8 @@ static void load_helper_init(void)
 
 	/* MI_STORE_DATA can only use GTT address on gen4+/g33 and needs
 	 * snoopable mem on pre-gen6. Hence load-helper only works on gen6+, but
-	 * that's also all we care about for the rps testcase*/
+	 * that's also all we care about for the rps testcase
+	 */
 	igt_assert(intel_gen(lh.devid) >= 6);
 	lh.bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
 	igt_assert(lh.bufmgr);
@@ -384,6 +391,54 @@ static int get_hw_rounded_freq(int target)
 	return ret;
 }
 
+/* Checks if GPU is idle reading debugfs */
+static bool is_in_idle(void)
+{
+	char buf[1024];
+
+	igt_debugfs_read(drm_fd, "i915_runtime_pm_status", buf);
+	return strstr(buf, "GPU idle: yes\n");
+}
+
+#define UP_MASK (1<<5)
+#define DOWN_MASK (1<<4)
+/** Checks PMINTRMSK register for changes in up mask and down mask bits.
+ * Depending on current frequency down and up interrupts can be enabled or
+ * disabled.
+ * e.g. if current frequency is at MIN we expect down interrupts should be
+ * disabled.
+ * There is a special case when both down and up interrupts should be disabled
+ * - GPU is idle or MIN and MAX frequencies are equal.
+ */
+static void check_pmintrmsk(int *freqs)
+{
+	uint32_t pmintrmsk;
+	bool down_disabled, up_disabled;
+
+	read_freqs(freqs);
+	dump(freqs);
+	pmintrmsk = intel_register_read(GEN6_PMINTRMSK);
+
+	up_disabled = pmintrmsk & UP_MASK;
+	down_disabled = pmintrmsk & DOWN_MASK;
+
+	if ((freqs[CUR] == freqs[MIN] && freqs[CUR] == freqs[MAX])
+							|| is_in_idle()) {
+		igt_assert_eq(up_disabled, 1);
+		igt_assert_eq(down_disabled, 1);
+	} else if (freqs[CUR] == freqs[MAX] || freqs[CUR] == freqs[BOOST]) {
+		igt_assert_eq(up_disabled, 1);
+		igt_assert_eq(down_disabled, 0);
+	} else if (freqs[CUR] == freqs[MIN]) {
+		igt_assert_eq(up_disabled, 0);
+		igt_assert_eq(down_disabled, 1);
+	} else {
+		igt_assert_eq(up_disabled, 0);
+		igt_assert_eq(down_disabled, 0);
+	}
+
+}
+
 static void min_max_config(void (*check)(void), bool load_gpu)
 {
 	int fmid = (origfreqs[RPn] + origfreqs[RP0]) / 2;
@@ -481,6 +536,7 @@ static void basic_check(void)
 	read_freqs(freqs);
 	dump(freqs);
 	checkit(freqs);
+	check_pmintrmsk(freqs);
 }
 
 #define IDLE_WAIT_TIMESTEP_MSEC 250
@@ -491,7 +547,8 @@ static void idle_check(void)
 	int wait = 0;
 
 	/* Monitor frequencies until cur settles down to min, which should
-	 * happen within the allotted time */
+	 * happen within the allotted time
+	 */
 	do {
 		read_freqs(freqs);
 		dump(freqs);
@@ -502,6 +559,7 @@ static void idle_check(void)
 		wait += IDLE_WAIT_TIMESTEP_MSEC;
 	} while (wait < IDLE_WAIT_TIMEOUT_MSEC);
 
+	check_pmintrmsk(freqs);
 	igt_assert_eq(freqs[CUR], freqs[RPn]);
 	igt_debug("Required %d msec to reach cur=idle\n", wait);
 }
@@ -514,7 +572,8 @@ static void loaded_check(void)
 	int wait = 0;
 
 	/* Monitor frequencies until cur increases to max, which should
-	 * happen within the allotted time */
+	 * happen within the allotted time
+	 */
 	do {
 		read_freqs(freqs);
 		dump(freqs);
@@ -525,6 +584,7 @@ static void loaded_check(void)
 		wait += LOADED_WAIT_TIMESTEP_MSEC;
 	} while (wait < LOADED_WAIT_TIMEOUT_MSEC);
 
+	check_pmintrmsk(freqs);
 	igt_assert_lte(freqs[MAX], freqs[CUR]);
 	igt_debug("Required %d msec to reach cur=max\n", wait);
 }
@@ -556,6 +616,7 @@ static void stabilize_check(int *out)
 static void reset_gpu(void)
 {
 	int fd = drm_open_driver(DRIVER_INTEL);
+
 	igt_post_hang_ring(fd, igt_hang_ring(fd, I915_EXEC_DEFAULT));
 	close(fd);
 }
@@ -566,6 +627,7 @@ static void boost_freq(int fd, int *boost_freqs)
 	int ring = -1;
 	igt_spin_t *load;
 
+	igt_debug("Trying to boost freq\n");
 	load = igt_spin_batch_new(fd, ring, 0);
 
 	/* Waiting will grant us a boost to maximum */
@@ -573,6 +635,7 @@ static void boost_freq(int fd, int *boost_freqs)
 
 	read_freqs(boost_freqs);
 	dump(boost_freqs);
+	check_pmintrmsk(boost_freqs);
 
 	igt_spin_batch_free(fd, load);
 }
@@ -639,15 +702,23 @@ igt_main
 		const int device = drm_get_card();
 		struct junk *junk = stuff;
 		int ret;
+		struct pci_device *pci_dev;
 
-		/* Use drm_open_driver to verify device existence */
-		drm_fd = drm_open_driver(DRIVER_INTEL);
+		/* Use drm_open_driver_master to force running tests as drm
+		 * master
+		 */
+		drm_fd = drm_open_driver_master(DRIVER_INTEL);
 		igt_require_gem(drm_fd);
 		igt_require(gem_can_store_dword(drm_fd, 0));
 
+		pci_dev = intel_get_pci_device();
+		igt_require(pci_dev);
+		intel_register_access_init(pci_dev, 0, drm_fd);
+
 		do {
 			int val = -1;
 			char *path;
+
 			ret = asprintf(&path, sysfs_base_path, device, junk->name);
 			igt_assert(ret != -1);
 			junk->filp = fopen(path, junk->mode);
@@ -657,7 +728,7 @@ igt_main
 			val = readval(junk->filp);
 			igt_assert(val >= 0);
 			junk++;
-		} while(junk->name != NULL);
+		} while (junk->name != NULL);
 
 		read_freqs(origfreqs);
 
@@ -684,4 +755,7 @@ igt_main
 	igt_subtest("reset")
 		waitboost(true);
 
+	igt_fixture {
+		intel_register_access_fini();
+	}
 }
-- 
2.13.4

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




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux