All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] igt: Add drv_workarounds
@ 2014-08-01 17:46 Mika Kuoppala
  2014-08-01 17:46 ` [PATCH] tests: " Mika Kuoppala
  0 siblings, 1 reply; 3+ messages in thread
From: Mika Kuoppala @ 2014-08-01 17:46 UTC (permalink / raw)
  To: intel-gfx; +Cc: miku

Hi,

With ivb we currently drop 5 out of 11 static workarounds due to
hang/reset recovery.

With bdw we see that some workarounds wont stick even after init, due
to rc6 entry dropping some regs that are not part of power context?

Mika Kuoppala (1):
  tests: Add drv_workarounds

 lib/intel_chipset.h     |    4 +
 lib/intel_workaround.h  |  142 +++++++++++++++++++++++++++
 tests/Makefile.sources  |    1 +
 tests/drv_workarounds.c |  244 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 391 insertions(+)
 create mode 100644 lib/intel_workaround.h
 create mode 100644 tests/drv_workarounds.c

-- 
1.7.9.5

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

* [PATCH] tests: Add drv_workarounds
  2014-08-01 17:46 [PATCH] igt: Add drv_workarounds Mika Kuoppala
@ 2014-08-01 17:46 ` Mika Kuoppala
  2014-08-04  8:43   ` Daniel Vetter
  0 siblings, 1 reply; 3+ messages in thread
From: Mika Kuoppala @ 2014-08-01 17:46 UTC (permalink / raw)
  To: intel-gfx; +Cc: miku

To check that static workarounds are set and stay after init,
hang and suspend/restore. Checks are currently provided for ivb
and bdw only.

Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 lib/intel_chipset.h     |    4 +
 lib/intel_workaround.h  |  142 +++++++++++++++++++++++++++
 tests/Makefile.sources  |    1 +
 tests/drv_workarounds.c |  244 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 391 insertions(+)
 create mode 100644 lib/intel_workaround.h
 create mode 100644 tests/drv_workarounds.c

diff --git a/lib/intel_chipset.h b/lib/intel_chipset.h
index 404c632..5a03f2b 100644
--- a/lib/intel_chipset.h
+++ b/lib/intel_chipset.h
@@ -263,6 +263,10 @@ void intel_check_pch(void);
 				 (devid) == PCI_CHIP_IVYBRIDGE_S || \
 				 (devid) == PCI_CHIP_IVYBRIDGE_S_GT2)
 
+#define IS_IVB_GT1(devid)	((devid) == PCI_CHIP_IVYBRIDGE_GT1 || \
+				 (devid) == PCI_CHIP_IVYBRIDGE_M_GT1 || \
+				 (devid) == PCI_CHIP_IVYBRIDGE_S)
+
 #define IS_VALLEYVIEW(devid)	((devid) == PCI_CHIP_VALLEYVIEW_PO || \
 				 (devid) == PCI_CHIP_VALLEYVIEW_1 || \
 				 (devid) == PCI_CHIP_VALLEYVIEW_2 || \
diff --git a/lib/intel_workaround.h b/lib/intel_workaround.h
new file mode 100644
index 0000000..87e3a44
--- /dev/null
+++ b/lib/intel_workaround.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright © 2013,2014 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.
+ *
+ * Authors:
+ *    Mika Kuoppala <mika.kuoppala@intel.com>
+ *
+ */
+
+#ifndef INTEL_WORKAROUNDS
+#define INTEL_WORKAROUNDS
+
+#include "intel_chipset.h"
+#include "intel_io.h"
+#include "igt_core.h"
+
+static int __wa_devid = 0;
+
+struct wa {
+	const char * const name;
+	int (*f)(const int devid);
+};
+
+static void wa_init(const int devid)
+{
+	__wa_devid = devid;
+	intel_register_access_init(intel_get_pci_device(), 0);
+}
+
+static void wa_fini(void)
+{
+	__wa_devid = 0;
+	intel_register_access_fini();
+}
+
+static int wa_check(const struct wa *wa)
+{
+	igt_assert(__wa_devid);
+	igt_assert(wa->name);
+	igt_assert(wa->f);
+	return wa->f(__wa_devid);
+}
+
+#define WA(_name) /* _name */ static int _name##_fun(const int devid);	\
+	static const struct wa _name =					\
+	{ #_name, _name##_fun };					\
+	static int _name##_fun(const int devid)
+
+#define wa_assert_m(reg, val, mask) {					\
+		unsigned int x;						\
+		igt_assert(mask);					\
+		x = intel_register_read(reg);				\
+		if (((x) & (mask)) != (val)) {				\
+			igt_warn("a:0x%08x r:0x%08x m:0%08x v:0%08x\n", reg, x, mask, val); \
+			return 1;					\
+		}							\
+	}
+
+#define wa_assert(reg, val) wa_assert_m(reg, val, 0xffffffff)
+#define wa_assert_bit_set(reg, bit) wa_assert_m(reg, (1 << bit), (1 << bit))
+#define wa_assert_bit_clr(reg, bit) wa_assert_m(reg, 0, (1 << bit))
+
+#define WA_MASK(_name, reg, val, mask)			\
+	WA(_name) {					\
+		wa_assert_m(reg, val, mask);		\
+		return 0;				\
+	}
+
+#define WA_BIT_SET(_name, reg, bit) WA_MASK(_name, reg, (1 << bit), (1 << bit))
+#define WA_BIT_CLR(_name, reg, bit) WA_MASK(_name, reg, 0, (1 << bit))
+
+
+/* *** ivb workarounds ***************************************/
+WA(WaDisablePSDDualDispatchEnable) {
+	if (IS_IVB_GT1(devid))
+		wa_assert_bit_set(0xe100, 3);
+
+	return 0;
+}
+
+WA_BIT_SET(WaFbcAsynchFlipDisableFbcQueue, 0x42000, 22);
+WA_BIT_SET(WaDisableEarlyCull, 0x2090, 10);
+WA_MASK(WaDisableBackToBackFlipFix, 0x4200c, 1 << 2 | 1 << 5, 1 << 2 | 1 << 5);
+WA_BIT_SET(WaDisableRHWOptimizationForRenderHang, 0x7010, 10);
+
+WA(WaApplyL3ControlAndL3ChickenMode) {
+	wa_assert_m(0xb01c, 0x3C47FF8C, 0xFFFFFFFF);
+	wa_assert_m(0xb030, 0x20000000, 0xFFFFFFFF);
+
+	wa_assert_bit_set(0xe4f4, 0);
+	if (!IS_IVB_GT1(devid))
+		wa_assert_bit_set(0xf4f4, 0);
+
+	return 0;
+}
+
+WA_BIT_CLR(WaForceL3Serialization, 0xb034, 27);
+WA_BIT_SET(WaDisableRCZUnitClockGating_ivb, 0x9404, 13);
+WA_BIT_SET(WaCatErrorRejectionIssue, 0x9030, 11);
+WA_BIT_SET(WaDisable4x2SubspanOptimization, 0x7004, 6);
+WA_MASK(WaVSThreadDispatchOverride, 0x20a0, 0, (1 << 4) | (1 << 12) | (1 << 16));
+/*************************************************************/
+
+/* *** bdw workarounds ***************************************/
+WA_BIT_SET(WaDisablePartialInstShootdown, 0xe4f0, 8);
+WA_BIT_SET(WaDisableThreadStallDopClockGating, 0xe4f0, 5);
+WA_BIT_SET(WaDisableDopClockGating, 0xe4f4, 0);
+WA_BIT_SET(WaSwitchSolVfFArbitrationPriority, 0x4090, 6);
+WA_BIT_SET(WaPsrDPAMaskVBlankInSRD, 0x42080, 15);
+
+WA(WaPsrDPRSUnmaskVBlankInSRD) {
+	wa_assert_bit_set(0x420b0, 0);
+	wa_assert_bit_set(0x420b4, 0);
+	wa_assert_bit_set(0x420b8, 0);
+	return 0;
+}
+
+WA_BIT_CLR(WaVSRefCountFullforceMissDisable, 0x20a0, 15);
+WA_BIT_CLR(WaDSRefCountFullforceMissDisable, 0x20a0, 19);
+WA_BIT_SET(WaDisableSDEUnitClockGating, 0x9430, 14);
+WA_BIT_SET(Wa4x4STCOptimizationDisable, 0x7004, 6);
+/*************************************************************/
+
+#endif
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 0eb9369..e87f81d 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -18,6 +18,7 @@ TESTS_progs_M = \
 	core_get_client_auth \
 	drv_suspend \
 	drv_hangman \
+	drv_workarounds \
 	gem_bad_reloc \
 	gem_basic \
 	gem_caching \
diff --git a/tests/drv_workarounds.c b/tests/drv_workarounds.c
new file mode 100644
index 0000000..9afce23
--- /dev/null
+++ b/tests/drv_workarounds.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright © 2014 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.
+ *
+ * Authors:
+ *    Mika Kuoppala <mika.kuoppala@intel.com>
+ *
+ */
+
+#include <string.h>
+#include "drm.h"
+#include "ioctl_wrappers.h"
+#include "drmtest.h"
+#include "intel_io.h"
+#include "igt_debugfs.h"
+#include "igt_aux.h"
+#include "intel_workaround.h"
+
+static const struct wa *ivb_workarounds[] = {
+	&WaDisableEarlyCull,
+	&WaDisableBackToBackFlipFix,
+	&WaDisablePSDDualDispatchEnable,
+	&WaDisableRHWOptimizationForRenderHang,
+	&WaApplyL3ControlAndL3ChickenMode,
+	&WaForceL3Serialization,
+	&WaDisableRCZUnitClockGating_ivb,
+	&WaCatErrorRejectionIssue,
+	&WaVSRefCountFullforceMissDisable,
+	&WaDisable4x2SubspanOptimization,
+	&WaVSThreadDispatchOverride,
+	NULL,
+};
+
+static const struct wa *bdw_workarounds[] = {
+	&WaDisablePartialInstShootdown,
+	&WaDisableThreadStallDopClockGating,
+	&WaDisableDopClockGating,
+	&WaSwitchSolVfFArbitrationPriority,
+	&WaPsrDPAMaskVBlankInSRD,
+	&WaPsrDPRSUnmaskVBlankInSRD,
+	&WaVSRefCountFullforceMissDisable,
+	&WaDSRefCountFullforceMissDisable,
+	&WaDisableSDEUnitClockGating,
+	&Wa4x4STCOptimizationDisable,
+	NULL,
+};
+
+static void strip_arch(const char* testname, const char *arch, char *tmp, int l)
+{
+	char *p;
+	int bytes;
+
+	p = strstr(testname, arch);
+	if (p)
+		bytes = p - testname - 1;
+	else
+		bytes = strlen(testname);
+
+	if (bytes < 0)
+		bytes = 0;
+
+	if (bytes >= (l-1))
+		bytes = l-1;
+
+	strncpy(tmp, testname, bytes);
+	tmp[bytes] = '\0';
+}
+
+static int devid;
+
+static int check_workarounds(const struct wa **workarounds, const char *arch)
+{
+	const struct wa **p;
+	char tmpname[256];
+	int fail_count = 0, wa_count = 0;
+	int ret;
+	p  = workarounds;
+
+	wa_init(devid);
+
+	while(*p) {
+		wa_count++;
+		ret = wa_check(*p);
+		strip_arch((*p)->name, arch, tmpname, sizeof(tmpname));
+		printf("%-8s %s:%s\n", ret ? "FAIL" : "OK", tmpname, arch);
+		if (ret)
+			fail_count++;
+		p++;
+	}
+
+	if (fail_count) {
+		printf("%d workarounds tested, %d passed, %d failed\n",
+		      wa_count, wa_count - fail_count, fail_count);
+	}
+
+	wa_fini();
+
+	return fail_count;
+}
+
+#define do_check(was, arch) igt_assert(check_workarounds(was, arch) == 0)
+
+typedef enum { SIMPLE, HANG, SUSPEND } test_type;
+
+static int exec(int fd, uint32_t handle)
+{
+        struct drm_i915_gem_execbuffer2 execbuf;
+        struct drm_i915_gem_exec_object2 gem_exec[1];
+        int ret = 0;
+
+        gem_exec[0].handle = handle;
+        gem_exec[0].relocation_count = 0;
+        gem_exec[0].relocs_ptr = 0;
+        gem_exec[0].alignment = 0;
+        gem_exec[0].offset = 0;
+        gem_exec[0].flags = 0;
+        gem_exec[0].rsvd1 = 0;
+        gem_exec[0].rsvd2 = 0;
+
+        execbuf.buffers_ptr = (uintptr_t)gem_exec;
+        execbuf.buffer_count = 1;
+        execbuf.batch_start_offset = 0;
+        execbuf.batch_len = 8;
+        execbuf.cliprects_ptr = 0;
+        execbuf.num_cliprects = 0;
+        execbuf.DR1 = 0;
+        execbuf.DR4 = 0;
+        execbuf.flags = I915_EXEC_RENDER;
+        i915_execbuffer2_set_context_id(execbuf, 0);
+        execbuf.rsvd2 = 0;
+
+	ret = drmIoctl(fd,
+		       DRM_IOCTL_I915_GEM_EXECBUFFER2,
+		       &execbuf);
+
+        gem_sync(fd, handle);
+
+        return ret;
+}
+
+static void exec_nop(void)
+{
+	uint32_t batch[2] = {MI_BATCH_BUFFER_END};
+	uint32_t handle;
+	int fd;
+
+	fd = drm_open_any();
+
+	handle = gem_create(fd, 4096);
+	gem_write(fd, handle, 0, batch, sizeof(batch));
+
+	igt_assert(exec(fd, handle) == 0);
+}
+
+static void do_hang(void)
+{
+	int timeout = 300;
+
+	igt_set_stop_rings(STOP_RING_DEFAULTS);
+	exec_nop();
+	while (timeout-- && igt_get_stop_rings())
+		usleep(1000 * 100);
+}
+
+static void do_test(const struct wa **workarounds, const char *arch, test_type tt)
+{
+	do_check(workarounds, arch);
+
+	switch (tt) {
+	case SIMPLE:
+		return;
+
+	case HANG:
+		do_hang();
+		break;
+
+	case SUSPEND:
+		igt_system_suspend_autoresume();
+		break;
+	}
+
+	do_check(workarounds, arch);
+}
+
+static void wa_check_ivb_t(test_type t)
+{
+	igt_require(intel_gen(devid) == 7);
+	do_test(&ivb_workarounds[0], "ivb", t);
+}
+
+static void wa_check_bdw_t(test_type t)
+{
+	igt_require(IS_BROADWELL(devid));
+	do_test(&bdw_workarounds[0], "bdw", t);
+}
+
+static struct subtypes {
+	test_type type;
+	const char *name;
+} stypes[] = {
+	{ SIMPLE, "simple" },
+	{ HANG, "hang" },
+	{ SUSPEND, "suspend" },
+};
+
+#define WA_TESTS(x) { for (int i = 0; i < sizeof(stypes)/sizeof(struct subtypes); i++) {  \
+			      igt_subtest_f("wa-%s-%s", #x, stypes[i].name) \
+				      wa_check_ ## x ## _t(stypes[i].type); \
+			      } \
+		      }
+
+igt_main
+{
+	igt_fixture {
+		int fd;
+
+		fd = drm_open_any();
+		devid = intel_get_drm_devid(fd);
+		close(fd);
+
+		igt_skip_on(!IS_INTEL(devid));
+	}
+
+	WA_TESTS(ivb);
+	WA_TESTS(bdw);
+}
-- 
1.7.9.5

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

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

* Re: [PATCH] tests: Add drv_workarounds
  2014-08-01 17:46 ` [PATCH] tests: " Mika Kuoppala
