Skip to contentSkip to conversation

drm/i915: Add pineview_update_wm callback to update watermark for pineview

PATCH In review Zhenyu Wang 4 participants 5 messages Apr 12, 2010 – Apr 13, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 drm/i915: Add pineview_update_wm callback to update watermark for pineview

From: Zhao Yakui <[email protected]>

Now we don't define the update_wm callback function explicitly for pineview platform. But as it also belongs to mobile platform, we will use the function of i9xx_update_wm function to update its watermark again after we configure the watermark. This is incorrect.

So we will add a update_wm callback function for pineview to update watermark.

BTW: We will disable the self-refresh and never enable it any more if we can't find the appropriate the latency on pineview plaftorm. In such case the update_wm callback will be NULL.

The bitmask macro is also defined to access the corresponding fifo watermark register.

---
 drivers/gpu/drm/i915/i915_reg.h      |    9 ++
 drivers/gpu/drm/i915/intel_display.c |  153 +++++++++++++++++----------------
 2 files changed, 88 insertions(+), 74 deletions(-)
drivers/gpu/drm/i915/i915_reg.h +9 -0
index 8de8194..33967dd 100644
@@ -1986,15 +1986,24 @@
 
 #define DSPFW1			0x70034
 #define   DSPFW_SR_SHIFT	23
+#define   DSPFW_SR_MASK 	(0x1ff<<23)
 #define   DSPFW_CURSORB_SHIFT	16
+#define   DSPFW_CURSORB_MASK	(0x3f<<16)
 #define   DSPFW_PLANEB_SHIFT	8
+#define   DSPFW_PLANEB_MASK	(0x7f<<8)
+#define   DSPFW_PLANEA_MASK	(0x7f)
 #define DSPFW2			0x70038
 #define   DSPFW_CURSORA_MASK	0x00003f00
 #define   DSPFW_CURSORA_SHIFT	8
+#define   DSPFW_PLANEC_MASK	(0x7f)
 #define DSPFW3			0x7003c
 #define   DSPFW_HPLL_SR_EN	(1<<31)
 #define   DSPFW_CURSOR_SR_SHIFT	24
 #define   PINEVIEW_SELF_REFRESH_EN	(1<<30)
+#define   DSPFW_CURSOR_SR_MASK		(0x3f<<24)
+#define   DSPFW_HPLL_CURSOR_SHIFT	16
+#define   DSPFW_HPLL_CURSOR_MASK	(0x3f<<16)
+#define   DSPFW_HPLL_SR_MASK		(0x1ff)
 
 /* FIFO watermark sizes etc */
 #define G4X_FIFO_LINE_SIZE	64
drivers/gpu/drm/i915/intel_display.c +79 -74

183 lines not on this page · raw message

Signature · 1 line
1.6.3.3
#1 lore raw

PATCH 2/2 drm/i915: Add the support of memory self-refresh on Ironlake

Update the self-refresh watermark for display plane/cursor and enable the memory self-refresh on Ironlake. The watermark is also updated for the active display plane.

More than 1W idle power is saved on one Ironlake laptop after enabling memory self-refresh.

---
 drivers/gpu/drm/i915/i915_reg.h      |   44 +++++++++
 drivers/gpu/drm/i915/intel_display.c |  160 +++++++++++++++++++++++++++++++++-
 2 files changed, 201 insertions(+), 3 deletions(-)
drivers/gpu/drm/i915/i915_reg.h +44 -0
index 33967dd..0a3dbfc 100644
@@ -2030,6 +2030,43 @@
 #define PINEVIEW_CURSOR_DFT_WM	0
 #define PINEVIEW_CURSOR_GUARD_WM	5
 
