[Intel-gfx] [PATCH 1/6] drm/i915: Implement L3 partitioning set-up from the workaround list.
Francisco Jerez
currojerez at riseup.net
Wed Oct 7 04:44:00 PDT 2015
This programs the L3 configuration based on the sizes given for each
partition as arguments. The relevant register writes are added to the
workaround list so that they are re-applied to each context while it's
initialized, preventing state leaks from other userspace processes
which may have modified the L3 partitioning from its boot-up state,
since all relevant registers are part of the software and hardware
command checker whitelists.
Some userspace clients (DDX and current versions of Mesa not patched
with my L3 partitioning series [1]) assume that the L3 configuration,
in particular the URB size, comes up in certain state when a context
is created, but nothing in the kernel guarantees this assumption, the
registers that control the partitioning of the L3 cache were being
left untouched.
Note that the VLV_L3SQCREG1_SQGHPCI_DEFAULT macro defined here has the
same value as the previously defined VLV_B0_WA_L3SQCREG1_VALUE, but
the latter will be removed in a future commit.
[1] http://lists.freedesktop.org/archives/mesa-dev/2015-September/093550.html
Signed-off-by: Francisco Jerez <currojerez at riseup.net>
---
drivers/gpu/drm/i915/i915_reg.h | 13 ++++++
drivers/gpu/drm/i915/intel_ringbuffer.c | 80 +++++++++++++++++++++++++++++++++
2 files changed, 93 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a7c9e8c..663bc8f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5920,11 +5920,21 @@ enum skl_disp_power_wells {
# define CHV_HZ_8X8_MODE_IN_1X (1<<15)
# define BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE (1<<3)
+#define GEN8_L3CNTLREG 0x7034
+#define GEN8_L3CNTLREG_URB_ALLOC(n) ((n) << 1)
+#define GEN8_L3CNTLREG_RO_ALLOC(n) ((n) << 11)
+#define GEN8_L3CNTLREG_DC_ALLOC(n) ((n) << 18)
+#define GEN8_L3CNTLREG_ALL_ALLOC(n) ((n) << 25)
+
#define GEN9_SLICE_COMMON_ECO_CHICKEN0 0x7308
#define DISABLE_PIXEL_MASK_CAMMING (1<<14)
#define GEN7_L3SQCREG1 0xB010
#define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000
+#define IVB_L3SQCREG1_SQGHPCI_DEFAULT 0x00730000
+#define VLV_L3SQCREG1_SQGHPCI_DEFAULT 0x00D30000
+#define HSW_L3SQCREG1_SQGHPCI_DEFAULT 0x00610000
+#define GEN7_L3SQCREG1_CONV_DC_UC (1 << 24)
#define GEN8_L3SQCREG1 0xB100
#define BDW_WA_L3SQCREG1_DEFAULT 0x784000
@@ -5933,6 +5943,9 @@ enum skl_disp_power_wells {
#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C47FF8C
#define GEN7_L3AGDIS (1<<19)
#define GEN7_L3CNTLREG2 0xB020
+#define GEN7_L3CNTLREG2_URB_ALLOC(n) ((n) << 1)
+#define GEN7_L3CNTLREG2_RO_ALLOC(n) ((n) << 14)
+#define GEN7_L3CNTLREG2_DC_ALLOC(n) ((n) << 21)
#define GEN7_L3CNTLREG3 0xB024
#define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 9035f8c..54ca344 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -800,6 +800,86 @@ static int wa_add(struct drm_i915_private *dev_priv,
#define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val)
+/**
+ * init_l3_partitioning_workarounds - Add L3 partitioning set-up to the WA list.
+ *
+ * @ring - Ring to program the L3 partitioning for.
+ * @n_urb - Number of ways to allocate for the URB.
+ * @n_ro - Number of ways to allocate for read-only L3 clients.
+ * @n_dc - Number of ways to allocate for the DC read-write L3 client.
+ * @n_all - Number of ways to allocate for the common pool shared
+ * among all L3 clients.
+ *
+ * Note that for this to work correctly the L3 cache must be
+ * completely flushed whenever the workaround list is applied to a
+ * context.
+ */
+static int init_l3_partitioning_workarounds(struct intel_engine_cs *ring,
+ unsigned int n_urb,
+ unsigned int n_ro,
+ unsigned int n_dc,
+ unsigned int n_all)
+{
+ struct drm_device *dev = ring->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (INTEL_INFO(dev)->gen >= 8) {
+ /*
+ * The ALL partition may not be used simultaneously
+ * with RO and DC.
+ */
+ BUG_ON(n_all && (n_ro || n_dc));
+
+ /* Just need to set up the L3 partitioning. */
+ WA_WRITE(GEN8_L3CNTLREG,
+ GEN8_L3CNTLREG_URB_ALLOC(n_urb) |
+ GEN8_L3CNTLREG_RO_ALLOC(n_ro) |
+ GEN8_L3CNTLREG_DC_ALLOC(n_dc) |
+ GEN8_L3CNTLREG_ALL_ALLOC(n_all));
+
+ } else if (INTEL_INFO(dev)->gen >= 7) {
+ /*
+ * Offset applied by the hardware to the number of
+ * ways allocated to the URB, which is also the
+ * minimum legal URB allocation.
+ */
+ const unsigned int n0_urb = (IS_VALLEYVIEW(dev) ? 32 : 0);
+ BUG_ON(n_urb < n0_urb);
+
+ /* The ALL partition is not supported on Gen7. */
+ BUG_ON(n_all);
+
+ /*
+ * Init the L3SQ General and high priority credit
+ * initialization value to the hardware defaults
+ * (except for VLV B0 which supposedly defaults to a
+ * value different to the one we set here), and demote
+ * the DC to LLC if it has no ways assigned.
+ *
+ * WaIncreaseL3CreditsForVLVB0:vlv
+ */
+ WA_WRITE(GEN7_L3SQCREG1,
+ (IS_HASWELL(dev) ? HSW_L3SQCREG1_SQGHPCI_DEFAULT :
+ IS_VALLEYVIEW(dev) ? VLV_L3SQCREG1_SQGHPCI_DEFAULT :
+ IVB_L3SQCREG1_SQGHPCI_DEFAULT) |
+ (n_dc ? 0 : GEN7_L3SQCREG1_CONV_DC_UC));
+
+ /* Set up the L3 partitioning. */
+ WA_WRITE(GEN7_L3CNTLREG2,
+ GEN7_L3CNTLREG2_URB_ALLOC(n_urb - n0_urb) |
+ GEN7_L3CNTLREG2_RO_ALLOC(n_ro) |
+ GEN7_L3CNTLREG2_DC_ALLOC(n_dc));
+
+ WA_WRITE(GEN7_L3CNTLREG3, 0);
+
+ } else {
+ /* No L3 on pre-Gen7 hardware. */
+ BUG();
+ }
+
+ return 0;
+}
+
static int gen8_init_workarounds(struct intel_engine_cs *ring)
{
struct drm_device *dev = ring->dev;
--
2.5.1
More information about the Intel-gfx
mailing list