@ 2014-08-04  8:43   ` Daniel Vetter
  0 siblings, 0 replies; 3+ messages in thread
From: Daniel Vetter @ 2014-08-04  8:43 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: intel-gfx, miku

On Fri, Aug 01, 2014 at 08:46:25PM +0300, Mika Kuoppala wrote:
> To check that static workarounds are set and stay after init,
> hang and suspend/restore. Checks are currently provided for ivb
> and bdw only.
> 
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>  lib/intel_chipset.h     |    4 +
>  lib/intel_workaround.h  |  142 +++++++++++++++++++++++++++
>  tests/Makefile.sources  |    1 +
>  tests/drv_workarounds.c |  244 +++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 391 insertions(+)
>  create mode 100644 lib/intel_workaround.h
>  create mode 100644 tests/drv_workarounds.c
> 
> diff --git a/lib/intel_chipset.h b/lib/intel_chipset.h
> index 404c632..5a03f2b 100644
> --- a/lib/intel_chipset.h
> +++ b/lib/intel_chipset.h
> @@ -263,6 +263,10 @@ void intel_check_pch(void);
>  				 (devid) == PCI_CHIP_IVYBRIDGE_S || \
>  				 (devid) == PCI_CHIP_IVYBRIDGE_S_GT2)
>  
> +#define IS_IVB_GT1(devid)	((devid) == PCI_CHIP_IVYBRIDGE_GT1 || \
> +				 (devid) == PCI_CHIP_IVYBRIDGE_M_GT1 || \
> +				 (devid) == PCI_CHIP_IVYBRIDGE_S)
> +
>  #define IS_VALLEYVIEW(devid)	((devid) == PCI_CHIP_VALLEYVIEW_PO || \
>  				 (devid) == PCI_CHIP_VALLEYVIEW_1 || \
>  				 (devid) == PCI_CHIP_VALLEYVIEW_2 || \
> diff --git a/lib/intel_workaround.h b/lib/intel_workaround.h
> new file mode 100644
> index 0000000..87e3a44
> --- /dev/null
> +++ b/lib/intel_workaround.h
> @@ -0,0 +1,142 @@
> +/*
> + * Copyright © 2013,2014 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.
> + *
> + * Authors:
> + *    Mika Kuoppala <mika.kuoppala@intel.com>
> + *
> + */
> +
> +#ifndef INTEL_WORKAROUNDS
> +#define INTEL_WORKAROUNDS
> +
> +#include "intel_chipset.h"
> +#include "intel_io.h"
> +#include "igt_core.h"
> +
> +static int __wa_devid = 0;
> +
> +struct wa {
> +	const char * const name;
> +	int (*f)(const int devid);
> +};
> +
> +static void wa_init(const int devid)
> +{
> +	__wa_devid = devid;
> +	intel_register_access_init(intel_get_pci_device(), 0);
> +}
> +
> +static void wa_fini(void)
> +{
> +	__wa_devid = 0;
> +	intel_register_access_fini();
> +}
> +
> +static int wa_check(const struct wa *wa)
> +{
> +	igt_assert(__wa_devid);
> +	igt_assert(wa->name);
> +	igt_assert(wa->f);
> +	return wa->f(__wa_devid);
> +}
> +
> +#define WA(_name) /* _name */ static int _name##_fun(const int devid);	\
> +	static const struct wa _name =					\
> +	{ #_name, _name##_fun };					\
> +	static int _name##_fun(const int devid)
> +
> +#define wa_assert_m(reg, val, mask) {					\
> +		unsigned int x;						\
> +		igt_assert(mask);					\
> +		x = intel_register_read(reg);				\
> +		if (((x) & (mask)) != (val)) {				\
> +			igt_warn("a:0x%08x r:0x%08x m:0%08x v:0%08x\n", reg, x, mask, val); \
> +			return 1;					\
> +		}							\
> +	}
> +
> +#define wa_assert(reg, val) wa_assert_m(reg, val, 0xffffffff)
> +#define wa_assert_bit_set(reg, bit) wa_assert_m(reg, (1 << bit), (1 << bit))
> +#define wa_assert_bit_clr(reg, bit) wa_assert_m(reg, 0, (1 << bit))
> +
> +#define WA_MASK(_name, reg, val, mask)			\
> +	WA(_name) {					\
> +		wa_assert_m(reg, val, mask);		\
> +		return 0;				\
> +	}
> +
> +#define WA_BIT_SET(_name, reg, bit) WA_MASK(_name, reg, (1 << bit), (1 << bit))
> +#define WA_BIT_CLR(_name, reg, bit) WA_MASK(_name, reg, 0, (1 << bit))
> +
> +
> +/* *** ivb workarounds ***************************************/
> +WA(WaDisablePSDDualDispatchEnable) {
> +	if (IS_IVB_GT1(devid))
> +		wa_assert_bit_set(0xe100, 3);
> +
> +	return 0;
> +}
> +
> +WA_BIT_SET(WaFbcAsynchFlipDisableFbcQueue, 0x42000, 22);
> +WA_BIT_SET(WaDisableEarlyCull, 0x2090, 10);
> +WA_MASK(WaDisableBackToBackFlipFix, 0x4200c, 1 << 2 | 1 << 5, 1 << 2 | 1 << 5);
> +WA_BIT_SET(WaDisableRHWOptimizationForRenderHang, 0x7010, 10);
> +
> +WA(WaApplyL3ControlAndL3ChickenMode) {
> +	wa_assert_m(0xb01c, 0x3C47FF8C, 0xFFFFFFFF);
> +	wa_assert_m(0xb030, 0x20000000, 0xFFFFFFFF);
> +
> +	wa_assert_bit_set(0xe4f4, 0);
> +	if (!IS_IVB_GT1(devid))
> +		wa_assert_bit_set(0xf4f4, 0);
> +
> +	return 0;
> +}
> +
> +WA_BIT_CLR(WaForceL3Serialization, 0xb034, 27);
> +WA_BIT_SET(WaDisableRCZUnitClockGating_ivb, 0x9404, 13);
> +WA_BIT_SET(WaCatErrorRejectionIssue, 0x9030, 11);
> +WA_BIT_SET(WaDisable4x2SubspanOptimization, 0x7004, 6);
> +WA_MASK(WaVSThreadDispatchOverride, 0x20a0, 0, (1 << 4) | (1 << 12) | (1 << 16));
> +/*************************************************************/
> +
> +/* *** bdw workarounds ***************************************/
> +WA_BIT_SET(WaDisablePartialInstShootdown, 0xe4f0, 8);
> +WA_BIT_SET(WaDisableThreadStallDopClockGating, 0xe4f0, 5);
> +WA_BIT_SET(WaDisableDopClockGating, 0xe4f4, 0);
> +WA_BIT_SET(WaSwitchSolVfFArbitrationPriority, 0x4090, 6);
> +WA_BIT_SET(WaPsrDPAMaskVBlankInSRD, 0x42080, 15);
> +
> +WA(WaPsrDPRSUnmaskVBlankInSRD) {
> +	wa_assert_bit_set(0x420b0, 0);
> +	wa_assert_bit_set(0x420b4, 0);
> +	wa_assert_bit_set(0x420b8, 0);
> +	return 0;
> +}
> +
> +WA_BIT_CLR(WaVSRefCountFullforceMissDisable, 0x20a0, 15);
> +WA_BIT_CLR(WaDSRefCountFullforceMissDisable, 0x20a0, 19);
> +WA_BIT_SET(WaDisableSDEUnitClockGating, 0x9430, 14);
> +WA_BIT_SET(Wa4x4STCOptimizationDisable, 0x7004, 6);
> +/*************************************************************/
> +
> +#endif
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index 0eb9369..e87f81d 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -18,6 +18,7 @@ TESTS_progs_M = \
>  	core_get_client_auth \
>  	drv_suspend \
>  	drv_hangman \
> +	drv_workarounds \
>  	gem_bad_reloc \
>  	gem_basic \
>  	gem_caching \
> diff --git a/tests/drv_workarounds.c b/tests/drv_workarounds.c
> new file mode 100644
> index 0000000..9afce23
> --- /dev/null
> +++ b/tests/drv_workarounds.c
> @@ -0,0 +1,244 @@
> +/*
> + * Copyright © 2014 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.
> + *
> + * Authors:
> + *    Mika Kuoppala <mika.kuoppala@intel.com>
> + *
> + */
> +
> +#include <string.h>
> +#include "drm.h"
> +#include "ioctl_wrappers.h"
> +#include "drmtest.h"
> +#include "intel_io.h"
> +#include "igt_debugfs.h"
> +#include "igt_aux.h"
> +#include "intel_workaround.h"
> +
> +static const struct wa *ivb_workarounds[] = {
> +	&WaDisableEarlyCull,
> +	&WaDisableBackToBackFlipFix,
> +	&WaDisablePSDDualDispatchEnable,
> +	&WaDisableRHWOptimizationForRenderHang,
> +	&WaApplyL3ControlAndL3ChickenMode,
> +	&WaForceL3Serialization,
> +	&WaDisableRCZUnitClockGating_ivb,
> +	&WaCatErrorRejectionIssue,
> +	&WaVSRefCountFullforceMissDisable,
> +	&WaDisable4x2SubspanOptimization,
> +	&WaVSThreadDispatchOverride,
> +	NULL,
> +};
> +
> +static const struct wa *bdw_workarounds[] = {
> +	&WaDisablePartialInstShootdown,
> +	&WaDisableThreadStallDopClockGating,
> +	&WaDisableDopClockGating,
> +	&WaSwitchSolVfFArbitrationPriority,
> +	&WaPsrDPAMaskVBlankInSRD,
> +	&WaPsrDPRSUnmaskVBlankInSRD,
> +	&WaVSRefCountFullforceMissDisable,
> +	&WaDSRefCountFullforceMissDisable,
> +	&WaDisableSDEUnitClockGating,
> +	&Wa4x4STCOptimizationDisable,
> +	NULL,
> +};

This tastes a bit like a maintaince hell burden - we're pretty much
guaranteed to get out of sync with these lists. My idea would be to only
have a list of w/a relevant registers (maybe with a mask to cut away stuff
that can change) and simply compare them after module reload,
suspend/resume, runtime pm and gpu reset (they all matter a bit
differently).

Bonus points if we can generate that list of registers from the kernel
sources. But I don't really see an easy way to do this, so definitely a
follow-up task.
-Daniel

> +
> +static void strip_arch(const char* testname, const char *arch, char *tmp, int l)
> +{
> +	char *p;
> +	int bytes;
> +
> +	p = strstr(testname, arch);
> +	if (p)
> +		bytes = p - testname - 1;
> +	else
> +		bytes = strlen(testname);
> +
> +	if (bytes < 0)
> +		bytes = 0;
> +
> +	if (bytes >= (l-1))
> +		bytes = l-1;
> +
> +	strncpy(tmp, testname, bytes);
> +	tmp[bytes] = '\0';
> +}
> +
> +static int devid;
> +
> +static int check_workarounds(const struct wa **workarounds, const char *arch)
> +{
> +	const struct wa **p;
> +	char tmpname[256];
> +	int fail_count = 0, wa_count = 0;
> +	int ret;
> +	p  = workarounds;
> +
> +	wa_init(devid);
> +
> +	while(*p) {
> +		wa_count++;
> +		ret = wa_check(*p);
> +		strip_arch((*p)->name, arch, tmpname, sizeof(tmpname));
> +		printf("%-8s %s:%s\n", ret ? "FAIL" : "OK", tmpname, arch);
> +		if (ret)
> +			fail_count++;
> +		p++;
> +	}
> +
> +	if (fail_count) {
> +		printf("%d workarounds tested, %d passed, %d failed\n",
> +		      wa_count, wa_count - fail_count, fail_count);
> +	}
> +
> +	wa_fini();
> +
> +	return fail_count;
> +}
> +
> +#define do_check(was, arch) igt_assert(check_workarounds(was, arch) == 0)
> +
> +typedef enum { SIMPLE, HANG, SUSPEND } test_type;
> +
> +static int exec(int fd, uint32_t handle)
> +{
> +        struct drm_i915_gem_execbuffer2 execbuf;
> +        struct drm_i915_gem_exec_object2 gem_exec[1];
> +        int ret = 0;
> +
> +        gem_exec[0].handle = handle;
> +        gem_exec[0].relocation_count = 0;
> +        gem_exec[0].relocs_ptr = 0;
> +        gem_exec[0].alignment = 0;
> +        gem_exec[0].offset = 0;
> +        gem_exec[0].flags = 0;
> +        gem_exec[0].rsvd1 = 0;
> +        gem_exec[0].rsvd2 = 0;
> +
> +        execbuf.buffers_ptr = (uintptr_t)gem_exec;
> +        execbuf.buffer_count = 1;
> +        execbuf.batch_start_offset = 0;
> +        execbuf.batch_len = 8;
> +        execbuf.cliprects_ptr = 0;
> +        execbuf.num_cliprects = 0;
> +        execbuf.DR1 = 0;
> +        execbuf.DR4 = 0;
> +        execbuf.flags = I915_EXEC_RENDER;
> +        i915_execbuffer2_set_context_id(execbuf, 0);
> +        execbuf.rsvd2 = 0;
> +
> +	ret = drmIoctl(fd,
> +		       DRM_IOCTL_I915_GEM_EXECBUFFER2,
> +		       &execbuf);
> +
> +        gem_sync(fd, handle);
> +
> +        return ret;
> +}
> +
> +static void exec_nop(void)
> +{
> +	uint32_t batch[2] = {MI_BATCH_BUFFER_END};
> +	uint32_t handle;
> +	int fd;
> +
> +	fd = drm_open_any();
> +
> +	handle = gem_create(fd, 4096);
> +	gem_write(fd, handle, 0, batch, sizeof(batch));
> +
> +	igt_assert(exec(fd, handle) == 0);
> +}
> +
> +static void do_hang(void)
> +{
> +	int timeout = 300;
> +
> +	igt_set_stop_rings(STOP_RING_DEFAULTS);
> +	exec_nop();
> +	while (timeout-- && igt_get_stop_rings())
> +		usleep(1000 * 100);
> +}
> +
> +static void do_test(const struct wa **workarounds, const char *arch, test_type tt)
> +{
> +	do_check(workarounds, arch);
> +
> +	switch (tt) {
> +	case SIMPLE:
> +		return;
> +
> +	case HANG:
> +		do_hang();
> +		break;
> +
> +	case SUSPEND:
> +		igt_system_suspend_autoresume();
> +		break;
> +	}
> +
> +	do_check(workarounds, arch);
> +}
> +
> +static void wa_check_ivb_t(test_type t)
> +{
> +	igt_require(intel_gen(devid) == 7);
> +	do_test(&ivb_workarounds[0], "ivb", t);
> +}
> +
> +static void wa_check_bdw_t(test_type t)
> +{
> +	igt_require(IS_BROADWELL(devid));
> +	do_test(&bdw_workarounds[0], "bdw", t);
> +}
> +
> +static struct subtypes {
> +	test_type type;
> +	const char *name;
> +} stypes[] = {
> +	{ SIMPLE, "simple" },
> +	{ HANG, "hang" },
> +	{ SUSPEND, "suspend" },
> +};
> +
> +#define WA_TESTS(x) { for (int i = 0; i < sizeof(stypes)/sizeof(struct subtypes); i++) {  \
> +			      igt_subtest_f("wa-%s-%s", #x, stypes[i].name) \
> +				      wa_check_ ## x ## _t(stypes[i].type); \
> +			      } \
> +		      }
> +
> +igt_main
> +{
> +	igt_fixture {
> +		int fd;
> +
> +		fd = drm_open_any();
> +		devid = intel_get_drm_devid(fd);
> +		close(fd);
> +
> +		igt_skip_on(!IS_INTEL(devid));
> +	}
> +
> +	WA_TESTS(ivb);
> +	WA_TESTS(bdw);
> +}
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

end of thread, other threads:[~2014-08-04  8:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-01 17:46 [PATCH] igt: Add drv_workarounds Mika Kuoppala
2014-08-01 17:46 ` [PATCH] tests: " Mika Kuoppala
2014-08-04  8:43   ` Daniel Vetter

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.