+
+/* define the Watermark register on Ironlake */
+#define WM0_PIPEA_ILK		0x45100
+#define  WM0_PIPE_PLANE_MASK	(0x7f<<16)
+#define  WM0_PIPE_PLANE_SHIFT	16
+#define  WM0_PIPE_SPRITE_MASK	(0x3f<<8)
+#define  WM0_PIPE_SPRITE_SHIFT	8
+#define  WM0_PIPE_CURSOR_MASK	(0x1f)
+
+#define WM0_PIPEB_ILK		0x45104
+#define WM1_LP_ILK		0x45108
+#define  WM1_LP_SR_EN		(1<<31)
+#define  WM1_LP_LATENCY_SHIFT	24
+#define  WM1_LP_LATENCY_MASK	(0x7f<<24)
+#define  WM1_LP_SR_MASK		(0x1ff<<8)
+#define  WM1_LP_SR_SHIFT	8
+#define  WM1_LP_CURSOR_MASK	(0x3f)
+
+/* Memory latency timer register */
+#define MLTR_ILK		0x11222
+/* the unit of memory self-refresh latency time is 0.5us */
+#define  ILK_SRLT_MASK		0x3f
+
+/* define the fifo size on Ironlake */
+#define ILK_DISPLAY_FIFO	128
+#define ILK_DISPLAY_MAXWM	64
+#define ILK_DISPLAY_DFTWM	8
+
+#define ILK_DISPLAY_SR_FIFO	512
+#define ILK_DISPLAY_MAX_SRWM	0x1ff
+#define ILK_DISPLAY_DFT_SRWM	0x3f
+#define ILK_CURSOR_SR_FIFO	64
+#define ILK_CURSOR_MAX_SRWM	0x3f
+#define ILK_CURSOR_DFT_SRWM	8
+
+#define ILK_FIFO_LINE_SIZE	64
+
 /*
  * The two pipe frame counter registers are not synchronized, so
  * reading a stable value is somewhat tricky. The following code
@@ -2310,8 +2347,15 @@
 #define GTIIR   0x44018
 #define GTIER   0x4401c
 
+#define ILK_DISPLAY_CHICKEN2	0x42004
+#define  ILK_DPARB_GATE	(1<<22)
+#define  ILK_VSDPFD_FULL	(1<<21)
+#define ILK_DSPCLK_GATE		0x42020
+#define  ILK_DPARB_CLK_GATE	(1<<5)
+
 #define DISP_ARB_CTL	0x45000
 #define  DISP_TILE_SURFACE_SWIZZLING	(1<<13)
+#define  DISP_FBC_WM_DIS		(1<<15)
 
 /* PCH */
 
drivers/gpu/drm/i915/intel_display.c +157 -3

184 lines not on this page · raw message

Signature · 1 line
1.6.3.3
#2 lore raw

Re: [PATCH 2/2] drm/i915: Add the support of memory self-refresh on Ironlake

Quoted 6 lines · Zhenyu Wang

Update the self-refresh watermark for display plane/cursor and enable the memory self-refresh on Ironlake. The watermark is also updated for the active display plane.

More than 1W idle power is saved on one Ironlake laptop after enabling memory self-refresh.

Looks good at a quick read, though I haven't tested it yet.

Quoted 11 lines
drivers/gpu/drm/i915/intel_display.c +11 -0
+	/* Calculate and update the watermark for plane A */
+	if (planea_clock) {
+		entries_required = ((planea_clock / 1000) * pixel_size *
+				     ILK_LP0_PLANE_LATENCY) / 1000;
+		entries_required = DIV_ROUND_UP(entries_required,
+				   ironlake_display_wm_info.cacheline_size);
+		planea_wm = entries_required +
+			    ironlake_display_wm_info.guard_size;
+
+		if (planea_wm > (int)ironlake_display_wm_info.max_wm)
+			planea_wm = ironlake_display_wm_info.max_wm;

drivers/gpu/drm/i915/intel_display.c static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, · line 3090

Quoted 10 lines
drivers/gpu/drm/i915/intel_display.c +10 -0
+
+		cursora_wm = 16;
+		reg_value = I915_READ(WM0_PIPEA_ILK);
+		reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK);
+		reg_value |= (planea_wm << WM0_PIPE_PLANE_SHIFT) |
+			     (cursora_wm & WM0_PIPE_CURSOR_MASK);
+		I915_WRITE(WM0_PIPEA_ILK, reg_value);
+		DRM_DEBUG_KMS("FIFO watermarks For pipe A - plane %d, "
+				"cursor: %d\n", planea_wm, cursora_wm);
+	}

