* [PATCH 01/28] drm/i915/skl: Read the Memory Latency Values for WM computation
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-05 10:25 ` Daniel Vetter
2014-11-04 17:06 ` [PATCH 02/28] drm/i915/skl: Register definitions and macros for SKL Watermark regs Damien Lespiau
` (27 subsequent siblings)
28 siblings, 1 reply; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Pradeep Bhat
From: Pradeep Bhat <pradeep.bhat@intel.com>
This patch reads the memory latency values for all the 8 levels for
SKL. These values are needed for the Watermark computation.
v2: Incorporated the review comments from Damien on register
indentation.
v3: Updated the code to use the sandybridge_pcode_read for reading
memory latencies for GEN9.
v4: Don't put gen 9 in the middle of an ordered list of ifs
(Damien)
v5: take the rps.hw_lock around sandybridge_pcode_read() (Damien)
v6: Use gen >= 9 in the pcode_read() function for data1.
Move the defines near the gen6 ones and prefix them with PCODE.
Remove unused timeout define (the pcode_read() code has a larger
timeout already).
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 6 ++++
drivers/gpu/drm/i915/i915_reg.h | 7 ++++
drivers/gpu/drm/i915/intel_pm.c | 76 +++++++++++++++++++++++++++++++++++++----
3 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 54691bc..05fcbe5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1678,6 +1678,12 @@ struct drm_i915_private {
uint16_t spr_latency[5];
/* cursor */
uint16_t cur_latency[5];
+ /*
+ * Raw watermark memory latency values
+ * for SKL for all 8 levels
+ * in 1us units.
+ */
+ uint16_t skl_latency[8];
/* current hardware state */
struct ilk_wm_values hw;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f32c624..3f469c8 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5957,6 +5957,13 @@ enum punit_power_well {
#define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8
#define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16
+#define GEN9_PCODE_DATA1 0x13812C
+#define GEN9_PCODE_READ_MEM_LATENCY 0x6
+#define GEN9_MEM_LATENCY_LEVEL_MASK 0xFF
+#define GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT 8
+#define GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT 16
+#define GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT 24
+
#define GEN6_GT_CORE_STATUS 0x138060
#define GEN6_CORE_CPD_STATE_MASK (7<<4)
#define GEN6_RCn_MASK 7
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7a69eba..761c884 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2271,11 +2271,56 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
PIPE_WM_LINETIME_TIME(linetime);
}
-static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5])
+static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+ if (IS_GEN9(dev)) {
+ uint32_t val;
+ int ret;
+
+ /* 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);
+ ret = sandybridge_pcode_read(dev_priv,
+ GEN9_PCODE_READ_MEM_LATENCY,
+ &val);
+ mutex_unlock(&dev_priv->rps.hw_lock);
+
+ if (ret) {
+ DRM_ERROR("SKL Mailbox read error = %d\n", ret);
+ return;
+ }
+
+ wm[0] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
+ wm[1] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
+ GEN9_MEM_LATENCY_LEVEL_MASK;
+ wm[2] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
+ GEN9_MEM_LATENCY_LEVEL_MASK;
+ wm[3] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
+ GEN9_MEM_LATENCY_LEVEL_MASK;
+
+ /* 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);
+ ret = sandybridge_pcode_read(dev_priv,
+ GEN9_PCODE_READ_MEM_LATENCY,
+ &val);
+ mutex_unlock(&dev_priv->rps.hw_lock);
+ if (ret) {
+ DRM_ERROR("SKL Mailbox read error = %d\n", ret);
+ return;
+ }
+
+ wm[4] = val & GEN9_MEM_LATENCY_LEVEL_MASK;
+ wm[5] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) &
+ GEN9_MEM_LATENCY_LEVEL_MASK;
+ wm[6] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) &
+ GEN9_MEM_LATENCY_LEVEL_MASK;
+ wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
+ GEN9_MEM_LATENCY_LEVEL_MASK;
+
+ } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
uint64_t sskpd = I915_READ64(MCH_SSKPD);
wm[0] = (sskpd >> 56) & 0xFF;
@@ -2323,7 +2368,9 @@ static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5])
int ilk_wm_max_level(const struct drm_device *dev)
{
/* how many WM levels are we expecting */
- if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+ if (IS_GEN9(dev))
+ return 7;
+ else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
return 4;
else if (INTEL_INFO(dev)->gen >= 6)
return 3;
@@ -2333,7 +2380,7 @@ int ilk_wm_max_level(const struct drm_device *dev)
static void intel_print_wm_latency(struct drm_device *dev,
const char *name,
- const uint16_t wm[5])
+ const uint16_t wm[8])
{
int level, max_level = ilk_wm_max_level(dev);
@@ -2346,8 +2393,13 @@ static void intel_print_wm_latency(struct drm_device *dev,
continue;
}
- /* WM1+ latency values in 0.5us units */
- if (level > 0)
+ /*
+ * - latencies are in us on gen9.
+ * - before then, WM1+ latency values are in 0.5us units
+ */
+ if (IS_GEN9(dev))
+ latency *= 10;
+ else if (level > 0)
latency *= 5;
DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n",
@@ -2415,6 +2467,14 @@ static void ilk_setup_wm_latency(struct drm_device *dev)
snb_wm_latency_quirk(dev);
}
+static void skl_setup_wm_latency(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ intel_read_wm_latency(dev, dev_priv->wm.skl_latency);
+ intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
+}
+
static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
struct ilk_pipe_wm_parameters *p)
{
@@ -6127,6 +6187,8 @@ void intel_init_pm(struct drm_device *dev)
/* For FIFO watermark updates */
if (IS_GEN9(dev)) {
+ skl_setup_wm_latency(dev);
+
dev_priv->display.init_clock_gating = gen9_init_clock_gating;
} else if (HAS_PCH_SPLIT(dev)) {
ilk_setup_wm_latency(dev);
@@ -6219,6 +6281,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val)
}
I915_WRITE(GEN6_PCODE_DATA, *val);
+ if (INTEL_INFO(dev_priv)->gen >= 9)
+ I915_WRITE(GEN9_PCODE_DATA1, 0);
I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* Re: [PATCH 01/28] drm/i915/skl: Read the Memory Latency Values for WM computation
2014-11-04 17:06 ` [PATCH 01/28] drm/i915/skl: Read the Memory Latency Values for WM computation Damien Lespiau
@ 2014-11-05 10:25 ` Daniel Vetter
2014-11-05 10:29 ` Daniel Vetter
0 siblings, 1 reply; 33+ messages in thread
From: Daniel Vetter @ 2014-11-05 10:25 UTC (permalink / raw)
To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat
On Tue, Nov 04, 2014 at 05:06:38PM +0000, Damien Lespiau wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
>
> This patch reads the memory latency values for all the 8 levels for
> SKL. These values are needed for the Watermark computation.
>
> v2: Incorporated the review comments from Damien on register
> indentation.
>
> v3: Updated the code to use the sandybridge_pcode_read for reading
> memory latencies for GEN9.
>
> v4: Don't put gen 9 in the middle of an ordered list of ifs
> (Damien)
>
> v5: take the rps.hw_lock around sandybridge_pcode_read() (Damien)
>
> v6: Use gen >= 9 in the pcode_read() function for data1.
> Move the defines near the gen6 ones and prefix them with PCODE.
> Remove unused timeout define (the pcode_read() code has a larger
> timeout already).
>
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 6 ++++
> drivers/gpu/drm/i915/i915_reg.h | 7 ++++
> drivers/gpu/drm/i915/intel_pm.c | 76 +++++++++++++++++++++++++++++++++++++----
> 3 files changed, 83 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 54691bc..05fcbe5 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1678,6 +1678,12 @@ struct drm_i915_private {
> uint16_t spr_latency[5];
> /* cursor */
> uint16_t cur_latency[5];
> + /*
> + * Raw watermark memory latency values
> + * for SKL for all 8 levels
> + * in 1us units.
> + */
> + uint16_t skl_latency[8];
>
> /* current hardware state */
> struct ilk_wm_values hw;
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index f32c624..3f469c8 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -5957,6 +5957,13 @@ enum punit_power_well {
> #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8
> #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16
>
> +#define GEN9_PCODE_DATA1 0x13812C
> +#define GEN9_PCODE_READ_MEM_LATENCY 0x6
> +#define GEN9_MEM_LATENCY_LEVEL_MASK 0xFF
> +#define GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT 8
> +#define GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT 16
> +#define GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT 24
> +
> #define GEN6_GT_CORE_STATUS 0x138060
> #define GEN6_CORE_CPD_STATE_MASK (7<<4)
> #define GEN6_RCn_MASK 7
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 7a69eba..761c884 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2271,11 +2271,56 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
> PIPE_WM_LINETIME_TIME(linetime);
> }
>
> -static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5])
> +static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
Imo we should split this into an ilk_read_wm_latency and a
skl_read_wm_latency function. It's big and all the callers seem to only
care about one or the other. Care for a follow-up patch?
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 33+ messages in thread* Re: [PATCH 01/28] drm/i915/skl: Read the Memory Latency Values for WM computation
2014-11-05 10:25 ` Daniel Vetter
@ 2014-11-05 10:29 ` Daniel Vetter
0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2014-11-05 10:29 UTC (permalink / raw)
To: Damien Lespiau; +Cc: intel-gfx, Pradeep Bhat
On Wed, Nov 05, 2014 at 11:25:51AM +0100, Daniel Vetter wrote:
> On Tue, Nov 04, 2014 at 05:06:38PM +0000, Damien Lespiau wrote:
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index 7a69eba..761c884 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -2271,11 +2271,56 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
> > PIPE_WM_LINETIME_TIME(linetime);
> > }
> >
> > -static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5])
> > +static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
>
> Imo we should split this into an ilk_read_wm_latency and a
> skl_read_wm_latency function. It's big and all the callers seem to only
> care about one or the other. Care for a follow-up patch?
Actually there seem to be a few more functions which are platform
specific. E.g. the intel_fixup* functions - tbh we might as well just
inline them.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 02/28] drm/i915/skl: Register definitions and macros for SKL Watermark regs
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
2014-11-04 17:06 ` [PATCH 01/28] drm/i915/skl: Read the Memory Latency Values for WM computation Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 03/28] drm/i915/skl: Definition of SKL WM param structs for pipe/plane Damien Lespiau
` (26 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Pradeep Bhat
From: Pradeep Bhat <pradeep.bhat@intel.com>
This patch defines SKL specific PLANE_WM Watermark registers. It also
defines macros to get the addresses of different LP levels within a pipe.
v2: Reworked the register definitions and associated macros to make it more
generic and be able to use for_each_pipe in values computation.
Incorporated Damien's review comments and indentation.
v3: Added default values for lines and blocks. Provided mask for blocks.
v4: Prefix intermedidate (internal-only) macros with _ (Ville)
v5: Remove the lines and block defaults value (Ville)
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> (v4)
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 3f469c8..e22221b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4102,6 +4102,41 @@ enum punit_power_well {
#define I965_CURSOR_MAX_WM 32
#define I965_CURSOR_DFT_WM 8
+/* Watermark register definitions for SKL */
+#define CUR_WM_A_0 0x70140
+#define CUR_WM_B_0 0x71140
+#define PLANE_WM_1_A_0 0x70240
+#define PLANE_WM_1_B_0 0x71240
+#define PLANE_WM_2_A_0 0x70340
+#define PLANE_WM_2_B_0 0x71340
+#define PLANE_WM_TRANS_1_A_0 0x70268
+#define PLANE_WM_TRANS_1_B_0 0x71268
+#define PLANE_WM_TRANS_2_A_0 0x70368
+#define PLANE_WM_TRANS_2_B_0 0x71368
+#define CUR_WM_TRANS_A_0 0x70168
+#define CUR_WM_TRANS_B_0 0x71168
+#define PLANE_WM_EN (1 << 31)
+#define PLANE_WM_LINES_SHIFT 14
+#define PLANE_WM_LINES_MASK 0x1f
+#define PLANE_WM_BLOCKS_MASK 0x3ff
+
+#define CUR_WM_0(pipe) _PIPE(pipe, CUR_WM_A_0, CUR_WM_B_0)
+#define CUR_WM(pipe, level) (CUR_WM_0(pipe) + ((4) * (level)))
+#define CUR_WM_TRANS(pipe) _PIPE(pipe, CUR_WM_TRANS_A_0, CUR_WM_TRANS_B_0)
+
+#define _PLANE_WM_1(pipe) _PIPE(pipe, PLANE_WM_1_A_0, PLANE_WM_1_B_0)
+#define _PLANE_WM_2(pipe) _PIPE(pipe, PLANE_WM_2_A_0, PLANE_WM_2_B_0)
+#define _PLANE_WM_BASE(pipe, plane) \
+ _PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe))
+#define PLANE_WM(pipe, plane, level) \
+ (_PLANE_WM_BASE(pipe, plane) + ((4) * (level)))
+#define _PLANE_WM_TRANS_1(pipe) \
+ _PIPE(pipe, PLANE_WM_TRANS_1_A_0, PLANE_WM_TRANS_1_B_0)
+#define _PLANE_WM_TRANS_2(pipe) \
+ _PIPE(pipe, PLANE_WM_TRANS_2_A_0, PLANE_WM_TRANS_2_B_0)
+#define PLANE_WM_TRANS(pipe, plane) \
+ _PLANE(plane, _PLANE_WM_TRANS_1(pipe), _PLANE_WM_TRANS_2(pipe))
+
/* define the Watermark register on Ironlake */
#define WM0_PIPEA_ILK 0x45100
#define WM0_PIPE_PLANE_MASK (0xffff<<16)
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 03/28] drm/i915/skl: Definition of SKL WM param structs for pipe/plane
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
2014-11-04 17:06 ` [PATCH 01/28] drm/i915/skl: Read the Memory Latency Values for WM computation Damien Lespiau
2014-11-04 17:06 ` [PATCH 02/28] drm/i915/skl: Register definitions and macros for SKL Watermark regs Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 04/28] drm/i915/skl: Add DDB allocation management structures Damien Lespiau
` (25 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Pradeep Bhat
From: Pradeep Bhat <pradeep.bhat@intel.com>
This patch defines the structures needed for computation of
watermarks of pipes and planes for SKL.
v2: Incorporated Damien's review comments and removed unused fields
in structs for future features like rotation, drrs and scaling.
The skl_wm_values struct is now made more generic across planes
and cursor planes for all pipes.
v3: implemented the plane/cursor split.
v4: Change the wm union back to a structure (Ville, Daniel)
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 18 ++++++++++++++++++
drivers/gpu/drm/i915/intel_drv.h | 8 ++++++++
drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++
3 files changed, 34 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 05fcbe5..19bc2d0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1387,6 +1387,24 @@ struct ilk_wm_values {
enum intel_ddb_partitioning partitioning;
};
+struct skl_wm_values {
+ bool dirty[I915_MAX_PIPES];
+ uint32_t wm_linetime[I915_MAX_PIPES];
+ uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
+ uint32_t cursor[I915_MAX_PIPES][8];
+ uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
+ uint32_t cursor_trans[I915_MAX_PIPES];
+};
+
+struct skl_wm_level {
+ bool plane_en[I915_MAX_PLANES];
+ uint16_t plane_res_b[I915_MAX_PLANES];
+ uint8_t plane_res_l[I915_MAX_PLANES];
+ bool cursor_en;
+ uint16_t cursor_res_b;
+ uint8_t cursor_res_l;
+};
+
/*
* This struct helps tracking the state needed for runtime PM, which puts the
* device in PCI D3 state. Notice that when this happens, nothing on the
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c8ddde6..446be27 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -412,6 +412,12 @@ struct intel_mmio_flip {
struct work_struct work;
};
+struct skl_pipe_wm {
+ struct skl_wm_level wm[8];
+ struct skl_wm_level trans_wm;
+ uint32_t linetime;
+};
+
struct intel_crtc {
struct drm_crtc base;
enum pipe pipe;
@@ -459,6 +465,8 @@ struct intel_crtc {
struct {
/* watermarks currently being used */
struct intel_pipe_wm active;
+ /* SKL wm values currently in use */
+ struct skl_pipe_wm skl_active;
} wm;
int scanline_offset;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 761c884..ca2080b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1960,6 +1960,14 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
}
+struct skl_pipe_wm_parameters {
+ bool active;
+ uint32_t pipe_htotal;
+ uint32_t pixel_rate; /* in KHz */
+ struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
+ struct intel_plane_wm_parameters cursor;
+};
+
struct ilk_pipe_wm_parameters {
bool active;
uint32_t pipe_htotal;
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 04/28] drm/i915/skl: Add DDB allocation management structures
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (2 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 03/28] drm/i915/skl: Definition of SKL WM param structs for pipe/plane Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 05/28] drm/i915/skl: SKL Watermark Computation Damien Lespiau
` (24 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
We now need to allocate space in the DDB for planes being scanned out
ourselves. The data structure to represent an allocation mirrors what
we'll need to write in the registers later on: (start, end).
We add that allocation datat to the skl_wm_values structure as part of
the values to program the hardware with.
v2: Split planes and cursor for consistency.
v3: Make the skl_ddb_entry_size() parameter const
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 19bc2d0..aa8607a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1387,8 +1387,27 @@ struct ilk_wm_values {
enum intel_ddb_partitioning partitioning;
};
+struct skl_ddb_entry {
+ uint16_t start, end; /* in number of blocks */
+};
+
+static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
+{
+ /* end not set, clearly no allocation here. start can be 0 though */
+ if (entry->end == 0)
+ return 0;
+
+ return entry->end - entry->start + 1;
+}
+
+struct skl_ddb_allocation {
+ struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
+ struct skl_ddb_entry cursor[I915_MAX_PIPES];
+};
+
struct skl_wm_values {
bool dirty[I915_MAX_PIPES];
+ struct skl_ddb_allocation ddb;
uint32_t wm_linetime[I915_MAX_PIPES];
uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
uint32_t cursor[I915_MAX_PIPES][8];
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 05/28] drm/i915/skl: SKL Watermark Computation
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (3 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 04/28] drm/i915/skl: Add DDB allocation management structures Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 06/28] drm/i915/skl: Allocate DDB portions for display planes Damien Lespiau
` (23 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Pradeep Bhat
From: Pradeep Bhat <pradeep.bhat@intel.com>
This patch implements the watermark algorithm and its necessary
functions. Two function pointers skl_update_wm and
skl_update_sprite_wm are provided. The skl_update_wm will update
the watermarks for the crtc provided as an argument and then
checks for change in DDB allocation for other active pipes and
recomputes the watermarks for those Pipes and planes as well.
Finally it does the register programming for all dirty pipes.
The trigger of the Watermark double buffer registers will have
to be once the plane configurations are done by the caller.
v2: fixed the divide-by-0 error in the results computation func.
Also reworked the PLANE_WM register values computation func to
make it more compact. Incorporated all other review comments
from Damien.
v3: Changed the skl_compute_plane_wm function to now return success
or failure. Also the result blocks and lines are computed here
instead of in skl_compute_wm_results function.
v4: Adjust skl_ddb_alloc_changed() to the new planes/cursor split
(Damien)
v5: Reworked the affected functions to implement new plane/cursor
split.
v6: Rework the logic that triggers the DDB allocation and WM computation
of skl_update_other_pipe_wm() to not depend on non-computed DDB
values.
Always give a valid cursor_width (at boot it's 0) to keep the
invariant that we consider the cursor plane always enabled.
Otherwise we end up dividing by 0 in skl_compute_plane_wm()
(Damien Lespiau)
v7: Spell out allocation
skl_ddb_ functions should have the ddb as first argument
Make the skl_ddb_alloc_changed() parameters const
(Damien)
v8: Rebase on top of the crtc->primary changes
v9: Split the staging results structure to not exceed the 1Kb stack
allocation in skl_update_wm()
v10: Make skl_pipe_pixel_rate() take a pointer to the pipe config
Add a comment about overflow considerations for skl_wm_method1()
Various additions of const
Various use of sizeof(variable) instead of sizeof(type)
Various move of variable definitons to a narrower scope
Zero initialize some stack allocated structures to make sure we
don't have garbage in case we don't write all the values
(Ville)
v11: Remove non-necessary default number of blocks/lines when the plane
is disabled (Ville)
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 12 +-
drivers/gpu/drm/i915/intel_pm.c | 422 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 433 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index aa8607a..fbe18ae 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1722,8 +1722,18 @@ struct drm_i915_private {
*/
uint16_t skl_latency[8];
+ /*
+ * The skl_wm_values structure is a bit too big for stack
+ * allocation, so we keep the staging struct where we store
+ * intermediate results here instead.
+ */
+ struct skl_wm_values skl_results;
+
/* current hardware state */
- struct ilk_wm_values hw;
+ union {
+ struct ilk_wm_values hw;
+ struct skl_wm_values skl_hw;
+ };
} wm;
struct i915_runtime_pm pm;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ca2080b..5500c53 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2973,6 +2973,426 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
}
+static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config)
+{
+ /* TODO: Take into account the scalers once we support them */
+ return config->adjusted_mode.crtc_clock;
+}
+
+/*
+ * The max latency should be 257 (max the punit can code is 255 and we add 2us
+ * for the read latency) and bytes_per_pixel should always be <= 8, so that
+ * should allow pixel_rate up to ~2 GHz which seems sufficient since max
+ * 2xcdclk is 1350 MHz and the pixel rate should never exceed that.
+*/
+static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel,
+ uint32_t latency)
+{
+ uint32_t wm_intermediate_val, ret;
+
+ if (latency == 0)
+ return UINT_MAX;
+
+ wm_intermediate_val = latency * pixel_rate * bytes_per_pixel;
+ ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
+
+ return ret;
+}
+
+static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
+ uint32_t horiz_pixels, uint8_t bytes_per_pixel,
+ uint32_t latency)
+{
+ uint32_t ret, plane_bytes_per_line, wm_intermediate_val;
+
+ if (latency == 0)
+ return UINT_MAX;
+
+ plane_bytes_per_line = horiz_pixels * bytes_per_pixel;
+ wm_intermediate_val = latency * pixel_rate;
+ ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
+ plane_bytes_per_line;
+
+ return ret;
+}
+
+static void skl_compute_transition_wm(struct drm_crtc *crtc,
+ struct skl_pipe_wm_parameters *params,
+ struct skl_pipe_wm *pipe_wm)
+{
+ /*
+ * For now it is suggested to use the LP0 wm val of corresponding
+ * plane as transition wm val. This is done while computing results.
+ */
+ if (!params->active)
+ return;
+}
+
+static uint32_t
+skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
+{
+ if (!intel_crtc_active(crtc))
+ return 0;
+
+ return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
+
+}
+
+static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
+ const struct intel_crtc *intel_crtc)
+{
+ struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
+ enum pipe pipe = intel_crtc->pipe;
+
+ if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe],
+ sizeof(new_ddb->plane[pipe])))
+ return true;
+
+ if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe],
+ sizeof(new_ddb->cursor[pipe])))
+ return true;
+
+ return false;
+}
+
+static void skl_compute_wm_global_parameters(struct drm_device *dev,
+ struct intel_wm_config *config)
+{
+ struct drm_crtc *crtc;
+ struct drm_plane *plane;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ config->num_pipes_active += intel_crtc_active(crtc);
+
+ /* FIXME: I don't think we need those two global parameters on SKL */
+ list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+
+ config->sprites_enabled |= intel_plane->wm.enabled;
+ config->sprites_scaled |= intel_plane->wm.scaled;
+ }
+}
+
+static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
+ struct skl_pipe_wm_parameters *p)
+{
+ struct drm_device *dev = crtc->dev;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ enum pipe pipe = intel_crtc->pipe;
+ struct drm_plane *plane;
+ int i = 1; /* Index for sprite planes start */
+
+ p->active = intel_crtc_active(crtc);
+ if (p->active) {
+ p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal;
+ p->pixel_rate = skl_pipe_pixel_rate(&intel_crtc->config);
+
+ /*
+ * For now, assume primary and cursor planes are always enabled.
+ */
+ p->plane[0].enabled = true;
+ p->plane[0].bytes_per_pixel =
+ crtc->primary->fb->bits_per_pixel / 8;
+ p->plane[0].horiz_pixels = intel_crtc->config.pipe_src_w;
+ p->plane[0].vert_pixels = intel_crtc->config.pipe_src_h;
+
+ p->cursor.enabled = true;
+ p->cursor.bytes_per_pixel = 4;
+ p->cursor.horiz_pixels = intel_crtc->cursor_width ?
+ intel_crtc->cursor_width : 64;
+ }
+
+ list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+
+ if (intel_plane->pipe == pipe)
+ p->plane[i++] = intel_plane->wm;
+ }
+}
+
+static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
+ struct intel_plane_wm_parameters *p_params,
+ uint16_t max_page_buff_alloc,
+ uint32_t mem_value,
+ uint16_t *res_blocks, /* out */
+ uint8_t *res_lines /* out */)
+{
+ uint32_t method1, method2, plane_bytes_per_line;
+ uint32_t result_bytes;
+
+ if (!p->active || !p_params->enabled)
+ return false;
+
+ method1 = skl_wm_method1(p->pixel_rate,
+ p_params->bytes_per_pixel,
+ mem_value);
+ method2 = skl_wm_method2(p->pixel_rate,
+ p->pipe_htotal,
+ p_params->horiz_pixels,
+ p_params->bytes_per_pixel,
+ mem_value);
+
+ plane_bytes_per_line = p_params->horiz_pixels *
+ p_params->bytes_per_pixel;
+
+ /* For now xtile and linear */
+ if (((max_page_buff_alloc * 512) / plane_bytes_per_line) >= 1)
+ result_bytes = min(method1, method2);
+ else
+ result_bytes = method1;
+
+ *res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1;
+ *res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line);
+
+ return true;
+}
+
+static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+ struct skl_ddb_allocation *ddb,
+ struct skl_pipe_wm_parameters *p,
+ enum pipe pipe,
+ int level,
+ int num_planes,
+ struct skl_wm_level *result)
+{
+ uint16_t latency = dev_priv->wm.skl_latency[level];
+ uint16_t ddb_blocks;
+ int i;
+
+ for (i = 0; i < num_planes; i++) {
+ ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
+
+ result->plane_en[i] = skl_compute_plane_wm(p, &p->plane[i],
+ ddb_blocks,
+ latency,
+ &result->plane_res_b[i],
+ &result->plane_res_l[i]);
+ }
+
+ ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]);
+ result->cursor_en = skl_compute_plane_wm(p, &p->cursor, ddb_blocks,
+ latency, &result->cursor_res_b,
+ &result->cursor_res_l);
+}
+
+static void skl_compute_pipe_wm(struct drm_crtc *crtc,
+ struct skl_ddb_allocation *ddb,
+ struct skl_pipe_wm_parameters *params,
+ struct skl_pipe_wm *pipe_wm)
+{
+ struct drm_device *dev = crtc->dev;
+ const struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ int level, max_level = ilk_wm_max_level(dev);
+
+ for (level = 0; level <= max_level; level++) {
+ skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
+ level, intel_num_planes(intel_crtc),
+ &pipe_wm->wm[level]);
+ }
+ pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
+
+ skl_compute_transition_wm(crtc, params, pipe_wm);
+}
+
+static void skl_compute_wm_results(struct drm_device *dev,
+ struct skl_pipe_wm_parameters *p,
+ struct skl_pipe_wm *p_wm,
+ struct skl_wm_values *r,
+ struct intel_crtc *intel_crtc)
+{
+ int level, max_level = ilk_wm_max_level(dev);
+ enum pipe pipe = intel_crtc->pipe;
+
+ for (level = 0; level <= max_level; level++) {
+ uint16_t ddb_blocks;
+ uint32_t temp;
+ int i;
+
+ for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+ temp = 0;
+ ddb_blocks = skl_ddb_entry_size(&r->ddb.plane[pipe][i]);
+
+ if ((p_wm->wm[level].plane_res_b[i] > ddb_blocks) ||
+ (p_wm->wm[level].plane_res_l[i] > 31))
+ p_wm->wm[level].plane_en[i] = false;
+
+ temp |= p_wm->wm[level].plane_res_l[i] <<
+ PLANE_WM_LINES_SHIFT;
+ temp |= p_wm->wm[level].plane_res_b[i];
+ if (p_wm->wm[level].plane_en[i])
+ temp |= PLANE_WM_EN;
+
+ r->plane[pipe][i][level] = temp;
+ /* Use the LP0 WM value for transition WM for now. */
+ if (level == 0)
+ r->plane_trans[pipe][i] = temp;
+ }
+
+ temp = 0;
+ ddb_blocks = skl_ddb_entry_size(&r->ddb.cursor[pipe]);
+
+ if ((p_wm->wm[level].cursor_res_b > ddb_blocks) ||
+ (p_wm->wm[level].cursor_res_l > 31))
+ p_wm->wm[level].cursor_en = false;
+
+ temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT;
+ temp |= p_wm->wm[level].cursor_res_b;
+
+ if (p_wm->wm[level].cursor_en)
+ temp |= PLANE_WM_EN;
+
+ r->cursor[pipe][level] = temp;
+ /* Use the LP0 WM value for transition WM for now. */
+ if (level == 0)
+ r->cursor_trans[pipe] = temp;
+
+ }
+
+ r->wm_linetime[pipe] = p_wm->linetime;
+}
+
+static void skl_write_wm_values(struct drm_i915_private *dev_priv,
+ const struct skl_wm_values *new)
+{
+ struct drm_device *dev = dev_priv->dev;
+ struct intel_crtc *crtc;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
+ int i, level, max_level = ilk_wm_max_level(dev);
+ enum pipe pipe = crtc->pipe;
+
+ if (new->dirty[pipe]) {
+ I915_WRITE(PIPE_WM_LINETIME(pipe),
+ new->wm_linetime[pipe]);
+
+ for (level = 0; level <= max_level; level++) {
+ for (i = 0; i < intel_num_planes(crtc); i++)
+ I915_WRITE(PLANE_WM(pipe, i, level),
+ new->plane[pipe][i][level]);
+ I915_WRITE(CUR_WM(pipe, level),
+ new->cursor[pipe][level]);
+ }
+ for (i = 0; i < intel_num_planes(crtc); i++)
+ I915_WRITE(PLANE_WM_TRANS(pipe, i),
+ new->plane_trans[pipe][i]);
+ I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
+ }
+ }
+
+ dev_priv->wm.skl_hw = *new;
+}
+
+static bool skl_update_pipe_wm(struct drm_crtc *crtc,
+ struct skl_pipe_wm_parameters *params,
+ struct intel_wm_config *config,
+ struct skl_ddb_allocation *ddb, /* out */
+ struct skl_pipe_wm *pipe_wm /* out */)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+ skl_compute_wm_pipe_parameters(crtc, params);
+ skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
+
+ if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
+ return false;
+
+ intel_crtc->wm.skl_active = *pipe_wm;
+ return true;
+}
+
+static void skl_update_other_pipe_wm(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ struct intel_wm_config *config,
+ struct skl_wm_values *r)
+{
+ struct intel_crtc *intel_crtc;
+ struct intel_crtc *this_crtc = to_intel_crtc(crtc);
+
+ /*
+ * If the WM update hasn't changed the allocation for this_crtc (the
+ * crtc we are currently computing the new WM values for), other
+ * enabled crtcs will keep the same allocation and we don't need to
+ * recompute anything for them.
+ */
+ if (!skl_ddb_allocation_changed(&r->ddb, this_crtc))
+ return;
+
+ /*
+ * Otherwise, because of this_crtc being freshly enabled/disabled, the
+ * other active pipes need new DDB allocation and WM values.
+ */
+ list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
+ base.head) {
+ struct skl_pipe_wm_parameters params = {};
+ struct skl_pipe_wm pipe_wm = {};
+ bool wm_changed;
+
+ if (this_crtc->pipe == intel_crtc->pipe)
+ continue;
+
+ if (!intel_crtc->active)
+ continue;
+
+ wm_changed = skl_update_pipe_wm(&intel_crtc->base,
+ ¶ms, config,
+ &r->ddb, &pipe_wm);
+
+ /*
+ * If we end up re-computing the other pipe WM values, it's
+ * because it was really needed, so we expect the WM values to
+ * be different.
+ */
+ WARN_ON(!wm_changed);
+
+ skl_compute_wm_results(dev, ¶ms, &pipe_wm, r, intel_crtc);
+ r->dirty[intel_crtc->pipe] = true;
+ }
+}
+
+static void skl_update_wm(struct drm_crtc *crtc)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct skl_pipe_wm_parameters params = {};
+ struct skl_wm_values *results = &dev_priv->wm.skl_results;
+ struct skl_pipe_wm pipe_wm = {};
+ struct intel_wm_config config = {};
+
+ memset(results, 0, sizeof(*results));
+
+ skl_compute_wm_global_parameters(dev, &config);
+
+ if (!skl_update_pipe_wm(crtc, ¶ms, &config,
+ &results->ddb, &pipe_wm))
+ return;
+
+ skl_compute_wm_results(dev, ¶ms, &pipe_wm, results, intel_crtc);
+ results->dirty[intel_crtc->pipe] = true;
+
+ skl_update_other_pipe_wm(dev, crtc, &config, results);
+ skl_write_wm_values(dev_priv, results);
+}
+
+static void
+skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
+ uint32_t sprite_width, uint32_t sprite_height,
+ int pixel_size, bool enabled, bool scaled)
+{
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+
+ intel_plane->wm.enabled = enabled;
+ intel_plane->wm.scaled = scaled;
+ intel_plane->wm.horiz_pixels = sprite_width;
+ intel_plane->wm.vert_pixels = sprite_height;
+ intel_plane->wm.bytes_per_pixel = pixel_size;
+
+ skl_update_wm(crtc);
+}
+
static void ilk_update_wm(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -6198,6 +6618,8 @@ void intel_init_pm(struct drm_device *dev)
skl_setup_wm_latency(dev);
dev_priv->display.init_clock_gating = gen9_init_clock_gating;
+ dev_priv->display.update_wm = skl_update_wm;
+ dev_priv->display.update_sprite_wm = skl_update_sprite_wm;
} else if (HAS_PCH_SPLIT(dev)) {
ilk_setup_wm_latency(dev);
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 06/28] drm/i915/skl: Allocate DDB portions for display planes
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (4 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 05/28] drm/i915/skl: SKL Watermark Computation Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 07/28] drm/i915/skl: Program the DDB allocation Damien Lespiau
` (22 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
v2: Fix the 3rd plane/cursor logic (Pradeep Bhat)
v3: Fix one-by-one error in the DDB allocation code
v4: Rebase on top of the skl_pipe_pixel_rate() argument change
v5: Replace the available/start/end output parameters of
skl_ddb_get_pipe_allocation_limits() by a single ddb entry constify
a few arguments
Make nth_active_pipe 0 indexed
Use sizeof(variable) instead of sizeof(type)
(Ville)
v6: Use the for_each_crtc() macro instead of list_for_each_entry()
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 148 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 148 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5500c53..b5c7c4b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2973,6 +2973,153 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
}
+/*
+ * On gen9, we need to allocate Display Data Buffer (DDB) portions to the
+ * different active planes.
+ */
+
+#define SKL_DDB_SIZE 896 /* in blocks */
+
+static void
+skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+ struct drm_crtc *for_crtc,
+ const struct intel_wm_config *config,
+ const struct skl_pipe_wm_parameters *params,
+ struct skl_ddb_entry *alloc /* out */)
+{
+ struct drm_crtc *crtc;
+ unsigned int pipe_size, ddb_size;
+ int nth_active_pipe;
+
+ if (!params->active) {
+ alloc->start = 0;
+ alloc->end = 0;
+ return;
+ }
+
+ ddb_size = SKL_DDB_SIZE;
+
+ ddb_size -= 4; /* 4 blocks for bypass path allocation */
+
+ nth_active_pipe = 0;
+ for_each_crtc(dev, crtc) {
+ if (!intel_crtc_active(crtc))
+ continue;
+
+ if (crtc == for_crtc)
+ break;
+
+ nth_active_pipe++;
+ }
+
+ pipe_size = ddb_size / config->num_pipes_active;
+ alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active;
+ alloc->end = alloc->start + pipe_size - 1;
+}
+
+static unsigned int skl_cursor_allocation(const struct intel_wm_config *config)
+{
+ if (config->num_pipes_active == 1)
+ return 32;
+
+ return 8;
+}
+
+static unsigned int
+skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p)
+{
+ return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
+}
+
+/*
+ * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
+ * a 8192x4096@32bpp framebuffer:
+ * 3 * 4096 * 8192 * 4 < 2^32
+ */
+static unsigned int
+skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
+ const struct skl_pipe_wm_parameters *params)
+{
+ unsigned int total_data_rate = 0;
+ int plane;
+
+ for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
+ const struct intel_plane_wm_parameters *p;
+
+ p = ¶ms->plane[plane];
+ if (!p->enabled)
+ continue;
+
+ total_data_rate += skl_plane_relative_data_rate(p);
+ }
+
+ return total_data_rate;
+}
+
+static void
+skl_allocate_pipe_ddb(struct drm_crtc *crtc,
+ const struct intel_wm_config *config,
+ const struct skl_pipe_wm_parameters *params,
+ struct skl_ddb_allocation *ddb /* out */)
+{
+ struct drm_device *dev = crtc->dev;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ enum pipe pipe = intel_crtc->pipe;
+ struct skl_ddb_entry alloc;
+ uint16_t alloc_size, start, cursor_blocks;
+ unsigned int total_data_rate;
+ int plane;
+
+ skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, &alloc);
+ alloc_size = skl_ddb_entry_size(&alloc);
+ if (alloc_size == 0) {
+ memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+ memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe]));
+ return;
+ }
+
+ cursor_blocks = skl_cursor_allocation(config);
+ ddb->cursor[pipe].start = alloc.end - cursor_blocks + 1;
+ ddb->cursor[pipe].end = alloc.end;
+
+ alloc_size -= cursor_blocks;
+ alloc.end -= cursor_blocks;
+
+ /*
+ * Each active plane get a portion of the remaining space, in
+ * proportion to the amount of data they need to fetch from memory.
+ *
+ * FIXME: we may not allocate every single block here.
+ */
+ total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
+
+ start = alloc.start;
+ for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
+ const struct intel_plane_wm_parameters *p;
+ unsigned int data_rate;
+ uint16_t plane_blocks;
+
+ p = ¶ms->plane[plane];
+ if (!p->enabled)
+ continue;
+
+ data_rate = skl_plane_relative_data_rate(p);
+
+ /*
+ * promote the expression to 64 bits to avoid overflowing, the
+ * result is < available as data_rate / total_data_rate < 1
+ */
+ plane_blocks = div_u64((uint64_t)alloc_size * data_rate,
+ total_data_rate);
+
+ ddb->plane[pipe][plane].start = start;
+ ddb->plane[pipe][plane].end = start + plane_blocks - 1;
+
+ start += plane_blocks;
+ }
+
+}
+
static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config)
{
/* TODO: Take into account the scalers once we support them */
@@ -3294,6 +3441,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
skl_compute_wm_pipe_parameters(crtc, params);
+ skl_allocate_pipe_ddb(crtc, config, params, ddb);
skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 07/28] drm/i915/skl: Program the DDB allocation
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (5 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 06/28] drm/i915/skl: Allocate DDB portions for display planes Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 08/28] drm/i915/skl: Read the pipe WM HW state Damien Lespiau
` (21 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
v2: Adapt to the planes/cursor split
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 16 ++++++++++++++++
drivers/gpu/drm/i915/intel_pm.c | 9 +++++++++
2 files changed, 25 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e22221b..7fea33d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4696,6 +4696,8 @@ enum punit_power_well {
#define _PLANE_KEYMSK_2_A 0x70298
#define _PLANE_KEYMAX_1_A 0x701a0
#define _PLANE_KEYMAX_2_A 0x702a0
+#define _PLANE_BUF_CFG_1_A 0x7027c
+#define _PLANE_BUF_CFG_2_A 0x7037c
#define _PLANE_CTL_1_B 0x71180
#define _PLANE_CTL_2_B 0x71280
@@ -4773,6 +4775,20 @@ enum punit_power_well {
#define PLANE_KEYMAX(pipe, plane) \
_PLANE(plane, _PLANE_KEYMAX_1(pipe), _PLANE_KEYMAX_2(pipe))
+#define _PLANE_BUF_CFG_1_B 0x7127c
+#define _PLANE_BUF_CFG_2_B 0x7137c
+#define _PLANE_BUF_CFG_1(pipe) \
+ _PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B)
+#define _PLANE_BUF_CFG_2(pipe) \
+ _PIPE(pipe, _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B)
+#define PLANE_BUF_CFG(pipe, plane) \
+ _PLANE(plane, _PLANE_BUF_CFG_1(pipe), _PLANE_BUF_CFG_2(pipe))
+
+/* SKL new cursor registers */
+#define _CUR_BUF_CFG_A 0x7017c
+#define _CUR_BUF_CFG_B 0x7117c
+#define CUR_BUF_CFG(pipe) _PIPE(pipe, _CUR_BUF_CFG_A, _CUR_BUF_CFG_B)
+
/* VBIOS regs */
#define VGACNTRL 0x71400
# define VGA_DISP_DISABLE (1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b5c7c4b..c2f1441 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3426,6 +3426,15 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
I915_WRITE(PLANE_WM_TRANS(pipe, i),
new->plane_trans[pipe][i]);
I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
+
+ for (i = 0; i < intel_num_planes(crtc); i++)
+ I915_WRITE(PLANE_BUF_CFG(pipe, i),
+ new->ddb.plane[pipe][i].end << 16 |
+ new->ddb.plane[pipe][i].start);
+
+ I915_WRITE(CUR_BUF_CFG(pipe),
+ new->ddb.cursor[pipe].end << 16 |
+ new->ddb.cursor[pipe].start);
}
}
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 08/28] drm/i915/skl: Read the pipe WM HW state
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (6 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 07/28] drm/i915/skl: Program the DDB allocation Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 09/28] drm/i915/gen9: Add 2us read latency to WM level Damien Lespiau
` (20 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx; +Cc: Pradeep Bhat
From: Pradeep Bhat <pradeep.bhat@intel.com>
This patch provides the implementation for reading the pipe wm HW
state.
v2: Incorporated Damien's review comments and also made modifications
to incorporate the plane/cursor split.
v3: No need to ident a line that was fitting 80 chars
Return early instead of indenting the remaining of a function
(Damien)
v4: Rebase on top of nightly (minor conflict in intel_drv.h)
v5: Rebase on top of nightly (minor conflict in intel_drv.h)
v6: Rebase on top of nightly (minor conflict in intel_drv.h)
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 4 +-
drivers/gpu/drm/i915/intel_drv.h | 1 +
drivers/gpu/drm/i915/intel_pm.c | 104 +++++++++++++++++++++++++++++++++++
3 files changed, 108 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f3ff8e8..ecba620 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13267,7 +13267,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
pll->on = false;
}
- if (HAS_PCH_SPLIT(dev))
+ if (IS_GEN9(dev))
+ skl_wm_get_hw_state(dev);
+ else if (HAS_PCH_SPLIT(dev))
ilk_wm_get_hw_state(dev);
if (force_restore) {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 446be27..1cdd6f9 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1164,6 +1164,7 @@ void gen6_update_ring_freq(struct drm_device *dev);
void gen6_rps_idle(struct drm_i915_private *dev_priv);
void gen6_rps_boost(struct drm_i915_private *dev_priv);
void ilk_wm_get_hw_state(struct drm_device *dev);
+void skl_wm_get_hw_state(struct drm_device *dev);
/* intel_sdvo.c */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c2f1441..09a81b3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3624,6 +3624,110 @@ ilk_update_sprite_wm(struct drm_plane *plane,
ilk_update_wm(crtc);
}
+static void skl_pipe_wm_active_state(uint32_t val,
+ struct skl_pipe_wm *active,
+ bool is_transwm,
+ bool is_cursor,
+ int i,
+ int level)
+{
+ bool is_enabled = (val & PLANE_WM_EN) != 0;
+
+ if (!is_transwm) {
+ if (!is_cursor) {
+ active->wm[level].plane_en[i] = is_enabled;
+ active->wm[level].plane_res_b[i] =
+ val & PLANE_WM_BLOCKS_MASK;
+ active->wm[level].plane_res_l[i] =
+ (val >> PLANE_WM_LINES_SHIFT) &
+ PLANE_WM_LINES_MASK;
+ } else {
+ active->wm[level].cursor_en = is_enabled;
+ active->wm[level].cursor_res_b =
+ val & PLANE_WM_BLOCKS_MASK;
+ active->wm[level].cursor_res_l =
+ (val >> PLANE_WM_LINES_SHIFT) &
+ PLANE_WM_LINES_MASK;
+ }
+ } else {
+ if (!is_cursor) {
+ active->trans_wm.plane_en[i] = is_enabled;
+ active->trans_wm.plane_res_b[i] =
+ val & PLANE_WM_BLOCKS_MASK;
+ active->trans_wm.plane_res_l[i] =
+ (val >> PLANE_WM_LINES_SHIFT) &
+ PLANE_WM_LINES_MASK;
+ } else {
+ active->trans_wm.cursor_en = is_enabled;
+ active->trans_wm.cursor_res_b =
+ val & PLANE_WM_BLOCKS_MASK;
+ active->trans_wm.cursor_res_l =
+ (val >> PLANE_WM_LINES_SHIFT) &
+ PLANE_WM_LINES_MASK;
+ }
+ }
+}
+
+static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct skl_pipe_wm *active = &intel_crtc->wm.skl_active;
+ enum pipe pipe = intel_crtc->pipe;
+ int level, i, max_level;
+ uint32_t temp;
+
+ max_level = ilk_wm_max_level(dev);
+
+ hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
+
+ for (level = 0; level <= max_level; level++) {
+ for (i = 0; i < intel_num_planes(intel_crtc); i++)
+ hw->plane[pipe][i][level] =
+ I915_READ(PLANE_WM(pipe, i, level));
+ hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level));
+ }
+
+ for (i = 0; i < intel_num_planes(intel_crtc); i++)
+ hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i));
+ hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe));
+
+ if (!intel_crtc_active(crtc))
+ return;
+
+ hw->dirty[pipe] = true;
+
+ active->linetime = hw->wm_linetime[pipe];
+
+ for (level = 0; level <= max_level; level++) {
+ for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+ temp = hw->plane[pipe][i][level];
+ skl_pipe_wm_active_state(temp, active, false,
+ false, i, level);
+ }
+ temp = hw->cursor[pipe][level];
+ skl_pipe_wm_active_state(temp, active, false, true, i, level);
+ }
+
+ for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+ temp = hw->plane_trans[pipe][i];
+ skl_pipe_wm_active_state(temp, active, true, false, i, 0);
+ }
+
+ temp = hw->cursor_trans[pipe];
+ skl_pipe_wm_active_state(temp, active, true, true, i, 0);
+}
+
+void skl_wm_get_hw_state(struct drm_device *dev)
+{
+ struct drm_crtc *crtc;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ skl_pipe_wm_get_hw_state(crtc);
+}
+
static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 09/28] drm/i915/gen9: Add 2us read latency to WM level
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (7 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 08/28] drm/i915/skl: Read the pipe WM HW state Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 10/28] drm/i915/gen9: Disable WM if corresponding latency is 0 Damien Lespiau
` (19 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
From: Vandana Kannan <vandana.kannan@intel.com>
According to the updated Bspec, The mailbox response data is not currently
accounting for memory read latency. Add 2 microseconds to the result for
each level.
This patch adds 2us to latency of level 0 for all cases and
for all other levels (1-7) only if latency[level] > 0.
v2: Slightly rework the patch and add a big comment (Damien)
v3: Rebase on top of the renames of the memory latency defines
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> (v1)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> (v2)
Reviewed-by: M, Satheeshakrishna <satheeshakrishna.m@intel.com> (v1)
Cc: Lespiau, Damien <damien.lespiau@intel.com>
Cc: M, Satheeshakrishna <satheeshakrishna.m@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 09a81b3..44fecfc 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2286,6 +2286,7 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
if (IS_GEN9(dev)) {
uint32_t val;
int ret;
+ int level, max_level = ilk_wm_max_level(dev);
/* read the first set of memory latencies[0:3] */
val = 0; /* data0 to be programmed to 0 for first set */
@@ -2328,6 +2329,21 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
GEN9_MEM_LATENCY_LEVEL_MASK;
+ /*
+ * punit doesn't take into account the read latency so we need
+ * to add 2us to the various latency levels we retrieve from
+ * the punit.
+ * - W0 is a bit special in that it's the only level that
+ * can't be disabled if we want to have display working, so
+ * we always add 2us there.
+ * - For levels >=1, punit returns 0us latency when they are
+ * disabled, so we respect that and don't add 2us then
+ */
+ wm[0] += 2;
+ for (level = 1; level <= max_level; level++)
+ if (wm[level] != 0)
+ wm[level] += 2;
+
} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
uint64_t sskpd = I915_READ64(MCH_SSKPD);
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 10/28] drm/i915/gen9: Disable WM if corresponding latency is 0
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (8 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 09/28] drm/i915/gen9: Add 2us read latency to WM level Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 11/28] drm/i915/skl: Store the new WM state at the very end of the update Damien Lespiau
` (18 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
From: Vandana Kannan <vandana.kannan@intel.com>
According to updated BSpec, If level 1 or any higher level has a value of 0x00,
that level and any higher levels are unused and the associated watermark
registers must not be enabled.
This patch checks for latency 0 for level >=1 and does not enable WM
corresponding to level m | m>=n, if level n (n != 0) has a 0us latency.
v2: Satheesh's review comments
- zero-out latency values (for all higher levels if latency of given
level is zero ) in read_wm_latency() function itself
v3: removed redundant check as per Satheesh's observation.
v4: rebase on top before merging (Damien)
v5: Rebase on top of the default value removal (Ville)
Reviewed-by: Satheeshakrishna M <satheeshakrishna.m@intel.com> (v3)
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 44fecfc..bf2cd65 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2285,7 +2285,7 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
if (IS_GEN9(dev)) {
uint32_t val;
- int ret;
+ int ret, i;
int level, max_level = ilk_wm_max_level(dev);
/* read the first set of memory latencies[0:3] */
@@ -2338,12 +2338,22 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
* we always add 2us there.
* - For levels >=1, punit returns 0us latency when they are
* disabled, so we respect that and don't add 2us then
+ *
+ * Additionally, if a level n (n > 1) has a 0us latency, all
+ * levels m (m >= n) need to be disabled. We make sure to
+ * sanitize the values out of the punit to satisfy this
+ * requirement.
*/
wm[0] += 2;
for (level = 1; level <= max_level; level++)
if (wm[level] != 0)
wm[level] += 2;
+ else {
+ for (i = level + 1; i <= max_level; i++)
+ wm[i] = 0;
+ break;
+ }
} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
uint64_t sskpd = I915_READ64(MCH_SSKPD);
@@ -3285,7 +3295,7 @@ static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
uint32_t method1, method2, plane_bytes_per_line;
uint32_t result_bytes;
- if (!p->active || !p_params->enabled)
+ if (mem_value == 0 || !p->active || !p_params->enabled)
return false;
method1 = skl_wm_method1(p->pixel_rate,
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 11/28] drm/i915/skl: Store the new WM state at the very end of the update
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (9 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 10/28] drm/i915/gen9: Disable WM if corresponding latency is 0 Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 12/28] drm/i915/skl: Read back the DDB allocation hw state Damien Lespiau
` (17 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
We're going to add a new step, let's not hide the copy of the new WM
state inside one inner function, but as a 1st level operation in the WM
update.
v2: Split the staging results structure to not exceed the 1Kb stack
allocation in skl_update_wm()
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index bf2cd65..a4294b1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3463,8 +3463,6 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
new->ddb.cursor[pipe].start);
}
}
-
- dev_priv->wm.skl_hw = *new;
}
static bool skl_update_pipe_wm(struct drm_crtc *crtc,
@@ -3558,6 +3556,9 @@ static void skl_update_wm(struct drm_crtc *crtc)
skl_update_other_pipe_wm(dev, crtc, &config, results);
skl_write_wm_values(dev_priv, results);
+
+ /* store the new configuration */
+ dev_priv->wm.skl_hw = *results;
}
static void
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 12/28] drm/i915/skl: Read back the DDB allocation hw state
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (10 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 11/28] drm/i915/skl: Store the new WM state at the very end of the update Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 13/28] drm/i915/skl: Augment the latency debugfs files for SKL Damien Lespiau
` (16 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
This logically belongs to the WM state, so do it there.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a4294b1..8b7abc7 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3051,6 +3051,32 @@ static unsigned int skl_cursor_allocation(const struct intel_wm_config *config)
return 8;
}
+static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
+{
+ entry->start = reg & 0x3ff;
+ entry->end = (reg >> 16) & 0x3ff;
+}
+
+static void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+ struct skl_ddb_allocation *ddb /* out */)
+{
+ struct drm_device *dev = dev_priv->dev;
+ enum pipe pipe;
+ int plane;
+ u32 val;
+
+ for_each_pipe(dev_priv, pipe) {
+ for_each_plane(pipe, plane) {
+ val = I915_READ(PLANE_BUF_CFG(pipe, plane));
+ skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane],
+ val);
+ }
+
+ val = I915_READ(CUR_BUF_CFG(pipe));
+ skl_ddb_entry_init_from_hw(&ddb->cursor[pipe], val);
+ }
+}
+
static unsigned int
skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p)
{
@@ -3749,8 +3775,11 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
void skl_wm_get_hw_state(struct drm_device *dev)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb;
struct drm_crtc *crtc;
+ skl_ddb_get_hw_state(dev_priv, ddb);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
skl_pipe_wm_get_hw_state(crtc);
}
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 13/28] drm/i915/skl: Augment the latency debugfs files for SKL
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (11 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 12/28] drm/i915/skl: Read back the DDB allocation hw state Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 14/28] drm/i915/skl: Add a debugfs file to dump the DDB allocation Damien Lespiau
` (15 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
v2: Use the gen >= 9 in the debugfs file condition (Ville)
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 76 ++++++++++++++++++++++++++++++-------
1 file changed, 62 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 0a69813..b1cbfbf 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3523,7 +3523,7 @@ static const struct file_operations i915_display_crc_ctl_fops = {
.write = display_crc_ctl_write
};
-static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
+static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
{
struct drm_device *dev = m->private;
int num_levels = ilk_wm_max_level(dev) + 1;
@@ -3534,13 +3534,17 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
for (level = 0; level < num_levels; level++) {
unsigned int latency = wm[level];
- /* WM1+ latency values in 0.5us units */
- if (level > 0)
+ /*
+ * - WM1+ latency values in 0.5us units
+ * - latencies are in us on gen9
+ */
+ if (INTEL_INFO(dev)->gen >= 9)
+ latency *= 10;
+ else if (level > 0)
latency *= 5;
seq_printf(m, "WM%d %u (%u.%u usec)\n",
- level, wm[level],
- latency / 10, latency % 10);
+ level, wm[level], latency / 10, latency % 10);
}
drm_modeset_unlock_all(dev);
@@ -3549,8 +3553,15 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
static int pri_wm_latency_show(struct seq_file *m, void *data)
{
struct drm_device *dev = m->private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const uint16_t *latencies;
+
+ if (INTEL_INFO(dev)->gen >= 9)
+ latencies = dev_priv->wm.skl_latency;
+ else
+ latencies = to_i915(dev)->wm.pri_latency;
- wm_latency_show(m, to_i915(dev)->wm.pri_latency);
+ wm_latency_show(m, latencies);
return 0;
}
@@ -3558,8 +3569,15 @@ static int pri_wm_latency_show(struct seq_file *m, void *data)
static int spr_wm_latency_show(struct seq_file *m, void *data)
{
struct drm_device *dev = m->private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const uint16_t *latencies;
+
+ if (INTEL_INFO(dev)->gen >= 9)
+ latencies = dev_priv->wm.skl_latency;
+ else
+ latencies = to_i915(dev)->wm.spr_latency;
- wm_latency_show(m, to_i915(dev)->wm.spr_latency);
+ wm_latency_show(m, latencies);
return 0;
}
@@ -3567,8 +3585,15 @@ static int spr_wm_latency_show(struct seq_file *m, void *data)
static int cur_wm_latency_show(struct seq_file *m, void *data)
{
struct drm_device *dev = m->private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const uint16_t *latencies;
+
+ if (INTEL_INFO(dev)->gen >= 9)
+ latencies = dev_priv->wm.skl_latency;
+ else
+ latencies = to_i915(dev)->wm.cur_latency;
- wm_latency_show(m, to_i915(dev)->wm.cur_latency);
+ wm_latency_show(m, latencies);
return 0;
}
@@ -3604,11 +3629,11 @@ static int cur_wm_latency_open(struct inode *inode, struct file *file)
}
static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
- size_t len, loff_t *offp, uint16_t wm[5])
+ size_t len, loff_t *offp, uint16_t wm[8])
{
struct seq_file *m = file->private_data;
struct drm_device *dev = m->private;
- uint16_t new[5] = { 0 };
+ uint16_t new[8] = { 0 };
int num_levels = ilk_wm_max_level(dev) + 1;
int level;
int ret;
@@ -3622,7 +3647,9 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
tmp[len] = '\0';
- ret = sscanf(tmp, "%hu %hu %hu %hu %hu", &new[0], &new[1], &new[2], &new[3], &new[4]);
+ ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu",
+ &new[0], &new[1], &new[2], &new[3],
+ &new[4], &new[5], &new[6], &new[7]);
if (ret != num_levels)
return -EINVAL;
@@ -3642,8 +3669,15 @@ static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
{
struct seq_file *m = file->private_data;
struct drm_device *dev = m->private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint16_t *latencies;
- return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.pri_latency);
+ if (INTEL_INFO(dev)->gen >= 9)
+ latencies = dev_priv->wm.skl_latency;
+ else
+ latencies = to_i915(dev)->wm.pri_latency;
+
+ return wm_latency_write(file, ubuf, len, offp, latencies);
}
static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
@@ -3651,8 +3685,15 @@ static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
{
struct seq_file *m = file->private_data;
struct drm_device *dev = m->private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint16_t *latencies;
- return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.spr_latency);
+ if (INTEL_INFO(dev)->gen >= 9)
+ latencies = dev_priv->wm.skl_latency;
+ else
+ latencies = to_i915(dev)->wm.spr_latency;
+
+ return wm_latency_write(file, ubuf, len, offp, latencies);
}
static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
@@ -3660,8 +3701,15 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
{
struct seq_file *m = file->private_data;
struct drm_device *dev = m->private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint16_t *latencies;
+
+ if (INTEL_INFO(dev)->gen >= 9)
+ latencies = dev_priv->wm.skl_latency;
+ else
+ latencies = to_i915(dev)->wm.cur_latency;
- return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.cur_latency);
+ return wm_latency_write(file, ubuf, len, offp, latencies);
}
static const struct file_operations i915_pri_wm_latency_fops = {
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 14/28] drm/i915/skl: Add a debugfs file to dump the DDB allocation
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (12 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 13/28] drm/i915/skl: Augment the latency debugfs files for SKL Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 15/28] drm/i915/skl: Check the DDB state at modeset Damien Lespiau
` (14 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
v2: minor conflict in i915_debugfs.c
v3: Rebase on top of the for_each_pipe() change adding dev_priv as first
argument.
v4: minor conflict in the i915_debugfs_files array
v5: minor conflict in the i915_debugfs_files array
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index b1cbfbf..319da61 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2679,6 +2679,42 @@ static int i915_wa_registers(struct seq_file *m, void *unused)
return 0;
}
+static int i915_ddb_info(struct seq_file *m, void *unused)
+{
+ struct drm_info_node *node = m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct skl_ddb_allocation *ddb;
+ struct skl_ddb_entry *entry;
+ enum pipe pipe;
+ int plane;
+
+ drm_modeset_lock_all(dev);
+
+ ddb = &dev_priv->wm.skl_hw.ddb;
+
+ seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
+
+ for_each_pipe(dev_priv, pipe) {
+ seq_printf(m, "Pipe %c\n", pipe_name(pipe));
+
+ for_each_plane(pipe, plane) {
+ entry = &ddb->plane[pipe][plane];
+ seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane + 1,
+ entry->start, entry->end,
+ skl_ddb_entry_size(entry));
+ }
+
+ entry = &ddb->cursor[pipe];
+ seq_printf(m, " %-13s%8u%8u%8u\n", "Cursor", entry->start,
+ entry->end, skl_ddb_entry_size(entry));
+ }
+
+ drm_modeset_unlock_all(dev);
+
+ return 0;
+}
+
struct pipe_crc_info {
const char *name;
struct drm_device *dev;
@@ -4252,6 +4288,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_shared_dplls_info", i915_shared_dplls_info, 0},
{"i915_dp_mst_info", i915_dp_mst_info, 0},
{"i915_wa_registers", i915_wa_registers, 0},
+ {"i915_ddb_info", i915_ddb_info, 0},
};
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 15/28] drm/i915/skl: Check the DDB state at modeset
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (13 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 14/28] drm/i915/skl: Add a debugfs file to dump the DDB allocation Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-05 10:33 ` Daniel Vetter
2014-11-04 17:06 ` [PATCH 16/28] drm/i915/skl: Make 'end' of the DDB allocation entry exclusive Damien Lespiau
` (13 subsequent siblings)
28 siblings, 1 reply; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
v2: Don't check DDB on pre-SKL platforms
Don't check DDB state on disabled pipes
v3: Squash "Expose skl_ddb_get_hw_state()"
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 9 +++++++
drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_drv.h | 2 ++
drivers/gpu/drm/i915/intel_pm.c | 4 +--
4 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fbe18ae..ee744a2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1400,6 +1400,15 @@ static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
return entry->end - entry->start + 1;
}
+static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
+ const struct skl_ddb_entry *e2)
+{
+ if (e1->start == e2->start && e1->end == e2->end)
+ return true;
+
+ return false;
+}
+
struct skl_ddb_allocation {
struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
struct skl_ddb_entry cursor[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ecba620..9ec1ab7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10509,6 +10509,56 @@ intel_pipe_config_compare(struct drm_device *dev,
return true;
}
+static void check_wm_state(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct skl_ddb_allocation hw_ddb, *sw_ddb;
+ struct intel_crtc *intel_crtc;
+ int plane;
+
+ if (INTEL_INFO(dev)->gen < 9)
+ return;
+
+ skl_ddb_get_hw_state(dev_priv, &hw_ddb);
+ sw_ddb = &dev_priv->wm.skl_hw.ddb;
+
+ for_each_intel_crtc(dev, intel_crtc) {
+ struct skl_ddb_entry *hw_entry, *sw_entry;
+ const enum pipe pipe = intel_crtc->pipe;
+
+ if (!intel_crtc->active)
+ continue;
+
+ /* planes */
+ for_each_plane(pipe, plane) {
+ hw_entry = &hw_ddb.plane[pipe][plane];
+ sw_entry = &sw_ddb->plane[pipe][plane];
+
+ if (skl_ddb_entry_equal(hw_entry, sw_entry))
+ continue;
+
+ DRM_ERROR("mismatch in DDB state pipe %c plane %d "
+ "(expected (%u,%u), found (%u,%u))\n",
+ pipe_name(pipe), plane + 1,
+ sw_entry->start, sw_entry->end,
+ hw_entry->start, hw_entry->end);
+ }
+
+ /* cursor */
+ hw_entry = &hw_ddb.cursor[pipe];
+ sw_entry = &sw_ddb->cursor[pipe];
+
+ if (skl_ddb_entry_equal(hw_entry, sw_entry))
+ continue;
+
+ DRM_ERROR("mismatch in DDB state pipe %c cursor "
+ "(expected (%u,%u), found (%u,%u))\n",
+ pipe_name(pipe),
+ sw_entry->start, sw_entry->end,
+ hw_entry->start, hw_entry->end);
+ }
+}
+
static void
check_connector_state(struct drm_device *dev)
{
@@ -10708,6 +10758,7 @@ check_shared_dpll_state(struct drm_device *dev)
void
intel_modeset_check_state(struct drm_device *dev)
{
+ check_wm_state(dev);
check_connector_state(dev);
check_encoder_state(dev);
check_crtc_state(dev);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1cdd6f9..cb0e9db 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1165,6 +1165,8 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv);
void gen6_rps_boost(struct drm_i915_private *dev_priv);
void ilk_wm_get_hw_state(struct drm_device *dev);
void skl_wm_get_hw_state(struct drm_device *dev);
+void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+ struct skl_ddb_allocation *ddb /* out */);
/* intel_sdvo.c */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8b7abc7..159c2e0 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3057,8 +3057,8 @@ static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
entry->end = (reg >> 16) & 0x3ff;
}
-static void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
- struct skl_ddb_allocation *ddb /* out */)
+void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+ struct skl_ddb_allocation *ddb /* out */)
{
struct drm_device *dev = dev_priv->dev;
enum pipe pipe;
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* Re: [PATCH 15/28] drm/i915/skl: Check the DDB state at modeset
2014-11-04 17:06 ` [PATCH 15/28] drm/i915/skl: Check the DDB state at modeset Damien Lespiau
@ 2014-11-05 10:33 ` Daniel Vetter
0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2014-11-05 10:33 UTC (permalink / raw)
To: Damien Lespiau; +Cc: intel-gfx
On Tue, Nov 04, 2014 at 05:06:52PM +0000, Damien Lespiau wrote:
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index ecba620..9ec1ab7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10509,6 +10509,56 @@ intel_pipe_config_compare(struct drm_device *dev,
> return true;
> }
>
> +static void check_wm_state(struct drm_device *dev)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct skl_ddb_allocation hw_ddb, *sw_ddb;
> + struct intel_crtc *intel_crtc;
> + int plane;
> +
> + if (INTEL_INFO(dev)->gen < 9)
> + return;
> +
> + skl_ddb_get_hw_state(dev_priv, &hw_ddb);
> + sw_ddb = &dev_priv->wm.skl_hw.ddb;
This looks like a pretty nifty layering violation, with exposing the skl
function and all. I guess the long-term plan is to have just one wm
structure for everyone, as part of the plane state? And then we'll just
read out the plane state and cross-check that one?
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 16/28] drm/i915/skl: Make 'end' of the DDB allocation entry exclusive
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (14 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 15/28] drm/i915/skl: Check the DDB state at modeset Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 17/28] drm/i915/skl: Use a more descriptive parameter name in skl_compute_plane_wm() Damien Lespiau
` (12 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
Ville suggested that we should use the same semantics as C arrays to
reduce the number of those pesky +1/-1 in the allocation code.
This patch leaves the debugfs file as is, showing the internal DDB
allocation structure, not the values written in the registers.
v2: Remove the test on ->end in skl_ddb_entry_size() (Ville)
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 8 ++------
drivers/gpu/drm/i915/intel_pm.c | 28 +++++++++++++++++++---------
2 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ee744a2..84e8cdb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1388,16 +1388,12 @@ struct ilk_wm_values {
};
struct skl_ddb_entry {
- uint16_t start, end; /* in number of blocks */
+ uint16_t start, end; /* in number of blocks, 'end' is exclusive */
};
static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
{
- /* end not set, clearly no allocation here. start can be 0 though */
- if (entry->end == 0)
- return 0;
-
- return entry->end - entry->start + 1;
+ return entry->end - entry->start;
}
static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 159c2e0..e417a6a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3040,7 +3040,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
pipe_size = ddb_size / config->num_pipes_active;
alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active;
- alloc->end = alloc->start + pipe_size - 1;
+ alloc->end = alloc->start + pipe_size;
}
static unsigned int skl_cursor_allocation(const struct intel_wm_config *config)
@@ -3055,6 +3055,8 @@ static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg)
{
entry->start = reg & 0x3ff;
entry->end = (reg >> 16) & 0x3ff;
+ if (entry->end)
+ entry->end += 1;
}
void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
@@ -3131,7 +3133,7 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
}
cursor_blocks = skl_cursor_allocation(config);
- ddb->cursor[pipe].start = alloc.end - cursor_blocks + 1;
+ ddb->cursor[pipe].start = alloc.end - cursor_blocks;
ddb->cursor[pipe].end = alloc.end;
alloc_size -= cursor_blocks;
@@ -3165,7 +3167,7 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
total_data_rate);
ddb->plane[pipe][plane].start = start;
- ddb->plane[pipe][plane].end = start + plane_blocks - 1;
+ ddb->plane[pipe][plane].end = start + plane_blocks;
start += plane_blocks;
}
@@ -3453,6 +3455,15 @@ static void skl_compute_wm_results(struct drm_device *dev,
r->wm_linetime[pipe] = p_wm->linetime;
}
+static void skl_ddb_entry_write(struct drm_i915_private *dev_priv, uint32_t reg,
+ const struct skl_ddb_entry *entry)
+{
+ if (entry->end)
+ I915_WRITE(reg, (entry->end - 1) << 16 | entry->start);
+ else
+ I915_WRITE(reg, 0);
+}
+
static void skl_write_wm_values(struct drm_i915_private *dev_priv,
const struct skl_wm_values *new)
{
@@ -3480,13 +3491,12 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
for (i = 0; i < intel_num_planes(crtc); i++)
- I915_WRITE(PLANE_BUF_CFG(pipe, i),
- new->ddb.plane[pipe][i].end << 16 |
- new->ddb.plane[pipe][i].start);
+ skl_ddb_entry_write(dev_priv,
+ PLANE_BUF_CFG(pipe, i),
+ &new->ddb.plane[pipe][i]);
- I915_WRITE(CUR_BUF_CFG(pipe),
- new->ddb.cursor[pipe].end << 16 |
- new->ddb.cursor[pipe].start);
+ skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
+ &new->ddb.cursor[pipe]);
}
}
}
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 17/28] drm/i915/skl: Use a more descriptive parameter name in skl_compute_plane_wm()
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (15 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 16/28] drm/i915/skl: Make 'end' of the DDB allocation entry exclusive Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 18/28] drm/i915/skl: Make res_blocks/lines intermediate values 32 bits Damien Lespiau
` (11 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
What we're talking about here is the DDB allocation (in blocks). That's
more descriptive than 'max_page_buff_alloc'.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index e417a6a..0142ad1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3315,7 +3315,7 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
struct intel_plane_wm_parameters *p_params,
- uint16_t max_page_buff_alloc,
+ uint16_t ddb_allocation,
uint32_t mem_value,
uint16_t *res_blocks, /* out */
uint8_t *res_lines /* out */)
@@ -3339,7 +3339,7 @@ static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
p_params->bytes_per_pixel;
/* For now xtile and linear */
- if (((max_page_buff_alloc * 512) / plane_bytes_per_line) >= 1)
+ if (((ddb_allocation * 512) / plane_bytes_per_line) >= 1)
result_bytes = min(method1, method2);
else
result_bytes = method1;
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 18/28] drm/i915/skl: Make res_blocks/lines intermediate values 32 bits
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (16 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 17/28] drm/i915/skl: Use a more descriptive parameter name in skl_compute_plane_wm() Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 19/28] drm/i915/skl: Reduce the number of holes in struct skl_wm_level Damien Lespiau
` (10 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
To align with the ilk WM code and because it makes sense to test against
the upper bounds as soon as possible on variables that are bigger than
the number of bits in the register, let's move the maximum checks from
skl_compute_wm_results() to skl_compute_plane_wm().
v2: Leave the result values to 0 when overflowing the limits (Ville)
Use 32 bits intermediate variables (Damien)
Instead of using the 16 and 8 bits space we have in the result
structure, use 32 bits local variables until we're sure they fit into
the constraints.
Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 27 +++++++++++----------------
1 file changed, 11 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0142ad1..8580298 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3317,10 +3317,10 @@ static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
struct intel_plane_wm_parameters *p_params,
uint16_t ddb_allocation,
uint32_t mem_value,
- uint16_t *res_blocks, /* out */
- uint8_t *res_lines /* out */)
+ uint16_t *out_blocks, /* out */
+ uint8_t *out_lines /* out */)
{
- uint32_t method1, method2, plane_bytes_per_line;
+ uint32_t method1, method2, plane_bytes_per_line, res_blocks, res_lines;
uint32_t result_bytes;
if (mem_value == 0 || !p->active || !p_params->enabled)
@@ -3344,8 +3344,14 @@ static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
else
result_bytes = method1;
- *res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1;
- *res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line);
+ res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1;
+ res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line);
+
+ if (res_blocks > ddb_allocation || res_lines > 31)
+ return false;
+
+ *out_blocks = res_blocks;
+ *out_lines = res_lines;
return true;
}
@@ -3408,17 +3414,11 @@ static void skl_compute_wm_results(struct drm_device *dev,
enum pipe pipe = intel_crtc->pipe;
for (level = 0; level <= max_level; level++) {
- uint16_t ddb_blocks;
uint32_t temp;
int i;
for (i = 0; i < intel_num_planes(intel_crtc); i++) {
temp = 0;
- ddb_blocks = skl_ddb_entry_size(&r->ddb.plane[pipe][i]);
-
- if ((p_wm->wm[level].plane_res_b[i] > ddb_blocks) ||
- (p_wm->wm[level].plane_res_l[i] > 31))
- p_wm->wm[level].plane_en[i] = false;
temp |= p_wm->wm[level].plane_res_l[i] <<
PLANE_WM_LINES_SHIFT;
@@ -3433,11 +3433,6 @@ static void skl_compute_wm_results(struct drm_device *dev,
}
temp = 0;
- ddb_blocks = skl_ddb_entry_size(&r->ddb.cursor[pipe]);
-
- if ((p_wm->wm[level].cursor_res_b > ddb_blocks) ||
- (p_wm->wm[level].cursor_res_l > 31))
- p_wm->wm[level].cursor_en = false;
temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT;
temp |= p_wm->wm[level].cursor_res_b;
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 19/28] drm/i915/skl: Reduce the number of holes in struct skl_wm_level
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (17 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 18/28] drm/i915/skl: Make res_blocks/lines intermediate values 32 bits Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 20/28] drm/i915/skl: Move all the WM compute functions in one place Damien Lespiau
` (9 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 84e8cdb..cf84b6d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1422,9 +1422,9 @@ struct skl_wm_values {
struct skl_wm_level {
bool plane_en[I915_MAX_PLANES];
+ bool cursor_en;
uint16_t plane_res_b[I915_MAX_PLANES];
uint8_t plane_res_l[I915_MAX_PLANES];
- bool cursor_en;
uint16_t cursor_res_b;
uint8_t cursor_res_l;
};
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 20/28] drm/i915/skl: Move all the WM compute functions in one place
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (18 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 19/28] drm/i915/skl: Reduce the number of holes in struct skl_wm_level Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 21/28] drm/i915/skl: Rework when the transition WMs are computed Damien Lespiau
` (8 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
The DDB allocation code managed to split in two the compute functions.
Bring back skl_compute_transition_wm() and skl_compute_linetime_wm()
with their little friends.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 44 ++++++++++++++++++++---------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8580298..66f142b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3217,28 +3217,6 @@ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
return ret;
}
-static void skl_compute_transition_wm(struct drm_crtc *crtc,
- struct skl_pipe_wm_parameters *params,
- struct skl_pipe_wm *pipe_wm)
-{
- /*
- * For now it is suggested to use the LP0 wm val of corresponding
- * plane as transition wm val. This is done while computing results.
- */
- if (!params->active)
- return;
-}
-
-static uint32_t
-skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
-{
- if (!intel_crtc_active(crtc))
- return 0;
-
- return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
-
-}
-
static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
const struct intel_crtc *intel_crtc)
{
@@ -3384,6 +3362,28 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
&result->cursor_res_l);
}
+static uint32_t
+skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
+{
+ if (!intel_crtc_active(crtc))
+ return 0;
+
+ return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
+
+}
+
+static void skl_compute_transition_wm(struct drm_crtc *crtc,
+ struct skl_pipe_wm_parameters *params,
+ struct skl_pipe_wm *pipe_wm)
+{
+ /*
+ * For now it is suggested to use the LP0 wm val of corresponding
+ * plane as transition wm val.
+ */
+ if (!params->active)
+ return;
+}
+
static void skl_compute_pipe_wm(struct drm_crtc *crtc,
struct skl_ddb_allocation *ddb,
struct skl_pipe_wm_parameters *params,
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 21/28] drm/i915/skl: Rework when the transition WMs are computed
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (19 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 20/28] drm/i915/skl: Move all the WM compute functions in one place Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:06 ` [PATCH 22/28] drm/i915/skl: Correctly align skl_compute_plane_wm() arguments Damien Lespiau
` (7 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
The transition WMs code was doing a shortcut and the values were copied
from the WM0 ones at compute_wm_results() time. Going forward, we want
to compute them like the other WMs and resolve their final register
values in the same way as well.
This patch does just that and isolate the transtion WM compute code in
skl_compute_transition_wm() while skl_compute_wm_results() takes care of
the register values.
We also take the opportunity to disable the transition WMs for now.
We've noticed underruns and they seem to be the culprit.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 46 +++++++++++++++++++++++++++--------------
1 file changed, 31 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 66f142b..41cfb26 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3374,14 +3374,18 @@ skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
static void skl_compute_transition_wm(struct drm_crtc *crtc,
struct skl_pipe_wm_parameters *params,
- struct skl_pipe_wm *pipe_wm)
+ struct skl_wm_level *trans_wm /* out */)
{
- /*
- * For now it is suggested to use the LP0 wm val of corresponding
- * plane as transition wm val.
- */
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ int i;
+
if (!params->active)
return;
+
+ /* Until we know more, just disable transition WMs */
+ for (i = 0; i < intel_num_planes(intel_crtc); i++)
+ trans_wm->plane_en[i] = false;
+ trans_wm->cursor_en = false;
}
static void skl_compute_pipe_wm(struct drm_crtc *crtc,
@@ -3401,7 +3405,7 @@ static void skl_compute_pipe_wm(struct drm_crtc *crtc,
}
pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
- skl_compute_transition_wm(crtc, params, pipe_wm);
+ skl_compute_transition_wm(crtc, params, &pipe_wm->trans_wm);
}
static void skl_compute_wm_results(struct drm_device *dev,
@@ -3412,11 +3416,10 @@ static void skl_compute_wm_results(struct drm_device *dev,
{
int level, max_level = ilk_wm_max_level(dev);
enum pipe pipe = intel_crtc->pipe;
+ uint32_t temp;
+ int i;
for (level = 0; level <= max_level; level++) {
- uint32_t temp;
- int i;
-
for (i = 0; i < intel_num_planes(intel_crtc); i++) {
temp = 0;
@@ -3427,9 +3430,6 @@ static void skl_compute_wm_results(struct drm_device *dev,
temp |= PLANE_WM_EN;
r->plane[pipe][i][level] = temp;
- /* Use the LP0 WM value for transition WM for now. */
- if (level == 0)
- r->plane_trans[pipe][i] = temp;
}
temp = 0;
@@ -3441,12 +3441,28 @@ static void skl_compute_wm_results(struct drm_device *dev,
temp |= PLANE_WM_EN;
r->cursor[pipe][level] = temp;
- /* Use the LP0 WM value for transition WM for now. */
- if (level == 0)
- r->cursor_trans[pipe] = temp;
}
+ /* transition WMs */
+ for (i = 0; i < intel_num_planes(intel_crtc); i++) {
+ temp = 0;
+ temp |= p_wm->trans_wm.plane_res_l[i] << PLANE_WM_LINES_SHIFT;
+ temp |= p_wm->trans_wm.plane_res_b[i];
+ if (p_wm->trans_wm.plane_en[i])
+ temp |= PLANE_WM_EN;
+
+ r->plane_trans[pipe][i] = temp;
+ }
+
+ temp = 0;
+ temp |= p_wm->trans_wm.cursor_res_l << PLANE_WM_LINES_SHIFT;
+ temp |= p_wm->trans_wm.cursor_res_b;
+ if (p_wm->trans_wm.cursor_en)
+ temp |= PLANE_WM_EN;
+
+ r->cursor_trans[pipe] = temp;
+
r->wm_linetime[pipe] = p_wm->linetime;
}
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 22/28] drm/i915/skl: Correctly align skl_compute_plane_wm() arguments
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (20 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 21/28] drm/i915/skl: Rework when the transition WMs are computed Damien Lespiau
@ 2014-11-04 17:06 ` Damien Lespiau
2014-11-04 17:07 ` [PATCH 23/28] drm/i915/skl: Reduce the indentation level in skl_write_wm_values() Damien Lespiau
` (6 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:06 UTC (permalink / raw)
To: intel-gfx
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 41cfb26..176e9ef 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3292,11 +3292,11 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
}
static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
- struct intel_plane_wm_parameters *p_params,
- uint16_t ddb_allocation,
- uint32_t mem_value,
- uint16_t *out_blocks, /* out */
- uint8_t *out_lines /* out */)
+ struct intel_plane_wm_parameters *p_params,
+ uint16_t ddb_allocation,
+ uint32_t mem_value,
+ uint16_t *out_blocks, /* out */
+ uint8_t *out_lines /* out */)
{
uint32_t method1, method2, plane_bytes_per_line, res_blocks, res_lines;
uint32_t result_bytes;
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 23/28] drm/i915/skl: Reduce the indentation level in skl_write_wm_values()
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (21 preceding siblings ...)
2014-11-04 17:06 ` [PATCH 22/28] drm/i915/skl: Correctly align skl_compute_plane_wm() arguments Damien Lespiau
@ 2014-11-04 17:07 ` Damien Lespiau
2014-11-04 17:07 ` [PATCH 24/28] drm/i915/skl: Stage the pipe DDB allocation Damien Lespiau
` (5 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:07 UTC (permalink / raw)
To: intel-gfx
We can reduce the indentation level by continuing early.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 42 ++++++++++++++++++++---------------------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 176e9ef..7fdccba 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3485,30 +3485,30 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
int i, level, max_level = ilk_wm_max_level(dev);
enum pipe pipe = crtc->pipe;
- if (new->dirty[pipe]) {
- I915_WRITE(PIPE_WM_LINETIME(pipe),
- new->wm_linetime[pipe]);
-
- for (level = 0; level <= max_level; level++) {
- for (i = 0; i < intel_num_planes(crtc); i++)
- I915_WRITE(PLANE_WM(pipe, i, level),
- new->plane[pipe][i][level]);
- I915_WRITE(CUR_WM(pipe, level),
- new->cursor[pipe][level]);
- }
- for (i = 0; i < intel_num_planes(crtc); i++)
- I915_WRITE(PLANE_WM_TRANS(pipe, i),
- new->plane_trans[pipe][i]);
- I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
+ if (!new->dirty[pipe])
+ continue;
- for (i = 0; i < intel_num_planes(crtc); i++)
- skl_ddb_entry_write(dev_priv,
- PLANE_BUF_CFG(pipe, i),
- &new->ddb.plane[pipe][i]);
+ I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]);
- skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
- &new->ddb.cursor[pipe]);
+ for (level = 0; level <= max_level; level++) {
+ for (i = 0; i < intel_num_planes(crtc); i++)
+ I915_WRITE(PLANE_WM(pipe, i, level),
+ new->plane[pipe][i][level]);
+ I915_WRITE(CUR_WM(pipe, level),
+ new->cursor[pipe][level]);
}
+ for (i = 0; i < intel_num_planes(crtc); i++)
+ I915_WRITE(PLANE_WM_TRANS(pipe, i),
+ new->plane_trans[pipe][i]);
+ I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
+
+ for (i = 0; i < intel_num_planes(crtc); i++)
+ skl_ddb_entry_write(dev_priv,
+ PLANE_BUF_CFG(pipe, i),
+ &new->ddb.plane[pipe][i]);
+
+ skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
+ &new->ddb.cursor[pipe]);
}
}
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 24/28] drm/i915/skl: Stage the pipe DDB allocation
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (22 preceding siblings ...)
2014-11-04 17:07 ` [PATCH 23/28] drm/i915/skl: Reduce the indentation level in skl_write_wm_values() Damien Lespiau
@ 2014-11-04 17:07 ` Damien Lespiau
2014-11-04 17:07 ` [PATCH 25/28] drm/i915/skl: Flush the WM configuration Damien Lespiau
` (4 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:07 UTC (permalink / raw)
To: intel-gfx
To correctly flush the new DDB allocation we need to know about the pipe
allocation layout inside the DDB in order to sequence the re-allocation
to not cause a newly allocated pipe to fetch from a space that was
previously allocated to another pipe.
This patch preserves the per-pipe (start,end) allocation to be used in
the flush.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/intel_pm.c | 14 +++++++-------
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cf84b6d..01d741d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1406,6 +1406,7 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
}
struct skl_ddb_allocation {
+ struct skl_ddb_entry pipe[I915_MAX_PIPES];
struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
struct skl_ddb_entry cursor[I915_MAX_PIPES];
};
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7fdccba..cd2b335 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3119,13 +3119,13 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum pipe pipe = intel_crtc->pipe;
- struct skl_ddb_entry alloc;
+ struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
uint16_t alloc_size, start, cursor_blocks;
unsigned int total_data_rate;
int plane;
- skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, &alloc);
- alloc_size = skl_ddb_entry_size(&alloc);
+ skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc);
+ alloc_size = skl_ddb_entry_size(alloc);
if (alloc_size == 0) {
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe]));
@@ -3133,11 +3133,11 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
}
cursor_blocks = skl_cursor_allocation(config);
- ddb->cursor[pipe].start = alloc.end - cursor_blocks;
- ddb->cursor[pipe].end = alloc.end;
+ ddb->cursor[pipe].start = alloc->end - cursor_blocks;
+ ddb->cursor[pipe].end = alloc->end;
alloc_size -= cursor_blocks;
- alloc.end -= cursor_blocks;
+ alloc->end -= cursor_blocks;
/*
* Each active plane get a portion of the remaining space, in
@@ -3147,7 +3147,7 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
*/
total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
- start = alloc.start;
+ start = alloc->start;
for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
const struct intel_plane_wm_parameters *p;
unsigned int data_rate;
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 25/28] drm/i915/skl: Flush the WM configuration
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (23 preceding siblings ...)
2014-11-04 17:07 ` [PATCH 24/28] drm/i915/skl: Stage the pipe DDB allocation Damien Lespiau
@ 2014-11-04 17:07 ` Damien Lespiau
2014-11-04 17:07 ` [PATCH 26/28] drm/i915/skl: Log the order in which we flush the pipes in the WM code Damien Lespiau
` (3 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:07 UTC (permalink / raw)
To: intel-gfx
When we write new values for the DDB allocation and WM parameters, we now
need to trigger the double buffer update for the pipe to take the new
configuration into account.
As the DDB is a global resource shared between planes, enabling or
disabling one plane will result in changes for all planes that are
currently in use, thus the need write PLANE_SURF/CUR_BASE for more than
the plane we're touching.
v2: Don't wait for pipes that are off
v3: Split the staging results structure to not exceed the 1Kb stack
allocation in skl_update_wm()
v4: Rework and document the algorithm after Ville found that it was all
wrong.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 135 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 135 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index cd2b335..ec7b86b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3512,6 +3512,140 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
}
}
+/*
+ * When setting up a new DDB allocation arrangement, we need to correctly
+ * sequence the times at which the new allocations for the pipes are taken into
+ * account or we'll have pipes fetching from space previously allocated to
+ * another pipe.
+ *
+ * Roughly the sequence looks like:
+ * 1. re-allocate the pipe(s) with the allocation being reduced and not
+ * overlapping with a previous light-up pipe (another way to put it is:
+ * pipes with their new allocation strickly included into their old ones).
+ * 2. re-allocate the other pipes that get their allocation reduced
+ * 3. allocate the pipes having their allocation increased
+ *
+ * Steps 1. and 2. are here to take care of the following case:
+ * - Initially DDB looks like this:
+ * | B | C |
+ * - enable pipe A.
+ * - pipe B has a reduced DDB allocation that overlaps with the old pipe C
+ * allocation
+ * | A | B | C |
+ *
+ * We need to sequence the re-allocation: C, B, A (and not B, C, A).
+ */
+
+static void skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
+{
+ struct drm_device *dev = dev_priv->dev;
+ int plane;
+
+ for_each_plane(pipe, plane) {
+ I915_WRITE(PLANE_SURF(pipe, plane),
+ I915_READ(PLANE_SURF(pipe, plane)));
+ }
+ I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
+}
+
+static bool
+skl_ddb_allocation_included(const struct skl_ddb_allocation *old,
+ const struct skl_ddb_allocation *new,
+ enum pipe pipe)
+{
+ uint16_t old_size, new_size;
+
+ old_size = skl_ddb_entry_size(&old->pipe[pipe]);
+ new_size = skl_ddb_entry_size(&new->pipe[pipe]);
+
+ return old_size != new_size &&
+ new->pipe[pipe].start >= old->pipe[pipe].start &&
+ new->pipe[pipe].end <= old->pipe[pipe].end;
+}
+
+static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
+ struct skl_wm_values *new_values)
+{
+ struct drm_device *dev = dev_priv->dev;
+ struct skl_ddb_allocation *cur_ddb, *new_ddb;
+ bool reallocated[I915_MAX_PIPES] = {false, false, false};
+ struct intel_crtc *crtc;
+ enum pipe pipe;
+
+ new_ddb = &new_values->ddb;
+ cur_ddb = &dev_priv->wm.skl_hw.ddb;
+
+ /*
+ * First pass: flush the pipes with the new allocation contained into
+ * the old space.
+ *
+ * We'll wait for the vblank on those pipes to ensure we can safely
+ * re-allocate the freed space without this pipe fetching from it.
+ */
+ for_each_intel_crtc(dev, crtc) {
+ if (!crtc->active)
+ continue;
+
+ pipe = crtc->pipe;
+
+ if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe))
+ continue;
+
+ skl_wm_flush_pipe(dev_priv, pipe);
+ intel_wait_for_vblank(dev, pipe);
+
+ reallocated[pipe] = true;
+ }
+
+
+ /*
+ * Second pass: flush the pipes that are having their allocation
+ * reduced, but overlapping with a previous allocation.
+ *
+ * Here as well we need to wait for the vblank to make sure the freed
+ * space is not used anymore.
+ */
+ for_each_intel_crtc(dev, crtc) {
+ if (!crtc->active)
+ continue;
+
+ pipe = crtc->pipe;
+
+ if (reallocated[pipe])
+ continue;
+
+ if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) <
+ skl_ddb_entry_size(&cur_ddb->pipe[pipe])) {
+ skl_wm_flush_pipe(dev_priv, pipe);
+ intel_wait_for_vblank(dev, pipe);
+ }
+
+ reallocated[pipe] = true;
+ }
+
+ /*
+ * Third pass: flush the pipes that got more space allocated.
+ *
+ * We don't need to actively wait for the update here, next vblank
+ * will just get more DDB space with the correct WM values.
+ */
+ for_each_intel_crtc(dev, crtc) {
+ if (!crtc->active)
+ continue;
+
+ pipe = crtc->pipe;
+
+ /*
+ * At this point, only the pipes more space than before are
+ * left to re-allocate.
+ */
+ if (reallocated[pipe])
+ continue;
+
+ skl_wm_flush_pipe(dev_priv, pipe);
+ }
+}
+
static bool skl_update_pipe_wm(struct drm_crtc *crtc,
struct skl_pipe_wm_parameters *params,
struct intel_wm_config *config,
@@ -3603,6 +3737,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
skl_update_other_pipe_wm(dev, crtc, &config, results);
skl_write_wm_values(dev_priv, results);
+ skl_flush_wm_values(dev_priv, results);
/* store the new configuration */
dev_priv->wm.skl_hw = *results;
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 26/28] drm/i915/skl: Log the order in which we flush the pipes in the WM code
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (24 preceding siblings ...)
2014-11-04 17:07 ` [PATCH 25/28] drm/i915/skl: Flush the WM configuration Damien Lespiau
@ 2014-11-04 17:07 ` Damien Lespiau
2014-11-04 17:07 ` [PATCH 27/28] drm/i915/skl: Gen9 Forcewake Damien Lespiau
` (2 subsequent siblings)
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:07 UTC (permalink / raw)
To: intel-gfx
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ec7b86b..d0dbd65 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3536,11 +3536,14 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
* We need to sequence the re-allocation: C, B, A (and not B, C, A).
*/
-static void skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
+static void
+skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass)
{
struct drm_device *dev = dev_priv->dev;
int plane;
+ DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass);
+
for_each_plane(pipe, plane) {
I915_WRITE(PLANE_SURF(pipe, plane),
I915_READ(PLANE_SURF(pipe, plane)));
@@ -3591,7 +3594,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe))
continue;
- skl_wm_flush_pipe(dev_priv, pipe);
+ skl_wm_flush_pipe(dev_priv, pipe, 1);
intel_wait_for_vblank(dev, pipe);
reallocated[pipe] = true;
@@ -3616,7 +3619,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) <
skl_ddb_entry_size(&cur_ddb->pipe[pipe])) {
- skl_wm_flush_pipe(dev_priv, pipe);
+ skl_wm_flush_pipe(dev_priv, pipe, 2);
intel_wait_for_vblank(dev, pipe);
}
@@ -3642,7 +3645,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
if (reallocated[pipe])
continue;
- skl_wm_flush_pipe(dev_priv, pipe);
+ skl_wm_flush_pipe(dev_priv, pipe, 3);
}
}
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 27/28] drm/i915/skl: Gen9 Forcewake
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (25 preceding siblings ...)
2014-11-04 17:07 ` [PATCH 26/28] drm/i915/skl: Log the order in which we flush the pipes in the WM code Damien Lespiau
@ 2014-11-04 17:07 ` Damien Lespiau
2014-11-04 17:07 ` [PATCH 28/28] drm/i915/skl: Enable Gen9 RC6 Damien Lespiau
2014-11-05 11:28 ` [PATCH 00/28] SKL stage 1, a few more patches Daniel Vetter
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:07 UTC (permalink / raw)
To: intel-gfx
From: Zhe Wang <zhe1.wang@intel.com>
Implement common forcewake functions shared by Gen9 features.
v2: Make the focewake_{get,put} functions static (Mika)
Small coding style fix in the function definition (Damien)
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: Zhe Wang <zhe1.wang@intel.com> (v1)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v2)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 5 +-
drivers/gpu/drm/i915/i915_reg.h | 6 ++
drivers/gpu/drm/i915/intel_uncore.c | 175 +++++++++++++++++++++++++++++++++++-
3 files changed, 184 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 01d741d..0f00e58 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -549,6 +549,7 @@ struct intel_uncore {
unsigned fw_rendercount;
unsigned fw_mediacount;
+ unsigned fw_blittercount;
struct timer_list force_wake_timer;
};
@@ -2979,7 +2980,9 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
#define FORCEWAKE_RENDER (1 << 0)
#define FORCEWAKE_MEDIA (1 << 1)
-#define FORCEWAKE_ALL (FORCEWAKE_RENDER | FORCEWAKE_MEDIA)
+#define FORCEWAKE_BLITTER (1 << 2)
+#define FORCEWAKE_ALL (FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
+ FORCEWAKE_BLITTER)
#define I915_READ8(reg) dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7fea33d..15f227b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5833,6 +5833,12 @@ enum punit_power_well {
#define VLV_GTLC_PW_MEDIA_STATUS_MASK (1 << 5)
#define VLV_GTLC_PW_RENDER_STATUS_MASK (1 << 7)
#define FORCEWAKE_MT 0xa188 /* multi-threaded */
+#define FORCEWAKE_MEDIA_GEN9 0xa270
+#define FORCEWAKE_RENDER_GEN9 0xa278
+#define FORCEWAKE_BLITTER_GEN9 0xa188
+#define FORCEWAKE_ACK_MEDIA_GEN9 0x0D88
+#define FORCEWAKE_ACK_RENDER_GEN9 0x0D84
+#define FORCEWAKE_ACK_BLITTER_GEN9 0x130044
#define FORCEWAKE_KERNEL 0x1
#define FORCEWAKE_USER 0x2
#define FORCEWAKE_MT_ACK 0x130040
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 9427641..68e722b 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -296,6 +296,154 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
+static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
+{
+ __raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
+ _MASKED_BIT_DISABLE(0xffff));
+
+ __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
+ _MASKED_BIT_DISABLE(0xffff));
+
+ __raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
+ _MASKED_BIT_DISABLE(0xffff));
+}
+
+static void
+__gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
+{
+ /* Check for Render Engine */
+ if (FORCEWAKE_RENDER & fw_engine) {
+ if (wait_for_atomic((__raw_i915_read32(dev_priv,
+ FORCEWAKE_ACK_RENDER_GEN9) &
+ FORCEWAKE_KERNEL) == 0,
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
+
+ __raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
+ _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+
+ if (wait_for_atomic((__raw_i915_read32(dev_priv,
+ FORCEWAKE_ACK_RENDER_GEN9) &
+ FORCEWAKE_KERNEL),
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out: waiting for Render to ack.\n");
+ }
+
+ /* Check for Media Engine */
+ if (FORCEWAKE_MEDIA & fw_engine) {
+ if (wait_for_atomic((__raw_i915_read32(dev_priv,
+ FORCEWAKE_ACK_MEDIA_GEN9) &
+ FORCEWAKE_KERNEL) == 0,
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
+
+ __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
+ _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+
+ if (wait_for_atomic((__raw_i915_read32(dev_priv,
+ FORCEWAKE_ACK_MEDIA_GEN9) &
+ FORCEWAKE_KERNEL),
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out: waiting for Media to ack.\n");
+ }
+
+ /* Check for Blitter Engine */
+ if (FORCEWAKE_BLITTER & fw_engine) {
+ if (wait_for_atomic((__raw_i915_read32(dev_priv,
+ FORCEWAKE_ACK_BLITTER_GEN9) &
+ FORCEWAKE_KERNEL) == 0,
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out: Blitter forcewake old ack to clear.\n");
+
+ __raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
+ _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
+
+ if (wait_for_atomic((__raw_i915_read32(dev_priv,
+ FORCEWAKE_ACK_BLITTER_GEN9) &
+ FORCEWAKE_KERNEL),
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out: waiting for Blitter to ack.\n");
+ }
+}
+
+static void
+__gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
+{
+ /* Check for Render Engine */
+ if (FORCEWAKE_RENDER & fw_engine)
+ __raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
+ _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+
+ /* Check for Media Engine */
+ if (FORCEWAKE_MEDIA & fw_engine)
+ __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
+ _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+
+ /* Check for Blitter Engine */
+ if (FORCEWAKE_BLITTER & fw_engine)
+ __raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
+ _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+}
+
+static void
+gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
+{
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+ if (FORCEWAKE_RENDER & fw_engine) {
+ if (dev_priv->uncore.fw_rendercount++ == 0)
+ dev_priv->uncore.funcs.force_wake_get(dev_priv,
+ FORCEWAKE_RENDER);
+ }
+
+ if (FORCEWAKE_MEDIA & fw_engine) {
+ if (dev_priv->uncore.fw_mediacount++ == 0)
+ dev_priv->uncore.funcs.force_wake_get(dev_priv,
+ FORCEWAKE_MEDIA);
+ }
+
+ if (FORCEWAKE_BLITTER & fw_engine) {
+ if (dev_priv->uncore.fw_blittercount++ == 0)
+ dev_priv->uncore.funcs.force_wake_get(dev_priv,
+ FORCEWAKE_BLITTER);
+ }
+
+ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
+static void
+gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
+{
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+ if (FORCEWAKE_RENDER & fw_engine) {
+ WARN_ON(dev_priv->uncore.fw_rendercount == 0);
+ if (--dev_priv->uncore.fw_rendercount == 0)
+ dev_priv->uncore.funcs.force_wake_put(dev_priv,
+ FORCEWAKE_RENDER);
+ }
+
+ if (FORCEWAKE_MEDIA & fw_engine) {
+ WARN_ON(dev_priv->uncore.fw_mediacount == 0);
+ if (--dev_priv->uncore.fw_mediacount == 0)
+ dev_priv->uncore.funcs.force_wake_put(dev_priv,
+ FORCEWAKE_MEDIA);
+ }
+
+ if (FORCEWAKE_BLITTER & fw_engine) {
+ WARN_ON(dev_priv->uncore.fw_blittercount == 0);
+ if (--dev_priv->uncore.fw_blittercount == 0)
+ dev_priv->uncore.funcs.force_wake_put(dev_priv,
+ FORCEWAKE_BLITTER);
+ }
+
+ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+}
+
static void gen6_force_wake_timer(unsigned long arg)
{
struct drm_i915_private *dev_priv = (void *)arg;
@@ -334,6 +482,9 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
__gen7_gt_force_wake_mt_reset(dev_priv);
+ if (IS_GEN9(dev))
+ __gen9_gt_force_wake_mt_reset(dev_priv);
+
if (restore) { /* If reset with a user forcewake, try to restore */
unsigned fw = 0;
@@ -343,6 +494,15 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
if (dev_priv->uncore.fw_mediacount)
fw |= FORCEWAKE_MEDIA;
+ } else if (IS_GEN9(dev)) {
+ if (dev_priv->uncore.fw_rendercount)
+ fw |= FORCEWAKE_RENDER;
+
+ if (dev_priv->uncore.fw_mediacount)
+ fw |= FORCEWAKE_MEDIA;
+
+ if (dev_priv->uncore.fw_blittercount)
+ fw |= FORCEWAKE_BLITTER;
} else {
if (dev_priv->uncore.forcewake_count)
fw = FORCEWAKE_ALL;
@@ -414,6 +574,10 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
intel_runtime_pm_get(dev_priv);
+ /* Redirect to Gen9 specific routine */
+ if (IS_GEN9(dev_priv->dev))
+ return gen9_force_wake_get(dev_priv, fw_engine);
+
/* Redirect to VLV specific routine */
if (IS_VALLEYVIEW(dev_priv->dev))
return vlv_force_wake_get(dev_priv, fw_engine);
@@ -435,6 +599,12 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
if (!dev_priv->uncore.funcs.force_wake_put)
return;
+ /* Redirect to Gen9 specific routine */
+ if (IS_GEN9(dev_priv->dev)) {
+ gen9_force_wake_put(dev_priv, fw_engine);
+ goto out;
+ }
+
/* Redirect to VLV specific routine */
if (IS_VALLEYVIEW(dev_priv->dev)) {
vlv_force_wake_put(dev_priv, fw_engine);
@@ -855,7 +1025,10 @@ void intel_uncore_init(struct drm_device *dev)
__intel_uncore_early_sanitize(dev, false);
- if (IS_VALLEYVIEW(dev)) {
+ if (IS_GEN9(dev)) {
+ dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
+ dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
+ } else if (IS_VALLEYVIEW(dev)) {
dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* [PATCH 28/28] drm/i915/skl: Enable Gen9 RC6
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (26 preceding siblings ...)
2014-11-04 17:07 ` [PATCH 27/28] drm/i915/skl: Gen9 Forcewake Damien Lespiau
@ 2014-11-04 17:07 ` Damien Lespiau
2014-11-05 11:28 ` [PATCH 00/28] SKL stage 1, a few more patches Daniel Vetter
28 siblings, 0 replies; 33+ messages in thread
From: Damien Lespiau @ 2014-11-04 17:07 UTC (permalink / raw)
To: intel-gfx
From: Zhe Wang <zhe1.wang@intel.com>
Configure and enable RC6 for Gen9.
v2: Rebase on top of BDW rc6 support (Damien)
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: Zhe Wang <zhe1.wang@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 52 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d0dbd65..300d7e5 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4539,6 +4539,13 @@ static void gen8_disable_rps_interrupts(struct drm_device *dev)
I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events);
}
+static void gen9_disable_rps(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_WRITE(GEN6_RC_CONTROL, 0);
+}
+
static void gen6_disable_rps_interrupts(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4699,6 +4706,45 @@ static void parse_rp_state_cap(struct drm_i915_private *dev_priv, u32 rp_state_c
dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq;
}
+static void gen9_enable_rps(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_engine_cs *ring;
+ uint32_t rc6_mask = 0;
+ int unused;
+
+ /* 1a: Software RC state - RC0 */
+ I915_WRITE(GEN6_RC_STATE, 0);
+
+ /* 1b: Get forcewake during program sequence. Although the driver
+ * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
+ gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+
+ /* 2a: Disable RC states. */
+ I915_WRITE(GEN6_RC_CONTROL, 0);
+
+ /* 2b: Program RC6 thresholds.*/
+ I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
+ I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
+ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
+ for_each_ring(ring, dev_priv, unused)
+ I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
+ I915_WRITE(GEN6_RC_SLEEP, 0);
+ I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
+
+ /* 3a: Enable RC6 */
+ if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
+ rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
+ DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
+ "on" : "off");
+ I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
+ GEN6_RC_CTL_EI_MODE(1) |
+ rc6_mask);
+
+ gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+
+}
+
static void gen8_enable_rps(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6233,7 +6279,9 @@ void intel_disable_gt_powersave(struct drm_device *dev)
intel_suspend_gt_powersave(dev);
mutex_lock(&dev_priv->rps.hw_lock);
- if (IS_CHERRYVIEW(dev))
+ if (INTEL_INFO(dev)->gen >= 9)
+ gen9_disable_rps(dev);
+ else if (IS_CHERRYVIEW(dev))
cherryview_disable_rps(dev);
else if (IS_VALLEYVIEW(dev))
valleyview_disable_rps(dev);
@@ -6257,6 +6305,8 @@ static void intel_gen6_powersave_work(struct work_struct *work)
cherryview_enable_rps(dev);
} else if (IS_VALLEYVIEW(dev)) {
valleyview_enable_rps(dev);
+ } else if (INTEL_INFO(dev)->gen >= 9) {
+ gen9_enable_rps(dev);
} else if (IS_BROADWELL(dev)) {
gen8_enable_rps(dev);
__gen6_update_ring_freq(dev);
--
1.8.3.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 33+ messages in thread* Re: [PATCH 00/28] SKL stage 1, a few more patches
2014-11-04 17:06 [PATCH 00/28] SKL stage 1, a few more patches Damien Lespiau
` (27 preceding siblings ...)
2014-11-04 17:07 ` [PATCH 28/28] drm/i915/skl: Enable Gen9 RC6 Damien Lespiau
@ 2014-11-05 11:28 ` Daniel Vetter
28 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2014-11-05 11:28 UTC (permalink / raw)
To: Damien Lespiau; +Cc: intel-gfx
On Tue, Nov 04, 2014 at 05:06:37PM +0000, Damien Lespiau wrote:
> We might as well try to push a few more patches while waiting for the next
> batch of reviews. Here's the WM code and 2 bonus patches around forcewake and
> rc6.
>
> The attentive reader will notice the lack of r-b tag for:
> "drm/i915/skl: Make res_blocks/lines intermediate values 32 bits"
>
> This patch does address the known review comment though. At some point we have
> to be realistic about our process, try to push stuff forward anyway, and have
> confidence we can fix problems when they arise, especially when the risk is low
> (new platform code, not running on any of the previous platforms).
>
> Next stop. SKL clocks.
Ok, vacuumed them all up into dinq, thanks. Some random comments while
reading through. I've mentioned that the wm code is mind-boggling, right?
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 33+ messages in thread