This doesn't adjust the video sprite plane watermark. I suppose it doesn't really matter, since we're not enabling it yet, but for clarity I'd also mask off WM0_PIPE_SPRITE_MASK.

Also, the cursor watermark is a magic number. I assume it's derived from the hardware cursor size. In which case, it'd be nice to show the derivation; Ironlake can do hardware cursors up to 256x256, it'd be nice to have that work automatically when and if we enable that in the driver.

drivers/gpu/drm/i915/intel_display.c static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, · line 3153

Quoted 11 lines
drivers/gpu/drm/i915/intel_display.c +11 -0
+		/* configure watermark and enable self-refresh */
+		reg_value = I915_READ(WM1_LP_ILK);
+		reg_value &= ~(WM1_LP_LATENCY_MASK | WM1_LP_SR_MASK |
+			       WM1_LP_CURSOR_MASK);
+		reg_value |= WM1_LP_SR_EN |
+			     (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) |
+			     (sr_wm << WM1_LP_SR_SHIFT) | cursor_wm;
+
+		I915_WRITE(WM1_LP_ILK, reg_value);
+		DRM_DEBUG_KMS("self-refresh watermark: display plane %d "
+				"cursor %d\n", sr_wm, cursor_wm);

What are the conditions for entering LP2 or LP3 state, and is it worth trying to set them up too?

drivers/gpu/drm/i915/intel_display.c void intel_init_clock_gating(struct drm_device *dev) · line 5138

Quoted 11 lines
drivers/gpu/drm/i915/intel_display.c +11 -0
+		/*
+		 * According to the spec the following bits should be set in
+		 * order to enable memory self-refresh
+		 * The bit 22/21 of 0x42004
+		 * The bit 5 of 0x42020
+		 * The bit 15 of 0x45000
+		 */
+		if (IS_IRONLAKE(dev)) {
+			I915_WRITE(ILK_DISPLAY_CHICKEN2,
+					(I915_READ(ILK_DISPLAY_CHICKEN2) |
+					ILK_DPARB_GATE | ILK_VSDPFD_FULL));

I can only hope this is named "chicken" in allusion to:

http://en.wikipedia.org/wiki/Chicken_(game)

I certainly can't find any reference to it in the documentation.

- ajax

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

#3 lore raw

Re: [PATCH 2/2] drm/i915: Add the support of memory self-refresh on Ironlake

Quoted 71 lines · On Mon, 12 Apr 2010 10:43:04 -0400 Adam Jackson <[email protected]> wrote:
Quoted 6 lines · Zhenyu Wang

Update the self-refresh watermark for display plane/cursor and enable the memory self-refresh on Ironlake. The watermark is also updated for the active display plane.

More than 1W idle power is saved on one Ironlake laptop after enabling memory self-refresh.

Looks good at a quick read, though I haven't tested it yet.

Quoted 11 lines
drivers/gpu/drm/i915/intel_display.c +11 -0
+	/* Calculate and update the watermark for plane A */
+	if (planea_clock) {
+		entries_required = ((planea_clock / 1000) * pixel_size *
+				     ILK_LP0_PLANE_LATENCY) / 1000;
+		entries_required = DIV_ROUND_UP(entries_required,
+				   ironlake_display_wm_info.cacheline_size);
+		planea_wm = entries_required +
+			    ironlake_display_wm_info.guard_size;
+
+		if (planea_wm > (int)ironlake_display_wm_info.max_wm)
+			planea_wm = ironlake_display_wm_info.max_wm;

drivers/gpu/drm/i915/intel_display.c static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, · line 3090

Quoted 10 lines
drivers/gpu/drm/i915/intel_display.c +10 -0
+
+		cursora_wm = 16;
+		reg_value = I915_READ(WM0_PIPEA_ILK);
+		reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK);
+		reg_value |= (planea_wm << WM0_PIPE_PLANE_SHIFT) |
+			     (cursora_wm & WM0_PIPE_CURSOR_MASK);
+		I915_WRITE(WM0_PIPEA_ILK, reg_value);
+		DRM_DEBUG_KMS("FIFO watermarks For pipe A - plane %d, "
+				"cursor: %d\n", planea_wm, cursora_wm);
+	}

This doesn't adjust the video sprite plane watermark. I suppose it doesn't really matter, since we're not enabling it yet, but for clarity I'd also mask off WM0_PIPE_SPRITE_MASK.

Also, the cursor watermark is a magic number. I assume it's derived from the hardware cursor size. In which case, it'd be nice to show the derivation; Ironlake can do hardware cursors up to 256x256, it'd be nice to have that work automatically when and if we enable that in the driver.

drivers/gpu/drm/i915/intel_display.c static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, · line 3153

Quoted 11 lines
drivers/gpu/drm/i915/intel_display.c +11 -0
+		/* configure watermark and enable self-refresh */
+		reg_value = I915_READ(WM1_LP_ILK);
+		reg_value &= ~(WM1_LP_LATENCY_MASK | WM1_LP_SR_MASK |
+			       WM1_LP_CURSOR_MASK);
+		reg_value |= WM1_LP_SR_EN |
+			     (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) |
+			     (sr_wm << WM1_LP_SR_SHIFT) | cursor_wm;
+
+		I915_WRITE(WM1_LP_ILK, reg_value);
+		DRM_DEBUG_KMS("self-refresh watermark: display plane %d "
+				"cursor %d\n", sr_wm, cursor_wm);

What are the conditions for entering LP2 or LP3 state, and is it worth trying to set them up too?

drivers/gpu/drm/i915/intel_display.c void intel_init_clock_gating(struct drm_device *dev) · line 5138

Quoted 11 lines
drivers/gpu/drm/i915/intel_display.c +11 -0
+		/*
+		 * According to the spec the following bits should be set in
+		 * order to enable memory self-refresh
+		 * The bit 22/21 of 0x42004
+		 * The bit 5 of 0x42020
+		 * The bit 15 of 0x45000
+		 */
+		if (IS_IRONLAKE(dev)) {
+			I915_WRITE(ILK_DISPLAY_CHICKEN2,
+					(I915_READ(ILK_DISPLAY_CHICKEN2) |
+					ILK_DPARB_GATE | ILK_VSDPFD_FULL));

I can only hope this is named "chicken" in allusion to:

Quoted 3 lines

http://en.wikipedia.org/wiki/Chicken_(game)

I certainly can't find any reference to it in the documentation.

We should probably add a comment about that. The chicken bits generally control whether new features are enabled in hw, so-called because the designers were too chicken to just enable them unconditionally. :)

Signature · 1 line
Jesse Barnes, Intel Open Source Technology Center
#4 lore raw

Re: [PATCH 2/2] drm/i915: Add the support of memory self-refresh on Ironlake

In reply to Adam Jackson
Quoted 27 lines · Adam Jackson
Quoted 6 lines · Zhenyu Wang

Update the self-refresh watermark for display plane/cursor and enable the memory self-refresh on Ironlake. The watermark is also updated for the active display plane.

More than 1W idle power is saved on one Ironlake laptop after enabling memory self-refresh.

Looks good at a quick read, though I haven't tested it yet.

Quoted 17 lines
drivers/gpu/drm/i915/intel_display.c +17 -0
+	/* Calculate and update the watermark for plane A */
+	if (planea_clock) {
+		entries_required = ((planea_clock / 1000) * pixel_size *
+				     ILK_LP0_PLANE_LATENCY) / 1000;
+		entries_required = DIV_ROUND_UP(entries_required,
+				   ironlake_display_wm_info.cacheline_size);
+		planea_wm = entries_required +
+			    ironlake_display_wm_info.guard_size;
+
+		if (planea_wm > (int)ironlake_display_wm_info.max_wm)
+			planea_wm = ironlake_display_wm_info.max_wm;
+
+		cursora_wm = 16;
+		reg_value = I915_READ(WM0_PIPEA_ILK);
+		reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK);
+		reg_value |= (planea_wm << WM0_PIPE_PLANE_SHIFT) |
+			     (cursora_wm & WM0_PIPE_CURSOR_MASK);
Quoted 8 lines

drivers/gpu/drm/i915/intel_display.c static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, · line 3090

Quoted 4 lines
drivers/gpu/drm/i915/intel_display.c +4 -0
+		I915_WRITE(WM0_PIPEA_ILK, reg_value);
+		DRM_DEBUG_KMS("FIFO watermarks For pipe A - plane %d, "
+				"cursor: %d\n", planea_wm, cursora_wm);
+	}

This doesn't adjust the video sprite plane watermark. I suppose it doesn't really matter, since we're not enabling it yet, but for clarity I'd also mask off WM0_PIPE_SPRITE_MASK.

As the sprite plane is not touched, it will be better to reserve the corresponding sprite watermark.

Quoted 6 lines

Also, the cursor watermark is a magic number. I assume it's derived from the hardware cursor size. In which case, it'd be nice to show the derivation; Ironlake can do hardware cursors up to 256x256, it'd be nice to have that work automatically when and if we enable that in the driver.

Very good point. Yes. It seems that the Ironlake can support up to 256X256@32bpp cursor. This is not considered in this patch.

We can add another patch to calculate the cursor watermark.

Quoted 15 lines

drivers/gpu/drm/i915/intel_display.c static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, · line 3153

Quoted 12 lines
drivers/gpu/drm/i915/intel_display.c +11 -0
+		/* configure watermark and enable self-refresh */
+		reg_value = I915_READ(WM1_LP_ILK);
+		reg_value &= ~(WM1_LP_LATENCY_MASK | WM1_LP_SR_MASK |
+			       WM1_LP_CURSOR_MASK);
+		reg_value |= WM1_LP_SR_EN |
+			     (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) |
+			     (sr_wm << WM1_LP_SR_SHIFT) | cursor_wm;
+
+		I915_WRITE(WM1_LP_ILK, reg_value);
+		DRM_DEBUG_KMS("self-refresh watermark: display plane %d "
+				"cursor %d\n", sr_wm, cursor_wm);

What are the conditions for entering LP2 or LP3 state, and is it worth trying to set them up too?

LP3 is not supported on ironlake.

After consulting the hardware group, it is not worth setting up the LP2. It is complex to set up the LP2 but the power saving is very small. (Not more than 0.1W).

Quoted 15 lines

drivers/gpu/drm/i915/intel_display.c void intel_init_clock_gating(struct drm_device *dev) · line 5138

Quoted 12 lines
drivers/gpu/drm/i915/intel_display.c +11 -0
+		/*
+		 * According to the spec the following bits should be set in
+		 * order to enable memory self-refresh
+		 * The bit 22/21 of 0x42004
+		 * The bit 5 of 0x42020
+		 * The bit 15 of 0x45000
+		 */
+		if (IS_IRONLAKE(dev)) {
+			I915_WRITE(ILK_DISPLAY_CHICKEN2,
+					(I915_READ(ILK_DISPLAY_CHICKEN2) |
+					ILK_DPARB_GATE | ILK_VSDPFD_FULL));

I can only hope this is named "chicken" in allusion to:

Quoted 3 lines

http://en.wikipedia.org/wiki/Chicken_(game)

I certainly can't find any reference to it in the documentation.

This is defined in the spec from hardware group.

What Jesse said is right. Maybe we should add more comments about it.

Quoted 2 lines

- ajax