Re: [Intel-gfx] [PATCH] drm/i915/icl: MBUS B credit change

2018-10-05 Thread Kumar, Mahesh

Hi,

LGTM

Reviewed-by: Mahesh Kumar 

On 10/4/2018 8:48 PM, Rodrigo Vivi wrote:

No functional change. But just a minor change to keep
up with Spec, since it has changed since commit c3cc39c539d4
("drm/i915/icl: program mbus during pipe enable")

The instructions previously said to program pipe's
B credit = 24 / number of pipes, which is 8 for ICL.
Now the spec gives us direct values independent of number
of pipes. Let's keep in sync.

Also just a reorder on fields to make easier to compare
against spec's sequence: A -> BW -> B.

Cc: Lucas De Marchi 
Cc: Paulo Zanoni 
Cc: Mahesh Kumar 
Cc: Arthur J Runyan 
Signed-off-by: Rodrigo Vivi 
---
  drivers/gpu/drm/i915/intel_display.c | 7 +++
  1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 36434c5359b1..eb2250a984a8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5683,10 +5683,9 @@ static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
enum pipe pipe = crtc->pipe;
uint32_t val;
  
-	val = MBUS_DBOX_BW_CREDIT(1) | MBUS_DBOX_A_CREDIT(2);

-
-   /* Program B credit equally to all pipes */
-   val |= MBUS_DBOX_B_CREDIT(24 / INTEL_INFO(dev_priv)->num_pipes);
+   val = MBUS_DBOX_A_CREDIT(2);
+   val |= MBUS_DBOX_BW_CREDIT(1);
+   val |= MBUS_DBOX_B_CREDIT(8);
  
  	I915_WRITE(PIPE_MBUS_DBOX_CTL(pipe), val);

  }


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


Re: [Intel-gfx] [PATCH v4] drm/i915: use for_each_pipe loop to assign crtc_mask

2018-09-14 Thread Kumar, Mahesh

Hi,

just a ping for review :)

-Mahesh
On 9/8/2018 11:40 AM, Mahesh Kumar wrote:

This cleanup patch makes changes to use for_each_pipe loop
during bit-mask assignment of allowed crtc with encoder.

changes:
  - use BIT(i) macro instead of (1 << i) (Chris)
changes from V2:
  - use int for consistency (Jani)
changes from V3:
  - instead use enum pipe (Ville)

Cc: Jani Nikula 
Cc: Rodrigo Vivi 
Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/intel_ddi.c  | 4 +++-
  drivers/gpu/drm/i915/intel_dp.c   | 5 -
  drivers/gpu/drm/i915/intel_hdmi.c | 5 -
  3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index cd01a09c5e0f..0ef2448fd350 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3751,6 +3751,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, 
enum port port)
struct intel_encoder *intel_encoder;
struct drm_encoder *encoder;
bool init_hdmi, init_dp, init_lspcon = false;
+   enum pipe pipe;
  
  
  	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||

@@ -3801,8 +3802,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, 
enum port port)
intel_encoder->type = INTEL_OUTPUT_DDI;
intel_encoder->power_domain = intel_port_to_power_domain(port);
intel_encoder->port = port;
-   intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_encoder->cloneable = 0;
+   for_each_pipe(dev_priv, pipe)
+   intel_encoder->crtc_mask |= BIT(pipe);
  
  	if (INTEL_GEN(dev_priv) >= 11)

intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 436c22de33b6..7302b5807884 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -6709,7 +6709,10 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
else
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
} else {
-   intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+   enum pipe pipe;
+
+   for_each_pipe(dev_priv, pipe)
+   intel_encoder->crtc_mask |= BIT(pipe);
}
intel_encoder->cloneable = 0;
intel_encoder->port = port;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index a2dab0b6bde6..0d4c6f565d65 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -2468,7 +2468,10 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
else
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
} else {
-   intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+   enum pipe pipe;
+
+   for_each_pipe(dev_priv, pipe)
+   intel_encoder->crtc_mask |= BIT(pipe);
}
intel_encoder->cloneable = 1 << INTEL_OUTPUT_ANALOG;
/*


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


Re: [Intel-gfx] [PATCH v2] drm/i915: use for_each_pipe loop to assign crtc_mask

2018-09-07 Thread Kumar, Mahesh

Hi,

I used u8 because internally num_pipes variable used by for_each_pipe 
macro is of u8 type.

If you think it's good to have int for consistency I can update the patch.

Regards,
-Mahesh

On 9/7/2018 6:34 PM, Jani Nikula wrote:

On Fri, 07 Sep 2018, Mahesh Kumar  wrote:

This cleanup patch makes changes to use for_each_pipe loop
during bit-mask assignment of allowed crtc with encoder.

changes:
  - use BIT(i) macro instead of (1 << i) (Chris)

Cc: Jani Nikula 
Cc: Rodrigo Vivi 
Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/intel_ddi.c  | 4 +++-
  drivers/gpu/drm/i915/intel_dp.c   | 5 -
  drivers/gpu/drm/i915/intel_hdmi.c | 5 -
  3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index cd01a09c5e0f..88dfca245099 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3751,6 +3751,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, 
enum port port)
struct intel_encoder *intel_encoder;
struct drm_encoder *encoder;
bool init_hdmi, init_dp, init_lspcon = false;
+   u8 i;

Please use int instead of u8 throughout. u8 only makes sense when you
actually need the specific size, or need to be concerned about the size.

BR,
Jani.

  
  
  	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||

@@ -3801,8 +3802,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, 
enum port port)
intel_encoder->type = INTEL_OUTPUT_DDI;
intel_encoder->power_domain = intel_port_to_power_domain(port);
intel_encoder->port = port;
-   intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_encoder->cloneable = 0;
+   for_each_pipe(dev_priv, i)
+   intel_encoder->crtc_mask |= BIT(i);
  
  	if (INTEL_GEN(dev_priv) >= 11)

intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 436c22de33b6..1f954debdc55 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -6709,7 +6709,10 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
else
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
} else {
-   intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+   u8 i;
+
+   for_each_pipe(dev_priv, i)
+   intel_encoder->crtc_mask |= BIT(i);
}
intel_encoder->cloneable = 0;
intel_encoder->port = port;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
b/drivers/gpu/drm/i915/intel_hdmi.c
index a2dab0b6bde6..647e38de7980 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -2468,7 +2468,10 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
else
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
} else {
-   intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+   u8 i;
+
+   for_each_pipe(dev_priv, i)
+   intel_encoder->crtc_mask |= BIT(i);
}
intel_encoder->cloneable = 1 << INTEL_OUTPUT_ANALOG;
/*


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


Re: [Intel-gfx] [PATCH 4/4] drm/i915: Enable Y210, Y212, Y216 format for primary and sprite planes

2018-08-27 Thread Kumar, Mahesh



On 8/27/2018 12:17 PM, Swati Sharma wrote:

From: Vidya Srinivas 

In this patch, a list for icl specific pixel formats is created
in which Y210, Y212 and Y216 pixel formats are added along with
legacy pixel formats for primary and sprite plane.

Signed-off-by: Swati Sharma 
Signed-off-by: Vidya Srinivas 
---
  drivers/gpu/drm/i915/intel_display.c | 25 +++--
  drivers/gpu/drm/i915/intel_sprite.c  | 22 --
  2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 91aa8cc..30065e3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -104,6 +104,24 @@
DRM_FORMAT_NV12,
  };
  
+static const uint32_t icl_primary_formats[] = {

+   DRM_FORMAT_C8,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XRGB2101010,
+   DRM_FORMAT_XBGR2101010,
+   DRM_FORMAT_YUYV,
+   DRM_FORMAT_YVYU,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_VYUY,
+   DRM_FORMAT_Y210,
+   DRM_FORMAT_Y212,
+   DRM_FORMAT_Y216,
+};
+
  static const uint64_t skl_format_modifiers_noccs[] = {
I915_FORMAT_MOD_Yf_TILED,
I915_FORMAT_MOD_Y_TILED,
@@ -13718,8 +13736,11 @@ bool skl_plane_has_planar(struct drm_i915_private 
*dev_priv,
if (INTEL_GEN(dev_priv) >= 9) {
primary->has_ccs = skl_plane_has_ccs(dev_priv, pipe,
 PLANE_PRIMARY);
-
-   if (skl_plane_has_planar(dev_priv, pipe, PLANE_PRIMARY)) {
+   if (INTEL_GEN(dev_priv) >= 11) {
+   intel_primary_formats = icl_primary_formats;
+   num_formats = ARRAY_SIZE(icl_primary_formats);
+   } else if (skl_plane_has_planar(dev_priv, pipe,
+   PLANE_PRIMARY)) {
intel_primary_formats = skl_pri_planar_formats;
num_formats = ARRAY_SIZE(skl_pri_planar_formats);
} else {
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 417501f..2abdd85 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1281,6 +1281,21 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device 
*dev, void *data,
DRM_FORMAT_NV12,
  };
  
+static uint32_t icl_plane_formats[] = {

+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_YUYV,
+   DRM_FORMAT_YVYU,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_VYUY,
+   DRM_FORMAT_Y210,
+   DRM_FORMAT_Y212,
+   DRM_FORMAT_Y216,
+};
+
  static const uint64_t skl_plane_format_modifiers_noccs[] = {
I915_FORMAT_MOD_Yf_TILED,
I915_FORMAT_MOD_Y_TILED,
@@ -1536,8 +1551,11 @@ struct intel_plane *
intel_plane->disable_plane = skl_disable_plane;
intel_plane->get_hw_state = skl_plane_get_hw_state;
  
-		if (skl_plane_has_planar(dev_priv, pipe,

-PLANE_SPRITE0 + plane)) {
+   if (INTEL_GEN(dev_priv) >= 11) {
+   plane_formats = icl_plane_formats;
+   num_plane_formats = ARRAY_SIZE(icl_plane_formats);

64 bits pixel formats are supported only with HDR planes.

-Mahesh

+   } else if (skl_plane_has_planar(dev_priv, pipe,
+   PLANE_SPRITE0 + plane)) {
plane_formats = skl_planar_formats;
num_plane_formats = ARRAY_SIZE(skl_planar_formats);
} else {


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


Re: [Intel-gfx] [PATCH 3/4] drm/i915: Preparations for enabling Y210, Y212, Y216 formats

2018-08-27 Thread Kumar, Mahesh

Hi,


On 8/27/2018 12:17 PM, Swati Sharma wrote:

From: Vidya Srinivas 

Signed-off-by: Swati Sharma 
Signed-off-by: Vidya Srinivas 
---
  drivers/gpu/drm/i915/intel_display.c | 15 +++
  drivers/gpu/drm/i915/intel_sprite.c  |  3 +++
  2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 30fdfd1..91aa8cc 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3511,6 +3511,12 @@ static u32 skl_plane_ctl_format(uint32_t pixel_format)
return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
case DRM_FORMAT_NV12:
return PLANE_CTL_FORMAT_NV12;
+   case DRM_FORMAT_Y210:
+   return PLANE_CTL_FORMAT_Y210;
+   case DRM_FORMAT_Y212:
+   return PLANE_CTL_FORMAT_Y212;
+   case DRM_FORMAT_Y216:
+   return PLANE_CTL_FORMAT_Y216;
While programming YUV pixel format, you also need to program order of 
samples in bits [17:16]
BTW 64 bits pixel format are not supported in all the planes, these are 
supported only in HDR planes.

You should handle that as well.

-Mahesh

default:
MISSING_CASE(pixel_format);
}
@@ -4959,6 +4965,9 @@ static int skl_update_scaler_plane(struct 
intel_crtc_state *crtc_state,
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
case DRM_FORMAT_NV12:
+   case DRM_FORMAT_Y210:
+   case DRM_FORMAT_Y212:
+   case DRM_FORMAT_Y216:
break;
default:
DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported scaling format 
0x%x\n",
@@ -13413,6 +13422,9 @@ static bool skl_plane_format_mod_supported(struct 
drm_plane *_plane,
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
+   case DRM_FORMAT_Y210:
+   case DRM_FORMAT_Y212:
+   case DRM_FORMAT_Y216:
case DRM_FORMAT_NV12:
if (modifier == I915_FORMAT_MOD_Yf_TILED)
return true;
@@ -14544,6 +14556,9 @@ static int intel_framebuffer_init(struct 
intel_framebuffer *intel_fb,
case DRM_FORMAT_UYVY:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_VYUY:
+   case DRM_FORMAT_Y210:
+   case DRM_FORMAT_Y212:
+   case DRM_FORMAT_Y216:
if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv)) {
DRM_DEBUG_KMS("unsupported pixel format: %s\n",
  drm_get_format_name(mode_cmd->pixel_format, 
_name));
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index c286dda..417501f 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1419,6 +1419,9 @@ static bool skl_plane_format_mod_supported(struct 
drm_plane *_plane,
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
+   case DRM_FORMAT_Y210:
+   case DRM_FORMAT_Y212:
+   case DRM_FORMAT_Y216:
case DRM_FORMAT_NV12:
if (modifier == I915_FORMAT_MOD_Yf_TILED)
return true;


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


Re: [Intel-gfx] [PATCH 1/4] drm: Add Y210, Y212, Y216 format definitions and fourcc

2018-08-27 Thread Kumar, Mahesh


On 8/27/2018 12:47 PM, Kumar, Mahesh wrote:

Hi,


On 8/27/2018 12:17 PM, Swati Sharma wrote:

From: Vidya Srinivas 

The following pixel formats are packed format that follows 4:2:2
chroma sampling. For memory represenation each component is
allocated 16 bits each. Thus each pixel occupies a DWORD.

Y210: Valid data occupies MSB 10 bits.
LSB 6 bits are filled with zeroes.
Y212: Valid data occupies MSB 12 bits.
LSB 4 bits are filled with zeroes.
Y216: Valid data occupies 16 bits,
doesn't require any padding bits.

First 16 bits stores the Y value and the next 16 bits stores one
of the chroma samples alternatively. The first luma sample will
be accompanied by first U sample and second luma sample is
accompanied by the first V sample.

Signed-off-by: Swati Sharma 
Signed-off-by: Vidya Srinivas 
---
  drivers/gpu/drm/drm_fourcc.c  | 3 +++
  include/uapi/drm/drm_fourcc.h | 4 
  2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 35c1e27..4bf04a5 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -173,6 +173,9 @@ const struct drm_format_info 
*__drm_format_info(u32 format)
  { .format = DRM_FORMAT_UYVY,    .depth = 0, .num_planes 
= 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
  { .format = DRM_FORMAT_VYUY,    .depth = 0, .num_planes 
= 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
  { .format = DRM_FORMAT_AYUV,    .depth = 0, .num_planes 
= 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, 
.is_yuv = true },
+    { .format = DRM_FORMAT_Y210,    .depth = 0, 
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 2, .vsub = 1 },
+    { .format = DRM_FORMAT_Y212,    .depth = 0, 
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 2, .vsub = 1 },
+    { .format = DRM_FORMAT_Y216,    .depth = 0, 
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 2, .vsub = 1 },

  };

you should also set is_yuv to true.

Apart from this there can be different order for YUV samples, Are you 
going to add those as well?



-Mahesh

    unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h 
b/include/uapi/drm/drm_fourcc.h

index 2ed46e9..6a03e6d 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -149,6 +149,10 @@
    #define DRM_FORMAT_AYUV    fourcc_code('A', 'Y', 'U', 'V') /* 
[31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
  +#define DRM_FORMAT_Y210 fourcc_code('Y', '2', '1', '0') /* 
[63:0] Y0:Cb0:Y1:Cr1 10:10:10:10 little endian */
+#define DRM_FORMAT_Y212 fourcc_code('Y', '2', '1', '2') /* 
[63:0] Y0:Cb0:Y1:Cr1 12:12:12:12 little endian */
+#define DRM_FORMAT_Y216 fourcc_code('Y', '2', '1', '6') /* 
[63:0] Y0:Cb0:Y1:Cr1 16:16:16:16 little endian */

+
  /*
   * 2 plane RGB + A
   * index 0 = RGB plane, same format as the corresponding non _A8 
format has




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


Re: [Intel-gfx] [PATCH 2/4] drm/i915: Add Y210, Y212, Y216 plane control definitions

2018-08-27 Thread Kumar, Mahesh

Hi,

Please include platform name in subject line:




On 8/27/2018 12:17 PM, Swati Sharma wrote:

From: Vidya Srinivas 

Added needed plane control flag definitions for Y210, Y212 and
Y216 formats.

may be, add more info in commit message

-Mahesh


Signed-off-by: Swati Sharma 
Signed-off-by: Vidya Srinivas 
---
  drivers/gpu/drm/i915/i915_reg.h | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8534f88..926e42d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6504,6 +6504,9 @@ enum {
  #define   PLANE_CTL_FORMAT_RGB_565(14 << 24)
  #define   ICL_PLANE_CTL_FORMAT_MASK   (0x1f << 23)
  #define   PLANE_CTL_PIPE_CSC_ENABLE   (1 << 23) /* Pre-GLK */
+#define   PLANE_CTL_FORMAT_Y210(1 << 23)
+#define   PLANE_CTL_FORMAT_Y212(3 << 23)
+#define   PLANE_CTL_FORMAT_Y216(5 << 23)
  #define   PLANE_CTL_KEY_ENABLE_MASK   (0x3 << 21)
  #define   PLANE_CTL_KEY_ENABLE_SOURCE (1 << 21)
  #define   PLANE_CTL_KEY_ENABLE_DESTINATION(2 << 21)


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


Re: [Intel-gfx] [PATCH 1/4] drm: Add Y210, Y212, Y216 format definitions and fourcc

2018-08-27 Thread Kumar, Mahesh

Hi,


On 8/27/2018 12:17 PM, Swati Sharma wrote:

From: Vidya Srinivas 

The following pixel formats are packed format that follows 4:2:2
chroma sampling. For memory represenation each component is
allocated 16 bits each. Thus each pixel occupies a DWORD.

Y210:   Valid data occupies MSB 10 bits.
LSB 6 bits are filled with zeroes.
Y212:   Valid data occupies MSB 12 bits.
LSB 4 bits are filled with zeroes.
Y216:   Valid data occupies 16 bits,
doesn't require any padding bits.

First 16 bits stores the Y value and the next 16 bits stores one
of the chroma samples alternatively. The first luma sample will
be accompanied by first U sample and second luma sample is
accompanied by the first V sample.

Signed-off-by: Swati Sharma 
Signed-off-by: Vidya Srinivas 
---
  drivers/gpu/drm/drm_fourcc.c  | 3 +++
  include/uapi/drm/drm_fourcc.h | 4 
  2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 35c1e27..4bf04a5 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -173,6 +173,9 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_UYVY,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_VYUY,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_AYUV,.depth = 0,  
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, 
.is_yuv = true },
+   { .format = DRM_FORMAT_Y210,.depth = 0,  
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 2, .vsub = 1 },
+   { .format = DRM_FORMAT_Y212,.depth = 0,  
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 2, .vsub = 1 },
+   { .format = DRM_FORMAT_Y216,.depth = 0,  
.num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 2, .vsub = 1 },
};

you should also set is_yuv to true.

-Mahesh
  
  	unsigned int i;

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 2ed46e9..6a03e6d 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -149,6 +149,10 @@
  
  #define DRM_FORMAT_AYUV		fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
  
+#define DRM_FORMAT_Y210 fourcc_code('Y', '2', '1', '0') /* [63:0] Y0:Cb0:Y1:Cr1 10:10:10:10 little endian */

+#define DRM_FORMAT_Y212 fourcc_code('Y', '2', '1', '2') /* [63:0] 
Y0:Cb0:Y1:Cr1 12:12:12:12 little endian */
+#define DRM_FORMAT_Y216 fourcc_code('Y', '2', '1', '6') /* [63:0] 
Y0:Cb0:Y1:Cr1 16:16:16:16 little endian */
+
  /*
   * 2 plane RGB + A
   * index 0 = RGB plane, same format as the corresponding non _A8 format has


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


Re: [Intel-gfx] [PATCH 4/5] drm/i915/kbl+: Enable IPC only for symmetric memory configurations

2018-08-22 Thread Kumar, Mahesh

Hi,


On 8/22/2018 12:26 AM, Rodrigo Vivi wrote:

On Tue, Aug 21, 2018 at 09:30:21PM +0530, Kumar, Mahesh wrote:

Hi,


On 8/21/2018 8:27 PM, Kumar, Mahesh wrote:

Hi,


On 8/17/2018 11:50 PM, Rodrigo Vivi wrote:

On Thu, Jul 26, 2018 at 07:44:09PM +0530, Mahesh Kumar wrote:

IPC may cause underflows if not used with dual channel symmetric
memory configuration. Disable IPC for non symmetric configurations in
affected platforms.
Display WA #1141

Signed-off-by: Mahesh Kumar 
---
   drivers/gpu/drm/i915/i915_drv.c | 43
-
   drivers/gpu/drm/i915/i915_drv.h |  1 +
   drivers/gpu/drm/i915/intel_pm.c |  2 +-
   3 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c
b/drivers/gpu/drm/i915/i915_drv.c
index 86bc2e685522..2273664166bc 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1141,21 +1141,47 @@ skl_dram_get_channel_info(struct
dram_channel_info *ch, u32 val)
   return 0;
   }

+static bool
+intel_is_dram_ipc_capable(struct drm_i915_private *dev_priv,
+  u32 val_ch0, u32 val_ch1,
+  struct dram_channel_info *ch0)

what about
intel_is_dram_symmetric() ?

sounds good.

+{
+    /* Display WA #1141: SKL:all KBL:all CNL:A CNL:B */

move this to the wa call, not the the function check...


+    if (INTEL_GEN(dev_priv) > 9 &&
+    !IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0))

please don't add CNL pre-prod wa

ok sure

+    return true;
+
+    if (!IS_KABYLAKE(dev_priv) && !IS_SKYLAKE(dev_priv))
+    return true;

actually remove all platforms checks here...

Agree will remove these checks, function will just return if memory is
symmetric.

+
+    if (val_ch0 != val_ch1)
+    return false;
+
+    if (ch0->s_info.size == 0)
+    return true;
+    if (ch0->l_info.size == ch0->s_info.size &&
+    ch0->l_info.width == ch0->s_info.width &&
+    ch0->l_info.rank == ch0->s_info.rank)
+    return true;
+
+    return false;

return (val_ch0 == val_ch1 && (ch0->s_info.size == 0 ||
     (ch0->l_info.size == ch0->s_info.size &&
   ch0->l_info.width == ch0->s_info.width &&
   ch0->l_info.rank == ch0->s_info.rank)))


+}
+
   static int
   skl_dram_get_channels_info(struct drm_i915_private *dev_priv)
   {
   struct dram_info *dram_info = _priv->dram_info;
   struct dram_channel_info ch0, ch1;
-    u32 val;
+    u32 val_ch0, val_ch1;
   int ret;

-    val = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
-    ret = skl_dram_get_channel_info(, val);
+    val_ch0 = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
+    ret = skl_dram_get_channel_info(, val_ch0);
   if (ret == 0)
   dram_info->num_channels++;

-    val = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
-    ret = skl_dram_get_channel_info(, val);
+    val_ch1 = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
+    ret = skl_dram_get_channel_info(, val_ch1);
   if (ret == 0)
   dram_info->num_channels++;

@@ -1185,6 +1211,13 @@ skl_dram_get_channels_info(struct
drm_i915_private *dev_priv)
   if (ch0.is_16gb_dimm || ch1.is_16gb_dimm)
   dram_info->is_16gb_dimm = true;

+    if (intel_is_dram_ipc_capable(dev_priv, val_ch0, val_ch1, ))
+    dev_priv->ipc_capable_mem = true;
+    else
+    dev_priv->ipc_capable_mem = false;
+
+    DRM_DEBUG_KMS("memory configuration is %sIPC capable\n",
+  dev_priv->ipc_capable_mem ? "" : "not ");
   return 0;
   }

diff --git a/drivers/gpu/drm/i915/i915_drv.h
b/drivers/gpu/drm/i915/i915_drv.h
index 854f3c828e01..036d6554c017 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2112,6 +2112,7 @@ struct drm_i915_private {
   bool chv_phy_assert[2];

   bool ipc_enabled;
+    bool ipc_capable_mem;

I don't think we need to stage this...

With above changes storing this info is not needed, But we need to keep
a flag in dram_info to check if "memory is symmetric", Otherwise we need
to compute all the memory related info again.

-Mahesh

   /* Used to save the pipe-to-encoder mapping for audio */
   struct intel_encoder *av_enc_map[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/intel_pm.c
b/drivers/gpu/drm/i915/intel_pm.c
index 2446f53adf21..39e400d5f555 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6097,7 +6097,7 @@ void intel_enable_ipc(struct
drm_i915_private *dev_priv)
   u32 val;

   /* Display WA #0477 WaDisableIPC: skl */
-    if (IS_SKYLAKE(dev_priv)) {
+    if (IS_SKYLAKE(dev_priv) || !dev_priv->ipc_capable_mem) {
   dev_priv->ipc_enabled = false;

This is not the WA 1141 for other platforms than SKL. Please only
keep skl here.

For the other WA add 4us across all watermark levels

Re: [Intel-gfx] [PATCH 4/5] drm/i915/kbl+: Enable IPC only for symmetric memory configurations

2018-08-21 Thread Kumar, Mahesh

Hi,


On 8/21/2018 8:27 PM, Kumar, Mahesh wrote:

Hi,


On 8/17/2018 11:50 PM, Rodrigo Vivi wrote:

On Thu, Jul 26, 2018 at 07:44:09PM +0530, Mahesh Kumar wrote:

IPC may cause underflows if not used with dual channel symmetric
memory configuration. Disable IPC for non symmetric configurations in
affected platforms.
Display WA #1141

Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/i915_drv.c | 43 
-

  drivers/gpu/drm/i915/i915_drv.h |  1 +
  drivers/gpu/drm/i915/intel_pm.c |  2 +-
  3 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c 
b/drivers/gpu/drm/i915/i915_drv.c

index 86bc2e685522..2273664166bc 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1141,21 +1141,47 @@ skl_dram_get_channel_info(struct 
dram_channel_info *ch, u32 val)

  return 0;
  }

+static bool
+intel_is_dram_ipc_capable(struct drm_i915_private *dev_priv,
+  u32 val_ch0, u32 val_ch1,
+  struct dram_channel_info *ch0)

what about
intel_is_dram_symmetric() ?

sounds good.

+{
+    /* Display WA #1141: SKL:all KBL:all CNL:A CNL:B */

move this to the wa call, not the the function check...


+    if (INTEL_GEN(dev_priv) > 9 &&
+    !IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0))

please don't add CNL pre-prod wa

ok sure



+    return true;
+
+    if (!IS_KABYLAKE(dev_priv) && !IS_SKYLAKE(dev_priv))
+    return true;

actually remove all platforms checks here...
Agree will remove these checks, function will just return if memory is 
symmetric.



+
+    if (val_ch0 != val_ch1)
+    return false;
+
+    if (ch0->s_info.size == 0)
+    return true;
+    if (ch0->l_info.size == ch0->s_info.size &&
+    ch0->l_info.width == ch0->s_info.width &&
+    ch0->l_info.rank == ch0->s_info.rank)
+    return true;
+
+    return false;

return (val_ch0 == val_ch1 && (ch0->s_info.size == 0 ||
    (ch0->l_info.size == ch0->s_info.size &&
  ch0->l_info.width == ch0->s_info.width &&
  ch0->l_info.rank == ch0->s_info.rank)))


+}
+
  static int
  skl_dram_get_channels_info(struct drm_i915_private *dev_priv)
  {
  struct dram_info *dram_info = _priv->dram_info;
  struct dram_channel_info ch0, ch1;
-    u32 val;
+    u32 val_ch0, val_ch1;
  int ret;

-    val = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
-    ret = skl_dram_get_channel_info(, val);
+    val_ch0 = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
+    ret = skl_dram_get_channel_info(, val_ch0);
  if (ret == 0)
  dram_info->num_channels++;

-    val = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
-    ret = skl_dram_get_channel_info(, val);
+    val_ch1 = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
+    ret = skl_dram_get_channel_info(, val_ch1);
  if (ret == 0)
  dram_info->num_channels++;

@@ -1185,6 +1211,13 @@ skl_dram_get_channels_info(struct 
drm_i915_private *dev_priv)

  if (ch0.is_16gb_dimm || ch1.is_16gb_dimm)
  dram_info->is_16gb_dimm = true;

+    if (intel_is_dram_ipc_capable(dev_priv, val_ch0, val_ch1, ))
+    dev_priv->ipc_capable_mem = true;
+    else
+    dev_priv->ipc_capable_mem = false;
+
+    DRM_DEBUG_KMS("memory configuration is %sIPC capable\n",
+  dev_priv->ipc_capable_mem ? "" : "not ");
  return 0;
  }

diff --git a/drivers/gpu/drm/i915/i915_drv.h 
b/drivers/gpu/drm/i915/i915_drv.h

index 854f3c828e01..036d6554c017 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2112,6 +2112,7 @@ struct drm_i915_private {
  bool chv_phy_assert[2];

  bool ipc_enabled;
+    bool ipc_capable_mem;

I don't think we need to stage this...
With above changes storing this info is not needed, But we need to 
keep a flag in dram_info to check if "memory is symmetric", Otherwise 
we need to compute all the memory related info again.


-Mahesh

  /* Used to save the pipe-to-encoder mapping for audio */
  struct intel_encoder *av_enc_map[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/intel_pm.c 
b/drivers/gpu/drm/i915/intel_pm.c

index 2446f53adf21..39e400d5f555 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6097,7 +6097,7 @@ void intel_enable_ipc(struct drm_i915_private 
*dev_priv)

  u32 val;

  /* Display WA #0477 WaDisableIPC: skl */
-    if (IS_SKYLAKE(dev_priv)) {
+    if (IS_SKYLAKE(dev_priv) || !dev_priv->ipc_capable_mem) {
  dev_priv->ipc_enabled = false;
This is not the WA 1141 for other platforms than SKL. Please only 
keep skl here.


For the other WA add 4us across all watermark levels

/* Display WA #1141: skl,kbl,cfl */
if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) &&
    intel_is_

Re: [Intel-gfx] [PATCH 4/5] drm/i915/kbl+: Enable IPC only for symmetric memory configurations

2018-08-21 Thread Kumar, Mahesh

Hi,


On 8/17/2018 11:50 PM, Rodrigo Vivi wrote:

On Thu, Jul 26, 2018 at 07:44:09PM +0530, Mahesh Kumar wrote:

IPC may cause underflows if not used with dual channel symmetric
memory configuration. Disable IPC for non symmetric configurations in
affected platforms.
Display WA #1141

Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/i915_drv.c | 43 -
  drivers/gpu/drm/i915/i915_drv.h |  1 +
  drivers/gpu/drm/i915/intel_pm.c |  2 +-
  3 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 86bc2e685522..2273664166bc 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1141,21 +1141,47 @@ skl_dram_get_channel_info(struct dram_channel_info *ch, 
u32 val)
return 0;
  }

+static bool
+intel_is_dram_ipc_capable(struct drm_i915_private *dev_priv,
+ u32 val_ch0, u32 val_ch1,
+ struct dram_channel_info *ch0)

what about
intel_is_dram_symmetric() ?

sounds good.

+{
+   /* Display WA #1141: SKL:all KBL:all CNL:A CNL:B */

move this to the wa call, not the the function check...


+   if (INTEL_GEN(dev_priv) > 9 &&
+   !IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0))

please don't add CNL pre-prod wa

ok sure



+   return true;
+
+   if (!IS_KABYLAKE(dev_priv) && !IS_SKYLAKE(dev_priv))
+   return true;

actually remove all platforms checks here...
Agree will remove these checks, function will just return if memory is 
symmetric.



+
+   if (val_ch0 != val_ch1)
+   return false;
+
+   if (ch0->s_info.size == 0)
+   return true;
+   if (ch0->l_info.size == ch0->s_info.size &&
+   ch0->l_info.width == ch0->s_info.width &&
+   ch0->l_info.rank == ch0->s_info.rank)
+   return true;
+
+   return false;

return (val_ch0 == val_ch1 && (ch0->s_info.size == 0 ||
(ch0->l_info.size == ch0->s_info.size &&
  ch0->l_info.width == ch0->s_info.width &&
  ch0->l_info.rank == ch0->s_info.rank)))


+}
+
  static int
  skl_dram_get_channels_info(struct drm_i915_private *dev_priv)
  {
struct dram_info *dram_info = _priv->dram_info;
struct dram_channel_info ch0, ch1;
-   u32 val;
+   u32 val_ch0, val_ch1;
int ret;

-   val = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
-   ret = skl_dram_get_channel_info(, val);
+   val_ch0 = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
+   ret = skl_dram_get_channel_info(, val_ch0);
if (ret == 0)
dram_info->num_channels++;

-   val = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
-   ret = skl_dram_get_channel_info(, val);
+   val_ch1 = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
+   ret = skl_dram_get_channel_info(, val_ch1);
if (ret == 0)
dram_info->num_channels++;

@@ -1185,6 +1211,13 @@ skl_dram_get_channels_info(struct drm_i915_private 
*dev_priv)
if (ch0.is_16gb_dimm || ch1.is_16gb_dimm)
dram_info->is_16gb_dimm = true;

+   if (intel_is_dram_ipc_capable(dev_priv, val_ch0, val_ch1, ))
+   dev_priv->ipc_capable_mem = true;
+   else
+   dev_priv->ipc_capable_mem = false;
+
+   DRM_DEBUG_KMS("memory configuration is %sIPC capable\n",
+ dev_priv->ipc_capable_mem ? "" : "not ");
return 0;
  }

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 854f3c828e01..036d6554c017 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2112,6 +2112,7 @@ struct drm_i915_private {
bool chv_phy_assert[2];

bool ipc_enabled;
+   bool ipc_capable_mem;

I don't think we need to stage this...
With above changes storing this info is not needed, But we need to keep 
a flag in dram_info to check if "memory is symmetric", Otherwise we need 
to compute all the memory related info again.


-Mahesh

/* Used to save the pipe-to-encoder mapping for audio */
struct intel_encoder *av_enc_map[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 2446f53adf21..39e400d5f555 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6097,7 +6097,7 @@ void intel_enable_ipc(struct drm_i915_private *dev_priv)
u32 val;

/* Display WA #0477 WaDisableIPC: skl */
-   if (IS_SKYLAKE(dev_priv)) {
+   if (IS_SKYLAKE(dev_priv) || !dev_priv->ipc_capable_mem) {
dev_priv->ipc_enabled = false;

This is not the WA 1141 for other platforms than SKL. Please only keep skl here.

For the other WA add 4us across all watermark levels

/* Display WA #1141: skl,kbl,cfl */
if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) &&
intel_is_dram_symmetric())
levels += 4;


   

Re: [Intel-gfx] [PATCH 2/5] drm/i915/skl+: Decode memory bandwidth and parameters

2018-08-21 Thread Kumar, Mahesh

Hi,


On 8/17/2018 4:05 AM, Rodrigo Vivi wrote:

On Thu, Jul 26, 2018 at 07:44:07PM +0530, Mahesh Kumar wrote:

This patch adds support to decode system memory bandwidth and other
parameters for skylake and Gen9+ platforms, which will be used for
arbitrated display memory bandwidth calculation in GEN9 based
platforms and WM latency level-0 Work-around calculation on GEN9+.

Changes Since V1:
  - s/memdev_info/dram_info
  - create a struct to hold channel info

Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/i915_drv.c | 131 ++--
  drivers/gpu/drm/i915/i915_drv.h |   7 +++
  drivers/gpu/drm/i915/i915_reg.h |  21 +++
  3 files changed, 155 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 16629601c9f4..ddf6bf9b500a 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1070,6 +1070,118 @@ static void intel_sanitize_options(struct 
drm_i915_private *dev_priv)
intel_gvt_sanitize_options(dev_priv);
  }
  
+static int

+skl_dram_get_channel_info(struct dram_channel_info *ch, u32 val)
+{
+   u8 l_rank, s_rank;
+   u8 l_size, s_size;
+   u8 l_width, s_width;
+   enum dram_rank rank;
+
+   if (!val)
+   return -1;

-SOMEERRNO?

ok sure.



+
+   l_size = (val >> SKL_DRAM_SIZE_L_SHIFT) & SKL_DRAM_SIZE_MASK;
+   s_size = (val >> SKL_DRAM_SIZE_S_SHIFT) & SKL_DRAM_SIZE_MASK;
+   l_width = (val >> SKL_DRAM_WIDTH_L_SHIFT) & SKL_DRAM_WIDTH_MASK;
+   s_width = (val >> SKL_DRAM_WIDTH_S_SHIFT) & SKL_DRAM_WIDTH_MASK;
+   l_rank = (val >> SKL_DRAM_RANK_L_SHIFT) & SKL_DRAM_RANK_MASK;
+   s_rank = (val >> SKL_DRAM_RANK_S_SHIFT) & SKL_DRAM_RANK_MASK;
+
+   if (l_size == 0 && s_size == 0)
+   return -1;

ditto


+
+   DRM_DEBUG_KMS("(size:width:rank) L(%dGB:X%d:%s) S(%dGB:X%d:%s)\n",
+ l_size, (1 << l_width) * 8, l_rank ? "dual" : "single",
+ s_size, (1 << s_width) * 8, s_rank ? "dual" : "single");
+
+   if (l_rank == SKL_DRAM_RANK_DUAL || s_rank == SKL_DRAM_RANK_DUAL)
+   rank = I915_DRAM_RANK_DUAL;
+   else if ((l_size && l_rank == SKL_DRAM_RANK_SINGLE) &&
+(s_size && s_rank == SKL_DRAM_RANK_SINGLE))
+   rank = I915_DRAM_RANK_DUAL;
+   else
+   rank = I915_DRAM_RANK_SINGLE;
+
+   ch->l_info.size = l_size;
+   ch->s_info.size = s_size;
+   ch->l_info.width = l_width;
+   ch->s_info.width = s_width;
+   ch->l_info.rank = l_rank;
+   ch->s_info.rank = s_rank;
+   ch->rank = rank;

could we do this directly without intermediates? not clear if we change
in the middle after printing...
This information is needed later while checking is memories are 
symmetric, that's why we need to keep this as well.



+
+   return 0;
+}
+
+static int
+skl_dram_get_channels_info(struct drm_i915_private *dev_priv)
+{
+   struct dram_info *dram_info = _priv->dram_info;
+   struct dram_channel_info ch0, ch1;
+   u32 val;
+   int ret;
+
+   val = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
+   ret = skl_dram_get_channel_info(, val);
+   if (ret == 0)
+   dram_info->num_channels++;
+
+   val = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
+   ret = skl_dram_get_channel_info(, val);
+   if (ret == 0)
+   dram_info->num_channels++;
+
+   if (dram_info->num_channels == 0) {
+   DRM_INFO("Number of memory channels is zero\n");
+   return -EINVAL;
+   }
+
+   /*
+* If any of the channel is single rank channel, worst case output
+* will be same as if single rank memory, so consider single rank
+* memory.
+*/
+   if (ch0.rank == I915_DRAM_RANK_SINGLE ||
+   ch1.rank == I915_DRAM_RANK_SINGLE)
+   dram_info->rank = I915_DRAM_RANK_SINGLE;
+   else
+   dram_info->rank = max(ch0.rank, ch1.rank);
+
+   if (dram_info->rank == I915_DRAM_RANK_INVALID) {
+   DRM_INFO("couldn't get memory rank information\n");
+   return -EINVAL;
+   }
+   return 0;
+}
+
+static int
+skl_get_dram_info(struct drm_i915_private *dev_priv)
+{
+   struct dram_info *dram_info = _priv->dram_info;
+   u32 mem_freq_khz, val;
+   int ret;
+
+   ret = skl_dram_get_channels_info(dev_priv);
+   if (ret)
+   return ret;
+
+   val = I915_READ(SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU);
+   mem_freq_khz = DIV_ROUND_UP((val & SKL_REQ_DATA_MASK) *
+   SKL_MEMORY_FREQ_MULTIPLIER_HZ, 1000);
+
+   dram_info->bandwidth_kbps = dram_info->num_channels *
+   mem_freq_khz * 8;
+
+   if (dram_info->bandwidth_kbps == 0) {
+   DRM_INFO("Couldn't get system memory bandwidth\n");
+   return -EINVAL;
+  

Re: [Intel-gfx] [PATCH 1/5] drm/i915/bxt: Decode memory bandwidth and parameters

2018-08-21 Thread Kumar, Mahesh

Hi,


On 8/17/2018 11:13 PM, Rodrigo Vivi wrote:

On Thu, Jul 26, 2018 at 07:44:06PM +0530, Mahesh Kumar wrote:

This patch adds support to decode system memory bandwidth and other
parameters for broxton platform, which will be used for arbitrated
display memory bandwidth calculation in GEN9 based platforms and
WM latency level-0 Work-around calculation on GEN9+ platforms.

Changes since V1:
  - s/memdev_info/dram_info

Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/i915_drv.c | 116 
  drivers/gpu/drm/i915/i915_drv.h |  11 
  drivers/gpu/drm/i915/i915_reg.h |  30 +++
  3 files changed, 157 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 18a45e7a3d7c..16629601c9f4 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1070,6 +1070,116 @@ static void intel_sanitize_options(struct 
drm_i915_private *dev_priv)
intel_gvt_sanitize_options(dev_priv);
  }

+static int
+bxt_get_dram_info(struct drm_i915_private *dev_priv)
+{
+   struct dram_info *dram_info = _priv->dram_info;
+   u32 dram_channels;
+   u32 mem_freq_khz, val;
+   u8 num_active_channels;
+   int i;
+
+   val = I915_READ(BXT_P_CR_MC_BIOS_REQ_0_0_0);
+   mem_freq_khz = DIV_ROUND_UP((val & BXT_REQ_DATA_MASK) *
+   BXT_MEMORY_FREQ_MULTIPLIER_HZ, 1000);
+
+   dram_channels = (val >> BXT_DRAM_CHANNEL_ACTIVE_SHIFT) &
+   BXT_DRAM_CHANNEL_ACTIVE_MASK;
+   num_active_channels = hweight32(dram_channels);
+
+   /* Each active bit represents 4-byte channel */
+   dram_info->bandwidth_kbps = (mem_freq_khz * num_active_channels * 4);
+
+   if (dram_info->bandwidth_kbps == 0) {
+   DRM_INFO("Couldn't get system memory bandwidth\n");
+   return -EINVAL;
+   }
+
+   /*
+* Now read each DUNIT8/9/10/11 to check the rank of each dimms.
+*/
+   for (i = BXT_D_CR_DRP0_DUNIT_START; i <= BXT_D_CR_DRP0_DUNIT_END; i++) {
+   u8 rank, size, width;
+   enum dram_rank ch_rank;
+
+   val = I915_READ(BXT_D_CR_DRP0_DUNIT(i));
+   if (val == 0x)
+   continue;
+
+   dram_info->num_channels++;
+   rank = val & BXT_DRAM_RANK_MASK;
+   width = (val >> BXT_DRAM_WIDTH_SHIFT) & BXT_DRAM_WIDTH_MASK;
+   size = (val >> BXT_DRAM_SIZE_SHIFT) & BXT_DRAM_SIZE_MASK;
+   if (rank == BXT_DRAM_RANK_SINGLE)
+   ch_rank = I915_DRAM_RANK_SINGLE;
+   else if (rank == BXT_DRAM_RANK_DUAL)
+   ch_rank = I915_DRAM_RANK_DUAL;
+   else
+   ch_rank = I915_DRAM_RANK_INVALID;
+
+   if (size == BXT_DRAM_SIZE_4GB)
+   size = 4;
+   else if (size == BXT_DRAM_SIZE_6GB)
+   size = 6;
+   else if (size == BXT_DRAM_SIZE_8GB)
+   size = 8;
+   else if (size == BXT_DRAM_SIZE_12GB)
+   size = 12;
+   else if (size == BXT_DRAM_SIZE_16GB)
+   size = 16;
+   else
+   size = 0;
+
+   width = (1 << width) * 8;
+   DRM_DEBUG_KMS("dram size:%dGB width:X%d rank:%s\n", size,
+ width, rank == BXT_DRAM_RANK_SINGLE ? "single" :
+ rank == BXT_DRAM_RANK_DUAL ? "dual" : "unknown");
+
+   /*
+* If any of the channel is single rank channel,
+* worst case output will be same as if single rank
+* memory, so consider single rank memory.
+*/
+   if (dram_info->rank == I915_DRAM_RANK_INVALID)
+   dram_info->rank = ch_rank;
+   else if (ch_rank == I915_DRAM_RANK_SINGLE)
+   dram_info->rank = I915_DRAM_RANK_SINGLE;
+   }
+
+   if (dram_info->rank == I915_DRAM_RANK_INVALID) {
+   DRM_INFO("couldn't get memory rank information\n");
+   return -EINVAL;
+   }
+
+   dram_info->valid = true;
+   return 0;
+}
+
+static void
+intel_get_dram_info(struct drm_i915_private *dev_priv)
+{
+   struct dram_info *dram_info = _priv->dram_info;
+   int ret;
+
+   dram_info->valid = false;
+   dram_info->rank = I915_DRAM_RANK_INVALID;
+   dram_info->bandwidth_kbps = 0;
+   dram_info->num_channels = 0;
+
+   if (!IS_BROXTON(dev_priv))
+   return;
+
+   ret = bxt_get_dram_info(dev_priv);
+   if (ret)
+   return;
+
+   DRM_DEBUG_KMS("DRAM bandwidth:%d KBps, total-channels: %u\n",
+ dram_info->bandwidth_kbps, dram_info->num_channels);
+   DRM_DEBUG_KMS("DRAM rank: %s rank\n",
+ 

Re: [Intel-gfx] [PATCH V2 1/3] drm/vkms/crc: Implement verify_crc_source callback

2018-08-20 Thread Kumar, Mahesh

Hi Haneen,


On 8/21/2018 4:09 AM, Haneen Mohammed wrote:

On Tue, Aug 14, 2018 at 08:31:03AM +0530, Mahesh Kumar wrote:

This patch implements "verify_crc_source" callback function for
Virtual KMS drm driver.

Changes Since V1:
- update values_cnt in verify_crc_source

Cc: Haneen Mohammed 
Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/vkms/vkms_crc.c  | 38 ++
  drivers/gpu/drm/vkms/vkms_crtc.c |  1 +
  drivers/gpu/drm/vkms/vkms_drv.h  |  2 ++
  3 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_crc.c b/drivers/gpu/drm/vkms/vkms_crc.c
index 37d717f38e3c..b2a484b4e2ad 100644
--- a/drivers/gpu/drm/vkms/vkms_crc.c
+++ b/drivers/gpu/drm/vkms/vkms_crc.c
@@ -70,6 +70,37 @@ void vkms_crc_work_handle(struct work_struct *work)
drm_crtc_add_crc_entry(crtc, true, crtc_state->n_frame, );
  }
  
+static int vkms_crc_parse_source(const char *src_name, bool *enabled)

+{
+   int ret = 0;
+
+   if (!src_name) {
+   *enabled = false;
+   } else if (strcmp(src_name, "auto") == 0) {
+   *enabled = true;
+   } else {
+   *enabled = false;
+   ret = -EINVAL;
+   }
+
+   return ret;
+}
+
+int vkms_verify_crc_source(struct drm_crtc *crtc, const char *src_name,
+  size_t *values_cnt)
+{
+   bool enabled;
+
+   if (vkms_crc_parse_source(src_name, ) < 0) {
+   DRM_DEBUG_DRIVER("unknown source %s\n", src_name);
+   return -EINVAL;
+   }
+
+   *values_cnt = 1;
+
+   return 0;
+}
+
  int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name,
size_t *values_cnt)
  {
@@ -78,10 +109,9 @@ int vkms_set_crc_source(struct drm_crtc *crtc, const char 
*src_name,
unsigned long flags;
int ret = 0;
  
-	if (src_name && strcmp(src_name, "auto") == 0)

-   enabled = true;
-   else if (src_name)
-   ret = -EINVAL;
+   ret = vkms_crc_parse_source(src_name, );
+   if (ret)
+   return ret;

I think the return value after vkms_crc_parse_source should be called
once instead at the end of vkms_set_crc_source otherwise crc_enabled
won't be updated?
Here I'm assuming if src_name is wrong we don't need to proceed further, 
let the CRC generation to continue whatever it was doing (enabled or 
disabled).
But anyway that is changing the original design, will remove above 
return to keep the behavior same.


-Mahesh


- Haneen

  
  	*values_cnt = 1;
  
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c

index bfe6e0312cc4..9d0b1a325a78 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -140,6 +140,7 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = {
.enable_vblank  = vkms_enable_vblank,
.disable_vblank = vkms_disable_vblank,
.set_crc_source = vkms_set_crc_source,
+   .verify_crc_source  = vkms_verify_crc_source,
  };
  
  static void vkms_crtc_atomic_enable(struct drm_crtc *crtc,

diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index f156c930366a..090c5e4f5544 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -125,6 +125,8 @@ void vkms_gem_vunmap(struct drm_gem_object *obj);
  /* CRC Support */
  int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name,
size_t *values_cnt);
+int vkms_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
+  size_t *values_cnt);
  void vkms_crc_work_handle(struct work_struct *work);
  
  #endif /* _VKMS_DRV_H_ */

--
2.16.2



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


Re: [Intel-gfx] [PATCH i-g-t] tests/kms_pipe_crc_basic: expect setting bad source to fail

2018-08-02 Thread Kumar, Mahesh

Hi,


On 8/2/2018 4:13 PM, Maarten Lankhorst wrote:

Op 02-08-18 om 12:42 schreef Maarten Lankhorst:

Op 02-07-18 om 13:27 schreef Maarten Lankhorst:

Op 02-07-18 om 13:16 schreef Mahesh Kumar:

Now crc-core framework verifies the source string passed by the user.
So setting bad-source will fail. Expect file write to fail in bad-source
subtest of kms_pipe_crc_basic.

Signed-off-by: Mahesh Kumar 
---
  tests/kms_pipe_crc_basic.c | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tests/kms_pipe_crc_basic.c b/tests/kms_pipe_crc_basic.c
index 235fdc38..2d4dfee8 100644
--- a/tests/kms_pipe_crc_basic.c
+++ b/tests/kms_pipe_crc_basic.c
@@ -48,8 +48,7 @@ static struct {
  
  static void test_bad_source(data_t *data)

  {
-   igt_assert(igt_sysfs_set(data->debugfs, "crtc-0/crc/control", "foo"));
-   igt_assert(openat(data->debugfs, "crtc-0/crc/data", O_WRONLY) == -1);
+   igt_assert(!igt_sysfs_set(data->debugfs, "crtc-0/crc/control", "foo"));
  }
  
  #define N_CRCS	3

New behavior makes more sense.

Reviewed-by: Maarten Lankhorst 

Do you have igt commit rights?


Any objections if we change this to allow both behaviors?

diff --git a/tests/kms_pipe_crc_basic.c b/tests/kms_pipe_crc_basic.c
index 235fdc386ba2..91909fa42f2f 100644
--- a/tests/kms_pipe_crc_basic.c
+++ b/tests/kms_pipe_crc_basic.c
@@ -48,8 +48,11 @@ static struct {
  
  static void test_bad_source(data_t *data)

  {
-   igt_assert(igt_sysfs_set(data->debugfs, "crtc-0/crc/control", "foo"));
-   igt_assert(openat(data->debugfs, "crtc-0/crc/data", O_WRONLY) == -1);
+   errno = 0;
+   if (igt_sysfs_set(data->debugfs, "crtc-0/crc/control", "foo"))
+   igt_assert(openat(data->debugfs, "crtc-0/crc/data", O_WRONLY) 
== -1);
+   else
+   igt_assert_eq(errno, EINVAL);
  }
  
  #define N_CRCS	3



Hm without the else, errno should be EINVAL in any case..

agree, with this change
Reviewed-by: Mahesh Kumar 

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


Re: [Intel-gfx] [PATCH] drm/i915/icl: avoid unclaimed PLANE_NV12_BUF_CFG register

2018-08-01 Thread Kumar, Mahesh

Hi,

Reviewed-by: Mahesh Kumar 

-Mahesh
On 8/1/2018 6:16 AM, Paulo Zanoni wrote:

We don't have proper watermark NV12 support on ICL due to differences
in how it should be implemented. In commit 234059da0f33
("drm/i915/icl: NV12 y-plane ddb is not in same plane") we avoided
writing the non-existent PLANE_NV12_BUF_CFG registers but we forgot to
also avoid them on the hardware state readout. While the code is still
not correct, at least now we can avoid unclaimed register error
messages when dealing with RGB formats, which makes CI happier.

Also add some FIXME comments in order to make it even more clear that
there's still work to do.

References: commit 234059da0f33 ("drm/i915/icl: NV12 y-plane ddb is
  not in same plane")
Cc: Mahesh Kumar 
Signed-off-by: Paulo Zanoni 
---
  drivers/gpu/drm/i915/intel_pm.c | 8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 2531eb75bdce..04cef1369e8c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3909,7 +3909,12 @@ skl_ddb_get_hw_plane_state(struct drm_i915_private 
*dev_priv,
  val & PLANE_CTL_ALPHA_MASK);
  
  	val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));

-   val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id));
+   /*
+* FIXME: add proper NV12 support for ICL. Avoid reading unclaimed
+* registers for now.
+*/
+   if (INTEL_GEN(dev_priv) < 11)
+   val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id));
  
  	if (fourcc == DRM_FORMAT_NV12) {

skl_ddb_entry_init_from_hw(dev_priv,
@@ -4977,6 +4982,7 @@ static void skl_write_plane_wm(struct intel_crtc 
*intel_crtc,
  
  	skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),

>plane[pipe][plane_id]);
+   /* FIXME: add proper NV12 support for ICL. */
if (INTEL_GEN(dev_priv) >= 11)
return skl_ddb_entry_write(dev_priv,
   PLANE_BUF_CFG(pipe, plane_id),


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


Re: [Intel-gfx] [PATCH 3/5] drm/i915: Implement 16GB dimm wa for latency level-0

2018-07-31 Thread Kumar, Mahesh

Hi,


On 7/28/2018 11:18 AM, Rodrigo Vivi wrote:

On Fri, Jul 27, 2018 at 11:40:14AM +0530, Kumar, Mahesh wrote:

Hi Matt,


On 7/27/2018 9:21 AM, Matt Turner wrote:

On Thu, Jul 26, 2018 at 7:14 AM, Mahesh Kumar  wrote:

Bspec: 4381

Do we know that these numbers are stable?

yes these numbers are fixed in Bspec

I don't know if this form is common in the kernel, but in Mesa we
specify the name of the page which should always allow readers to find
it.

This is common practice in kernel to give Bspec Number reference instead of
name of the page.

Well, I believe Matt has a good point here.
It is stable for now and for a while, but we had seen changes
on the web interface in use. Also this number doesn't help devs who
don't use the web interface.
sure, will update this in next version. Will float updated series once 
receive review comments on other patches.


-Mahesh



-Mahesh

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


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


Re: [Intel-gfx] [PATCH] drm/i915/skl: distribute DDB based on panel resolution

2018-07-31 Thread Kumar, Mahesh

Hi Chris,

Thanks for review.

On 7/30/2018 9:08 PM, Chris Wilson wrote:

Quoting Mahesh Kumar (2018-07-30 15:12:02)

We distribute DDB equally among all pipes irrespective of display
buffer requirement of each pipe. This leads to a situation where high
resolution y-tiled display can not be enabled with 2 low resolution
displays.

Main contributing factor for DDB requirement is width of the display.
This patch make changes to distribute ddb based on display width.
So display with higher width will get bigger chunk of DDB.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107113
Cc: raviraj.p.sita...@intel.com
Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/intel_pm.c | 55 +++--
  1 file changed, 42 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7312ecb73415..e092f0deb93d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3814,8 +3814,14 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device 
*dev,
 struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 struct drm_i915_private *dev_priv = to_i915(dev);
 struct drm_crtc *for_crtc = cstate->base.crtc;
+   enum pipe for_pipe = to_intel_crtc(for_crtc)->pipe;
+   const struct drm_crtc_state *crtc_state;
+   const struct drm_crtc *crtc;
+   u32 pipe_width[I915_MAX_PIPES] = {0};
+   u32 total_width = 0, width_before_pipe = 0;
 unsigned int pipe_size, ddb_size;
-   int nth_active_pipe;
+   u16 ddb_size_before_pipe;
+   u32 i;
  
 if (WARN_ON(!state) || !cstate->base.active) {

 alloc->start = 0;
@@ -3833,14 +3839,14 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device 
*dev,
   *num_active, ddb);
  
 /*

-* If the state doesn't change the active CRTC's, then there's
-* no need to recalculate; the existing pipe allocation limits
-* should remain unchanged.  Note that we're safe from racing
-* commits since any racing commit that changes the active CRTC
-* list would need to grab _all_ crtc locks, including the one
-* we currently hold.
+* If the state doesn't change the active CRTC's or there is no
+* modeset request, then there's no need to recalculate;
+* the existing pipe allocation limits should remain unchanged.
+* Note that we're safe from racing commits since any racing commit
+* that changes the active CRTC list or do modeset would need to
+* grab _all_ crtc locks, including the one we currently hold.
  */
-   if (!intel_state->active_pipe_changes) {
+   if (!intel_state->active_pipe_changes && !intel_state->modeset) {
 /*
  * alloc may be cleared by clear_intel_crtc_state,
  * copy from old state to be sure
@@ -3849,10 +3855,33 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device 
*dev,
 return;
 }
  
-   nth_active_pipe = hweight32(intel_state->active_crtcs &

-   (drm_crtc_mask(for_crtc) - 1));
-   pipe_size = ddb_size / hweight32(intel_state->active_crtcs);
-   alloc->start = nth_active_pipe * ddb_size / *num_active;
+   /*
+* Watermark/ddb requirement highly depends upon width of the
+* framebuffer, So instead of allocating DDB equally among pipes
+* distribute DDB based on resolution/width of the display.
+*/
+   for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+   const struct drm_display_mode *adjusted_mode;
+   int hdisplay, vdisplay;
+   enum pipe pipe;
+
+   if (!crtc_state->enable)
+   continue;
+
+   pipe = to_intel_crtc(crtc)->pipe;
+   adjusted_mode = _state->adjusted_mode;
+   drm_mode_get_hv_timing(adjusted_mode, , );
+   pipe_width[pipe] = hdisplay;
+   total_width += pipe_width[pipe];
+
+   if (pipe < for_pipe)
+   width_before_pipe += pipe_width[pipe];
+   }
+
+   ddb_size_before_pipe = div_u64(ddb_size * width_before_pipe,
+  total_width);

ddb_size is unsigned int (u32)
width_before_pipe is u32
ddb_size_before_pipe is u16

That mismash of types is itself perplexing, but u32*u16 is only u32, you
need to cast it to u64 to avoid the overflow: i.e.
div_u64(mul_u32_u32(ddb_size, width_before_pipe),
total_width);

But ddb_size_before_pipe obviously need to be the same type as ddb_size,
and if u16 is good enough, then you do not need a 64b divide!
hmm, ddb_size will not go beyond u16 as we have only 1024 blocks and in 
future also I'm not expecting it to overflow u16.
I don't wanted to change already used data-types , anyway will clean 
this 

Re: [Intel-gfx] [PATCH 3/5] drm/i915: Implement 16GB dimm wa for latency level-0

2018-07-27 Thread Kumar, Mahesh

Hi Matt,


On 7/27/2018 9:21 AM, Matt Turner wrote:

On Thu, Jul 26, 2018 at 7:14 AM, Mahesh Kumar  wrote:

Bspec: 4381

Do we know that these numbers are stable?

yes these numbers are fixed in Bspec

I don't know if this form is common in the kernel, but in Mesa we
specify the name of the page which should always allow readers to find
it.
This is common practice in kernel to give Bspec Number reference instead 
of name of the page.

-Mahesh

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


Re: [Intel-gfx] [PATCH] drm/i915: inline skl_copy_ddb_for_pipe() to its only caller

2018-07-26 Thread Kumar, Mahesh

Hi,

Patch LGTM.

Reviewed-by: Mahesh Kumar 

thanks,

-Mahesh
On 6/8/2018 4:37 AM, Paulo Zanoni wrote:

While things may have been different before, right now the function is
very simple and has a single caller. IMHO any possible benefits from
an abstraction here are gone and not worth the price of the current
indirection while reading the code.

Cc: Mahesh Kumar 
Signed-off-by: Paulo Zanoni 
---
  drivers/gpu/drm/i915/intel_pm.c | 16 
  1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 533e6886..018aae9f5769 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5141,17 +5141,6 @@ skl_compute_ddb(struct drm_atomic_state *state)
return 0;
  }
  
-static void

-skl_copy_ddb_for_pipe(struct skl_ddb_values *dst,
- struct skl_ddb_values *src,
- enum pipe pipe)
-{
-   memcpy(dst->ddb.uv_plane[pipe], src->ddb.uv_plane[pipe],
-  sizeof(dst->ddb.uv_plane[pipe]));
-   memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe],
-  sizeof(dst->ddb.plane[pipe]));
-}
-
  static void
  skl_print_wm_changes(const struct drm_atomic_state *state)
  {
@@ -5381,7 +5370,10 @@ static void skl_initial_wm(struct intel_atomic_state 
*state,
if (cstate->base.active_changed)
skl_atomic_update_crtc_wm(state, cstate);
  
-	skl_copy_ddb_for_pipe(hw_vals, results, pipe);

+   memcpy(hw_vals->ddb.uv_plane[pipe], results->ddb.uv_plane[pipe],
+  sizeof(hw_vals->ddb.uv_plane[pipe]));
+   memcpy(hw_vals->ddb.plane[pipe], results->ddb.plane[pipe],
+  sizeof(hw_vals->ddb.plane[pipe]));
  
  	mutex_unlock(_priv->wm.wm_mutex);

  }


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


Re: [Intel-gfx] [PATCH v4 10/10] drm/rcar-du/crc: Implement get_crc_sources callback

2018-07-19 Thread Kumar, Mahesh

Hi Laurent!

Thanks for the review. :)

will update patch and resubmit

-Mahesh

On 7/19/2018 4:42 PM, Laurent Pinchart wrote:

Hi Mahesh,

Thank you for the patch.

On Friday, 13 July 2018 16:59:42 EEST Mahesh Kumar wrote:

This patch implements get_crc_sources callback, which returns list of
all the crc sources supported by driver in current platform.

Changes Since V1:
  - move sources list per-crtc
  - init sources-list only for gen3

Signed-off-by: Mahesh Kumar 
Cc: Laurent Pinchart 
---
  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 96 ++-
  drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  3 ++
  2 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 6a29055a4ab0..bbe417e93fe3
100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -691,6 +691,79 @@ static const struct drm_crtc_helper_funcs
crtc_helper_funcs = { .atomic_disable = rcar_du_crtc_atomic_disable,
  };

+static void rcar_du_crtc_crc_sources_list_init(struct rcar_du_crtc *rcrtc)
+{
+   struct rcar_du_device *rcdu = rcrtc->group->dev;
+   struct drm_device *dev = rcrtc->crtc.dev;
+   struct drm_crtc *crtc = >crtc;
+   struct drm_plane *plane;
+   unsigned int count;
+   const char **sources;
+   u32 plane_mask;
+   int i = 0;

i never takes negative values, it can be an unsigned int.


+   /* CRC available only on Gen3 HW */

Please capitalize sentences and end them with a period in comments to match
the driver's style. This applies to other locations in this patch.


+   if (rcdu->info->gen < 3)
+   goto fail;

You can just return here, sources_count and sources are initialized to 0 when
the rcar_du_crtc structure is allocated.


+   drm_for_each_plane(plane, dev) {
+   if (drm_crtc_mask(crtc) & plane->possible_crtcs) {
+   count++;
+   plane_mask |= drm_plane_mask(plane);
+   }
+   }

You can instead iterate over the planes of the associated VSP (hardware
composer).

/* Reserve 1 for "auto" source. */
count = rcrtc->vsp->num_planes + 1;

and get rid of plane_mask.


+   /* reserve 1 for "auto" source */
+   count += 1;
+   sources = kmalloc_array(count, sizeof(char *), GFP_KERNEL);

s/sizeof(char *)/sizeof(*sources)/


+   if (!sources)
+   goto fail;
+
+   sources[i] = kstrdup("auto", GFP_KERNEL);
+   if (!sources[i])
+   goto fail_no_mem;
+
+   i++;
+   drm_for_each_plane_mask(plane, dev, plane_mask) {
+   char name[16];
+
+   sprintf(name, "plane%d", plane->base.id);

The ID is an unsigned integer, you should use %u.


+   sources[i] = kstrdup(name, GFP_KERNEL);
+   if (!sources[i])
+   goto fail_no_mem;

As there will be a single error label, you can just name it "error".


+   i++;
+   }

You can iterate over the VSP planes here too.

for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
struct drm_plane *plane = >vsp->planes[i].plane;
char name[16];

sprintf(name, "plane%u", plane->base.id);
sources[i+1] = kstrdup(name, GFP_KERNEL);
if (!sources[i+1])
goto error;
}


+   rcrtc->sources = sources;
+   rcrtc->sources_count = count;
+   return;
+
+fail_no_mem:
+   while (i > 0) {
+   i--;
+   kfree(sources[i]);
+   }

You'll have to adapt it based on the code above.


+   kfree(sources);
+fail:
+   rcrtc->sources = NULL;
+   rcrtc->sources_count = 0;
+}
+
+static void rcar_du_crtc_crc_sources_list_uninit(struct rcar_du_crtc
*rcrtc)
+{
+   unsigned int i;
+
+   if (!rcrtc->sources)
+   return;
+
+   for (i = 0; i < rcrtc->sources_count; i++)
+   kfree(rcrtc->sources[i]);
+   kfree(rcrtc->sources);
+
+   rcrtc->sources = NULL;
+   rcrtc->sources_count = 0;
+}
+
  static struct drm_crtc_state *
  rcar_du_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
  {
@@ -717,6 +790,15 @@ static void rcar_du_crtc_atomic_destroy_state(struct
drm_crtc *crtc, kfree(to_rcar_crtc_state(state));
  }

+static void rcar_du_crtc_cleanup(struct drm_crtc *crtc)
+{
+   struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+
+   rcar_du_crtc_crc_sources_list_uninit(rcrtc);
+
+   return drm_crtc_cleanup(crtc);
+}
+
  static void rcar_du_crtc_reset(struct drm_crtc *crtc)
  {
struct rcar_du_crtc_state *state;
@@ -811,6 +893,15 @@ static int rcar_du_crtc_verify_crc_source(struct
drm_crtc *crtc, return 0;
  }

+const char *const *rcar_du_crtc_get_crc_sources(struct drm_crtc *crtc,
+   size_t *count)
+{
+   struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+
+   

Re: [Intel-gfx] [PATCH 3/3] drm/i915: Implement 16GB dimm wa for latency level-0

2018-07-18 Thread Kumar, Mahesh

Hi,


On 7/18/2018 5:34 PM, Ville Syrjälä wrote:

On Sat, Jul 14, 2018 at 07:40:43PM +0530, Kumar, Mahesh wrote:

Hi,

Thanks for review.


On 7/13/2018 8:27 PM, Ville Syrjälä wrote:

On Fri, Jul 13, 2018 at 07:41:24PM +0530, Mahesh Kumar wrote:

Memory with 16GB dimms require an increase of 1us in level-0 latency.
This patch implements the same.
Bspec: 4381

Signed-off-by: Mahesh Kumar 
---
   drivers/gpu/drm/i915/i915_drv.c | 35 +--
   drivers/gpu/drm/i915/i915_drv.h |  2 ++
   drivers/gpu/drm/i915/intel_pm.c | 13 +
   3 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index b93194cbd820..c6d30653d70c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1063,6 +1063,29 @@ static void intel_sanitize_options(struct 
drm_i915_private *dev_priv)
intel_gvt_sanitize_options(dev_priv);
   }
   
+static void

+intel_memdev_is_16gb_dimm(struct memdev_info *memdev_info,
+ u8 rank, u8 size, u8 width)
+{
+   bool found_16gb_dimm = false;
+
+   if (size == 16 && width == SKL_DRAM_WIDTH_X8 &&
+   rank == SKL_DRAM_RANK_SINGLE)
+   found_16gb_dimm = true;
+   else if (size == 32 && width == SKL_DRAM_WIDTH_X8 &&
+rank == SKL_DRAM_RANK_DUAL)
+   found_16gb_dimm = true;
+   else if (size == 8 && width == SKL_DRAM_WIDTH_X16 &&
+rank == SKL_DRAM_RANK_SINGLE)
+   found_16gb_dimm = true;
+   else if (size == 16 && width == SKL_DRAM_WIDTH_X16 &&
+rank == SKL_DRAM_RANK_DUAL)
+   found_16gb_dimm = true;
+
+   if (!memdev_info->is_16gb_dimm)
+   memdev_info->is_16gb_dimm = found_16gb_dimm;
+}

Pure functions are generally more fun. Would also make the function name
match the implementation.

Are you suggesting to change the name to only "is_16gb_dimm" ?

I'm suggesting making it pure.

ok sure, got it.

-Mahesh




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


Re: [Intel-gfx] [PATCH 0/3] Decode memdev info and bandwidth and implemnt latency WA

2018-07-18 Thread Kumar, Mahesh

Hi,


On 7/18/2018 5:33 PM, Ville Syrjälä wrote:

On Sat, Jul 14, 2018 at 07:42:17PM +0530, Kumar, Mahesh wrote:


On 7/13/2018 8:21 PM, Ville Syrjälä wrote:

On Fri, Jul 13, 2018 at 07:41:21PM +0530, Mahesh Kumar wrote:

This series adds support to calculate system memdev parameters and calculate

What's "memdev"?

memory device.

Still not sure what that means. Makes me think of something akin to chardev
or blockdev. I guess I'd just call it mem_info or something like that.
It's in reality dram specification information, what about if we call it 
"dram_info"?

If ok, will update all the occurrence to s/memdev_info/dram_info

-Mahesh



-Mahesh

total system memory bandwidth. This parameters and BW will be used to enable
WM level-0 latency workaround and display memory bandwidth related WA for gen9.

Mahesh Kumar (3):
drm/i915/bxt: Decode memory bandwidth and parameters
drm/i915/skl+: Decode memory bandwidth and parameters
drm/i915: Implement 16GB dimm wa for latency level-0

   drivers/gpu/drm/i915/i915_drv.c | 261 

   drivers/gpu/drm/i915/i915_drv.h |  13 ++
   drivers/gpu/drm/i915/i915_reg.h |  51 
   drivers/gpu/drm/i915/intel_pm.c |  13 ++
   4 files changed, 338 insertions(+)

--
2.16.2

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


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


Re: [Intel-gfx] [PATCH 00/10] Improve crc-core driver interface

2018-07-16 Thread Kumar, Mahesh

Hi,

thanks for the review.


On 7/12/2018 4:38 PM, Laurent Pinchart wrote:

Hi Mahesh,

Thank you for the patches.

When resubmitting patch series, could you please add a version number to the
[PATCH] prefix ? Otherwise it gets difficult to figure out which version is
the latest. This can be done automatically with the -v argument to git-format-
patch.
sure :), added patch prefix (now v4) and re-floated the series after 
addressing review comments in patches 03/10, 08/10 & 10/10.


-Mahesh


On Thursday, 12 July 2018 11:36:25 EEST Mahesh Kumar wrote:

This series improves crc-core <-> driver interface.
This series adds following functionality in the crc-core
  - Now control node will print all the available sources if
implemented by driver along with current source.
  - Setting of sorce will fail if provided source is not supported
  - cleanup of crtc_crc_open function first allocate memory before
enabling CRC generation
  - Don't block open() call instead wait in crc read call.

Following IGT will fail due to crc-core <-> driver interface change
igt@kms_pipe_crc_basic@bad-source 
ig@kms_pipe_crc_basic@nonblocking-crc-pipe-X
ig@kms_pipe_crc_basic@nonblocking-crc-pipe-X-frame-sequence
In nonblocking crc tests we'll get lesser crc's due to skipping crc

AMD/Rockchip/rcar code path is not validated and need inputs

Cc: dri-de...@lists.freedesktop.org

Mahesh Kumar (10):
   drm: crc: Introduce verify_crc_source callback
   drm: crc: Introduce get_crc_sources callback
   drm/rockchip/crc: Implement verify_crc_source callback
   drm/amdgpu_dm/crc: Implement verify_crc_source callback
   drm/rcar-du/crc: Implement verify_crc_source callback
   drm/i915/crc: implement verify_crc_source callback
   drm/i915/crc: implement get_crc_sources callback
   drm/crc: Cleanup crtc_crc_open function
   Revert "drm: crc: Wait for a frame before returning from open()"
   drm/rcar-du/crc: Implement get_crc_sources callback

  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |   1 +
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h  |   7 +-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c  |  20 +++-
  drivers/gpu/drm/drm_debugfs_crc.c  |  92 +---
  drivers/gpu/drm/i915/intel_display.c   |   2 +
  drivers/gpu/drm/i915/intel_drv.h   |   9 +-
  drivers/gpu/drm/i915/intel_pipe_crc.c  | 119 +-
  drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  82 +++---
  drivers/gpu/drm/rcar-du/rcar_du_drv.c  |   2 +
  drivers/gpu/drm/rcar-du/rcar_du_drv.h  |   2 +
  drivers/gpu/drm/rcar-du/rcar_du_kms.c  |  67 
  drivers/gpu/drm/rcar-du/rcar_du_kms.h  |   1 +
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c|  26 -
  include/drm/drm_crtc.h |  40 ++-
  14 files changed, 396 insertions(+), 74 deletions(-)


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


Re: [Intel-gfx] [PATCH 0/3] Decode memdev info and bandwidth and implemnt latency WA

2018-07-14 Thread Kumar, Mahesh



On 7/13/2018 8:21 PM, Ville Syrjälä wrote:

On Fri, Jul 13, 2018 at 07:41:21PM +0530, Mahesh Kumar wrote:

This series adds support to calculate system memdev parameters and calculate

What's "memdev"?

memory device.
-Mahesh



total system memory bandwidth. This parameters and BW will be used to enable
WM level-0 latency workaround and display memory bandwidth related WA for gen9.

Mahesh Kumar (3):
   drm/i915/bxt: Decode memory bandwidth and parameters
   drm/i915/skl+: Decode memory bandwidth and parameters
   drm/i915: Implement 16GB dimm wa for latency level-0

  drivers/gpu/drm/i915/i915_drv.c | 261 
  drivers/gpu/drm/i915/i915_drv.h |  13 ++
  drivers/gpu/drm/i915/i915_reg.h |  51 
  drivers/gpu/drm/i915/intel_pm.c |  13 ++
  4 files changed, 338 insertions(+)

--
2.16.2

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


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


Re: [Intel-gfx] [PATCH 3/3] drm/i915: Implement 16GB dimm wa for latency level-0

2018-07-14 Thread Kumar, Mahesh

Hi,

Thanks for review.


On 7/13/2018 8:27 PM, Ville Syrjälä wrote:

On Fri, Jul 13, 2018 at 07:41:24PM +0530, Mahesh Kumar wrote:

Memory with 16GB dimms require an increase of 1us in level-0 latency.
This patch implements the same.
Bspec: 4381

Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/i915_drv.c | 35 +--
  drivers/gpu/drm/i915/i915_drv.h |  2 ++
  drivers/gpu/drm/i915/intel_pm.c | 13 +
  3 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index b93194cbd820..c6d30653d70c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1063,6 +1063,29 @@ static void intel_sanitize_options(struct 
drm_i915_private *dev_priv)
intel_gvt_sanitize_options(dev_priv);
  }
  
+static void

+intel_memdev_is_16gb_dimm(struct memdev_info *memdev_info,
+ u8 rank, u8 size, u8 width)
+{
+   bool found_16gb_dimm = false;
+
+   if (size == 16 && width == SKL_DRAM_WIDTH_X8 &&
+   rank == SKL_DRAM_RANK_SINGLE)
+   found_16gb_dimm = true;
+   else if (size == 32 && width == SKL_DRAM_WIDTH_X8 &&
+rank == SKL_DRAM_RANK_DUAL)
+   found_16gb_dimm = true;
+   else if (size == 8 && width == SKL_DRAM_WIDTH_X16 &&
+rank == SKL_DRAM_RANK_SINGLE)
+   found_16gb_dimm = true;
+   else if (size == 16 && width == SKL_DRAM_WIDTH_X16 &&
+rank == SKL_DRAM_RANK_DUAL)
+   found_16gb_dimm = true;
+
+   if (!memdev_info->is_16gb_dimm)
+   memdev_info->is_16gb_dimm = found_16gb_dimm;
+}

Pure functions are generally more fun. Would also make the function name
match the implementation.

Are you suggesting to change the name to only "is_16gb_dimm" ?

+
  static enum memdev_rank
  skl_memdev_get_channel_rank(struct memdev_info *memdev_info, u32 val)
  {
@@ -1084,6 +1107,8 @@ skl_memdev_get_channel_rank(struct memdev_info 
*memdev_info, u32 val)
if (l_size == 0 && s_size == 0)
return I915_DRAM_RANK_INVALID;
  
+	memdev_info->valid_dimm = true;

+
DRM_DEBUG_KMS("(size:width:rank) L(%dGB:X%d:%s) S(%dGB:X%d:%s)\n",
  l_size, (1 << l_width) * 8, l_rank ? "dual" : "single",
  s_size, (1 << s_width) * 8, s_rank ? "dual" : "single");
@@ -1096,6 +1121,9 @@ skl_memdev_get_channel_rank(struct memdev_info 
*memdev_info, u32 val)
else
rank = I915_DRAM_RANK_SINGLE;
  
+	intel_memdev_is_16gb_dimm(memdev_info, l_rank, l_size, l_width);

+   intel_memdev_is_16gb_dimm(memdev_info, s_rank, s_size, s_width);
+
return rank;
  }
  
@@ -1247,6 +1275,7 @@ bxt_get_memdev_info(struct drm_i915_private *dev_priv)

return -EINVAL;
}
  
+	memdev_info->valid_dimm = true;

memdev_info->valid = true;
return 0;
  }
@@ -1259,6 +1288,8 @@ intel_get_memdev_info(struct drm_i915_private *dev_priv)
int ret;
  
  	memdev_info->valid = false;

+   memdev_info->valid_dimm = false;
+   memdev_info->is_16gb_dimm = false;
memdev_info->rank = I915_DRAM_RANK_INVALID;
memdev_info->bandwidth_kbps = 0;
memdev_info->num_channels = 0;
@@ -1282,9 +1313,9 @@ intel_get_memdev_info(struct drm_i915_private *dev_priv)
sprintf(bandwidth_str, "unknown");
DRM_DEBUG_KMS("DRAM bandwidth:%s, total-channels: %u\n",
  bandwidth_str, memdev_info->num_channels);
-   DRM_DEBUG_KMS("DRAM rank: %s rank\n",
+   DRM_DEBUG_KMS("DRAM rank: %s rank 16GB-dimm:%s\n",
  (memdev_info->rank == I915_DRAM_RANK_DUAL) ?
- "dual" : "single");
+ "dual" : "single", yesno(memdev_info->is_16gb_dimm));
  }
  
  /**

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 845447d3806a..244adf8a30f1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1914,6 +1914,8 @@ struct drm_i915_private {
  
  	struct memdev_info {

bool valid;
+   bool valid_dimm;
+   bool is_16gb_dimm;
u8 num_channels;
enum memdev_rank {
I915_DRAM_RANK_INVALID = 0,
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 533e6886..f20f2f9118df 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2874,6 +2874,19 @@ static void intel_read_wm_latency(struct 
drm_i915_private *dev_priv,
}
}
  
+		/*

+* WA Level-0 adjustment for 16GB DIMMs: SKL+
+* If we could not get dimm info enable this WA to prevent from
+* any underrun. If not able to get Dimm info assume 16GB dimm
+* to avoid any underrun.
+*/
+  

Re: [Intel-gfx] [PATCH 08/10] drm/crc: Cleanup crtc_crc_open function

2018-07-10 Thread Kumar, Mahesh

Hi,

Thanks for the review.

On 7/10/2018 5:19 PM, Laurent Pinchart wrote:

Hi Mahesh,

Thank you for the patch.

On Monday, 2 July 2018 14:07:27 EEST Mahesh Kumar wrote:

This patch make changes to allocate crc-entries buffer before
enabling CRC generation.
It moves all the failure check early in the function before setting
the source or memory allocation.
Now set_crc_source takes only two variable inputs, values_cnt we
already gets as part of verify_crc_source.

Signed-off-by: Mahesh Kumar 
Cc: dri-de...@lists.freedesktop.org
Reviewed-by: Maarten Lankhorst 
---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h  |  3 +-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c  |  4 +-
  drivers/gpu/drm/drm_debugfs_crc.c  | 52 ---
  drivers/gpu/drm/i915/intel_drv.h   |  3 +-
  drivers/gpu/drm/i915/intel_pipe_crc.c  |  4 +-
  drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  5 +--
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c|  6 +--
  include/drm/drm_crtc.h |  3 +-
  8 files changed, 30 insertions(+), 50 deletions(-)

[snip]


diff --git a/drivers/gpu/drm/drm_debugfs_crc.c
b/drivers/gpu/drm/drm_debugfs_crc.c index f4d76528d24c..739a813b4b09 100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -124,11 +124,9 @@ static ssize_t crc_control_write(struct file *file,
const char __user *ubuf, if (source[len] == '\n')
source[len] = '\0';

-   if (crtc->funcs->verify_crc_source) {
-   ret = crtc->funcs->verify_crc_source(crtc, source, _cnt);
-   if (ret)
-   return ret;
-   }
+   ret = crtc->funcs->verify_crc_source(crtc, source, _cnt);
+   if (ret)
+   return ret;

spin_lock_irq(>lock);

@@ -193,12 +191,15 @@ static int crtc_crc_open(struct inode *inode, struct
file *filep) return ret;
}

-   if (crtc->funcs->verify_crc_source) {
-   ret = crtc->funcs->verify_crc_source(crtc, crc->source,
-_cnt);
-   if (ret)
-   return ret;
-   }
+   ret = crtc->funcs->verify_crc_source(crtc, crc->source, _cnt);
+   if (ret)
+   return ret;
+
+   if (WARN_ON(values_cnt > DRM_MAX_CRC_NR))
+   return -EINVAL;
+
+   if (WARN_ON(values_cnt == 0))
+   return -EINVAL;

spin_lock_irq(>lock);
if (!crc->opened)
@@ -210,30 +211,22 @@ static int crtc_crc_open(struct inode *inode, struct
file *filep) if (ret)
return ret;

-   ret = crtc->funcs->set_crc_source(crtc, crc->source, _cnt);
-   if (ret)
-   goto err;
-
-   if (WARN_ON(values_cnt > DRM_MAX_CRC_NR)) {
-   ret = -EINVAL;
-   goto err_disable;
-   }
-
-   if (WARN_ON(values_cnt == 0)) {
-   ret = -EINVAL;
-   goto err_disable;
-   }
-
entries = kcalloc(DRM_CRC_ENTRIES_NR, sizeof(*entries), GFP_KERNEL);
if (!entries) {
ret = -ENOMEM;
-   goto err_disable;
+   goto err;
}

If you moved allocation before the !crc->opened check, you could group the two
code blocks protected by the crc->lock.

agree, will update in next version.
-Mahesh

spin_lock_irq(>lock);
crc->entries = entries;
crc->values_cnt = values_cnt;
+   spin_unlock_irq(>lock);

+   ret = crtc->funcs->set_crc_source(crtc, crc->source);
+   if (ret)
+   goto err;
+
+   spin_lock_irq(>lock);
/*
 * Only return once we got a first frame, so userspace doesn't have to
 * guess when this particular piece of HW will be ready to start
@@ -250,7 +243,7 @@ static int crtc_crc_open(struct inode *inode, struct
file *filep) return 0;

  err_disable:
-   crtc->funcs->set_crc_source(crtc, NULL, _cnt);
+   crtc->funcs->set_crc_source(crtc, NULL);
  err:
spin_lock_irq(>lock);
crtc_crc_cleanup(crc);
@@ -262,9 +255,8 @@ static int crtc_crc_release(struct inode *inode, struct
file *filep) {
struct drm_crtc *crtc = filep->f_inode->i_private;
struct drm_crtc_crc *crc = >crc;
-   size_t values_cnt;

-   crtc->funcs->set_crc_source(crtc, NULL, _cnt);
+   crtc->funcs->set_crc_source(crtc, NULL);

spin_lock_irq(>lock);
crtc_crc_cleanup(crc);
@@ -370,7 +362,7 @@ int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc)
  {
struct dentry *crc_ent, *ent;

-   if (!crtc->funcs->set_crc_source)
+   if (!crtc->funcs->set_crc_source || !crtc->funcs->verify_crc_source)
return 0;

crc_ent = debugfs_create_dir("crc", crtc->debugfs_entry);

[snip]



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


Re: [Intel-gfx] [PATCH 05/10] drm/rcar-du/crc: Implement verify_crc_source callback

2018-07-10 Thread Kumar, Mahesh

Hi,

thanks foe the review.

On 7/10/2018 5:07 PM, Laurent Pinchart wrote:

Hi Mahesh,

Thank you for the patch.

On Monday, 2 July 2018 14:07:24 EEST Mahesh Kumar wrote:

This patch implements "verify_crc_source" callback function for
rcar drm driver.

Signed-off-by: Mahesh Kumar 
Cc: dri-de...@lists.freedesktop.org
Reviewed-by: Maarten Lankhorst 
---
  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 40 +++
  1 file changed, 40 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 15dc9caa128b..24eeaa7e14d7
100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -756,6 +756,45 @@ static void rcar_du_crtc_disable_vblank(struct drm_crtc
*crtc) rcrtc->vblank_enable = false;
  }

+static int rcar_du_crtc_verify_crc_source(struct drm_crtc *crtc,
+ const char *source_name,
+ size_t *values_cnt)
+{
+   struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+   unsigned int index = 0;
+   unsigned int i;
+   int ret;
+
+   /*
+* Parse the source name. Supported values are "plane%u" to compute the
+* CRC on an input plane (%u is the plane ID), and "auto" to compute the
+* CRC on the composer (VSP) output.
+*/
+   if (!source_name || !strcmp(source_name, "auto")) {
+   goto out;
+   } else if (strstarts(source_name, "plane")) {
+   ret = kstrtouint(source_name + strlen("plane"), 10, );
+   if (ret < 0)
+   return ret;
+
+   for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
+   if (index == rcrtc->vsp->planes[i].plane.base.id) {
+   index = i;
+   break;
+   }
+   }
+
+   if (i >= rcrtc->vsp->num_planes)
+   return -EINVAL;
+   } else {
+   return -EINVAL;
+   }
+
+out:
+   *values_cnt = 1;
+   return 0;

This duplicates lots of code from the rcar_du_crtc_set_crc_source() function.
Could you please extract it to a shared function ?

Agree, it duplicates the code but "index" is needed by set_crc_source call
anyway will create a wrapper to avoid duplication of code.


Could you please also implement support for the .get_crc_sources() operation ?
I think doing so might show limitations in the current API, namely the fact
that the list will need to be dynamically created for this driver.
for that I think rcar_du_crtc_create function can build a dynamic list 
during initializing crtc functions, unless plane can be dynamically 
allocated to any CRTC. this is the place where I need input from maintainer.


-Mahesh



+}
+
  static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
   const char *source_name,
   size_t *values_cnt)
@@ -861,6 +900,7 @@ static const struct drm_crtc_funcs crtc_funcs_gen3 = {
.enable_vblank = rcar_du_crtc_enable_vblank,
.disable_vblank = rcar_du_crtc_disable_vblank,
.set_crc_source = rcar_du_crtc_set_crc_source,
+   .verify_crc_source = rcar_du_crtc_verify_crc_source,
  };

  /* 


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


Re: [Intel-gfx] [PATCH 01/10] drm: crc: Introduce verify_crc_source callback

2018-07-10 Thread Kumar, Mahesh

Hi,


On 7/10/2018 5:40 PM, Laurent Pinchart wrote:

Hi Mahesh,

On Tuesday, 10 July 2018 14:54:11 EEST Kumar, Mahesh wrote:

On 7/10/2018 4:56 PM, Laurent Pinchart wrote:

On Monday, 2 July 2018 14:07:20 EEST Mahesh Kumar wrote:

This patch adds a new callback function "verify_crc_source" which will
be used during setting the crc source in control node and while opening
data node for crc reading. This will help in avoiding setting of wrong
string for source.

Why do you need to verify the source in the open() operation ? Isn't it
enough to verify it in the write() handler ? The answer to this question
might lie in patch 08/10, in which case I'd add the .verify_crc_source()
call in open() in that patch, not here.

Yes, final goal is achieved by patch 08/10. But if crc_read is called
before setting the source, it may have wrong source set in that case I
wanted to return early at least for the drivers implemented
verify_crc_source. If you still think otherwise I will modify
accordingly in next series.

I don't disagree with you, but I don't think this issue is new. As I got a bit
confused as to why the call is needed in open() (there's no explanation in
this patch), I think fixing the problem in 08/10 would be better.

ok sure :)
-Mahesh



Signed-off-by: Mahesh Kumar 
Cc: dri-de...@lists.freedesktop.org
Reviewed-by: Maarten Lankhorst 
---

   drivers/gpu/drm/drm_debugfs_crc.c | 15 +++
   include/drm/drm_crtc.h| 15 +++
   2 files changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/drm_debugfs_crc.c
b/drivers/gpu/drm/drm_debugfs_crc.c index 9f8312137cad..c6a725b79ac6
100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -87,6 +87,8 @@ static ssize_t crc_control_write(struct file *file,
const
char __user *ubuf, struct drm_crtc *crtc = m->private;

struct drm_crtc_crc *crc = >crc;
char *source;

+   size_t values_cnt;
+   int ret = 0;

if (len == 0)

return 0;

@@ -104,6 +106,12 @@ static ssize_t crc_control_write(struct file *file,
const char __user *ubuf, if (source[len] == '\n')

source[len] = '\0';

+   if (crtc->funcs->verify_crc_source) {
+   ret = crtc->funcs->verify_crc_source(crtc, source, _cnt);
+   if (ret)
+   return ret;
+   }
+

spin_lock_irq(>lock);

if (crc->opened) {

@@ -167,6 +175,13 @@ static int crtc_crc_open(struct inode *inode, struct
file *filep) return ret;

}

+   if (crtc->funcs->verify_crc_source) {
+   ret = crtc->funcs->verify_crc_source(crtc, crc->source,
+_cnt);
+   if (ret)
+   return ret;
+   }
+

spin_lock_irq(>lock);
if (!crc->opened)

crc->opened = true;

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 23eddbccab10..1a6dcbf91744 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -661,6 +661,21 @@ struct drm_crtc_funcs {

 */

int (*set_crc_source)(struct drm_crtc *crtc, const char *source,

  size_t *values_cnt);

+   /**
+* @verify_crc_source:
+*
+* verifies the source of CRC checksums of frames before setting the
+* source for CRC and during crc open.
+*
+* This callback is optional if the driver does not support any CRC
+* generation functionality.
+*
+* RETURNS:
+*
+* 0 on success or a negative error code on failure.
+*/
+   int (*verify_crc_source)(struct drm_crtc *crtc, const char *source,
+size_t *values_cnt);

/**

 * @atomic_print_state:




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


Re: [Intel-gfx] [PATCH 02/10] drm: crc: Introduce get_crc_sources callback

2018-07-10 Thread Kumar, Mahesh

Hi,


On 7/10/2018 5:39 PM, Laurent Pinchart wrote:

Hi Mahesh,

On Tuesday, 10 July 2018 15:01:38 EEST Kumar, Mahesh wrote:

On 7/10/2018 4:52 PM, Laurent Pinchart wrote:

Hi Mahesh,
On Monday, 2 July 2018 14:07:21 EEST Mahesh Kumar wrote:

This patch introduce a callback function "get_crc_sources" which
will be called during read of control node. It is an optional
callback function and if driver implements this callback, driver
should print list of available CRC sources in seq_file privided
as an input to the callback.

The commit message seems to be outdated, the callback doesn't take a
seq_file anymore.

ops, will update.


Changes Since V1: (Daniel)

   - return const pointer to an array of crc sources list
   - do validation of sources in CRC-core

Signed-off-by: Mahesh Kumar 
Cc: dri-de...@lists.freedesktop.org
Reviewed-by: Maarten Lankhorst 
---

   drivers/gpu/drm/drm_debugfs_crc.c | 20 +++-
   include/drm/drm_crtc.h| 16 
   2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_debugfs_crc.c
b/drivers/gpu/drm/drm_debugfs_crc.c index c6a725b79ac6..f4d76528d24c
100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -67,9 +67,27 @@

   static int crc_control_show(struct seq_file *m, void *data)
   {
   
   	struct drm_crtc *crtc = m->private;


+   size_t count;

Count it only used within the if () {} block, you can declare it there.

agree.


+
+   if (crtc->funcs->get_crc_sources) {
+   const char *const *sources = crtc->funcs->get_crc_sources(crtc,
+   );
+   size_t values_cnt;
+   int i;

I only takes positive values, it can be an unsigned int.

ok


+
+   if (count <= 0 || !sources)

count is a size_t, it can't be negative.

The .get_crc_sources() documentation doesn't clearly specify whether
sources should always be NULL when count is zero. I advise updating the
documentation, and possibly updating this check accordingly.

ok will update.


+   goto out;
+
+   seq_puts(m, "[");
+   for (i = 0; i < count; i++)
+   if (!crtc->funcs->verify_crc_source(crtc, sources[i],
+   _cnt))

I assume that you verify sources one by one here to avoid having to create
a list of sources dynamically in the .get_crc_sources() callback ? If so,
I think the .get_crc_sources() callback should document that.

You should also document that .verify_crc_source() is required when
get_crc_sources() is provided.

ok sure.


+   seq_printf(m, "%s ", sources[i]);
+   seq_puts(m, "] ");

This assumes that source names can't include a space. Isn't that too
restrictive ? Shouldn't a different separator be used ? How about one
source name per line ?

what about comma separated as I'm putting names inside square-brackets?


Additionally, shouldn't the active source be marked ?

active source is again printed by the code in next few lines. output
will be of following format.
[space separated list of valid sources] active_source

I had missed that, my bad.

The proposed format seems a bit hackish to me, in the sense that it forbids
both spaces and brackets in source names. One source per line would fix both
and be easy to parse. We would then need to mark the active source, which
could be done by adding a marker to the corresponding line (maybe a * at the
end of the line ?).

sounds good, will do that.
-Mahesh



+   }

+out:
seq_printf(m, "%s\n", crtc->crc.source);
-
return 0;
   }

[snip]



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


Re: [Intel-gfx] [PATCH 02/10] drm: crc: Introduce get_crc_sources callback

2018-07-10 Thread Kumar, Mahesh

Hi,

thanks for the review.
On 7/10/2018 4:52 PM, Laurent Pinchart wrote:

Hi Mahesh,

Thank you for the patch.

On Monday, 2 July 2018 14:07:21 EEST Mahesh Kumar wrote:

This patch introduce a callback function "get_crc_sources" which
will be called during read of control node. It is an optional
callback function and if driver implements this callback, driver
should print list of available CRC sources in seq_file privided
as an input to the callback.

The commit message seems to be outdated, the callback doesn't take a seq_file
anymore.

ops, will update.



Changes Since V1: (Daniel)
  - return const pointer to an array of crc sources list
  - do validation of sources in CRC-core

Signed-off-by: Mahesh Kumar 
Cc: dri-de...@lists.freedesktop.org
Reviewed-by: Maarten Lankhorst 
---
  drivers/gpu/drm/drm_debugfs_crc.c | 20 +++-
  include/drm/drm_crtc.h| 16 
  2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_debugfs_crc.c
b/drivers/gpu/drm/drm_debugfs_crc.c index c6a725b79ac6..f4d76528d24c 100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -67,9 +67,27 @@
  static int crc_control_show(struct seq_file *m, void *data)
  {
struct drm_crtc *crtc = m->private;
+   size_t count;

Count it only used within the if () {} block, you can declare it there.

agree.



+
+   if (crtc->funcs->get_crc_sources) {
+   const char *const *sources = crtc->funcs->get_crc_sources(crtc,
+   );
+   size_t values_cnt;
+   int i;

I only takes positive values, it can be an unsigned int.

ok



+
+   if (count <= 0 || !sources)

count is a size_t, it can't be negative.

The .get_crc_sources() documentation doesn't clearly specify whether sources
should always be NULL when count is zero. I advise updating the documentation,
and possibly updating this check accordingly.

ok will update.



+   goto out;
+
+   seq_puts(m, "[");
+   for (i = 0; i < count; i++)
+   if (!crtc->funcs->verify_crc_source(crtc, sources[i],
+   _cnt))

I assume that you verify sources one by one here to avoid having to create a
list of sources dynamically in the .get_crc_sources() callback ? If so, I
think the .get_crc_sources() callback should document that.

You should also document that .verify_crc_source() is required when
get_crc_sources() is provided.

ok sure.



+   seq_printf(m, "%s ", sources[i]);
+   seq_puts(m, "] ");

This assumes that source names can't include a space. Isn't that too
restrictive ? Shouldn't a different separator be used ? How about one source
name per line ?

what about comma separated as I'm putting names inside square-brackets?


Additionally, shouldn't the active source be marked ?
active source is again printed by the code in next few lines. output 
will be of following format.

[space separated list of valid sources] active_source

-Mahesh



+   }

+out:
seq_printf(m, "%s\n", crtc->crc.source);
-
return 0;
  }

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 1a6dcbf91744..ffaec138aeee 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -676,6 +676,22 @@ struct drm_crtc_funcs {
 */
int (*verify_crc_source)(struct drm_crtc *crtc, const char *source,
 size_t *values_cnt);
+   /**
+* @get_crc_sources:
+*
+* Driver callback for getting a list of all the available sources for
+* CRC generation.
+*
+* This callback is optional if the driver does not support exporting of
+* possible CRC sources list. CRC-core does the verification of sources.
+*
+* RETURNS:
+*
+* a constant character pointer to the list of all the available CRC
+* sources
+*/
+   const char *const *(*get_crc_sources)(struct drm_crtc *crtc,
+ size_t *count);

/**
 * @atomic_print_state:


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


Re: [Intel-gfx] [PATCH 01/10] drm: crc: Introduce verify_crc_source callback

2018-07-10 Thread Kumar, Mahesh

Hi,

Thanks for the review,
On 7/10/2018 4:56 PM, Laurent Pinchart wrote:

Hi Mahesh,

Thank you for the patch.

On Monday, 2 July 2018 14:07:20 EEST Mahesh Kumar wrote:

This patch adds a new callback function "verify_crc_source" which will
be used during setting the crc source in control node and while opening
data node for crc reading. This will help in avoiding setting of wrong
string for source.

Why do you need to verify the source in the open() operation ? Isn't it enough
to verify it in the write() handler ? The answer to this question might lie in
patch 08/10, in which case I'd add the .verify_crc_source() call in open() in
that patch, not here.
Yes, final goal is achieved by patch 08/10. But if crc_read is called 
before setting the source, it may have wrong source set in that case I 
wanted to return early at least for the drivers implemented 
verify_crc_source. If you still think otherwise I will modify 
accordingly in next series.


-Mahesh




Signed-off-by: Mahesh Kumar 
Cc: dri-de...@lists.freedesktop.org
Reviewed-by: Maarten Lankhorst 
---
  drivers/gpu/drm/drm_debugfs_crc.c | 15 +++
  include/drm/drm_crtc.h| 15 +++
  2 files changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/drm_debugfs_crc.c
b/drivers/gpu/drm/drm_debugfs_crc.c index 9f8312137cad..c6a725b79ac6 100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -87,6 +87,8 @@ static ssize_t crc_control_write(struct file *file, const
char __user *ubuf, struct drm_crtc *crtc = m->private;
struct drm_crtc_crc *crc = >crc;
char *source;
+   size_t values_cnt;
+   int ret = 0;

if (len == 0)
return 0;
@@ -104,6 +106,12 @@ static ssize_t crc_control_write(struct file *file,
const char __user *ubuf, if (source[len] == '\n')
source[len] = '\0';

+   if (crtc->funcs->verify_crc_source) {
+   ret = crtc->funcs->verify_crc_source(crtc, source, _cnt);
+   if (ret)
+   return ret;
+   }
+
spin_lock_irq(>lock);

if (crc->opened) {
@@ -167,6 +175,13 @@ static int crtc_crc_open(struct inode *inode, struct
file *filep) return ret;
}

+   if (crtc->funcs->verify_crc_source) {
+   ret = crtc->funcs->verify_crc_source(crtc, crc->source,
+_cnt);
+   if (ret)
+   return ret;
+   }
+
spin_lock_irq(>lock);
if (!crc->opened)
crc->opened = true;
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 23eddbccab10..1a6dcbf91744 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -661,6 +661,21 @@ struct drm_crtc_funcs {
 */
int (*set_crc_source)(struct drm_crtc *crtc, const char *source,
  size_t *values_cnt);
+   /**
+* @verify_crc_source:
+*
+* verifies the source of CRC checksums of frames before setting the
+* source for CRC and during crc open.
+*
+* This callback is optional if the driver does not support any CRC
+* generation functionality.
+*
+* RETURNS:
+*
+* 0 on success or a negative error code on failure.
+*/
+   int (*verify_crc_source)(struct drm_crtc *crtc, const char *source,
+size_t *values_cnt);

/**
 * @atomic_print_state:




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


Re: [Intel-gfx] [PATCH v2] drm/i915/skl+: ddb allocation algorithm optimization

2018-07-03 Thread Kumar, Mahesh

Hi,


On 7/3/2018 4:56 AM, Rodrigo Vivi wrote:

On Fri, Jun 29, 2018 at 03:13:35PM +0530, Mahesh Kumar wrote:

This patch implements new DDB allocation algorithm as per HW team
recommendation. This algo takecare of scenario where we allocate less DDB
for the planes with lower relative pixel rate, but they require more DDB
to work.
It also takes care of enabling same watermark level for each

Usually "It also" in a commit message is a good indication that we should
be doing more than one patch.
Enabling same watermark level for each plane in CRTC is byproduct of 
this algorithm.

But Agree will rework on patch and try to break it as much as possible.
I think I should Add old cover letter as well to explain what is new 
algo optimization all about.



plane in crtc, for efficient power saving.
This algorithm uses fixed ddb allocation for cursor planes.

Ealier version of this patch reverted due to regression. And it was root
caused to following:
New algorithm required more DDB for cursor plane but as cursor plane has
fixed allocation it's DDB was not sufficient and WM level-0 was getting
disabled, resulting in blank screen. Now we use old DDB allocation logic
only for cursor plane.

I really don't see on spec old and new DDB allocation logics.
Actually now spec have 2 method for DDB allocation (Added based on our 
request). So new Algorithm is nothing but second method of allocation logic.




Only thing different for cursor that I see there is that a workaround on
watermark calculation where "For each plane, except cursor..."

"Number of planes, except cursor..."

This is not what I see in this patch, but maybe because the patch is too big.
so for each plane we first calculate WM then try to find maximum level 
that can be enabled with available DDB for pipe and distribute DDB 
accordingly.
but for cursor Now I'm allocating DDB first (8block or 32 blocks based 
on number of CRTC similar to old method) that is the difference from 
previous version of patch.



Changes:
  - add reason for revert in commit msg (Maarten)
  - Fix checkpatch checks

Testcase: igt/kms_plane_multiple
Signed-off-by: Mahesh Kumar 
Cc: Rodrigo Vivi 

Well, since I'm on cc and I was the one that reverted that because I noticed
on my own machine I opened this patch for review many times here already,
but I gave up completely every time because this patch is hard to review.
Agree, My bad, will try to split this patch but I'm afraid main patch 
still be lengthy please bare with me.


So this time I won't fully give up and at least put some comments...

So, overall it is hard to match the spec differences because this patch
is trying to do all at once. Smaller patches should be better.


---
  drivers/gpu/drm/i915/i915_drv.h |   5 +-
  drivers/gpu/drm/i915/intel_pm.c | 376 +++-
  2 files changed, 219 insertions(+), 162 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2b684f431c60..f5d636a6d121 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1212,8 +1212,9 @@ struct skl_ddb_values {
  
  struct skl_wm_level {

bool plane_en;
-   uint16_t plane_res_b;
-   uint8_t plane_res_l;
+   u16 plane_res_b;
+   u8 plane_res_l;
+   u16 min_dbuf_req;
  };
  
  /* Stores plane specific WM parameters */

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 533e6886..d1564a08a202 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3802,17 +3802,37 @@ static unsigned int intel_get_ddb_size(struct 
drm_i915_private *dev_priv,
return ddb_size;
  }
  
+static int

+skl_get_num_pipes_active(struct drm_i915_private *dev_priv,
+const struct intel_crtc_state *cstate)
+{
+   struct drm_atomic_state *state = cstate->base.state;
+   const struct intel_atomic_state *intel_state;
+   int num_active;
+
+   if (WARN_ON(!state) || !cstate->base.active)
+   return hweight32(dev_priv->active_crtcs);
+
+   intel_state = to_intel_atomic_state(state);
+
+   if (intel_state->active_pipe_changes)
+   num_active = hweight32(intel_state->active_crtcs);
+   else
+   num_active = hweight32(dev_priv->active_crtcs);
+
+   return num_active;
+}

This entire function here is something that should come in a separated patch.
This is new change in this version. I should have created separate 
patch. will do so.



+
  static void
-skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
+skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
   const struct intel_crtc_state *cstate,
   const unsigned int total_data_rate,
   struct skl_ddb_allocation *ddb,
-  struct skl_ddb_entry *alloc, /* out */
-

Re: [Intel-gfx] [PATCH i-g-t] tests/kms_pipe_crc_basic: expect setting bad source to fail

2018-07-03 Thread Kumar, Mahesh

Hi,


On 7/2/2018 4:57 PM, Maarten Lankhorst wrote:

Op 02-07-18 om 13:16 schreef Mahesh Kumar:

Now crc-core framework verifies the source string passed by the user.
So setting bad-source will fail. Expect file write to fail in bad-source
subtest of kms_pipe_crc_basic.

Signed-off-by: Mahesh Kumar 
---
  tests/kms_pipe_crc_basic.c | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tests/kms_pipe_crc_basic.c b/tests/kms_pipe_crc_basic.c
index 235fdc38..2d4dfee8 100644
--- a/tests/kms_pipe_crc_basic.c
+++ b/tests/kms_pipe_crc_basic.c
@@ -48,8 +48,7 @@ static struct {
  
  static void test_bad_source(data_t *data)

  {
-   igt_assert(igt_sysfs_set(data->debugfs, "crtc-0/crc/control", "foo"));
-   igt_assert(openat(data->debugfs, "crtc-0/crc/data", O_WRONLY) == -1);
+   igt_assert(!igt_sysfs_set(data->debugfs, "crtc-0/crc/control", "foo"));
  }
  
  #define N_CRCS	3

New behavior makes more sense.

Reviewed-by: Maarten Lankhorst 

Do you have igt commit rights?

thanks for review.
I don't have commit rights
-Mahesh

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


Re: [Intel-gfx] [PATCH 02/10] drm: crc: Introduce pre_crc_read function

2018-06-27 Thread Kumar, Mahesh

Hi,


On 6/27/2018 8:48 PM, Maarten Lankhorst wrote:

Op 27-06-18 om 16:44 schreef Mahesh Kumar:

This patch implements a callback function "pre_crc_read" which will
be called before crc read. In this function driver can implement and
preparation work required for successfully reading CRC data.

Signed-off-by: Mahesh Kumar 
Cc: dri-de...@lists.freedesktop.org
---
  drivers/gpu/drm/drm_debugfs_crc.c |  8 
  include/drm/drm_crtc.h| 14 ++
  2 files changed, 22 insertions(+)

diff --git a/drivers/gpu/drm/drm_debugfs_crc.c 
b/drivers/gpu/drm/drm_debugfs_crc.c
index c6a725b79ac6..2b4a737c5aeb 100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -278,6 +278,14 @@ static ssize_t crtc_crc_read(struct file *filep, char 
__user *user_buf,
return 0;
}
  
+	if (crtc->funcs->pre_crc_read) {

+   ret = crtc->funcs->pre_crc_read(crtc);
+   if (ret) {
+   spin_unlock_irq(>lock);
+   return ret;
+   }
+   }
+
/* Nothing to read? */
while (crtc_crc_data_count(crc) == 0) {
if (filep->f_flags & O_NONBLOCK) {
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 1a6dcbf91744..bae432469616 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -676,6 +676,20 @@ struct drm_crtc_funcs {
 */
int (*verify_crc_source)(struct drm_crtc *crtc, const char *source,
 size_t *values_cnt);
+   /**
+* @pre_crc_read:
+*
+* Driver callback for performing any preparation work required by
+* driver before reading CRC
+*
+* This callback is optional if the driver does not support CRC
+* generation or no prework is required before reading the crc
+*
+* RETURNS:
+*
+* 0 on success or a negative error code on failure.
+*/
+   int (*pre_crc_read)(struct drm_crtc *crtc);
  
  	/**

 * @atomic_print_state:

I think this patch might have to be dropped, or reordered after the revert in 
10/10, because else in theory open could block. :)

Or maybe just drop until we have upstream kernel users?

thanks,
Can reorder it after patch-10 and if others also vote to drop it will 
take decision accordingly, atleast it should not block other patches :)


-Mahesh


~Maarten



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


Re: [Intel-gfx] [PATCH 04/10] drm/rockchip/crc: Implement verify_crc_source callback

2018-06-27 Thread Kumar, Mahesh

Hi,


On 6/27/2018 5:30 PM, Jani Nikula wrote:

On Tue, 26 Jun 2018, Mahesh Kumar  wrote:

This patch implements "verify_crc_source" callback function for
rockchip drm driver.

Signed-off-by: Mahesh Kumar 
Cc: dri-de...@lists.freedesktop.org
---
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 21 +
  1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index c9222119767d..ea4884ac4cb0 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1138,12 +1138,32 @@ static int vop_crtc_set_crc_source(struct drm_crtc 
*crtc,
  
  	return ret;

  }
+
+static int
+vop_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
+  size_t *values_cnt)
+{
+   if ((source_name && strcmp(source_name, "auto") == 0) || !source_name) {

Drive-by review:

IOW,

if (!source_name || strcmp(source_name, "auto") == 0)

Better yet, reverse the logic,

if (source_name && strcmp(source_name, "auto") != 0)
return -EINVAL;

*values_cnt = 3;

return 0;

thanks for review,
Will reverse the logic as suggested.

-Mahesh

BR,
Jani.


+   *values_cnt = 3;
+   return 0;
+   }
+
+   return -EINVAL;
+}
+
  #else
  static int vop_crtc_set_crc_source(struct drm_crtc *crtc,
   const char *source_name, size_t *values_cnt)
  {
return -ENODEV;
  }
+
+static int
+vop_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
+  size_t *values_cnt)
+{
+   return -ENODEV;
+}
  #endif
  
  static const struct drm_crtc_funcs vop_crtc_funcs = {

@@ -1156,6 +1176,7 @@ static const struct drm_crtc_funcs vop_crtc_funcs = {
.enable_vblank = vop_crtc_enable_vblank,
.disable_vblank = vop_crtc_disable_vblank,
.set_crc_source = vop_crtc_set_crc_source,
+   .verify_crc_source = vop_crtc_verify_crc_source,
  };
  
  static void vop_fb_unref_worker(struct drm_flip_work *work, void *val)


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


Re: [Intel-gfx] [PATCH 08/10] drm/i915/crc: implement get_crc_sources callback

2018-06-27 Thread Kumar, Mahesh

Hi,

thanks for review.
On 6/26/2018 1:59 PM, Daniel Vetter wrote:

On Tue, Jun 26, 2018 at 11:52:57AM +0530, Mahesh Kumar wrote:

This patch implements get_crc_sources callback, which returns list of
all the valid crc sources supported by driver in current platform.

Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/intel_display.c  |  1 +
  drivers/gpu/drm/i915/intel_drv.h  |  2 ++
  drivers/gpu/drm/i915/intel_pipe_crc.c | 12 
  3 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c0eb752b0901..93b4be2eee32 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12894,6 +12894,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
.atomic_destroy_state = intel_crtc_destroy_state,
.set_crc_source = intel_crtc_set_crc_source,
.verify_crc_source = intel_crtc_verify_crc_source,
+   .get_crc_sources = intel_crtc_get_crc_sources,
  };
  
  struct wait_rps_boost {

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 64e13adad9f5..17735cafdd72 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -2156,11 +2156,13 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, 
const char *source_name,
  size_t *values_cnt);
  int intel_crtc_verify_crc_source(struct drm_crtc *crtc,
 const char *source_name, size_t *values_cnt);
+void intel_crtc_get_crc_sources(struct seq_file *m, struct drm_crtc *crtc);
  void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc);
  void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc);
  #else
  #define intel_crtc_set_crc_source NULL
  #define intel_crtc_verify_crc_source NULL
+#define intel_crtc_get_crc_sources NULL
  static inline void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc)
  {
  }
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c 
b/drivers/gpu/drm/i915/intel_pipe_crc.c
index a37521380f94..d6807155a237 100644
--- a/drivers/gpu/drm/i915/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
@@ -1001,6 +1001,18 @@ intel_is_valid_crc_source(struct drm_i915_private 
*dev_priv,
return ivb_crc_source_valid(dev_priv, source);
  }
  
+void intel_crtc_get_crc_sources(struct seq_file *m, struct drm_crtc *crtc)

+{
+   struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+   enum intel_pipe_crc_source source;
+
+   seq_puts(m, "[");
+   for (source = 0; source < INTEL_PIPE_CRC_SOURCE_MAX; source++)
+   if (intel_is_valid_crc_source(dev_priv, source) == 0)
+   seq_printf(m, "%s,", pipe_crc_source_name(source));
+   seq_puts(m, "auto] ");

This seems to be a very quirky interface ... Can't you instead return a
real array, and then also push validation into the core? Same we do with
e.g. the per-plane drm_fourcc format support. Something like an array of
const char * pointers should be good.

sounds good, will  make the changes and return constant pointer to an array.
Will also push validation to the crc-core
-Mahesh

-Daniel


+}
+
  int intel_crtc_verify_crc_source(struct drm_crtc *crtc, const char 
*source_name,
 size_t *values_cnt)
  {
--
2.16.2

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


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


Re: [Intel-gfx] [PATCH 09/10] drm/crc: Cleanup crtc_crc_open function

2018-06-26 Thread Kumar, Mahesh

Cc: Laurent Pinchart 


On 6/26/2018 11:52 AM, Mahesh Kumar wrote:

This patch make changes to allocate crc-entries buffer before
enabling CRC generation.
It moves all the failure check early in the function before setting
the source or memory allocation.
Now set_crc_source takes only two variable input, values_cnt we
already gets as part of verify_crc_source.

Signed-off-by: Mahesh Kumar 
Cc: dri-de...@lists.freedesktop.org
---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h  |  3 +-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c  |  4 +-
  drivers/gpu/drm/drm_debugfs_crc.c  | 52 +-
  drivers/gpu/drm/i915/intel_drv.h   |  3 +-
  drivers/gpu/drm/i915/intel_pipe_crc.c  |  4 +-
  drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  5 +--
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c|  6 +--
  include/drm/drm_crtc.h |  3 +-
  8 files changed, 30 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 79b0a16652b9..a7a5551fee1b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -261,8 +261,7 @@ amdgpu_dm_remove_sink_from_freesync_module(struct 
drm_connector *connector);
  
  /* amdgpu_dm_crc.c */

  #ifdef CONFIG_DEBUG_FS
-int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name,
- size_t *values_cnt);
+int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name);
  int amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc,
 const char *src_name,
 size_t *values_cnt);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index dfcca594d52a..e7ad528f5853 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -62,8 +62,7 @@ amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const 
char *src_name,
return 0;
  }
  
-int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name,

-  size_t *values_cnt)
+int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
  {
struct dm_crtc_state *crtc_state = to_dm_crtc_state(crtc->state);
struct dc_stream_state *stream_state = crtc_state->stream;
@@ -99,7 +98,6 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, 
const char *src_name,
return -EINVAL;
}
  
-	*values_cnt = 3;

/* Reset crc_skipped on dm state */
crtc_state->crc_skip_count = 0;
return 0;
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c 
b/drivers/gpu/drm/drm_debugfs_crc.c
index 2751d124387d..834bc7ee5550 100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -109,11 +109,9 @@ static ssize_t crc_control_write(struct file *file, const 
char __user *ubuf,
if (source[len] == '\n')
source[len] = '\0';
  
-	if (crtc->funcs->verify_crc_source) {

-   ret = crtc->funcs->verify_crc_source(crtc, source, _cnt);
-   if (ret)
-   return ret;
-   }
+   ret = crtc->funcs->verify_crc_source(crtc, source, _cnt);
+   if (ret)
+   return ret;
  
  	spin_lock_irq(>lock);
  
@@ -178,12 +176,15 @@ static int crtc_crc_open(struct inode *inode, struct file *filep)

return ret;
}
  
-	if (crtc->funcs->verify_crc_source) {

-   ret = crtc->funcs->verify_crc_source(crtc, crc->source,
-_cnt);
-   if (ret)
-   return ret;
-   }
+   ret = crtc->funcs->verify_crc_source(crtc, crc->source, _cnt);
+   if (ret)
+   return ret;
+
+   if (WARN_ON(values_cnt > DRM_MAX_CRC_NR))
+   return -EINVAL;
+
+   if (WARN_ON(values_cnt == 0))
+   return -EINVAL;
  
  	spin_lock_irq(>lock);

if (!crc->opened)
@@ -195,30 +196,22 @@ static int crtc_crc_open(struct inode *inode, struct file 
*filep)
if (ret)
return ret;
  
-	ret = crtc->funcs->set_crc_source(crtc, crc->source, _cnt);

-   if (ret)
-   goto err;
-
-   if (WARN_ON(values_cnt > DRM_MAX_CRC_NR)) {
-   ret = -EINVAL;
-   goto err_disable;
-   }
-
-   if (WARN_ON(values_cnt == 0)) {
-   ret = -EINVAL;
-   goto err_disable;
-   }
-
entries = kcalloc(DRM_CRC_ENTRIES_NR, sizeof(*entries), GFP_KERNEL);
if (!entries) {
ret = -ENOMEM;
-   goto err_disable;
+   goto err;
}
  
  	spin_lock_irq(>lock);

crc->entries 

Re: [Intel-gfx] [PATCH 06/10] drm/rcar-du/crc: Implement verify_crc_source callback

2018-06-26 Thread Kumar, Mahesh

Cc: Laurent Pinchart 


On 6/26/2018 11:52 AM, Mahesh Kumar wrote:

This patch implements "verify_crc_source" callback function for
rcar drm driver.

Signed-off-by: Mahesh Kumar 
Cc: dri-de...@lists.freedesktop.org
---
  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 40 ++
  1 file changed, 40 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c 
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 15dc9caa128b..24eeaa7e14d7 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -756,6 +756,45 @@ static void rcar_du_crtc_disable_vblank(struct drm_crtc 
*crtc)
rcrtc->vblank_enable = false;
  }
  
+static int rcar_du_crtc_verify_crc_source(struct drm_crtc *crtc,

+ const char *source_name,
+ size_t *values_cnt)
+{
+   struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+   unsigned int index = 0;
+   unsigned int i;
+   int ret;
+
+   /*
+* Parse the source name. Supported values are "plane%u" to compute the
+* CRC on an input plane (%u is the plane ID), and "auto" to compute the
+* CRC on the composer (VSP) output.
+*/
+   if (!source_name || !strcmp(source_name, "auto")) {
+   goto out;
+   } else if (strstarts(source_name, "plane")) {
+   ret = kstrtouint(source_name + strlen("plane"), 10, );
+   if (ret < 0)
+   return ret;
+
+   for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
+   if (index == rcrtc->vsp->planes[i].plane.base.id) {
+   index = i;
+   break;
+   }
+   }
+
+   if (i >= rcrtc->vsp->num_planes)
+   return -EINVAL;
+   } else {
+   return -EINVAL;
+   }
+
+out:
+   *values_cnt = 1;
+   return 0;
+}
+
  static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
   const char *source_name,
   size_t *values_cnt)
@@ -861,6 +900,7 @@ static const struct drm_crtc_funcs crtc_funcs_gen3 = {
.enable_vblank = rcar_du_crtc_enable_vblank,
.disable_vblank = rcar_du_crtc_disable_vblank,
.set_crc_source = rcar_du_crtc_set_crc_source,
+   .verify_crc_source = rcar_du_crtc_verify_crc_source,
  };
  
  /* -


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


Re: [Intel-gfx] [PATCH 00/10] Improve crc-core driver interface

2018-06-26 Thread Kumar, Mahesh

Cc:dri-de...@lists.freedesktop.org


On 6/26/2018 11:52 AM, Mahesh Kumar wrote:

This series improves crc-core <-> driver interface.
This series adds following functionality in the crc-core
  - Now control node will print all the available sources if
implemented by driver along with current source.
  - Setting of sorce will fail if provided source is not supported
  - cleanup of crtc_crc_open function first allocate memory before
enabling CRC generation
  - Don't block open() call instead wait in crc read call.

Following IGT will fail due to crc-core <-> driver interface change
igt@kms_pipe_crc_basic@bad-source 
ig@kms_pipe_crc_basic@nonblocking-crc-pipe-X
ig@kms_pipe_crc_basic@nonblocking-crc-pipe-X-frame-sequence
In nonblocking crc tests we'll get lesser crc's due to skipping crc

AMD/Rockchip/rcar code path is not validated and need inputs

Changes:
  - Add dri-devel in Cc

Mahesh Kumar (10):
   drm: crc: Introduce verify_crc_source callback
   drm: crc: Introduce pre_crc_read function
   drm: crc: Introduce get_crc_sources callback
   drm/rockchip/crc: Implement verify_crc_source callback
   drm/amdgpu_dm/crc: Implement verify_crc_source callback
   drm/rcar-du/crc: Implement verify_crc_source callback
   drm/i915/crc: implement verify_crc_source callback
   drm/i915/crc: implement get_crc_sources callback
   drm/crc: Cleanup crtc_crc_open function
   Revert "drm: crc: Wait for a frame before returning from open()"

  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |   1 +
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h  |   7 +-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c  |  20 +++-
  drivers/gpu/drm/drm_debugfs_crc.c  |  62 ++-
  drivers/gpu/drm/i915/intel_display.c   |   2 +
  drivers/gpu/drm/i915/intel_drv.h   |   8 +-
  drivers/gpu/drm/i915/intel_pipe_crc.c  | 124 -
  drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  45 +++-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c|  27 -
  include/drm/drm_crtc.h |  42 ++-
  10 files changed, 288 insertions(+), 50 deletions(-)



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


Re: [Intel-gfx] [PATCH] drm/i915/skl+: ddb allocation algorithm optimization

2018-05-23 Thread Kumar, Mahesh



On 5/22/2018 1:27 PM, Maarten Lankhorst wrote:

Hey,

Op 21-05-18 om 13:36 schreef Mahesh Kumar:

From: "Kumar, Mahesh" <mahesh1.ku...@intel.com>

This patch implements new DDB allocation algorithm as per HW team
recommendation. This algo takecare of scenario where we allocate less DDB

takes care*

for the planes with lower relative pixel rate, but they require more DDB
to work.
It also takes care of enabling same watermark level for each
plane in crtc, for efficient power saving.
This algorithm uses fix ddb allocation for cursor planes.

fixed*

Because this is a resubmit for a commit that has been reverted, the commit 
message should at least point out what the regression was, and what has been 
done to fix it. :)

Thanks for review.
agree, will add commit msg in next version of patch.
Just to summarize, Regression was due to the Cursor-Plane WM for level-0 
getting disabled even if cursor plane was enabled.
With New algorithm WM requirement for cursor plane was more & this was 
resulting "8 blocks" not being sufficient. To solve above issue, earlier 
I proposed dynamic DDB allocation for cursor plane.
There was no issue till now for cursor plane with fixed 8/32 block 
allocation, So later decided to use old approach of WM calculation 
*only* for cursor plane (first allocate DDB & later decide/calculate WM).


-Mahesh


I've added Rodrigo to cc, since he reverted the original commit.

Signed-off-by: Mahesh Kumar <mahesh1.ku...@intel.com>
---
  drivers/gpu/drm/i915/i915_drv.h |   1 +
  drivers/gpu/drm/i915/intel_pm.c | 326 ++--
  2 files changed, 184 insertions(+), 143 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e33c380b43e3..5fc8fb67d5d1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1202,6 +1202,7 @@ struct skl_wm_level {
bool plane_en;
uint16_t plane_res_b;
uint8_t plane_res_l;
+   uint16_t min_dbuf_req;
  };
  
  /* Stores plane specific WM parameters */

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b85229e153c4..32665c7fcb2b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4271,13 +4271,58 @@ skl_ddb_calc_min(const struct intel_crtc_state *cstate, 
int num_active,
minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active);
  }
  
+static void

+skl_enable_plane_wm_levels(const struct drm_i915_private *dev_priv,
+  u16 plane_ddb,
+  u16 max_level,
+  struct skl_plane_wm *wm)
+{
+   int level;
+   /*
+* Now enable all levels in WM structure which can be enabled
+* using current DDB allocation
+*/
+   for (level = ilk_wm_max_level(dev_priv); level >= 0; level--) {
+   struct skl_wm_level *level_wm = >wm[level];
+
+   if (level > max_level || level_wm->min_dbuf_req > plane_ddb
+ || (level && level_wm->plane_res_l >= 31)
+ || level_wm->plane_res_b == 0) {
+   level_wm->plane_en = false;
+   level_wm->plane_res_b = 0;
+   level_wm->plane_res_l = 0;
+   } else {
+   level_wm->plane_en = true;
+   }
+
+   /*
+* Display WA #826 (SKL:ALL, BXT:ALL) & #1059 (CNL:A)
+* disable wm level 1-7 on NV12 planes
+*/
+   if (wm->is_planar && level >= 1 &&
+   (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) ||
+IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0))) {
+   level_wm->plane_en = false;
+   level_wm->plane_res_b = 0;
+   level_wm->plane_res_l = 0;
+   }
+   }
+
+   if (wm->trans_wm.plane_res_b && wm->trans_wm.plane_res_b < plane_ddb)
+   wm->trans_wm.plane_en = true;
+   else
+   wm->trans_wm.plane_en = false;
+}
+
  static int
  skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ struct skl_pipe_wm *pipe_wm,
  struct skl_ddb_allocation *ddb /* out */)
  {
struct drm_atomic_state *state = cstate->base.state;
struct drm_crtc *crtc = cstate->base.crtc;
struct drm_device *dev = crtc->dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum pipe pipe = intel_crtc->pipe;
struct skl_ddb_entry *alloc = >wm.skl.ddb;
@@ -4290,6 +4335,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
unsigned int plane_data_rate[I915_MAX_PLANES] = {};
   

Re: [Intel-gfx] [PATCH 03/24] drm/i915/icl: introduce tc_port

2018-05-22 Thread Kumar, Mahesh

Reviewed-by: Mahesh Kumar 


On 5/22/2018 5:55 AM, Paulo Zanoni wrote:

Add and enum for TC ports and auxiliary functions to handle them.
Icelake brings a lot of registers and other things that only apply to
the TC ports and are indexed starting from 0, so having an enum for
tc_ports that starts at 0 really helps the indexing.

This patch is based on previous patches written by Dhinakaran Pandiyan
and Mahesh Kumar.

Cc: Dhinakaran Pandiyan 
Cc: Mahesh Kumar 
Signed-off-by: Paulo Zanoni 
---
  drivers/gpu/drm/i915/intel_display.c | 16 
  drivers/gpu/drm/i915/intel_display.h | 11 +++
  drivers/gpu/drm/i915/intel_drv.h |  3 +++
  3 files changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c9ec88acad9c..64593b0fbebd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5807,6 +5807,22 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
I915_WRITE(BCLRPAT(crtc->pipe), 0);
  }
  
+bool intel_port_is_tc(struct drm_i915_private *dev_priv, enum port port)

+{
+   if (IS_ICELAKE(dev_priv))
+   return port >= PORT_C && port <= PORT_F;
+
+   return false;
+}
+
+enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv, enum port 
port)
+{
+   if (!intel_port_is_tc(dev_priv, port))
+   return PORT_TC_NONE;
+
+   return port - PORT_C;
+}
+
  enum intel_display_power_domain intel_port_to_power_domain(enum port port)
  {
switch (port) {
diff --git a/drivers/gpu/drm/i915/intel_display.h 
b/drivers/gpu/drm/i915/intel_display.h
index 2ef31617614a..c88185ed7594 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -126,6 +126,17 @@ enum port {
  
  #define port_name(p) ((p) + 'A')
  
+enum tc_port {

+   PORT_TC_NONE = -1,
+
+   PORT_TC1 = 0,
+   PORT_TC2,
+   PORT_TC3,
+   PORT_TC4,
+
+   I915_MAX_TC_PORTS
+};
+
  enum dpio_channel {
DPIO_CH0,
DPIO_CH1
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 22af249393a4..a54232c270e1 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1493,6 +1493,9 @@ void intel_connector_attach_encoder(struct 
intel_connector *connector,
struct intel_encoder *encoder);
  struct drm_display_mode *
  intel_encoder_current_mode(struct intel_encoder *encoder);
+bool intel_port_is_tc(struct drm_i915_private *dev_priv, enum port port);
+enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv,
+ enum port port);
  
  enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);

  int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,


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


Re: [Intel-gfx] ✗ Fi.CI.BAT: failure for Optimize use of DBuf slices (rev2)

2018-04-26 Thread Kumar, Mahesh

Hi,


On 4/26/2018 3:24 AM, Rodrigo Vivi wrote:

On Wed, Apr 25, 2018 at 09:46:23PM -, Patchwork wrote:

== Series Details ==

Series: Optimize use of DBuf slices (rev2)
URL   : https://patchwork.freedesktop.org/series/41180/
State : failure

== Summary ==

Applying: drm/i915/icl: track dbuf slice-2 status
error: Failed to merge in the changes.
Using index info to reconstruct a base tree...
M   drivers/gpu/drm/i915/i915_drv.h
M   drivers/gpu/drm/i915/intel_display.c
M   drivers/gpu/drm/i915/intel_pm.c
M   drivers/gpu/drm/i915/intel_runtime_pm.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/intel_runtime_pm.c
Auto-merging drivers/gpu/drm/i915/intel_pm.c
Auto-merging drivers/gpu/drm/i915/intel_display.c
Auto-merging drivers/gpu/drm/i915/i915_drv.h
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/i915_drv.h
Patch failed at 0001 drm/i915/icl: track dbuf slice-2 status
The copy of the patch that failed is found in: .git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

Mahesh, I'm really sorry for taking so long to review these patches

Could you please send a rebased version so after CI giving the okay we push it.

Thanks for review, Will resend the series after rebase.

Regards,
-Mahesh


Thanks in advance,
Rodrigo.


== Logs ==

For more details see: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8588/issues.html
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


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


Re: [Intel-gfx] [PATCH 1/3] drm/i915/icl: track dbuf slice-2 status

2018-04-05 Thread Kumar, Mahesh

Hi,


On 4/5/2018 1:55 PM, Jani Nikula wrote:

On Thu, 05 Apr 2018, Mahesh Kumar  wrote:

This patch adds support to start tracking status of DBUF slices.
This is foundation to introduce support for enabling/disabling second
DBUF slice dynamically for ICL.

Signed-off-by: Mahesh Kumar 
Reviewed-by: James Ausmus 
---
  drivers/gpu/drm/i915/i915_drv.h |  1 +
  drivers/gpu/drm/i915/intel_display.c|  5 +
  drivers/gpu/drm/i915/intel_pm.c | 20 
  drivers/gpu/drm/i915/intel_runtime_pm.c |  4 
  4 files changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5373b171bb96..e51da42297d8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1184,6 +1184,7 @@ static inline bool skl_ddb_entry_equal(const struct 
skl_ddb_entry *e1,
  struct skl_ddb_allocation {
struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* 
packed/uv */
struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES];
+   uint8_t enabled_slices; /* GEN11 has configurable 2 slices */

Please prefer kernel types u8/u16/u32/u64 over uint8_t and friends. It's
fine to use the stdint types when the context uses them, but please
let's not add new ones.

ok, sure will update in new version
-Mahesh


BR,
Jani.



  };
  
  struct skl_wm_values {

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 415fb8cf2cf4..96a1e6a7f69e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11385,6 +11385,11 @@ static void verify_wm_state(struct drm_crtc *crtc,
skl_ddb_get_hw_state(dev_priv, _ddb);
sw_ddb = _priv->wm.skl_hw.ddb;
  
+	if (INTEL_GEN(dev_priv) >= 11)

+   if (hw_ddb.enabled_slices != sw_ddb->enabled_slices)
+   DRM_ERROR("mismatch in DBUF Slices (expected %u, got 
%u)\n",
+ sw_ddb->enabled_slices,
+ hw_ddb.enabled_slices);
/* planes */
for_each_universal_plane(dev_priv, pipe, plane) {
hw_plane_wm = _wm.planes[plane];
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 19e82aaa9863..3ff37d5ba353 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3567,6 +3567,23 @@ bool ilk_disable_lp_wm(struct drm_device *dev)
return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
  }
  
+static uint8_t intel_enabled_dbuf_slices_num(struct drm_i915_private *dev_priv)

+{
+   uint8_t enabled_slices;
+
+   /* Slice 1 will always be enabled */
+   enabled_slices = 1;
+
+   /* Gen prior to GEN11 have only one DBuf slice */
+   if (INTEL_GEN(dev_priv) < 11)
+   return enabled_slices;
+
+   if (I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE)
+   enabled_slices++;
+
+   return enabled_slices;
+}
+
  /*
   * FIXME: We still don't have the proper code detect if we need to apply the 
WA,
   * so assume we'll always need it in order to avoid underruns.
@@ -3832,6 +3849,8 @@ void skl_ddb_get_hw_state(struct drm_i915_private 
*dev_priv,
  
  	memset(ddb, 0, sizeof(*ddb));
  
+	ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv);

+
for_each_intel_crtc(_priv->drm, crtc) {
enum intel_display_power_domain power_domain;
enum plane_id plane_id;
@@ -5050,6 +5069,7 @@ skl_copy_wm_for_pipe(struct skl_wm_values *dst,
   sizeof(dst->ddb.y_plane[pipe]));
memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe],
   sizeof(dst->ddb.plane[pipe]));
+   dst->ddb.enabled_slices = src->ddb.enabled_slices;
  }
  
  static void

diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c 
b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 53ea564f971e..58be542d660b 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -2664,6 +2664,8 @@ static void icl_dbuf_enable(struct drm_i915_private 
*dev_priv)
if (!(I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) ||
!(I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE))
DRM_ERROR("DBuf power enable timeout\n");
+   else
+   dev_priv->wm.skl_hw.ddb.enabled_slices = 2;
  }
  
  static void icl_dbuf_disable(struct drm_i915_private *dev_priv)

@@ -2677,6 +2679,8 @@ static void icl_dbuf_disable(struct drm_i915_private 
*dev_priv)
if ((I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) ||
(I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE))
DRM_ERROR("DBuf power disable timeout!\n");
+   else
+   dev_priv->wm.skl_hw.ddb.enabled_slices = 0;
  }
  
  static void icl_mbus_init(struct drm_i915_private *dev_priv)


___
Intel-gfx mailing list

Re: [Intel-gfx] [PATCH 1/3] drm/i915/cnl; Add macro to get PORT_TX register

2018-03-12 Thread Kumar, Mahesh

Hi,


On 3/10/2018 2:21 AM, Lucas De Marchi wrote:

On Fri, Mar 09, 2018 at 11:55:47AM -0800, Rodrigo Vivi wrote:

On Fri, Mar 09, 2018 at 06:28:56PM +0530, Mahesh Kumar wrote:

This patch creates a new macro to get PORT_TX register for any given DW.
This will remove the need of defining register address for each port & DW.

please squash patches 1 and 2. I had to open both simultaneously to review it
what indicates that they should be 1 patch.

ok, will merge.



Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/i915_reg.h | 28 
  1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e6a8c0ee7df1..30ef3513dc6f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1964,6 +1964,34 @@ enum i915_power_well_id {
_CNL_PORT_PCS_DW1_LN0_F)
  #define   COMMON_KEEPER_EN(1 << 26)
  
+/* CNL Port TX registers */

+#define _CNL_PORT_TX_AE_GRP_OFFSET 0x162340
+#define _CNL_PORT_TX_B_GRP_OFFSET  0x1623C0
+#define _CNL_PORT_TX_C_GRP_OFFSET  0x162B40
+#define _CNL_PORT_TX_D_GRP_OFFSET  0x162BC0
+#define _CNL_PORT_TX_F_GRP_OFFSET  0x162A40
+#define _CNL_PORT_TX_AE_LN0_OFFSET 0x162440
+#define _CNL_PORT_TX_B_LN0_OFFSET  0x162640
+#define _CNL_PORT_TX_C_LN0_OFFSET  0x162C40
+#define _CNL_PORT_TX_D_LN0_OFFSET  0x162E40
+#define _CNL_PORT_TX_F_LN0_OFFSET  0x162840
+#define CNL_PORT_TX_DW_GRP(port, dw)   (_PICK((port), \
+  _CNL_PORT_TX_AE_GRP_OFFSET, \
+  _CNL_PORT_TX_B_GRP_OFFSET, \
+  _CNL_PORT_TX_B_GRP_OFFSET, \
+  _CNL_PORT_TX_D_GRP_OFFSET, \
+  _CNL_PORT_TX_AE_GRP_OFFSET, \
+  _CNL_PORT_TX_F_GRP_OFFSET) + \
+  4*(dw))

the math is right. I'm glad someone could see some logic on all these
numbers. I with we had a basic offset and math for all the port registers, 
but...


+#define CNL_PORT_TX_DW_LN0(port, dw)   (_PICK((port), \

who converts the offset to MMIO reg now?

caller of this macro converts it to MMIO reg

I don't think this is supposed to be used outside the header is it?
I think it should have a underscore, because otherwise it's confusing
that CNL_PORT_TX_DW_LN0 returns an offsed and CNL_PORT_TX_DW[0-5]_LN0
return an mmio reg.

hmm, agree, will add underscore to the macros.


And if it's used elsewhere, maybe append _OFFSET to the macro?

this isn't intended to be used outside of header file.
-Mahesh


Lucas De Marchi


+  _CNL_PORT_TX_AE_LN0_OFFSET, \
+  _CNL_PORT_TX_B_LN0_OFFSET, \
+  _CNL_PORT_TX_B_LN0_OFFSET, \
+  _CNL_PORT_TX_D_LN0_OFFSET, \
+  _CNL_PORT_TX_AE_LN0_OFFSET, \
+  _CNL_PORT_TX_F_LN0_OFFSET) + \
+  4*(dw))
+
  #define _CNL_PORT_TX_DW2_GRP_AE   0x162348
  #define _CNL_PORT_TX_DW2_GRP_B0x1623C8
  #define _CNL_PORT_TX_DW2_GRP_C0x162B48
--
2.14.1

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

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


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


Re: [Intel-gfx] [PATCH v3] drm/i915/icl: remove port A/E lane sharing limitation.

2018-03-04 Thread Kumar, Mahesh

Please review.

thanks,

-Mahesh

On 2/6/2018 11:38 AM, Mahesh Kumar wrote:

Platforms before Gen11 were sharing lanes between port-A & port-E.
This limitation is no more there.

Changes since V1:
  - optimize the code (Shashank/Jani)
  - create helper function to get max lanes (ville)
Changes since V2:
  - Include BIOS fail fix-up in same helper function (ville)
Changes since V3:
  - remove confusing if/else (jani)
  - group intel_encoder initialization

Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/intel_ddi.c | 85 ++--
  1 file changed, 39 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index cfcd9cb37d5d..60fe2ba4b29c 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2842,39 +2842,45 @@ static bool intel_ddi_a_force_4_lanes(struct 
intel_digital_port *dport)
return false;
  }
  
+static int

+intel_ddi_max_lanes(struct intel_digital_port *intel_dport)
+{
+   struct drm_i915_private *dev_priv = to_i915(intel_dport->base.base.dev);
+   enum port port = intel_dport->base.port;
+   int max_lanes = 4;
+
+   if (INTEL_GEN(dev_priv) >= 11)
+   return max_lanes;
+
+   if (port == PORT_A || port == PORT_E) {
+   if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES)
+   max_lanes = port == PORT_A ? 4 : 0;
+   else
+   /* Both A and E share 2 lanes */
+   max_lanes = 2;
+   }
+
+   /*
+* Some BIOS might fail to set this bit on port A if eDP
+* wasn't lit up at boot.  Force this bit set when needed
+* so we use the proper lane count for our calculations.
+*/
+   if (intel_ddi_a_force_4_lanes(intel_dport)) {
+   DRM_DEBUG_KMS("Forcing DDI_A_4_LANES for port A\n");
+   intel_dport->saved_port_bits |= DDI_A_4_LANES;
+   max_lanes = 4;
+   }
+
+   return max_lanes;
+}
+
  void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
  {
struct intel_digital_port *intel_dig_port;
struct intel_encoder *intel_encoder;
struct drm_encoder *encoder;
bool init_hdmi, init_dp, init_lspcon = false;
-   int max_lanes;
  
-	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {

-   switch (port) {
-   case PORT_A:
-   max_lanes = 4;
-   break;
-   case PORT_E:
-   max_lanes = 0;
-   break;
-   default:
-   max_lanes = 4;
-   break;
-   }
-   } else {
-   switch (port) {
-   case PORT_A:
-   max_lanes = 2;
-   break;
-   case PORT_E:
-   max_lanes = 2;
-   break;
-   default:
-   max_lanes = 4;
-   break;
-   }
-   }
  
  	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||

 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
@@ -2920,10 +2926,17 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, 
enum port port)
intel_encoder->get_config = intel_ddi_get_config;
intel_encoder->suspend = intel_dp_encoder_suspend;
intel_encoder->get_power_domains = intel_ddi_get_power_domains;
+   intel_encoder->type = INTEL_OUTPUT_DDI;
+   intel_encoder->power_domain = intel_port_to_power_domain(port);
+   intel_encoder->port = port;
+   intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+   intel_encoder->cloneable = 0;
  
  	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &

  (DDI_BUF_PORT_REVERSAL |
   DDI_A_4_LANES);
+   intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
+   intel_dig_port->max_lanes = intel_ddi_max_lanes(intel_dig_port);
  
  	switch (port) {

case PORT_A:
@@ -2954,26 +2967,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, 
enum port port)
MISSING_CASE(port);
}
  
-	/*

-* Some BIOS might fail to set this bit on port A if eDP
-* wasn't lit up at boot.  Force this bit set when needed
-* so we use the proper lane count for our calculations.
-*/
-   if (intel_ddi_a_force_4_lanes(intel_dig_port)) {
-   DRM_DEBUG_KMS("Forcing DDI_A_4_LANES for port A\n");
-   intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
-   max_lanes = 4;
-   }
-
-   intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
-   intel_dig_port->max_lanes = max_lanes;
-
-   intel_encoder->type = INTEL_OUTPUT_DDI;
-   intel_encoder->power_domain = 

Re: [Intel-gfx] [PATCH 05/16] drm/i915/skl+: NV12 related changes for WM

2018-02-13 Thread Kumar, Mahesh

Hi,


On 2/7/2018 10:12 PM, Sharma, Shashank wrote:

Regards

Shashank


On 2/6/2018 6:28 PM, Vidya Srinivas wrote:

From: Mahesh Kumar 

NV12 requires WM calculation for UV plane as well.
UV plane WM should also fulfill all the WM related restrictions.

Signed-off-by: Mahesh Kumar 
---
  drivers/gpu/drm/i915/i915_drv.h  |  1 +
  drivers/gpu/drm/i915/intel_drv.h |  1 +
  drivers/gpu/drm/i915/intel_pm.c  | 54 


  3 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h 
b/drivers/gpu/drm/i915/i915_drv.h

index cca5414..778dc5a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1459,6 +1459,7 @@ struct skl_wm_level {
  struct skl_wm_params {
  bool x_tiled, y_tiled;
  bool rc_surface;
+    bool is_nv12;
  uint32_t width;
  uint8_t cpp;
  uint32_t plane_pixel_rate;
diff --git a/drivers/gpu/drm/i915/intel_drv.h 
b/drivers/gpu/drm/i915/intel_drv.h

index ed33840..65dac21 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -594,6 +594,7 @@ struct intel_pipe_wm {
    struct skl_plane_wm {
  struct skl_wm_level wm[8];
+    struct skl_wm_level uv_wm[8];
  struct skl_wm_level trans_wm;
  bool is_nv12;
  };
diff --git a/drivers/gpu/drm/i915/intel_pm.c 
b/drivers/gpu/drm/i915/intel_pm.c

index 4c9a811..b3d1bf7 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4421,7 +4421,7 @@ static int
  skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
  struct intel_crtc_state *cstate,
  const struct intel_plane_state *intel_pstate,
-    struct skl_wm_params *wp)
+    struct skl_wm_params *wp, int plane_num)
Is this plane_num intended for 'no of planes' or 'plane number' ? from 
the usage below looks like 'no of planes' but I could be wrong.

it's plane-number.

  {
  struct intel_plane *plane = 
to_intel_plane(intel_pstate->base.plane);

  const struct drm_plane_state *pstate = _pstate->base;
@@ -4434,6 +4434,12 @@ skl_compute_plane_wm_params(const struct 
drm_i915_private *dev_priv,

  if (!intel_wm_plane_visible(cstate, intel_pstate))
  return 0;
  +    /* only NV12 format has two planes */
+    if (plane_num == 1 && fb->format->format != DRM_FORMAT_NV12) {
+    DRM_DEBUG_KMS("Non NV12 format have single plane\n");
+    return -EINVAL;
+    }
The comment says only NV12 format can have two planes, but if format 
!= NV12 && plane_num == 1, why is this an error ? Also the debug 
message says "Non NV12 format have single plane". Shouldn't it ?
Looks like you are expecting plane_number = 0, 1 for NV12 planes, and 
when plane_num is non-zero, you expect it to be NV12 only ?
yes, non-planar formats will have single plane, that's why if format != 
NV12 & plane_num == 1 it's an error.



+
  wp->y_tiled = fb->modifier == I915_FORMAT_MOD_Y_TILED ||
    fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
    fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
@@ -4441,6 +4447,7 @@ skl_compute_plane_wm_params(const struct 
drm_i915_private *dev_priv,

  wp->x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED;
  wp->rc_surface = fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
   fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
+    wp->is_nv12 = fb->format->format == DRM_FORMAT_NV12;
    if (plane->id == PLANE_CURSOR) {
  wp->width = intel_pstate->base.crtc_w;
@@ -4453,7 +4460,10 @@ skl_compute_plane_wm_params(const struct 
drm_i915_private *dev_priv,

  wp->width = drm_rect_width(_pstate->base.src) >> 16;
  }
  -    wp->cpp = fb->format->cpp[0];
+    if (plane_num == 1 && wp->is_nv12)
+    wp->width /= 2;
+
+    wp->cpp = fb->format->cpp[plane_num];
  wp->plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate,
   intel_pstate);
  @@ -4649,7 +4659,8 @@ skl_compute_wm_levels(const struct 
drm_i915_private *dev_priv,

    struct intel_crtc_state *cstate,
    const struct intel_plane_state *intel_pstate,
    const struct skl_wm_params *wm_params,
-  struct skl_plane_wm *wm)
+  struct skl_plane_wm *wm,
+  int plane_num)

Same question here

  {
  struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
  struct drm_plane *plane = intel_pstate->base.plane;
@@ -4657,15 +4668,20 @@ skl_compute_wm_levels(const struct 
drm_i915_private *dev_priv,

  uint16_t ddb_blocks;
  enum pipe pipe = intel_crtc->pipe;
  int level, max_level = ilk_wm_max_level(dev_priv);
+    enum plane_id plane_id = intel_plane->id;
  int ret;
    if (WARN_ON(!intel_pstate->base.fb))
  return -EINVAL;
  -    ddb_blocks = 
skl_ddb_entry_size(>plane[pipe][intel_plane->id]);

+    if (plane_num == 0)
+   

Re: [Intel-gfx] [PATCH 08/16] drm/i915/skl+: nv12 workaround disable WM level 1-7

2018-02-08 Thread Kumar, Mahesh

Hi,


On 2/8/2018 2:01 PM, Sharma, Shashank wrote:

Regards

Shashank


On 2/6/2018 6:28 PM, Vidya Srinivas wrote:

From: Mahesh Kumar 

Display Workaround #0826 (SKL:ALL BXT:ALL) & #1059(CNL:A)
Hardware sometimes fails to wake memory from pkg C states fetching the
last few lines of planar YUV 420 (NV12) planes. This causes
intermittent underflow and corruption.
WA: Disable package C states or do not enable latency levels 1 through 7
(WM1 - WM7) on NV12 planes.

v2: Addressed review comments by Maarten.

Reviewed-by: Maarten Lankhorst 
Signed-off-by: Mahesh Kumar 
Signed-off-by: Vidya Srinivas 
---
  drivers/gpu/drm/i915/intel_pm.c | 11 +++
  1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c 
b/drivers/gpu/drm/i915/intel_pm.c

index d9801bf..c37d014 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4654,6 +4654,17 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,

  }
  }
  +    /*
+ * Display WA #826 (SKL:ALL, BXT:ALL) & #1059 (CNL:A)
+ * disable wm level 1-7 on NV12 planes
+ */
+    if (wp->is_nv12 && (level >= 1) &&
+    (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) ||
+ IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0))) {
Seeing that this WAR is applicable for all GEN9 and CNL some rev ids, 
Is this applicable for GLK too ?
Not really for all GEN-9, it's valid for SKL/BXT-ALL & CNL some id, so 
it doesn't seems to be applicable for GLK.


-Mahesh

- Shashank

+    result->plane_en = false;
+    return 0;
+    }
+
  result->plane_res_b = res_blocks;
  result->plane_res_l = res_lines;
  result->plane_en = true;




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


Re: [Intel-gfx] [PATCH] drm/i915/icl: remove port A/E lane sharing limitation.

2018-02-05 Thread Kumar, Mahesh

Hi,


On 2/2/2018 6:26 PM, Jani Nikula wrote:

On Fri, 02 Feb 2018, Mahesh Kumar  wrote:

Platforms before Gen11 were sharing lanes between port-A & port-E.
This limitation is no more there.

Changes since V1:
  - optimize the code (Shashank/Jani)
  - create helper function to get max lanes (ville)
Changes since V2:
  - Include BIOS fail fix-up in same helper function (ville)

Signed-off-by: Mahesh Kumar 
Reviewed-by: Dhinakaran Pandiyan 
---
  drivers/gpu/drm/i915/intel_ddi.c | 71 +++-
  1 file changed, 33 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index cfcd9cb37d5d..ee9ba78d19c8 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2842,39 +2842,44 @@ static bool intel_ddi_a_force_4_lanes(struct 
intel_digital_port *dport)
return false;
  }
  
+static int

+intel_ddi_max_lanes(struct drm_i915_private *dev_priv,
+   struct intel_digital_port *intel_dig_port)
+{

Please ditch the dev_priv parameter and add:

struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);

ok, sure.



+   enum port port = intel_dig_port->base.port;
+   int max_lanes = 4;

Unnecessary initialization.
for ports other than PORT_A/E will have max_lanes=4 that's the reason 
initializing it here, will fix the usages.



+
+   if (INTEL_GEN(dev_priv) >= 11) {
+   return 4;

Please either set max_lanes = 4 here, or remove the else. On early
returns, you don't need the else. Having both is confusing.

yes, agree, will remove the else



+   } else if (port == PORT_A || port == PORT_E) {
+   if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES)
+   max_lanes = port == PORT_A ? 4 : 0;
+   else
+   /* Both A and E share 2 lanes */
+   max_lanes = 2;
+   }
+
+   /*
+* Some BIOS might fail to set this bit on port A if eDP
+* wasn't lit up at boot.  Force this bit set when needed
+* so we use the proper lane count for our calculations.
+*/
+   if (intel_ddi_a_force_4_lanes(intel_dig_port)) {
+   DRM_DEBUG_KMS("Forcing DDI_A_4_LANES for port A\n");
+   intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
+   max_lanes = 4;
+   }
+
+   return max_lanes;
+}
+
  void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
  {
struct intel_digital_port *intel_dig_port;
struct intel_encoder *intel_encoder;
struct drm_encoder *encoder;
bool init_hdmi, init_dp, init_lspcon = false;
-   int max_lanes;
  
-	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {

-   switch (port) {
-   case PORT_A:
-   max_lanes = 4;
-   break;
-   case PORT_E:
-   max_lanes = 0;
-   break;
-   default:
-   max_lanes = 4;
-   break;
-   }
-   } else {
-   switch (port) {
-   case PORT_A:
-   max_lanes = 2;
-   break;
-   case PORT_E:
-   max_lanes = 2;
-   break;
-   default:
-   max_lanes = 4;
-   break;
-   }
-   }
  
  	init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||

 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
@@ -2954,19 +2959,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, 
enum port port)
MISSING_CASE(port);
}
  
-	/*

-* Some BIOS might fail to set this bit on port A if eDP
-* wasn't lit up at boot.  Force this bit set when needed
-* so we use the proper lane count for our calculations.
-*/
-   if (intel_ddi_a_force_4_lanes(intel_dig_port)) {
-   DRM_DEBUG_KMS("Forcing DDI_A_4_LANES for port A\n");
-   intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
-   max_lanes = 4;
-   }
-
intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
-   intel_dig_port->max_lanes = max_lanes;
  
  	intel_encoder->type = INTEL_OUTPUT_DDI;

intel_encoder->power_domain = intel_port_to_power_domain(port);
@@ -2974,6 +2967,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, 
enum port port)
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_encoder->cloneable = 0;
  
+	intel_dig_port->max_lanes = intel_ddi_max_lanes(dev_priv,

+   intel_dig_port);

Please keep this at the original location above.
I moved this here because intel_encoder->port was not initialized in 
original 

Re: [Intel-gfx] [PATCH 15/15] drm/i915: Add NV12 support to intel_framebuffer_init

2018-01-29 Thread Kumar, Mahesh

Hi,

On 1/30/2018 9:35 AM, Srinivas, Vidya wrote:



-Original Message-
From: Maarten Lankhorst [mailto:maarten.lankho...@linux.intel.com]
Sent: Monday, January 29, 2018 10:47 PM
To: Srinivas, Vidya ; intel-
g...@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 15/15] drm/i915: Add NV12 support to
intel_framebuffer_init

Op 20-01-18 om 22:45 schreef Vidya Srinivas:

From: Chandra Konduru 

This patch adds NV12 as supported format to intel_framebuffer_init and
performs various checks.

v2:
-Fix an issue in checks added (Chandra Konduru)

v3: rebased (me)

v4: Review comments by Ville addressed Added platform check for NV12
in intel_framebuffer_init Removed offset checks for NV12 case

v5: Addressed review comments by Clinton A Taylor This NV12 support
only correctly works on SKL.
Plane color space conversion is different on GLK and later platforms
causing the colors to display incorrectly.
Ville's plane color space property patch series in review will fix
this issue.
- Restricted the NV12 case in intel_framebuffer_init to SKL and BXT
only.

v6: Rebased (me)

v7: Addressed review comments by Ville Restricting the NV12 to BXT for
now.

v8: Rebased (me)
Restricting the NV12 changes to BXT and KBL for now.

v9: Rebased (me)

Hey,

Has NV12 been tested at all on skylake with rotation?

y_min_scanlines = 16 for 90°/270° rotation with cpp=1
skl_needs_memory_bw_wa() doubles the scanlines required, which will
trigger the following error quite easily when patching kms_rotation_crc to
use NV12:

[   67.049190] [drm:skl_compute_wm_levels [i915]] Requested display
configuration exceeds system watermark limitations [   67.049212]
[drm:skl_compute_wm_levels [i915]] [PLANE:28:plane 1A] blocks required =
161/572, lines required = 32/31

If we violate the spec for the workaround, by using 31 lines instead of 32 for
90/270 rotation, the tests work but this needs to be solved first before we
can move forward.
We are hitting this issue due to memory_bw_wa (this is applicable for 
GEN-9 only) & we are applying WA irrespective of it's required or not.
I had plan to apply this WA based on our discussion, but it never 
materialized :(

https://www.spinics.net/lists/intel-gfx/msg124872.html


We came across many such scenarios during NV12 testing on BXT. During 
downscaling,
the "Max supported pixel clock with scaling exceeded" is seen if the user layer 
tries to downscale
much. And rotation, as you mentioned we have seen such messages. We discussed 
the same during the meeting
long back and mentioned that if we remove the limitations, it works. But as per 
discussion, if limitations are removed, it may work,
but there may be certain conditions where it may not work. Hence we concluded 
that some such cases are expected not to work.
Either we can conclude that as a limitation (as expected behavior) OR we 
can enable WA only when it's required (as discussed, assuming all the 
planes are enabled with max supported scaling to avoid taking mutex in 
each flip). what you say?


-Mahesh

However, I will discuss once again with Mahesh Kumar (CC) who works on WM 
implementation to re-confirm on the same.


~Maarten


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


[Intel-gfx] [PATCH v4 5/8] drm/i915/skl+: reset y_plane ddb structure also during calculation

2016-10-13 Thread Kumar, Mahesh
From: Mahesh Kumar 

Current code clears only plane ddb allocation if total ddb allocated to
pipe in zero. y_plane ddb still contains old value, clear that as well.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5b8f715..a668204 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3381,6 +3381,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
alloc_size = skl_ddb_entry_size(alloc);
if (alloc_size == 0) {
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+   memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
return 0;
}
 
-- 
2.10.1

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


[Intel-gfx] [PATCH v4 7/8] drm/i915/skl+: change WM calc to fixed point 16.16

2016-10-13 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch changes Watermak calculation to fixed point calculation.
Problem with current calculation is during plane_blocks_per_line
calculation we divide intermediate blocks with min_scanlines and
takes floor of the result because of integer operation.
hence we end-up assigning less blocks than required. Which leads to
flickers.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0eaaadc..4263212 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3527,16 +3527,19 @@ static uint32_t skl_pipe_pixel_rate(const struct 
intel_crtc_state *config)
  * for the read latency) and cpp 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.
+ * Both Method1 & Method2 returns fixedpoint 16.16 output
 */
 static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp, uint32_t 
latency)
 {
-   uint32_t wm_intermediate_val, ret;
+   uint64_t wm_intermediate_val;
+   uint32_t ret;
 
if (latency == 0)
return UINT_MAX;
 
-   wm_intermediate_val = latency * pixel_rate * cpp / 512;
-   ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
+   wm_intermediate_val = latency * pixel_rate * cpp;
+   wm_intermediate_val <<= 16;
+   ret = DIV_ROUND_UP_ULL(wm_intermediate_val, 1000 * 512);
 
return ret;
 }
@@ -3658,12 +3661,15 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
if (y_tiled) {
plane_blocks_per_line =
  DIV_ROUND_UP(plane_bytes_per_line * y_min_scanlines, 512);
-   plane_blocks_per_line /= y_min_scanlines;
+   plane_blocks_per_line = (plane_blocks_per_line << 16) /
+   y_min_scanlines;
} else if (x_tiled) {
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+   plane_blocks_per_line <<= 16;
} else {
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512)
+ 1;
+   plane_blocks_per_line <<= 16;
}
 
method1 = skl_wm_method1(plane_pixel_rate, cpp, latency);
@@ -3690,7 +3696,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
selected_result = method1;
}
 
-   res_blocks = selected_result + 1;
+   res_blocks = DIV_ROUND_UP(selected_result, 1 << 16) + 1;
res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
 
if (level >= 1 && level <= 7) {
-- 
2.10.1

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


[Intel-gfx] [PATCH v4 6/8] drm/i915/skl: Add variables to check x_tile and y_tile

2016-10-13 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch adds variable to check for X_tiled & y_tiled planes, instead
of always checking against framebuffer-modifiers.

Changes:
 - Created separate patch as per Paulo's comment
 - Added x_tiled variable as well

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a668204..0eaaadc 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3602,6 +3602,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
uint32_t plane_pixel_rate;
uint32_t y_tile_minimum, y_min_scanlines;
enum watermark_memory_wa mem_wa;
+   bool y_tiled = false, x_tiled = false;
 
if (latency == 0 || !cstate->base.active || !intel_pstate->base.visible)
return 0;
@@ -3621,6 +3622,12 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
cpp = drm_format_plane_cpp(fb->pixel_format, 0);
plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate);
 
+   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)
+   y_tiled = true;
+   else if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
+   x_tiled = true;
+
if (intel_rotation_90_or_270(pstate->rotation)) {
int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
drm_format_plane_cpp(fb->pixel_format, 1) :
@@ -3648,16 +3655,15 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
y_min_scanlines *= 2;
 
plane_bytes_per_line = width * cpp;
-   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
-   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+   if (y_tiled) {
plane_blocks_per_line =
  DIV_ROUND_UP(plane_bytes_per_line * y_min_scanlines, 512);
plane_blocks_per_line /= y_min_scanlines;
-   } else if (fb->modifier[0] == DRM_FORMAT_MOD_NONE) {
+   } else if (x_tiled) {
+   plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+   } else {
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512)
+ 1;
-   } else {
-   plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
}
 
method1 = skl_wm_method1(plane_pixel_rate, cpp, latency);
@@ -3668,8 +3674,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
 
y_tile_minimum = plane_blocks_per_line * y_min_scanlines;
 
-   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
-   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+   if (y_tiled) {
selected_result = max(method2, y_tile_minimum);
} else {
uint32_t linetime_us = 0;
@@ -3689,8 +3694,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
 
if (level >= 1 && level <= 7) {
-   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
-   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+   if (y_tiled) {
res_blocks += y_tile_minimum;
res_lines += y_min_scanlines;
} else {
-- 
2.10.1

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


[Intel-gfx] [PATCH v4 1/8] drm/i915/skl+: use linetime latency instead of ddb size

2016-10-13 Thread Kumar, Mahesh
This patch make changes to use linetime latency instead of allocated
DDB size during plane watermark calculation in switch case, This is
required to implement new DDB allocation algorithm.

In New Algorithm DDB is allocated based on WM values, because of which
number of DDB blocks will not be available during WM calculation,
So this "linetime latency" is suggested by SV/HW team to use during
switch-case for WM blocks selection.

Changes since v1:
 - Rebase on top of Paulo's patch series
Changes since v2:
 - Fix if-else condition (pointed by Maarten)

Signed-off-by: "Kumar, Mahesh" <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7f1748a..098336d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3616,10 +3616,14 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
selected_result = max(method2, y_tile_minimum);
} else {
+   uint32_t linetime_us = 0;
+
+   linetime_us = DIV_ROUND_UP(width * 1000,
+   skl_pipe_pixel_rate(cstate));
if ((cpp * cstate->base.adjusted_mode.crtc_htotal / 512 < 1) &&
(plane_bytes_per_line / 512 < 1))
selected_result = method2;
-   else if ((ddb_allocation / plane_blocks_per_line) >= 1)
+   else if (latency >= linetime_us)
selected_result = min(method1, method2);
else
selected_result = method1;
-- 
2.10.1

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


[Intel-gfx] [PATCH v4 8/8] drm/i915/bxt: Enable IPC support

2016-10-13 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch adds IPC support for platforms. This patch enables IPC
only for BXT/KBL platform as for SKL recommendation is to keep is disabled.
IPC (Isochronous Priority Control) is the hardware feature, which
dynamically controles the memory read priority of Display.

When IPC is enabled, plane read requests are sent at high priority until
filling above the transition watermark, then the requests are sent at
lower priority until dropping below the level 0 watermark.
The lower priority requests allow other memory clients to have better
memory access. When IPC is disabled, all plane read requests are sent at
high priority.

Changes since V1:
 - Remove commandline parameter to disable ipc
 - Address Paulo's comments

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/i915_drv.c  |  2 ++
 drivers/gpu/drm/i915/i915_reg.h  |  1 +
 drivers/gpu/drm/i915/intel_drv.h |  1 +
 drivers/gpu/drm/i915/intel_pm.c  | 15 +++
 4 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index b5f601c..58abbaa 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1415,6 +1415,8 @@ int i915_driver_load(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 
intel_runtime_pm_enable(dev_priv);
 
+   intel_enable_ipc(dev_priv);
+
/* Everything is in place, we can now relax! */
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
 driver.name, driver.major, driver.minor, driver.patchlevel,
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a9c467c..c9ebf23 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6144,6 +6144,7 @@ enum {
 #define  DISP_FBC_WM_DIS   (1<<15)
 #define DISP_ARB_CTL2  _MMIO(0x45004)
 #define  DISP_DATA_PARTITION_5_6   (1<<6)
+#define  DISP_IPC_ENABLE   (1<<3)
 #define DBUF_CTL   _MMIO(0x45008)
 #define  DBUF_POWER_REQUEST(1<<31)
 #define  DBUF_POWER_STATE  (1<<30)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2c1897b..45b0fa4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1766,6 +1766,7 @@ void skl_write_plane_wm(struct intel_crtc *intel_crtc,
 uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config);
 bool ilk_disable_lp_wm(struct drm_device *dev);
 int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6);
+void intel_enable_ipc(struct drm_i915_private *dev_priv);
 static inline int intel_enable_rc6(void)
 {
return i915.enable_rc6;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 4263212..543aa5d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4833,6 +4833,21 @@ void intel_update_watermarks(struct drm_crtc *crtc)
dev_priv->display.update_wm(crtc);
 }
 
+void intel_enable_ipc(struct drm_i915_private *dev_priv)
+{
+   u32 val;
+
+   /* enable IPC only for Broxton for now*/
+   if (!IS_BROXTON(dev_priv) || !IS_KABYLAKE(dev_priv))
+   return;
+
+   val = I915_READ(DISP_ARB_CTL2);
+
+   val |= DISP_IPC_ENABLE;
+
+   I915_WRITE(DISP_ARB_CTL2, val);
+}
+
 /*
  * Lock protecting IPS related data structures
  */
-- 
2.10.1

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


[Intel-gfx] [PATCH v4 2/8] drm/i915/skl: New ddb allocation algorithm

2016-10-13 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch implements new DDB allocation algorithm as per HW team
recommendation. This algo takecare of scenario where we allocate less DDB
for the planes with lower relative pixel rate, but they require more DDB
to work.
It also takes care of enabling same watermark level for each
plane, for efficient power saving.

Changes since v1:
 - Rebase on top of Paulo's patch series

Changes since v2:
 - Fix the for loop condition to enable WM

Changes since v3:
 - Fix crash in cursor i-g-t reported by Maarten
 - Rebase after addressing Paulo's comments
 - Few other ULT fixes

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 149 +---
 1 file changed, 79 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 098336d..84ec6b1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3344,6 +3344,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
 
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ struct skl_pipe_wm *pipe_wm,
  struct skl_ddb_allocation *ddb /* out */)
 {
struct drm_atomic_state *state = cstate->base.state;
@@ -3359,8 +3360,12 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
uint16_t *minimum = cstate->wm.skl.minimum_blocks;
uint16_t *y_minimum = cstate->wm.skl.minimum_y_blocks;
unsigned int total_data_rate;
+   uint16_t total_min_blocks = 0;
+   uint16_t total_level_ddb = 0;
int num_active;
-   int id, i;
+   int max_level, level;
+   int id, i, ret = 0;
+
 
if (WARN_ON(!state))
return 0;
@@ -3409,19 +3414,42 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
}
 
for (i = 0; i < PLANE_CURSOR; i++) {
-   alloc_size -= minimum[i];
-   alloc_size -= y_minimum[i];
+   total_min_blocks += minimum[i];
+   total_min_blocks += y_minimum[i];
}
 
-   /*
-* 2. Distribute the remaining space in proportion to the amount of
-* data each plane needs to fetch from memory.
-*
-* FIXME: we may not allocate every single block here.
-*/
+   for (level = ilk_wm_max_level(dev); level >= 0; level--) {
+   total_level_ddb = 0;
+   for (i = 0; i < PLANE_CURSOR; i++) {
+   /*
+* TODO: We should calculate watermark values for Y/UV
+* plane both in case of NV12 format and use both values
+* for ddb calculation, As NV12 is disabled as of now.
+* using only single plane value here.
+*/
+   uint16_t min = minimum[i] + y_minimum[i];
+   uint16_t plane_level_ddb_wm =
+   max(pipe_wm->wm[level].plane_res_b[i], min);
+   total_level_ddb += plane_level_ddb_wm;
+   }
+
+   if (total_level_ddb <= alloc_size)
+   break;
+   }
+
+   if ((level < 0) || (total_min_blocks > alloc_size)) {
+   DRM_DEBUG_KMS("Requested display configuration exceeds system 
DDB limitations");
+   DRM_DEBUG_KMS("minimum required %d/%d\n", (level < 0) ?
+   total_level_ddb : total_min_blocks, alloc_size);
+   ret = -EINVAL;
+   goto exit;
+   }
+   max_level = level;
+   alloc_size -= total_level_ddb;
+
total_data_rate = skl_get_total_relative_data_rate(cstate);
if (total_data_rate == 0)
-   return 0;
+   goto exit;
 
start = alloc->start;
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
@@ -3436,7 +3464,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 * promote the expression to 64 bits to avoid overflowing, the
 * result is < available as data_rate / total_data_rate < 1
 */
-   plane_blocks = minimum[id];
+   plane_blocks = max(pipe_wm->wm[max_level].plane_res_b[id],
+   minimum[id]);
plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
total_data_rate);
 
@@ -3444,12 +3473,13 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
if (data_rate) {
ddb->plane[pipe][id].start = start;
ddb->plane[pipe][id].end = start + plane_blocks;
+   start += plane_blocks;
}
 
-   start += plane_blocks;
-
/*
 * allocation for y_plane part of planar format:
+* TODO: Once we start calculating 

[Intel-gfx] [PATCH v4 3/8] drm/i915: Decode system memory bandwidth

2016-10-13 Thread Kumar, Mahesh
This patch adds support to decode system memory bandwidth
which will be used for arbitrated display memory percentage
calculation in GEN9 based system.

Changes from v1:
 - Address comments from Paulo
 - implement decode function for SKL/KBL also

Signed-off-by: "Kumar, Mahesh" <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 170 
 drivers/gpu/drm/i915/i915_drv.h |  14 
 drivers/gpu/drm/i915/i915_reg.h |  38 +
 3 files changed, 222 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 89d3222..b5f601c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -979,6 +979,170 @@ static void intel_sanitize_options(struct 
drm_i915_private *dev_priv)
DRM_DEBUG_DRIVER("use GPU sempahores? %s\n", yesno(i915.semaphores));
 }
 
+static inline void skl_memdev_info_fill(struct memdev_info *info, uint32_t val)
+{
+   uint8_t channel_width, rank;
+
+   info->rank_valid = true;
+   channel_width = (val >> SKL_DRAM_CHANNEL_WIDTH_SHIFT) &
+   SKL_DRAM_CHANNEL_WIDTH_MASK;
+   if (channel_width == SKL_DRAM_WIDTH_1)
+   info->channel_width_bytes = 1;
+   else if (channel_width == SKL_DRAM_WIDTH_2)
+   info->channel_width_bytes = 2;
+   else
+   info->channel_width_bytes = 4;
+
+   rank = (val >> SKL_DRAM_RANK_SHIFT) & SKL_DRAM_RANK_MASK;
+   if (rank == SKL_DRAM_RANK_SINGLE)
+   info->rank = DRAM_RANK_SINGLE;
+   else
+   info->rank = DRAM_RANK_DUAL;
+}
+
+static int
+skl_get_memdev_info(struct drm_i915_private *dev_priv)
+{
+   uint32_t val = 0;
+   uint32_t mem_speed = 0;
+   struct memdev_info *memdev_info = _priv->memdev_info;
+
+   val = I915_READ(SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU);
+   mem_speed = div_u64((uint64_t) (val & SKL_REQ_DATA_MASK) *
+   SKL_MEMORY_FREQ_MULTIPLIER, 1000);
+
+   if (mem_speed == 0)
+   return -EINVAL;
+
+   memdev_info->valid = true;
+   memdev_info->mem_speed_khz = mem_speed;
+   memdev_info->num_channels  = 0;
+
+   memdev_info->rank_valid = false;
+   val = I915_READ(SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN);
+
+   if (val != 0x) {
+   memdev_info->num_channels++;
+   skl_memdev_info_fill(memdev_info, val);
+   }
+
+   val = I915_READ(SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN);
+
+   if (val != 0x) {
+   memdev_info->num_channels++;
+   if (!memdev_info->rank_valid)
+   skl_memdev_info_fill(memdev_info, val);
+   }
+
+   if (memdev_info->num_channels == 0)
+   memdev_info->valid = false;
+   return 0;
+}
+
+static int
+bxt_get_memdev_info(struct drm_i915_private *dev_priv)
+{
+   struct memdev_info *memdev_info = _priv->memdev_info;
+   uint32_t dram_channel;
+   uint32_t mem_speed, val;
+   uint8_t num_channel, dram_type;
+   int i;
+
+   val = I915_READ(BXT_P_CR_MC_BIOS_REQ_0_0_0);
+   mem_speed = div_u64((uint64_t) (val & BXT_REQ_DATA_MASK) *
+   SKL_MEMORY_FREQ_MULTIPLIER, 1000);
+
+   if (mem_speed == 0)
+   return -EINVAL;
+
+   memdev_info->valid = true;
+   memdev_info->mem_speed_khz = mem_speed;
+   dram_type = (val >> BXT_DRAM_TYPE_SHIFT) & BXT_DRAM_TYPE_MASK;
+   dram_channel = (val >> BXT_DRAM_CHANNEL_SHIFT) & BXT_DRAM_CHANNEL_MASK;
+   num_channel = hweight32(dram_channel);
+
+   /*
+* The lpddr3 and lpddr4 technologies can have 1-4 channels and the
+* channels are 32bits wide; while ddr3l technologies can have 1-2
+* channels and the channels are 64 bits wide. In case of single 64 bit
+* wide DDR3L dimm sets two channel-active bits in
+* P_CR_MC_BIOS_REQ_0_0_0 register and system with two DDR3L 64bit dimm
+* will set all four channel-active bits in above register.
+* In order to get actual number of channels in DDR3L DRAM we need to
+* device total channel-active bits set by 2.
+*/
+
+   switch (dram_type) {
+   case BXT_DRAM_TYPE_LPDDR3:
+   case BXT_DRAM_TYPE_LPDDR4:
+   memdev_info->channel_width_bytes = 4;
+   memdev_info->num_channels = num_channel;
+   break;
+   case BXT_DRAM_TYPE_DDR3L:
+   memdev_info->channel_width_bytes = 8;
+   memdev_info->num_channels = num_channel / 2;
+   break;
+   default:
+   DRM_DEBUG_KMS("Unknown DRAM type\n");
+   memdev_info->valid = false;
+   return -EINVAL;
+   }
+
+   /*
+* Now read each DUNIT8/9/10/11 to check the rank of 

[Intel-gfx] [PATCH v4 0/8] New DDB Algo and WM fixes

2016-10-13 Thread Kumar, Mahesh
From: Mahesh Kumar <mahesh1.ku...@intel.com>

This series implements new DDB allocation algorithm to solve the cases,
where we have sufficient DDB available to enable multiple planes, But
due to the current algorithm not dividing it properly among planes, we
end-up failing the flip.
It also takes care of enabling same watermark level for each
plane, for efficient power saving.
This series also implements Transition Watermarks and Gen-9 related
arbitrated display bandwidth Workarounds.

There are two steps in current WM programming.

1. Calculate minimum number of blocks required  for a WM level to be
enabled. For 1440x2560 panel we need 41 blocks as minimum number of
blocks to enable WM0. This is the step which doesn't use vertical size.
It only depends on Pipe drain rate and plane horizontal size as per the
current Bspec algorithm.
So all the plane below have minimum  number of blocks required to enable
WM0 as 41
Plane 1  - 1440x2560-Min blocks to enable WM0 = 41
Plane 2  - 1440x2560-Min blocks to enable WM0 = 41
Plane 3  - 1440x48  -Min blocks to enable WM0 = 41
Plane 4  - 1440x96  -Min blocks to enable WM0 = 41

2. Number of blocks allotted by the driver
Driver allocates  12 for Plane 3   &  16 for plane 4

Total Dbuf Available = 508
Dbuf Available after 32 blocks for cursor = 508 - (32)  = 476
allocate minimum blocks for each plane 8 * 4 = 32
remaining blocks = 476 - 32 = 444
Relative Data Rate for Planes
   Plane 1  =  1440 * 2560 * 3  =  11059200
   Plane 2  =  1440 * 2560 * 3  =  11059200
   Plane 3  =  1440 * 48   * 3  =  207360
   Plane 4  =  1440 * 96   * 3  =  414720
   Total Relative BW=  22740480

-   Allocate Buffer
buffer allocation = (Plane relative data rate / total data rate)
* total remaming DDB + minimum plane DDB
 Plane 1  buffer allocation = (11059200 / 22740480) * 444 + 8 = 223
 Plane 2  buffer allocation = (11059200 / 22740480) * 444 + 8 = 223
 Plane 3  buffer allocation = (207360   / 22740480) * 444 + 8 = 12
 Plane 4  buffer allocation = (414720   / 22740480) * 444 + 8 = 16

In this case it forced driver to disable Plane 3 & 4. Driver need to use
more efficient way to allocate buffer that is optimum for power.

New Algorithm suggested by HW team is:

1. Calculate minimum buffer allocations for each plane and for each
watermark level

2. Add minimum buffer allocations required for enabling WM7
for all the planes

Level 0 =  41 + 41 + 41 + 41  = 164
Level 1 =  42 + 42 + 42 + 42  = 168
Level 2 =  42 + 42 + 42 + 42  = 168
Level 3 =  94 + 94 + 94 + 94 =  376
Level 4 =  94 + 94 + 94 + 94 =  376
Level 5 =  94 + 94 + 94 + 94 =  376
Level 6 =  94 + 94 + 94 + 94 =  376
Level 7 =  94 + 94 + 94 + 94 =  376

3. Check to see how many buffer allocation are left and enable
the best case. In this case since we have 476 blocks we can enable
WM0-7 on all 4 planes.
Let's say if we have only 200 block available then the best cases
allocation is to enable Level2 which requires 168 blocks

Changes since v1:
 - Rebased the series on top of Paulo's patches (under review)
https://patchwork.freedesktop.org/series/12082/
 - Add changes to calculate WM in fixed point 16.16
 - Address review comments for Transition WM
Changes since v2:
 - Added Paulo's WM fixes series URL in cover letter
Changes since v3:
 - Address Review comments
 - Drop patch to set y-tile WA, as this is already there &
as per HW team always setting the WA doesn't harm.
 - Drop Transition WM and patch to reduce function parameter patch
 - split patches

Kumar, Mahesh (3):
  drm/i915/skl+: use linetime latency instead of ddb size
  drm/i915: Decode system memory bandwidth
  drm/i915/gen9: WM memory bandwidth related workaround

Mahesh Kumar (5):
  drm/i915/skl: New ddb allocation algorithm
  drm/i915/skl+: reset y_plane ddb structure also during calculation
  drm/i915/skl: Add variables to check x_tile and y_tile
  drm/i915/skl+: change WM calc to fixed point 16.16
  drm/i915/bxt: Enable IPC support

 drivers/gpu/drm/i915/i915_drv.c  | 172 +++
 drivers/gpu/drm/i915/i915_drv.h  |  23 +++
 drivers/gpu/drm/i915/i915_reg.h  |  39 +
 drivers/gpu/drm/i915/intel_drv.h |  12 ++
 drivers/gpu/drm/i915/intel_pm.c  | 351 ++-
 5 files changed, 514 insertions(+), 83 deletions(-)

-- 
2.10.1

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


[Intel-gfx] [PATCH v4 4/8] drm/i915/gen9: WM memory bandwidth related workaround

2016-10-13 Thread Kumar, Mahesh
This patch implemnets Workariunds related to display arbitrated memory
bandwidth. These WA are applicabe for all gen-9 based platforms.

Changes since v1:
 - Rebase on top of Paulo's patch series
Changes since v2:
 - Rebase/rework after addressing Paulo's comments in previous patch

Signed-off-by: "Kumar, Mahesh" <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |   9 +++
 drivers/gpu/drm/i915/intel_drv.h |  11 +++
 drivers/gpu/drm/i915/intel_pm.c  | 146 +++
 3 files changed, 166 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index adbd9aa..c169360 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1092,6 +1092,13 @@ enum intel_sbi_destination {
SBI_MPHY,
 };
 
+/* SKL+ Watermark arbitrated display bandwidth Workarounds */
+enum watermark_memory_wa {
+   WATERMARK_WA_NONE,
+   WATERMARK_WA_X_TILED,
+   WATERMARK_WA_Y_TILED,
+};
+
 #define QUIRK_PIPEA_FORCE (1<<0)
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)
 #define QUIRK_INVERT_BRIGHTNESS (1<<2)
@@ -1644,6 +1651,8 @@ struct skl_ddb_allocation {
 
 struct skl_wm_values {
unsigned dirty_pipes;
+   /* any WaterMark memory workaround Required */
+   enum watermark_memory_wa mem_wa;
struct skl_ddb_allocation ddb;
uint32_t wm_linetime[I915_MAX_PIPES];
uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f48e79a..2c1897b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1813,6 +1813,17 @@ intel_atomic_get_crtc_state(struct drm_atomic_state 
*state,
return to_intel_crtc_state(crtc_state);
 }
 
+static inline struct intel_crtc_state *
+intel_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+   struct drm_crtc_state *crtc_state;
+
+   crtc_state = drm_atomic_get_existing_crtc_state(state, >base);
+
+   return to_intel_crtc_state(crtc_state);
+}
+
 static inline struct intel_plane_state *
 intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
  struct intel_plane *plane)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 84ec6b1..5b8f715 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3589,6 +3589,8 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
 {
struct drm_plane_state *pstate = _pstate->base;
struct drm_framebuffer *fb = pstate->fb;
+   struct intel_atomic_state *intel_state =
+   to_intel_atomic_state(cstate->base.state);
uint32_t latency = dev_priv->wm.skl_latency[level];
uint32_t method1, method2;
uint32_t plane_bytes_per_line, plane_blocks_per_line;
@@ -3598,10 +3600,17 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
uint32_t width = 0, height = 0;
uint32_t plane_pixel_rate;
uint32_t y_tile_minimum, y_min_scanlines;
+   enum watermark_memory_wa mem_wa;
 
if (latency == 0 || !cstate->base.active || !intel_pstate->base.visible)
return 0;
 
+   mem_wa = intel_state ? intel_state->wm_results.mem_wa : 
WATERMARK_WA_NONE;
+   if (mem_wa != WATERMARK_WA_NONE) {
+   if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
+   latency += 15;
+   }
+
width = drm_rect_width(_pstate->base.src) >> 16;
height = drm_rect_height(_pstate->base.src) >> 16;
 
@@ -3634,6 +3643,9 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
y_min_scanlines = 4;
}
 
+   if (mem_wa == WATERMARK_WA_Y_TILED)
+   y_min_scanlines *= 2;
+
plane_bytes_per_line = width * cpp;
if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
@@ -4075,6 +4087,15 @@ skl_include_affected_pipes(struct drm_atomic_state 
*state)
intel_state->wm_results.dirty_pipes = ~0;
}
 
+   /*
+* If Watermark workaround is changed we need to recalculate
+* watermark values for all active pipes
+*/
+   if (intel_state->wm_results.mem_wa != dev_priv->wm.skl_hw.mem_wa) {
+   realloc_pipes = ~0;
+   intel_state->wm_results.dirty_pipes = ~0;
+   }
+
for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
struct intel_crtc_state *cstate;
 
@@ -4087,6 +4108,129 @@ skl_include_affected_pipes(struct drm_atomic_state 
*state)
 }
 
 static void
+skl_set_memory_bandwidth_wm_wa(struct drm_atomic_state *state)
+{
+   struct drm_device *dev = state->

[Intel-gfx] [PATCH v4] drm/i915/bxt: Implement Transition WM

2016-09-14 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch enables Transition WM for SKL+ platforms.

Transition WM are used if IPC is enabled, to decide, number of blocks
to be fetched before reducing the priority of display to fetch from
memory.

Changes since v1:
 - Don't enable transition WM for GEN9 (Art/Paulo)
 - Rebase to use fixed point 16.16 calculation
 - Fix the use of selected result from latency level-0

Changes since v2:
 - Fix transition WM enable condition

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 60 ++---
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index de2e738..4814a1a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2862,6 +2862,8 @@ bool ilk_disable_lp_wm(struct drm_device *dev)
 
 #define SKL_DDB_SIZE   896 /* in blocks */
 #define BXT_DDB_SIZE   512
+#define SKL_TRANS_WM_AMOUNT10  /* tunable value */
+#define SKL_TRANS_WM_MIN   14
 #define SKL_SAGV_BLOCK_TIME30 /* µs */
 
 /*
@@ -3583,6 +3585,48 @@ static uint32_t skl_adjusted_plane_pixel_rate(const 
struct intel_crtc_state *cst
return pixel_rate;
 }
 
+static void skl_compute_plane_trans_wm(const struct drm_i915_private *dev_priv,
+   struct skl_pipe_wm *pipe_wm,
+   struct intel_plane_state *intel_pstate,
+   uint32_t selected_result,
+   uint32_t y_tile_min,
+   bool y_tile)
+{
+   struct drm_plane_state *pstate = _pstate->base;
+   int id = skl_wm_plane_id(to_intel_plane(pstate->plane));
+   uint16_t *out_blocks = _wm->trans_wm.plane_res_b[id];
+   uint8_t *out_lines = _wm->trans_wm.plane_res_l[id];
+   uint32_t trans_min = 0, trans_offset_blocks;
+   uint32_t trans_y_tile_min = 0, res_blocks = 0;
+   uint16_t trans_res_blocks = 0;
+
+   /* Keep Trans WM disabled for GEN9 */
+   if (IS_GEN9(dev_priv))
+   goto exit;
+
+   trans_min = SKL_TRANS_WM_MIN;
+
+   trans_offset_blocks = (trans_min + SKL_TRANS_WM_AMOUNT) << 16;
+
+   if (y_tile) {
+   trans_y_tile_min = 2 * y_tile_min;
+   res_blocks = max(trans_y_tile_min, selected_result) +
+   trans_offset_blocks;
+   } else {
+   res_blocks = selected_result + trans_offset_blocks;
+   }
+
+   trans_res_blocks = DIV_ROUND_UP(res_blocks, 1 << 16) + 1;
+
+   /* WA BUG:1938466 add one block for non y-tile planes */
+   if (!y_tile)
+   trans_res_blocks += 1;
+exit:
+   *out_blocks = trans_res_blocks;
+   *out_lines = 0;
+}
+
+
 static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
struct intel_crtc_state *cstate,
struct intel_plane_state *intel_pstate,
@@ -3709,6 +3753,9 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
*out_blocks = res_blocks;
*out_lines = res_lines;
 
+   if (level == 0)
+   skl_compute_plane_trans_wm(dev_priv, pipe_wm, intel_pstate,
+   selected_result, y_tile_minimum, y_tiled);
return 0;
 }
 
@@ -3778,11 +3825,13 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
 }
 
 static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
- struct skl_wm_level *trans_wm /* out */)
+ struct skl_wm_level *trans_wm, /* out */
+ struct skl_ddb_allocation *ddb)
 {
struct drm_crtc *crtc = cstate->base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane;
+   enum pipe pipe = to_intel_crtc(crtc)->pipe;
 
if (!cstate->base.active)
return;
@@ -3790,8 +3839,13 @@ static void skl_compute_transition_wm(struct 
intel_crtc_state *cstate,
/* Until we know more, just disable transition WMs */
for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) {
int i = skl_wm_plane_id(intel_plane);
+   uint16_t plane_ddb = skl_ddb_entry_size(>plane[pipe][i]);
+   uint16_t trans_res_blocks = trans_wm->plane_res_b[i];
 
-   trans_wm->plane_en[i] = false;
+   if ((trans_res_blocks > 0) && (trans_res_blocks <= plane_ddb))
+   trans_wm->plane_en[i] = true;
+   else
+   trans_wm->plane_en[i] = false;
}
 }
 
@@ -3822,7 +3876,7 @@ static int skl_build_pipe_wm(struct intel_crtc_state 
*cstate,
 
pipe_wm->linetime = skl_compute_linetime_wm(cstate);
 
-   skl_compute_transition_wm(cstate, 

[Intel-gfx] [PATCH v4] drm/i915/skl: New ddb allocation algorithm

2016-09-13 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch implements new DDB allocation algorithm as per HW team
suggestion. This algo takecare of scenario where we allocate less DDB
for the planes with lower relative pixel rate, but they require more DDB
to work.
It also takes care of enabling same watermark level for each
plane, for efficient power saving.

Changes since v1:
 - Rebase on top of Paulo's patch series

Changes since v2:
 - Fix the for loop condition to enable WM

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 129 +---
 1 file changed, 67 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 3370fc8..c52cc57 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3348,6 +3348,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
 
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ struct skl_pipe_wm *pipe_wm,
  struct skl_ddb_allocation *ddb /* out */)
 {
struct drm_atomic_state *state = cstate->base.state;
@@ -3363,8 +3364,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
uint16_t *minimum = cstate->wm.skl.minimum_blocks;
uint16_t *y_minimum = cstate->wm.skl.minimum_y_blocks;
unsigned int total_data_rate;
+   uint16_t total_min_blocks = 0;
+   uint16_t total_level_ddb = 0;
int num_active;
-   int id, i;
+   int max_level, level;
+   int id, i, ret = 0;
 
if (WARN_ON(!state))
return 0;
@@ -3380,6 +3384,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
alloc_size = skl_ddb_entry_size(alloc);
if (alloc_size == 0) {
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+   memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
return 0;
}
 
@@ -3413,19 +3418,42 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
}
 
for (i = 0; i < PLANE_CURSOR; i++) {
-   alloc_size -= minimum[i];
-   alloc_size -= y_minimum[i];
+   total_min_blocks += minimum[i];
+   total_min_blocks += y_minimum[i];
}
 
-   /*
-* 2. Distribute the remaining space in proportion to the amount of
-* data each plane needs to fetch from memory.
-*
-* FIXME: we may not allocate every single block here.
-*/
+   for (level = ilk_wm_max_level(dev); level >= 0; level--) {
+   total_level_ddb = 0;
+   for (i = 0; i < PLANE_CURSOR; i++) {
+   /*
+* TODO: We should calculate watermark values for Y/UV
+* plane both in case of NV12 format and use both values
+* for ddb calculation, As NV12 is disabled as of now.
+* using only single plane value here.
+*/
+   uint16_t min = minimum[i] + y_minimum[i];
+   uint16_t plane_level_ddb_wm =
+   max(pipe_wm->wm[level].plane_res_b[i], min);
+   total_level_ddb += plane_level_ddb_wm;
+   }
+
+   if (total_level_ddb <= alloc_size)
+   break;
+   }
+
+   if ((level < 0) || (total_min_blocks > alloc_size)) {
+   DRM_DEBUG_KMS("Requested display configuration exceeds system 
DDB limitations");
+   DRM_DEBUG_KMS("minimum required %d/%d\n", (level < 0) ?
+   total_level_ddb : total_min_blocks, alloc_size);
+   ret = -EINVAL;
+   goto exit;
+   }
+   max_level = level;
+   alloc_size -= total_level_ddb;
+
total_data_rate = skl_get_total_relative_data_rate(cstate);
if (total_data_rate == 0)
-   return 0;
+   goto exit;
 
start = alloc->start;
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
@@ -3440,7 +3468,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 * promote the expression to 64 bits to avoid overflowing, the
 * result is < available as data_rate / total_data_rate < 1
 */
-   plane_blocks = minimum[id];
+   plane_blocks = max(pipe_wm->wm[max_level].plane_res_b[id],
+   minimum[id]);
plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
total_data_rate);
 
@@ -3454,6 +3483,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
/*
 * allocation for y_plane part of planar format:
+* TODO: Once we start calculating watermark values for Y/UV
+* plane both consider it for 

[Intel-gfx] [PATCH v3 4/9] drm/i915: Decode system memory bandwidth

2016-09-09 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch adds support to decode system memory bandwidth
which will be used for arbitrated display memory percentage
calculation in GEN9 based system.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/i915_drv.c | 96 +
 drivers/gpu/drm/i915/i915_drv.h | 18 
 drivers/gpu/drm/i915/i915_reg.h | 25 +++
 3 files changed, 139 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 02c34d6..0a4f18d 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -973,6 +973,96 @@ static void intel_sanitize_options(struct drm_i915_private 
*dev_priv)
DRM_DEBUG_DRIVER("use GPU sempahores? %s\n", yesno(i915.semaphores));
 }
 
+static void
+intel_get_memdev_info(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   uint32_t val = 0;
+   uint32_t mem_speed = 0;
+   uint8_t dram_type;
+   uint32_t dram_channel;
+   uint8_t num_channel;
+   bool rank_valid = false;
+
+   if (!IS_GEN9(dev_priv))
+   goto exit;
+
+   val = I915_READ(P_CR_MC_BIOS_REQ_0_0_0);
+   mem_speed = div_u64((uint64_t) (val & REQ_DATA_MASK) *
+   MEMORY_FREQ_MULTIPLIER, 1000);
+
+   if (mem_speed == 0)
+   goto exit;
+
+   dev_priv->memdev_info.valid = true;
+   dev_priv->memdev_info.mem_speed = mem_speed;
+   dram_type = (val >> DRAM_TYPE_SHIFT) & DRAM_TYPE_MASK;
+   dram_channel = (val >> DRAM_CHANNEL_SHIFT) & DRAM_CHANNEL_MASK;
+   num_channel = hweight32(dram_channel);
+
+   /*
+* The lpddr3 and lpddr4 technologies can have 1-4 channels and the
+* channels are 32bits wide; while ddr3l technologies can have 1-2
+* channels and the channels are 64 bits wide. But SV team found that in
+* case of single 64 bit wide DDR3L dimms two bits were set and system
+* with two DDR3L 64bit dimm all four bits were set.
+*/
+
+   switch (dram_type) {
+   case DRAM_TYPE_LPDDR3:
+   case DRAM_TYPE_LPDDR4:
+   dev_priv->memdev_info.data_width = 4;
+   dev_priv->memdev_info.num_channel = num_channel;
+   break;
+   case DRAM_TYPE_DDR3L:
+   dev_priv->memdev_info.data_width = 8;
+   dev_priv->memdev_info.num_channel = num_channel / 2;
+   break;
+   default:
+   dev_priv->memdev_info.data_width = 4;
+   dev_priv->memdev_info.num_channel = num_channel;
+   }
+
+   /*
+* Now read each DUNIT8/9/10/11 to check the rank of each dimms.
+* all the dimms should have same rank as in first valid Dimm
+*/
+#define D_CR_DRP0_DUNIT_INVALID0x
+
+   dev_priv->memdev_info.rank_valid = true;
+   if (I915_READ(D_CR_DRP0_DUNIT8) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT8);
+   rank_valid = true;
+   } else if (I915_READ(D_CR_DRP0_DUNIT9) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT9);
+   rank_valid = true;
+   } else if (I915_READ(D_CR_DRP0_DUNIT10) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT10);
+   rank_valid = true;
+   } else if (I915_READ(D_CR_DRP0_DUNIT11) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT11);
+   rank_valid = true;
+   }
+#undef D_CR_DRP0_DUNIT_INVALID
+
+   if (rank_valid) {
+   dev_priv->memdev_info.rank_valid = true;
+   dev_priv->memdev_info.rank = (val & DRAM_RANK_MASK);
+   }
+
+   DRM_DEBUG_DRIVER("valid:%s speed-%d width-%d num_channel-%d\n",
+   dev_priv->memdev_info.valid ? "true" : "false",
+   dev_priv->memdev_info.mem_speed,
+   dev_priv->memdev_info.data_width,
+   dev_priv->memdev_info.num_channel);
+   DRM_DEBUG_DRIVER("rank_valid:%s rank-%d\n",
+   dev_priv->memdev_info.rank_valid ? "true" : "false",
+   dev_priv->memdev_info.rank);
+   return;
+exit:
+   dev_priv->memdev_info.valid = false;
+}
+
 /**
  * i915_driver_init_hw - setup state requiring device access
  * @dev_priv: device private
@@ -1076,6 +1166,12 @@ static int i915_driver_init_hw(struct drm_i915_private 
*dev_priv)
DRM_DEBUG_DRIVER("can't enable MSI");
}
 
+   /*
+* Fill the memdev structure to get the system raw bandwidth
+* This will be used by WM algorithm, to implement GEN9 based WA
+*/
+   intel_get_memdev_info(dev);
+
return 0;
 
 out_ggtt:
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4ec23e5..4313992 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ 

[Intel-gfx] [PATCH v3 7/9] drm/i915/bxt: Enable IPC support

2016-09-09 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch adds IPC support for platforms. This patch enables IPC
only for BXT platform as for SKL recommendation is to keep is disabled
This patch also adds kernel command-line option to enable/disable
the IPC if required.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/i915_drv.c|  5 +
 drivers/gpu/drm/i915/i915_params.c |  5 +
 drivers/gpu/drm/i915/i915_params.h |  1 +
 drivers/gpu/drm/i915/i915_reg.h|  1 +
 drivers/gpu/drm/i915/intel_drv.h   |  1 +
 drivers/gpu/drm/i915/intel_pm.c| 21 +
 6 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 0a4f18d..22d84e6 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1335,6 +1335,11 @@ int i915_driver_load(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 
intel_runtime_pm_enable(dev_priv);
 
+   /*
+* Now enable the IPC for supported platforms
+*/
+   intel_enable_ipc(dev_priv);
+
/* Everything is in place, we can now relax! */
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
 driver.name, driver.major, driver.minor, driver.patchlevel,
diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index 768ad89..cc41b8d 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -62,6 +62,7 @@ struct i915_params i915 __read_mostly = {
.inject_load_failure = 0,
.enable_dpcd_backlight = false,
.enable_gvt = false,
+   .enable_ipc = true,
 };
 
 module_param_named(modeset, i915.modeset, int, 0400);
@@ -233,3 +234,7 @@ MODULE_PARM_DESC(enable_dpcd_backlight,
 module_param_named(enable_gvt, i915.enable_gvt, bool, 0400);
 MODULE_PARM_DESC(enable_gvt,
"Enable support for Intel GVT-g graphics virtualization host 
support(default:false)");
+
+module_param_named(enable_ipc, i915.enable_ipc, bool, 0400);
+MODULE_PARM_DESC(enable_ipc,
+   "Enable Isochronous Priority Control (default:true)");
diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index 3a0dd78..f99b9b9 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -65,6 +65,7 @@ struct i915_params {
bool enable_dp_mst;
bool enable_dpcd_backlight;
bool enable_gvt;
+   bool enable_ipc;
 };
 
 extern struct i915_params i915 __read_mostly;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b38445c..75b5b52 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6139,6 +6139,7 @@ enum {
 #define  DISP_FBC_WM_DIS   (1<<15)
 #define DISP_ARB_CTL2  _MMIO(0x45004)
 #define  DISP_DATA_PARTITION_5_6   (1<<6)
+#define  DISP_IPC_ENABLE   (1<<3)
 #define DBUF_CTL   _MMIO(0x45008)
 #define  DBUF_POWER_REQUEST(1<<31)
 #define  DBUF_POWER_STATE  (1<<30)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 66cb46c..56c8ac8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1753,6 +1753,7 @@ void skl_write_plane_wm(struct intel_crtc *intel_crtc,
 uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config);
 bool ilk_disable_lp_wm(struct drm_device *dev);
 int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6);
+void intel_enable_ipc(struct drm_i915_private *dev_priv);
 static inline int intel_enable_rc6(void)
 {
return i915.enable_rc6;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d4390e4..8d0037c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4793,6 +4793,27 @@ void intel_update_watermarks(struct drm_crtc *crtc)
 }
 
 /*
+ * enable IPC for Supported Platforms
+ */
+void intel_enable_ipc(struct drm_i915_private *dev_priv)
+{
+   u32 val;
+
+   /* enable IPC only for Broxton for now*/
+   if (!IS_BROXTON(dev_priv))
+   return;
+
+   val = I915_READ(DISP_ARB_CTL2);
+
+   if (i915.enable_ipc)
+   val |= DISP_IPC_ENABLE;
+   else
+   val &= ~DISP_IPC_ENABLE;
+
+   I915_WRITE(DISP_ARB_CTL2, val);
+}
+
+/*
  * Lock protecting IPS related data structures
  */
 DEFINE_SPINLOCK(mchdev_lock);
-- 
2.8.3

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


[Intel-gfx] [PATCH v3 6/9] drm/i915/skl+: change WM calc to fixed point 16.16

2016-09-09 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch changes Watermak calculation to fixed point calculation.
Problem with current calculation is during plane_blocks_per_line
calculation we divide intermediate blocks with min_scanlines and
takes floor of the result because of integer operation.
hence we end-up assigning less blocks than required. Which leads to
flickers.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0ec328b..d4390e4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3530,13 +3530,15 @@ static uint32_t skl_pipe_pixel_rate(const struct 
intel_crtc_state *config)
 */
 static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp, uint32_t 
latency)
 {
-   uint32_t wm_intermediate_val, ret;
+   uint64_t wm_intermediate_val;
+   uint32_t ret;
 
if (latency == 0)
return UINT_MAX;
 
-   wm_intermediate_val = latency * pixel_rate * cpp / 512;
-   ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
+   wm_intermediate_val = latency * pixel_rate * cpp;
+   wm_intermediate_val <<= 16;
+   ret = DIV_ROUND_UP_ULL(wm_intermediate_val, 1000 * 512);
 
return ret;
 }
@@ -3605,6 +3607,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
uint16_t *out_blocks = >plane_res_b[id];
uint8_t *out_lines = >plane_res_l[id];
enum watermark_memory_wa mem_wa;
+   bool y_tiled = false;
 
if (latency == 0 || !cstate->base.active || !intel_pstate->base.visible)
return 0;
@@ -3652,14 +3655,18 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
plane_bytes_per_line = width * cpp;
if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+   y_tiled = true;
plane_blocks_per_line =
  DIV_ROUND_UP(plane_bytes_per_line * y_min_scanlines, 512);
-   plane_blocks_per_line /= y_min_scanlines;
+   plane_blocks_per_line = (plane_blocks_per_line << 16) /
+   y_min_scanlines;
} else if (fb->modifier[0] == DRM_FORMAT_MOD_NONE) {
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512)
+ 1;
+   plane_blocks_per_line <<= 16;
} else {
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+   plane_blocks_per_line <<= 16;
}
 
method1 = skl_wm_method1(plane_pixel_rate, cpp, latency);
@@ -3670,8 +3677,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
 
y_tile_minimum = plane_blocks_per_line * y_min_scanlines;
 
-   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
-   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+   if (y_tiled) {
selected_result = max(method2, y_tile_minimum);
} else {
uint32_t linetime_us = 0;
@@ -3688,12 +3694,11 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
selected_result = method1;
}
 
-   res_blocks = selected_result + 1;
+   res_blocks = DIV_ROUND_UP(selected_result, 1 << 16) + 1;
res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
 
if (level >= 1 && level <= 7) {
-   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
-   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+   if (y_tiled) {
res_blocks += y_tile_minimum;
res_lines += y_min_scanlines;
} else {
-- 
2.8.3

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


[Intel-gfx] [PATCH v3 1/9] drm/i915/skl: pass pipe_wm in skl_compute_(wm_level/plane_wm) functions

2016-09-09 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch make use of plane_wm variable directly instead of passing
skl_plane_wm struct. this way reduces number of argument requirement
in watermark calculation functions.

It also gives more freedom of decision making to implement Bspec WM
workarounds.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 86c6d66..3fdec4d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3542,9 +3542,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
struct intel_plane_state *intel_pstate,
uint16_t ddb_allocation,
int level,
-   uint16_t *out_blocks, /* out */
-   uint8_t *out_lines, /* out */
-   bool *enabled /* out */)
+   struct skl_pipe_wm *pipe_wm)
 {
struct drm_plane_state *pstate = _pstate->base;
struct drm_framebuffer *fb = pstate->fb;
@@ -3557,6 +3555,11 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
uint32_t width = 0, height = 0;
uint32_t plane_pixel_rate;
uint32_t y_tile_minimum, y_min_scanlines;
+   int id = skl_wm_plane_id(to_intel_plane(pstate->plane));
+   struct skl_wm_level *result = _wm->wm[level];
+   uint16_t *out_blocks = >plane_res_b[id];
+   uint8_t *out_lines = >plane_res_l[id];
+   bool *enabled = >plane_en[id];
 
if (latency == 0 || !cstate->base.active || 
!intel_pstate->base.visible) {
*enabled = false;
@@ -3673,7 +3676,7 @@ skl_compute_wm_level(const struct drm_i915_private 
*dev_priv,
 struct skl_ddb_allocation *ddb,
 struct intel_crtc_state *cstate,
 int level,
-struct skl_wm_level *result)
+struct skl_pipe_wm *pipe_wm)
 {
struct drm_atomic_state *state = cstate->base.state;
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
@@ -3684,12 +3687,6 @@ skl_compute_wm_level(const struct drm_i915_private 
*dev_priv,
enum pipe pipe = intel_crtc->pipe;
int ret;
 
-   /*
-* We'll only calculate watermarks for planes that are actually
-* enabled, so make sure all other planes are set as disabled.
-*/
-   memset(result, 0, sizeof(*result));
-
for_each_intel_plane_mask(_priv->drm,
  intel_plane,
  cstate->base.plane_mask) {
@@ -3727,9 +3724,7 @@ skl_compute_wm_level(const struct drm_i915_private 
*dev_priv,
   intel_pstate,
   ddb_blocks,
   level,
-  >plane_res_b[i],
-  >plane_res_l[i],
-  >plane_en[i]);
+  pipe_wm);
if (ret)
return ret;
}
@@ -3777,9 +3772,15 @@ static int skl_build_pipe_wm(struct intel_crtc_state 
*cstate,
int level, max_level = ilk_wm_max_level(dev);
int ret;
 
+   /*
+* We'll only calculate watermarks for planes that are actually
+* enabled, so make sure all other planes are set as disabled.
+*/
+   memset(pipe_wm, 0, sizeof(*pipe_wm));
+
for (level = 0; level <= max_level; level++) {
ret = skl_compute_wm_level(dev_priv, ddb, cstate,
-  level, _wm->wm[level]);
+  level, pipe_wm);
if (ret)
return ret;
}
-- 
2.8.3

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


[Intel-gfx] [PATCH v3 9/9] drm/i915/bxt: Implement Transition WM

2016-09-09 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch enables Transition WM for SKL+ platforms.

Transition WM are used if IPC is enabled, to decide, number of blocks
to be fetched before reducing the priority of display to fetch from
memory.

Changes since v1:
 - Don't enable transition WM for GEN9 (Art/Paulo)
 - Rebase to use fixed point 16.16 calculation
 - Fix the use of selected result from latency level-0

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 60 ++---
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8d0037c..f6a3fab 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2862,6 +2862,8 @@ bool ilk_disable_lp_wm(struct drm_device *dev)
 
 #define SKL_DDB_SIZE   896 /* in blocks */
 #define BXT_DDB_SIZE   512
+#define SKL_TRANS_WM_AMOUNT10  /* tunable value */
+#define SKL_TRANS_WM_MIN   14
 #define SKL_SAGV_BLOCK_TIME30 /* µs */
 
 /*
@@ -3583,6 +3585,48 @@ static uint32_t skl_adjusted_plane_pixel_rate(const 
struct intel_crtc_state *cst
return pixel_rate;
 }
 
+static void skl_compute_plane_trans_wm(const struct drm_i915_private *dev_priv,
+   struct skl_pipe_wm *pipe_wm,
+   struct intel_plane_state *intel_pstate,
+   uint32_t selected_result,
+   uint32_t y_tile_min,
+   bool y_tile)
+{
+   struct drm_plane_state *pstate = _pstate->base;
+   int id = skl_wm_plane_id(to_intel_plane(pstate->plane));
+   uint16_t *out_blocks = _wm->trans_wm.plane_res_b[id];
+   uint8_t *out_lines = _wm->trans_wm.plane_res_l[id];
+   uint32_t trans_min = 0, trans_offset_blocks;
+   uint32_t trans_y_tile_min = 0, res_blocks = 0;
+   uint16_t trans_res_blocks = 0;
+
+   /* Keep Trans WM disabled for GEN9 */
+   if (IS_GEN9(dev_priv))
+   goto exit;
+
+   trans_min = SKL_TRANS_WM_MIN;
+
+   trans_offset_blocks = (trans_min + SKL_TRANS_WM_AMOUNT) << 16;
+
+   if (y_tile) {
+   trans_y_tile_min = 2 * y_tile_min;
+   res_blocks = max(trans_y_tile_min, selected_result) +
+   trans_offset_blocks;
+   } else {
+   res_blocks = selected_result + trans_offset_blocks;
+   }
+
+   trans_res_blocks = DIV_ROUND_UP(res_blocks, 1 << 16) + 1;
+
+   /* WA BUG:1938466 add one block for non y-tile planes */
+   if (!y_tile)
+   trans_res_blocks += 1;
+exit:
+   *out_blocks = trans_res_blocks;
+   *out_lines = 0;
+}
+
+
 static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
struct intel_crtc_state *cstate,
struct intel_plane_state *intel_pstate,
@@ -3709,6 +3753,9 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
*out_blocks = res_blocks;
*out_lines = res_lines;
 
+   if (level == 0)
+   skl_compute_plane_trans_wm(dev_priv, pipe_wm, intel_pstate,
+   selected_result, y_tile_minimum, y_tiled);
return 0;
 }
 
@@ -3778,11 +3825,13 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
 }
 
 static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
- struct skl_wm_level *trans_wm /* out */)
+ struct skl_wm_level *trans_wm, /* out */
+ struct skl_ddb_allocation *ddb)
 {
struct drm_crtc *crtc = cstate->base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane;
+   enum pipe pipe = to_intel_crtc(crtc)->pipe;
 
if (!cstate->base.active)
return;
@@ -3790,8 +3839,13 @@ static void skl_compute_transition_wm(struct 
intel_crtc_state *cstate,
/* Until we know more, just disable transition WMs */
for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) {
int i = skl_wm_plane_id(intel_plane);
+   uint16_t plane_ddb = skl_ddb_entry_size(>plane[pipe][i]);
+   uint16_t trans_res_blocks = trans_wm->plane_res_b[i];
 
-   trans_wm->plane_en[i] = false;
+   if ((plane_ddb > 0) && (trans_res_blocks > plane_ddb))
+   trans_wm->plane_en[i] = false;
+   else
+   trans_wm->plane_en[i] = true;
}
 }
 
@@ -3822,7 +3876,7 @@ static int skl_build_pipe_wm(struct intel_crtc_state 
*cstate,
 
pipe_wm->linetime = skl_compute_linetime_wm(cstate);
 
-   skl_compute_transition_wm(cstate, _wm->trans_wm);
+   skl_compute_transition_wm(cstate, 

[Intel-gfx] [PATCH v3 8/9] drm/i915/bxt: set chicken bit as IPC y-tile WA

2016-09-09 Thread Kumar, Mahesh
From: Mahesh Kumar 

It implements the WA to enable IDLE_WAKEMEM bit of CHICKEN_DCPR_1
register for Broxton platform. When IPC is enabled & Y-tile is
enabled in any of the enabled plane, above bit should be set.
Without this WA system observes random hang.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 drivers/gpu/drm/i915/i915_reg.h  |  3 +++
 drivers/gpu/drm/i915/intel_display.c | 50 
 3 files changed, 55 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4737a0e..79b9305 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1632,6 +1632,8 @@ struct skl_wm_values {
unsigned dirty_pipes;
/* any WaterMark memory workaround Required */
enum watermark_memory_wa mem_wa;
+   /* IPC Y-tiled WA related member */
+   u32 y_plane_mask;
struct skl_ddb_allocation ddb;
uint32_t wm_linetime[I915_MAX_PIPES];
uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 75b5b52..210d9b0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5658,6 +5658,9 @@ enum {
 #define PLANE_NV12_BUF_CFG(pipe, plane)\
_MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), 
_PLANE_NV12_BUF_CFG_2(pipe))
 
+#define CHICKEN_DCPR_1 _MMIO(0x46430)
+#define IDLE_WAKEMEM_MASK  (1 << 13)
+
 /* SKL new cursor registers */
 #define _CUR_BUF_CFG_A 0x7017c
 #define _CUR_BUF_CFG_B 0x7117c
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 5f50f53..ee7f88e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12415,6 +12415,8 @@ int intel_plane_atomic_calc_changes(struct 
drm_crtc_state *crtc_state,
bool is_crtc_enabled = crtc_state->active;
bool turn_off, turn_on, visible, was_visible;
struct drm_framebuffer *fb = plane_state->fb;
+   struct intel_atomic_state *intel_state =
+   to_intel_atomic_state(plane_state->state);
int ret;
 
if (INTEL_GEN(dev) >= 9 && plane->type != DRM_PLANE_TYPE_CURSOR) {
@@ -12501,6 +12503,15 @@ int intel_plane_atomic_calc_changes(struct 
drm_crtc_state *crtc_state,
!needs_scaling(old_plane_state))
pipe_config->disable_lp_wm = true;
 
+   if (fb && (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) {
+   intel_state->wm_results.y_plane_mask |=
+   (1 << drm_plane_index(plane));
+   } else {
+   intel_state->wm_results.y_plane_mask &=
+   ~(1 << drm_plane_index(plane));
+   }
+
return 0;
 }
 
@@ -13963,6 +13974,10 @@ static int intel_atomic_check(struct drm_device *dev,
if (ret)
return ret;
 
+   /* Copy the Y-tile WA related states */
+   intel_state->wm_results.y_plane_mask =
+   dev_priv->wm.skl_results.y_plane_mask;
+
for_each_crtc_in_state(state, crtc, crtc_state, i) {
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc_state);
@@ -14204,6 +14219,32 @@ static void intel_update_crtcs(struct drm_atomic_state 
*state,
}
 }
 
+/*
+ * GEN9 IPC WA for Y-tiled
+ */
+void bxt_set_ipc_wa(struct drm_i915_private *dev_priv, bool enable)
+{
+   u32 val;
+
+   if (!IS_BROXTON(dev_priv) || !i915.enable_ipc)
+   return;
+
+   val = I915_READ(CHICKEN_DCPR_1);
+   /*
+* If WA is already enabled or disabled
+* no need to re-enable or disable it.
+*/
+   if ((enable && (val & IDLE_WAKEMEM_MASK)) ||
+   (!enable && !(val & IDLE_WAKEMEM_MASK)))
+   return;
+
+   if (enable)
+   val |= IDLE_WAKEMEM_MASK;
+   else
+   val &= ~IDLE_WAKEMEM_MASK;
+   I915_WRITE(CHICKEN_DCPR_1, val);
+}
+
 static void skl_update_crtcs(struct drm_atomic_state *state,
 unsigned int *crtc_vblank_mask)
 {
@@ -14219,6 +14260,12 @@ static void skl_update_crtcs(struct drm_atomic_state 
*state,
enum pipe pipe;
 
/*
+* If IPC WA need to be enabled, enable it now
+*/
+   if (intel_state->wm_results.y_plane_mask)
+   bxt_set_ipc_wa(dev_priv, true);
+
+   /*
 * Whenever the number of active pipes changes, we need to make sure we
 * update the pipes in the right order so that their ddb allocations
 * never overlap with eachother inbetween CRTC updates. Otherwise we'll
@@ -14261,6 +14308,9 @@ static void 

[Intel-gfx] [PATCH v3 0/9] New DDB Algo and WM fixes

2016-09-09 Thread Kumar, Mahesh
From: Mahesh Kumar 

This series implements new DDB allocation algorithm to solve the cases,
where we have sufficient DDB available to enable multiple planes, But
due to the current algorithm not dividing it properly among planes, we
end-up failing the flip.
It also takes care of enabling same watermark level for each
plane, for efficient power saving.
This series also implements Transition Watermarks and Gen-9 related
arbitrated display bandwidth Workarounds.

There are two steps in current WM programming.

1. Calculate minimum number of blocks required  for a WM level to be
enabled. For 1440x2560 panel we need 41 blocks as minimum number of
blocks to enable WM0. This is the step which doesn't use vertical size.
It only depends on Pipe drain rate and plane horizontal size as per the
current Bspec algorithm.
So all the plane below have minimum  number of blocks required to enable
WM0 as 41
Plane 1  - 1440x2560-Min blocks to enable WM0 = 41
Plane 2  - 1440x2560-Min blocks to enable WM0 = 41
Plane 3  - 1440x48  -Min blocks to enable WM0 = 41
Plane 4  - 1440x96  -Min blocks to enable WM0 = 41

2. Number of blocks allotted by the driver
Driver allocates  12 for Plane 3   &  16 for plane 4

Total Dbuf Available = 508
Dbuf Available after 32 blocks for cursor = 508 - (32)  = 476
allocate minimum blocks for each plane 8 * 4 = 32
remaining blocks = 476 - 32 = 444
Relative Data Rate for Planes
   Plane 1  =  1440 * 2560 * 3  =  11059200
   Plane 2  =  1440 * 2560 * 3  =  11059200
   Plane 3  =  1440 * 48   * 3  =  207360
   Plane 4  =  1440 * 96   * 3  =  414720
   Total Relative BW=  22740480

-   Allocate Buffer
buffer allocation = (Plane relative data rate / total data rate)
* total remaming DDB + minimum plane DDB
 Plane 1  buffer allocation = (11059200 / 22740480) * 444 + 8 = 223
 Plane 2  buffer allocation = (11059200 / 22740480) * 444 + 8 = 223
 Plane 3  buffer allocation = (207360   / 22740480) * 444 + 8 = 12
 Plane 4  buffer allocation = (414720   / 22740480) * 444 + 8 = 16

In this case it forced driver to disable Plane 3 & 4. Driver need to use
more efficient way to allocate buffer that is optimum for power.

New Algorithm suggested by HW team is:

1. Calculate minimum buffer allocations for each plane and for each
watermark level

2. Add minimum buffer allocations required for enabling WM7
for all the planes

Level 0 =  41 + 41 + 41 + 41  = 164
Level 1 =  42 + 42 + 42 + 42  = 168
Level 2 =  42 + 42 + 42 + 42  = 168
Level 3 =  94 + 94 + 94 + 94 =  376
Level 4 =  94 + 94 + 94 + 94 =  376
Level 5 =  94 + 94 + 94 + 94 =  376
Level 6 =  94 + 94 + 94 + 94 =  376
Level 7 =  94 + 94 + 94 + 94 =  376

3. Check to see how many buffer allocation are left and enable
the best case. In this case since we have 476 blocks we can enable
WM0-7 on all 4 planes.
Let's say if we have only 200 block available then the best cases
allocation is to enable Level2 which requires 168 blocks

Changes since v1:
 - Rebased the series on top of Paulo's patches (under review)
https://patchwork.freedesktop.org/series/12082/
 - Add changes to calculate WM in fixed point 16.16
 - Address review comments for Transition WM
Changes since v2:
 - Added Paulo's WM fixes series URL in cover letter

Mahesh Kumar (9):
  drm/i915/skl: pass pipe_wm in skl_compute_(wm_level/plane_wm)
functions
  drm/i915/skl+: use linetime latency instead of ddb size
  drm/i915/skl: New ddb allocation algorithm
  drm/i915: Decode system memory bandwidth
  drm/i915/gen9: WM memory bandwidth related workaround
  drm/i915/skl+: change WM calc to fixed point 16.16
  drm/i915/bxt: Enable IPC support
  drm/i915/bxt: set chicken bit as IPC y-tile WA
  drm/i915/bxt: Implement Transition WM

 drivers/gpu/drm/i915/i915_drv.c  | 101 +
 drivers/gpu/drm/i915/i915_drv.h  |  29 +++
 drivers/gpu/drm/i915/i915_params.c   |   5 +
 drivers/gpu/drm/i915/i915_params.h   |   1 +
 drivers/gpu/drm/i915/i915_reg.h  |  29 +++
 drivers/gpu/drm/i915/intel_display.c |  50 +
 drivers/gpu/drm/i915/intel_drv.h |  12 +
 drivers/gpu/drm/i915/intel_pm.c  | 412 +++
 8 files changed, 551 insertions(+), 88 deletions(-)

-- 
2.8.3

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


[Intel-gfx] [PATCH v3 5/9] drm/i915/gen9: WM memory bandwidth related workaround

2016-09-09 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch implemnets Workarounds related to display arbitrated memory
bandwidth. These WA are applicabe for all gen-9 based platforms.

Changes since v1:
 - Rebase on top of Paulo's patch series

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |   9 +++
 drivers/gpu/drm/i915/intel_drv.h |  11 +++
 drivers/gpu/drm/i915/intel_pm.c  | 145 +++
 3 files changed, 165 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4313992..4737a0e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1074,6 +1074,13 @@ enum intel_sbi_destination {
SBI_MPHY,
 };
 
+/* SKL+ Watermark arbitrated display bandwidth Workarounds */
+enum watermark_memory_wa {
+   WATERMARK_WA_NONE,
+   WATERMARK_WA_X_TILED,
+   WATERMARK_WA_Y_TILED,
+};
+
 #define QUIRK_PIPEA_FORCE (1<<0)
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)
 #define QUIRK_INVERT_BRIGHTNESS (1<<2)
@@ -1623,6 +1630,8 @@ struct skl_ddb_allocation {
 
 struct skl_wm_values {
unsigned dirty_pipes;
+   /* any WaterMark memory workaround Required */
+   enum watermark_memory_wa mem_wa;
struct skl_ddb_allocation ddb;
uint32_t wm_linetime[I915_MAX_PIPES];
uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6cd7e8a..66cb46c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1800,6 +1800,17 @@ intel_atomic_get_crtc_state(struct drm_atomic_state 
*state,
return to_intel_crtc_state(crtc_state);
 }
 
+static inline struct intel_crtc_state *
+intel_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+   struct drm_crtc_state *crtc_state;
+
+   crtc_state = drm_atomic_get_existing_crtc_state(state, >base);
+
+   return to_intel_crtc_state(crtc_state);
+}
+
 static inline struct intel_plane_state *
 intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
  struct intel_plane *plane)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7c70e07..0ec328b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3589,6 +3589,8 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
 {
struct drm_plane_state *pstate = _pstate->base;
struct drm_framebuffer *fb = pstate->fb;
+   struct intel_atomic_state *intel_state =
+   to_intel_atomic_state(cstate->base.state);
uint32_t latency = dev_priv->wm.skl_latency[level];
uint32_t method1, method2;
uint32_t plane_bytes_per_line, plane_blocks_per_line;
@@ -3602,10 +3604,17 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
struct skl_wm_level *result = _wm->wm[level];
uint16_t *out_blocks = >plane_res_b[id];
uint8_t *out_lines = >plane_res_l[id];
+   enum watermark_memory_wa mem_wa;
 
if (latency == 0 || !cstate->base.active || !intel_pstate->base.visible)
return 0;
 
+   mem_wa = intel_state ? intel_state->wm_results.mem_wa : 
WATERMARK_WA_NONE;
+   if (mem_wa != WATERMARK_WA_NONE) {
+   if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
+   latency += 15;
+   }
+
width = drm_rect_width(_pstate->base.src) >> 16;
height = drm_rect_height(_pstate->base.src) >> 16;
 
@@ -3637,6 +3646,9 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
y_min_scanlines = 4;
}
 
+   if (mem_wa == WATERMARK_WA_Y_TILED)
+   y_min_scanlines *= 2;
+
plane_bytes_per_line = width * cpp;
if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
@@ -4041,6 +4053,15 @@ skl_include_affected_pipes(struct drm_atomic_state 
*state)
intel_state->wm_results.dirty_pipes = ~0;
}
 
+   /*
+* If Watermark workaround is changed we need to recalculate
+* watermark values for all active pipes
+*/
+   if (intel_state->wm_results.mem_wa != dev_priv->wm.skl_hw.mem_wa) {
+   realloc_pipes = ~0;
+   intel_state->wm_results.dirty_pipes = ~0;
+   }
+
for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
struct intel_crtc_state *cstate;
 
@@ -4057,6 +4078,128 @@ skl_include_affected_pipes(struct drm_atomic_state 
*state)
 }
 
 static void
+skl_set_memory_bandwidth_wm_wa(struct drm_atomic_state *state)
+{
+   struct drm_device *dev = state->dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   struct intel_crtc *intel_crtc;
+   struct 

[Intel-gfx] [PATCH v3 3/9] drm/i915/skl: New ddb allocation algorithm

2016-09-09 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch implements new DDB allocation algorithm as per HW team
suggestion. This algo takecare of scenario where we allocate less DDB
for the planes with lower relative pixel rate, but they require more DDB
to work.
It also takes care of enabling same watermark level for each
plane, for efficient power saving.

Changes since v1:
 - Rebase on top of Paulo's patch series

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 129 +---
 1 file changed, 67 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index cfd9b7d1..7c70e07 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3348,6 +3348,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
 
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ struct skl_pipe_wm *pipe_wm,
  struct skl_ddb_allocation *ddb /* out */)
 {
struct drm_atomic_state *state = cstate->base.state;
@@ -3363,8 +3364,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
uint16_t *minimum = cstate->wm.skl.minimum_blocks;
uint16_t *y_minimum = cstate->wm.skl.minimum_y_blocks;
unsigned int total_data_rate;
+   uint16_t total_min_blocks = 0;
+   uint16_t total_level_ddb = 0;
int num_active;
-   int id, i;
+   int max_level, level;
+   int id, i, ret = 0;
 
if (WARN_ON(!state))
return 0;
@@ -3380,6 +3384,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
alloc_size = skl_ddb_entry_size(alloc);
if (alloc_size == 0) {
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+   memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
return 0;
}
 
@@ -3413,19 +3418,42 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
}
 
for (i = 0; i < PLANE_CURSOR; i++) {
-   alloc_size -= minimum[i];
-   alloc_size -= y_minimum[i];
+   total_min_blocks += minimum[i];
+   total_min_blocks += y_minimum[i];
}
 
-   /*
-* 2. Distribute the remaining space in proportion to the amount of
-* data each plane needs to fetch from memory.
-*
-* FIXME: we may not allocate every single block here.
-*/
+   for (level = ilk_wm_max_level(dev); level >= 0; level--) {
+   total_level_ddb = 0;
+   for (i = 0; i < PLANE_CURSOR; i++) {
+   /*
+* TODO: We should calculate watermark values for Y/UV
+* plane both in case of NV12 format and use both values
+* for ddb calculation, As NV12 is disabled as of now.
+* using only single plane value here.
+*/
+   uint16_t min = minimum[i] + y_minimum[i];
+   uint16_t plane_level_ddb_wm =
+   max(pipe_wm->wm[level].plane_res_b[i], min);
+   total_level_ddb += plane_level_ddb_wm;
+   }
+
+   if (total_level_ddb <= alloc_size)
+   break;
+   }
+
+   if ((level < 0) || (total_min_blocks > alloc_size)) {
+   DRM_DEBUG_KMS("Requested display configuration exceeds system 
DDB limitations");
+   DRM_DEBUG_KMS("minimum required %d/%d\n", (level < 0) ?
+   total_level_ddb : total_min_blocks, alloc_size);
+   ret = -EINVAL;
+   goto exit;
+   }
+   max_level = level;
+   alloc_size -= total_level_ddb;
+
total_data_rate = skl_get_total_relative_data_rate(cstate);
if (total_data_rate == 0)
-   return 0;
+   goto exit;
 
start = alloc->start;
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
@@ -3440,7 +3468,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 * promote the expression to 64 bits to avoid overflowing, the
 * result is < available as data_rate / total_data_rate < 1
 */
-   plane_blocks = minimum[id];
+   plane_blocks = max(pipe_wm->wm[max_level].plane_res_b[id],
+   minimum[id]);
plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
total_data_rate);
 
@@ -3454,6 +3483,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
/*
 * allocation for y_plane part of planar format:
+* TODO: Once we start calculating watermark values for Y/UV
+* plane both consider it for initial allowed wm blocks.
 */

[Intel-gfx] [PATCH v3 2/9] drm/i915/skl+: use linetime latency instead of ddb size

2016-09-09 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch make changes to use linetime latency instead of allocated
DDB size during plane watermark calculation in switch case, This is
required to implement new DDB allocation algorithm.

In New Algorithm DDB is allocated based on WM values, because of which
number of DDB blocks will not be available during WM calculation,
So this "linetime latency" is suggested by SV/HW team to use during
switch-case for WM blocks selection.

Changes since v1:
 - Rebase on top of Paulo's patch series

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 3fdec4d..cfd9b7d1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3622,10 +3622,15 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
selected_result = max(method2, y_tile_minimum);
} else {
+   uint32_t linetime_us = 0;
+
+   linetime_us = DIV_ROUND_UP(width * 1000,
+   skl_pipe_pixel_rate(cstate));
+
if ((cpp * cstate->base.adjusted_mode.crtc_htotal / 512 < 1) &&
(plane_bytes_per_line / 512 < 1))
selected_result = method2;
-   else if ((ddb_allocation / plane_blocks_per_line) >= 1)
+   if (latency >= linetime_us)
selected_result = min(method1, method2);
else
selected_result = method1;
-- 
2.8.3

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


[Intel-gfx] [PATCH v2 3/9] drm/i915/skl: New ddb allocation algorithm

2016-09-08 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch implements new DDB allocation algorithm as per HW team
suggestion. This algo takecare of scenario where we allocate less DDB
for the planes with lower relative pixel rate, but they require more DDB
to work.
It also takes care of enabling same watermark level for each
plane, for efficient power saving.

Changes since v1:
 - Rebase on top of Paulo's patch series

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 129 +---
 1 file changed, 67 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index cfd9b7d1..7c70e07 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3348,6 +3348,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
 
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ struct skl_pipe_wm *pipe_wm,
  struct skl_ddb_allocation *ddb /* out */)
 {
struct drm_atomic_state *state = cstate->base.state;
@@ -3363,8 +3364,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
uint16_t *minimum = cstate->wm.skl.minimum_blocks;
uint16_t *y_minimum = cstate->wm.skl.minimum_y_blocks;
unsigned int total_data_rate;
+   uint16_t total_min_blocks = 0;
+   uint16_t total_level_ddb = 0;
int num_active;
-   int id, i;
+   int max_level, level;
+   int id, i, ret = 0;
 
if (WARN_ON(!state))
return 0;
@@ -3380,6 +3384,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
alloc_size = skl_ddb_entry_size(alloc);
if (alloc_size == 0) {
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+   memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
return 0;
}
 
@@ -3413,19 +3418,42 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
}
 
for (i = 0; i < PLANE_CURSOR; i++) {
-   alloc_size -= minimum[i];
-   alloc_size -= y_minimum[i];
+   total_min_blocks += minimum[i];
+   total_min_blocks += y_minimum[i];
}
 
-   /*
-* 2. Distribute the remaining space in proportion to the amount of
-* data each plane needs to fetch from memory.
-*
-* FIXME: we may not allocate every single block here.
-*/
+   for (level = ilk_wm_max_level(dev); level >= 0; level--) {
+   total_level_ddb = 0;
+   for (i = 0; i < PLANE_CURSOR; i++) {
+   /*
+* TODO: We should calculate watermark values for Y/UV
+* plane both in case of NV12 format and use both values
+* for ddb calculation, As NV12 is disabled as of now.
+* using only single plane value here.
+*/
+   uint16_t min = minimum[i] + y_minimum[i];
+   uint16_t plane_level_ddb_wm =
+   max(pipe_wm->wm[level].plane_res_b[i], min);
+   total_level_ddb += plane_level_ddb_wm;
+   }
+
+   if (total_level_ddb <= alloc_size)
+   break;
+   }
+
+   if ((level < 0) || (total_min_blocks > alloc_size)) {
+   DRM_DEBUG_KMS("Requested display configuration exceeds system 
DDB limitations");
+   DRM_DEBUG_KMS("minimum required %d/%d\n", (level < 0) ?
+   total_level_ddb : total_min_blocks, alloc_size);
+   ret = -EINVAL;
+   goto exit;
+   }
+   max_level = level;
+   alloc_size -= total_level_ddb;
+
total_data_rate = skl_get_total_relative_data_rate(cstate);
if (total_data_rate == 0)
-   return 0;
+   goto exit;
 
start = alloc->start;
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
@@ -3440,7 +3468,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 * promote the expression to 64 bits to avoid overflowing, the
 * result is < available as data_rate / total_data_rate < 1
 */
-   plane_blocks = minimum[id];
+   plane_blocks = max(pipe_wm->wm[max_level].plane_res_b[id],
+   minimum[id]);
plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
total_data_rate);
 
@@ -3454,6 +3483,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
/*
 * allocation for y_plane part of planar format:
+* TODO: Once we start calculating watermark values for Y/UV
+* plane both consider it for initial allowed wm blocks.
 */

[Intel-gfx] [PATCH v2 7/9] drm/i915/bxt: Enable IPC support

2016-09-08 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch adds IPC support for platforms. This patch enables IPC
only for BXT platform as for SKL recommendation is to keep is disabled
This patch also adds kernel command-line option to enable/disable
the IPC if required.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/i915_drv.c|  5 +
 drivers/gpu/drm/i915/i915_params.c |  5 +
 drivers/gpu/drm/i915/i915_params.h |  1 +
 drivers/gpu/drm/i915/i915_reg.h|  1 +
 drivers/gpu/drm/i915/intel_drv.h   |  1 +
 drivers/gpu/drm/i915/intel_pm.c| 21 +
 6 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 0a4f18d..22d84e6 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1335,6 +1335,11 @@ int i915_driver_load(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 
intel_runtime_pm_enable(dev_priv);
 
+   /*
+* Now enable the IPC for supported platforms
+*/
+   intel_enable_ipc(dev_priv);
+
/* Everything is in place, we can now relax! */
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
 driver.name, driver.major, driver.minor, driver.patchlevel,
diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index 768ad89..cc41b8d 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -62,6 +62,7 @@ struct i915_params i915 __read_mostly = {
.inject_load_failure = 0,
.enable_dpcd_backlight = false,
.enable_gvt = false,
+   .enable_ipc = true,
 };
 
 module_param_named(modeset, i915.modeset, int, 0400);
@@ -233,3 +234,7 @@ MODULE_PARM_DESC(enable_dpcd_backlight,
 module_param_named(enable_gvt, i915.enable_gvt, bool, 0400);
 MODULE_PARM_DESC(enable_gvt,
"Enable support for Intel GVT-g graphics virtualization host 
support(default:false)");
+
+module_param_named(enable_ipc, i915.enable_ipc, bool, 0400);
+MODULE_PARM_DESC(enable_ipc,
+   "Enable Isochronous Priority Control (default:true)");
diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index 3a0dd78..f99b9b9 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -65,6 +65,7 @@ struct i915_params {
bool enable_dp_mst;
bool enable_dpcd_backlight;
bool enable_gvt;
+   bool enable_ipc;
 };
 
 extern struct i915_params i915 __read_mostly;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b38445c..75b5b52 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6139,6 +6139,7 @@ enum {
 #define  DISP_FBC_WM_DIS   (1<<15)
 #define DISP_ARB_CTL2  _MMIO(0x45004)
 #define  DISP_DATA_PARTITION_5_6   (1<<6)
+#define  DISP_IPC_ENABLE   (1<<3)
 #define DBUF_CTL   _MMIO(0x45008)
 #define  DBUF_POWER_REQUEST(1<<31)
 #define  DBUF_POWER_STATE  (1<<30)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index bd45a2c..4645d6e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1760,6 +1760,7 @@ void skl_write_plane_wm(struct intel_crtc *intel_crtc,
 uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config);
 bool ilk_disable_lp_wm(struct drm_device *dev);
 int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6);
+void intel_enable_ipc(struct drm_i915_private *dev_priv);
 static inline int intel_enable_rc6(void)
 {
return i915.enable_rc6;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d4390e4..8d0037c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4793,6 +4793,27 @@ void intel_update_watermarks(struct drm_crtc *crtc)
 }
 
 /*
+ * enable IPC for Supported Platforms
+ */
+void intel_enable_ipc(struct drm_i915_private *dev_priv)
+{
+   u32 val;
+
+   /* enable IPC only for Broxton for now*/
+   if (!IS_BROXTON(dev_priv))
+   return;
+
+   val = I915_READ(DISP_ARB_CTL2);
+
+   if (i915.enable_ipc)
+   val |= DISP_IPC_ENABLE;
+   else
+   val &= ~DISP_IPC_ENABLE;
+
+   I915_WRITE(DISP_ARB_CTL2, val);
+}
+
+/*
  * Lock protecting IPS related data structures
  */
 DEFINE_SPINLOCK(mchdev_lock);
-- 
2.8.3

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


[Intel-gfx] [PATCH v2 5/9] drm/i915/gen9: WM memory bandwidth related workaround

2016-09-08 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch implemnets Workariunds related to display arbitrated memory
bandwidth. These WA are applicabe for all gen-9 based platforms.

Changes since v1:
 - Rebase on top of Paulo's patch series

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |   9 +++
 drivers/gpu/drm/i915/intel_drv.h |  11 +++
 drivers/gpu/drm/i915/intel_pm.c  | 145 +++
 3 files changed, 165 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8236927..7964c0f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1061,6 +1061,13 @@ enum intel_sbi_destination {
SBI_MPHY,
 };
 
+/* SKL+ Watermark arbitrated display bandwidth Workarounds */
+enum watermark_memory_wa {
+   WATERMARK_WA_NONE,
+   WATERMARK_WA_X_TILED,
+   WATERMARK_WA_Y_TILED,
+};
+
 #define QUIRK_PIPEA_FORCE (1<<0)
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)
 #define QUIRK_INVERT_BRIGHTNESS (1<<2)
@@ -1610,6 +1617,8 @@ struct skl_ddb_allocation {
 
 struct skl_wm_values {
unsigned dirty_pipes;
+   /* any WaterMark memory workaround Required */
+   enum watermark_memory_wa mem_wa;
struct skl_ddb_allocation ddb;
uint32_t wm_linetime[I915_MAX_PIPES];
uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ed6b53f..bd45a2c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1807,6 +1807,17 @@ intel_atomic_get_crtc_state(struct drm_atomic_state 
*state,
return to_intel_crtc_state(crtc_state);
 }
 
+static inline struct intel_crtc_state *
+intel_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+   struct drm_crtc_state *crtc_state;
+
+   crtc_state = drm_atomic_get_existing_crtc_state(state, >base);
+
+   return to_intel_crtc_state(crtc_state);
+}
+
 static inline struct intel_plane_state *
 intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
  struct intel_plane *plane)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7c70e07..0ec328b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3589,6 +3589,8 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
 {
struct drm_plane_state *pstate = _pstate->base;
struct drm_framebuffer *fb = pstate->fb;
+   struct intel_atomic_state *intel_state =
+   to_intel_atomic_state(cstate->base.state);
uint32_t latency = dev_priv->wm.skl_latency[level];
uint32_t method1, method2;
uint32_t plane_bytes_per_line, plane_blocks_per_line;
@@ -3602,10 +3604,17 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
struct skl_wm_level *result = _wm->wm[level];
uint16_t *out_blocks = >plane_res_b[id];
uint8_t *out_lines = >plane_res_l[id];
+   enum watermark_memory_wa mem_wa;
 
if (latency == 0 || !cstate->base.active || !intel_pstate->base.visible)
return 0;
 
+   mem_wa = intel_state ? intel_state->wm_results.mem_wa : 
WATERMARK_WA_NONE;
+   if (mem_wa != WATERMARK_WA_NONE) {
+   if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
+   latency += 15;
+   }
+
width = drm_rect_width(_pstate->base.src) >> 16;
height = drm_rect_height(_pstate->base.src) >> 16;
 
@@ -3637,6 +3646,9 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
y_min_scanlines = 4;
}
 
+   if (mem_wa == WATERMARK_WA_Y_TILED)
+   y_min_scanlines *= 2;
+
plane_bytes_per_line = width * cpp;
if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
@@ -4041,6 +4053,15 @@ skl_include_affected_pipes(struct drm_atomic_state 
*state)
intel_state->wm_results.dirty_pipes = ~0;
}
 
+   /*
+* If Watermark workaround is changed we need to recalculate
+* watermark values for all active pipes
+*/
+   if (intel_state->wm_results.mem_wa != dev_priv->wm.skl_hw.mem_wa) {
+   realloc_pipes = ~0;
+   intel_state->wm_results.dirty_pipes = ~0;
+   }
+
for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
struct intel_crtc_state *cstate;
 
@@ -4057,6 +4078,128 @@ skl_include_affected_pipes(struct drm_atomic_state 
*state)
 }
 
 static void
+skl_set_memory_bandwidth_wm_wa(struct drm_atomic_state *state)
+{
+   struct drm_device *dev = state->dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   struct intel_crtc *intel_crtc;
+   struct 

[Intel-gfx] [PATCH v2 6/9] drm/i915/skl+: change WM calc to fixed point 16.16

2016-09-08 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch changes Watermak calculation to fixed point calculation.
Problem with current calculation is during plane_blocks_per_line
calculation we divide intermediate blocks with min_scanlines and
takes floor of the result because of integer operation.
hence we end-up assigning less blocks than required. Which leads to
flickers.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0ec328b..d4390e4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3530,13 +3530,15 @@ static uint32_t skl_pipe_pixel_rate(const struct 
intel_crtc_state *config)
 */
 static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp, uint32_t 
latency)
 {
-   uint32_t wm_intermediate_val, ret;
+   uint64_t wm_intermediate_val;
+   uint32_t ret;
 
if (latency == 0)
return UINT_MAX;
 
-   wm_intermediate_val = latency * pixel_rate * cpp / 512;
-   ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
+   wm_intermediate_val = latency * pixel_rate * cpp;
+   wm_intermediate_val <<= 16;
+   ret = DIV_ROUND_UP_ULL(wm_intermediate_val, 1000 * 512);
 
return ret;
 }
@@ -3605,6 +3607,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
uint16_t *out_blocks = >plane_res_b[id];
uint8_t *out_lines = >plane_res_l[id];
enum watermark_memory_wa mem_wa;
+   bool y_tiled = false;
 
if (latency == 0 || !cstate->base.active || !intel_pstate->base.visible)
return 0;
@@ -3652,14 +3655,18 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
plane_bytes_per_line = width * cpp;
if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+   y_tiled = true;
plane_blocks_per_line =
  DIV_ROUND_UP(plane_bytes_per_line * y_min_scanlines, 512);
-   plane_blocks_per_line /= y_min_scanlines;
+   plane_blocks_per_line = (plane_blocks_per_line << 16) /
+   y_min_scanlines;
} else if (fb->modifier[0] == DRM_FORMAT_MOD_NONE) {
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512)
+ 1;
+   plane_blocks_per_line <<= 16;
} else {
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+   plane_blocks_per_line <<= 16;
}
 
method1 = skl_wm_method1(plane_pixel_rate, cpp, latency);
@@ -3670,8 +3677,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
 
y_tile_minimum = plane_blocks_per_line * y_min_scanlines;
 
-   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
-   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+   if (y_tiled) {
selected_result = max(method2, y_tile_minimum);
} else {
uint32_t linetime_us = 0;
@@ -3688,12 +3694,11 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
selected_result = method1;
}
 
-   res_blocks = selected_result + 1;
+   res_blocks = DIV_ROUND_UP(selected_result, 1 << 16) + 1;
res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
 
if (level >= 1 && level <= 7) {
-   if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
-   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+   if (y_tiled) {
res_blocks += y_tile_minimum;
res_lines += y_min_scanlines;
} else {
-- 
2.8.3

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


[Intel-gfx] [PATCH v2 0/9] New DDB Algo and WM fixes

2016-09-08 Thread Kumar, Mahesh
From: Mahesh Kumar 

This series implements new DDB allocation algorithm to solve the cases,
where we have sufficient DDB available to enable multiple planes, But
due to the current algorithm not dividing it properly among planes, we
end-up failing the flip.
It also takes care of enabling same watermark level for each
plane, for efficient power saving.
This series also implements Transition Watermarks and Gen-9 related
arbitrated display bandwidth Workarounds.

There are two steps in current WM programming.

1. Calculate minimum number of blocks required  for a WM level to be
enabled. For 1440x2560 panel we need 41 blocks as minimum number of
blocks to enable WM0. This is the step which doesn't use vertical size.
It only depends on Pipe drain rate and plane horizontal size as per the
current Bspec algorithm.
So all the plane below have minimum  number of blocks required to enable
WM0 as 41
Plane 1  - 1440x2560-Min blocks to enable WM0 = 41
Plane 2  - 1440x2560-Min blocks to enable WM0 = 41
Plane 3  - 1440x48  -Min blocks to enable WM0 = 41
Plane 4  - 1440x96  -Min blocks to enable WM0 = 41

2. Number of blocks allotted by the driver
Driver allocates  12 for Plane 3   &  16 for plane 4

Total Dbuf Available = 508
Dbuf Available after 32 blocks for cursor = 508 - (32)  = 476
allocate minimum blocks for each plane 8 * 4 = 32
remaining blocks = 476 - 32 = 444
Relative Data Rate for Planes
   Plane 1  =  1440 * 2560 * 3  =  11059200
   Plane 2  =  1440 * 2560 * 3  =  11059200
   Plane 3  =  1440 * 48   * 3  =  207360
   Plane 4  =  1440 * 96   * 3  =  414720
   Total Relative BW=  22740480

-   Allocate Buffer
buffer allocation = (Plane relative data rate / total data rate)
* total remaming DDB + minimum plane DDB
 Plane 1  buffer allocation = (11059200 / 22740480) * 444 + 8 = 223
 Plane 2  buffer allocation = (11059200 / 22740480) * 444 + 8 = 223
 Plane 3  buffer allocation = (207360   / 22740480) * 444 + 8 = 12
 Plane 4  buffer allocation = (414720   / 22740480) * 444 + 8 = 16

In this case it forced driver to disable Plane 3 & 4. Driver need to use
more efficient way to allocate buffer that is optimum for power.

New Algorithm suggested by HW team is:

1. Calculate minimum buffer allocations for each plane and for each
watermark level

2. Add minimum buffer allocations required for enabling WM7
for all the planes

Level 0 =  41 + 41 + 41 + 41  = 164
Level 1 =  42 + 42 + 42 + 42  = 168
Level 2 =  42 + 42 + 42 + 42  = 168
Level 3 =  94 + 94 + 94 + 94 =  376
Level 4 =  94 + 94 + 94 + 94 =  376
Level 5 =  94 + 94 + 94 + 94 =  376
Level 6 =  94 + 94 + 94 + 94 =  376
Level 7 =  94 + 94 + 94 + 94 =  376

3. Check to see how many buffer allocation are left and enable
the best case. In this case since we have 476 blocks we can enable
WM0-7 on all 4 planes.
Let's say if we have only 200 block available then the best cases
allocation is to enable Level2 which requires 168 blocks

Changes since v1:
 - Rebased the series on top of Paulo's patches
 - Add changes to calculate WM in fixed point 16.16
 - Address review comments for Transition WM

Mahesh Kumar (9):
  drm/i915/skl: pass pipe_wm in skl_compute_(wm_level/plane_wm)
functions
  drm/i915/skl+: use linetime latency instead of ddb size
  drm/i915/skl: New ddb allocation algorithm
  drm/i915: Decode system memory bandwidth
  drm/i915/gen9: WM memory bandwidth related workaround
  drm/i915/skl+: change WM calc to fixed point 16.16
  drm/i915/bxt: Enable IPC support
  drm/i915/bxt: set chicken bit as IPC y-tile WA
  drm/i915/bxt: Implement Transition WM

 drivers/gpu/drm/i915/i915_drv.c  | 101 +
 drivers/gpu/drm/i915/i915_drv.h  |  29 +++
 drivers/gpu/drm/i915/i915_params.c   |   5 +
 drivers/gpu/drm/i915/i915_params.h   |   1 +
 drivers/gpu/drm/i915/i915_reg.h  |  29 +++
 drivers/gpu/drm/i915/intel_display.c |  50 +
 drivers/gpu/drm/i915/intel_drv.h |  12 +
 drivers/gpu/drm/i915/intel_pm.c  | 412 +++
 8 files changed, 551 insertions(+), 88 deletions(-)

-- 
2.8.3

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


[Intel-gfx] [PATCH v2 4/9] drm/i915: Decode system memory bandwidth

2016-09-08 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch adds support to decode system memory bandwidth
which will be used for arbitrated display memory percentage
calculation in GEN9 based system.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/i915_drv.c | 96 +
 drivers/gpu/drm/i915/i915_drv.h | 18 
 drivers/gpu/drm/i915/i915_reg.h | 25 +++
 3 files changed, 139 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 02c34d6..0a4f18d 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -973,6 +973,96 @@ static void intel_sanitize_options(struct drm_i915_private 
*dev_priv)
DRM_DEBUG_DRIVER("use GPU sempahores? %s\n", yesno(i915.semaphores));
 }
 
+static void
+intel_get_memdev_info(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   uint32_t val = 0;
+   uint32_t mem_speed = 0;
+   uint8_t dram_type;
+   uint32_t dram_channel;
+   uint8_t num_channel;
+   bool rank_valid = false;
+
+   if (!IS_GEN9(dev_priv))
+   goto exit;
+
+   val = I915_READ(P_CR_MC_BIOS_REQ_0_0_0);
+   mem_speed = div_u64((uint64_t) (val & REQ_DATA_MASK) *
+   MEMORY_FREQ_MULTIPLIER, 1000);
+
+   if (mem_speed == 0)
+   goto exit;
+
+   dev_priv->memdev_info.valid = true;
+   dev_priv->memdev_info.mem_speed = mem_speed;
+   dram_type = (val >> DRAM_TYPE_SHIFT) & DRAM_TYPE_MASK;
+   dram_channel = (val >> DRAM_CHANNEL_SHIFT) & DRAM_CHANNEL_MASK;
+   num_channel = hweight32(dram_channel);
+
+   /*
+* The lpddr3 and lpddr4 technologies can have 1-4 channels and the
+* channels are 32bits wide; while ddr3l technologies can have 1-2
+* channels and the channels are 64 bits wide. But SV team found that in
+* case of single 64 bit wide DDR3L dimms two bits were set and system
+* with two DDR3L 64bit dimm all four bits were set.
+*/
+
+   switch (dram_type) {
+   case DRAM_TYPE_LPDDR3:
+   case DRAM_TYPE_LPDDR4:
+   dev_priv->memdev_info.data_width = 4;
+   dev_priv->memdev_info.num_channel = num_channel;
+   break;
+   case DRAM_TYPE_DDR3L:
+   dev_priv->memdev_info.data_width = 8;
+   dev_priv->memdev_info.num_channel = num_channel / 2;
+   break;
+   default:
+   dev_priv->memdev_info.data_width = 4;
+   dev_priv->memdev_info.num_channel = num_channel;
+   }
+
+   /*
+* Now read each DUNIT8/9/10/11 to check the rank of each dimms.
+* all the dimms should have same rank as in first valid Dimm
+*/
+#define D_CR_DRP0_DUNIT_INVALID0x
+
+   dev_priv->memdev_info.rank_valid = true;
+   if (I915_READ(D_CR_DRP0_DUNIT8) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT8);
+   rank_valid = true;
+   } else if (I915_READ(D_CR_DRP0_DUNIT9) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT9);
+   rank_valid = true;
+   } else if (I915_READ(D_CR_DRP0_DUNIT10) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT10);
+   rank_valid = true;
+   } else if (I915_READ(D_CR_DRP0_DUNIT11) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT11);
+   rank_valid = true;
+   }
+#undef D_CR_DRP0_DUNIT_INVALID
+
+   if (rank_valid) {
+   dev_priv->memdev_info.rank_valid = true;
+   dev_priv->memdev_info.rank = (val & DRAM_RANK_MASK);
+   }
+
+   DRM_DEBUG_DRIVER("valid:%s speed-%d width-%d num_channel-%d\n",
+   dev_priv->memdev_info.valid ? "true" : "false",
+   dev_priv->memdev_info.mem_speed,
+   dev_priv->memdev_info.data_width,
+   dev_priv->memdev_info.num_channel);
+   DRM_DEBUG_DRIVER("rank_valid:%s rank-%d\n",
+   dev_priv->memdev_info.rank_valid ? "true" : "false",
+   dev_priv->memdev_info.rank);
+   return;
+exit:
+   dev_priv->memdev_info.valid = false;
+}
+
 /**
  * i915_driver_init_hw - setup state requiring device access
  * @dev_priv: device private
@@ -1076,6 +1166,12 @@ static int i915_driver_init_hw(struct drm_i915_private 
*dev_priv)
DRM_DEBUG_DRIVER("can't enable MSI");
}
 
+   /*
+* Fill the memdev structure to get the system raw bandwidth
+* This will be used by WM algorithm, to implement GEN9 based WA
+*/
+   intel_get_memdev_info(dev);
+
return 0;
 
 out_ggtt:
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f05869b..8236927 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ 

[Intel-gfx] [PATCH v2 1/9] drm/i915/skl: pass pipe_wm in skl_compute_(wm_level/plane_wm) functions

2016-09-08 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch make use of plane_wm variable directly instead of passing
skl_plane_wm struct. this way reduces number of argument requirement
in watermark calculation functions.

It also gives more freedom of decision making to implement Bspec WM
workarounds.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 86c6d66..3fdec4d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3542,9 +3542,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
struct intel_plane_state *intel_pstate,
uint16_t ddb_allocation,
int level,
-   uint16_t *out_blocks, /* out */
-   uint8_t *out_lines, /* out */
-   bool *enabled /* out */)
+   struct skl_pipe_wm *pipe_wm)
 {
struct drm_plane_state *pstate = _pstate->base;
struct drm_framebuffer *fb = pstate->fb;
@@ -3557,6 +3555,11 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
uint32_t width = 0, height = 0;
uint32_t plane_pixel_rate;
uint32_t y_tile_minimum, y_min_scanlines;
+   int id = skl_wm_plane_id(to_intel_plane(pstate->plane));
+   struct skl_wm_level *result = _wm->wm[level];
+   uint16_t *out_blocks = >plane_res_b[id];
+   uint8_t *out_lines = >plane_res_l[id];
+   bool *enabled = >plane_en[id];
 
if (latency == 0 || !cstate->base.active || 
!intel_pstate->base.visible) {
*enabled = false;
@@ -3673,7 +3676,7 @@ skl_compute_wm_level(const struct drm_i915_private 
*dev_priv,
 struct skl_ddb_allocation *ddb,
 struct intel_crtc_state *cstate,
 int level,
-struct skl_wm_level *result)
+struct skl_pipe_wm *pipe_wm)
 {
struct drm_atomic_state *state = cstate->base.state;
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
@@ -3684,12 +3687,6 @@ skl_compute_wm_level(const struct drm_i915_private 
*dev_priv,
enum pipe pipe = intel_crtc->pipe;
int ret;
 
-   /*
-* We'll only calculate watermarks for planes that are actually
-* enabled, so make sure all other planes are set as disabled.
-*/
-   memset(result, 0, sizeof(*result));
-
for_each_intel_plane_mask(_priv->drm,
  intel_plane,
  cstate->base.plane_mask) {
@@ -3727,9 +3724,7 @@ skl_compute_wm_level(const struct drm_i915_private 
*dev_priv,
   intel_pstate,
   ddb_blocks,
   level,
-  >plane_res_b[i],
-  >plane_res_l[i],
-  >plane_en[i]);
+  pipe_wm);
if (ret)
return ret;
}
@@ -3777,9 +3772,15 @@ static int skl_build_pipe_wm(struct intel_crtc_state 
*cstate,
int level, max_level = ilk_wm_max_level(dev);
int ret;
 
+   /*
+* We'll only calculate watermarks for planes that are actually
+* enabled, so make sure all other planes are set as disabled.
+*/
+   memset(pipe_wm, 0, sizeof(*pipe_wm));
+
for (level = 0; level <= max_level; level++) {
ret = skl_compute_wm_level(dev_priv, ddb, cstate,
-  level, _wm->wm[level]);
+  level, pipe_wm);
if (ret)
return ret;
}
-- 
2.8.3

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


[Intel-gfx] [PATCH v2 9/9] drm/i915/bxt: Implement Transition WM

2016-09-08 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch enables Transition WM for SKL+ platforms.

Transition WM are used if IPC is enabled, to decide, number of blocks
to be fetched before reducing the priority of display to fetch from
memory.

Changes since v1:
 - Don't enable transition WM for GEN9 (Art/Paulo)
 - Rebase to use fixed point 16.16 calculation
 - Fix the use of selected result from latency level-0

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 60 ++---
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8d0037c..f6a3fab 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2862,6 +2862,8 @@ bool ilk_disable_lp_wm(struct drm_device *dev)
 
 #define SKL_DDB_SIZE   896 /* in blocks */
 #define BXT_DDB_SIZE   512
+#define SKL_TRANS_WM_AMOUNT10  /* tunable value */
+#define SKL_TRANS_WM_MIN   14
 #define SKL_SAGV_BLOCK_TIME30 /* µs */
 
 /*
@@ -3583,6 +3585,48 @@ static uint32_t skl_adjusted_plane_pixel_rate(const 
struct intel_crtc_state *cst
return pixel_rate;
 }
 
+static void skl_compute_plane_trans_wm(const struct drm_i915_private *dev_priv,
+   struct skl_pipe_wm *pipe_wm,
+   struct intel_plane_state *intel_pstate,
+   uint32_t selected_result,
+   uint32_t y_tile_min,
+   bool y_tile)
+{
+   struct drm_plane_state *pstate = _pstate->base;
+   int id = skl_wm_plane_id(to_intel_plane(pstate->plane));
+   uint16_t *out_blocks = _wm->trans_wm.plane_res_b[id];
+   uint8_t *out_lines = _wm->trans_wm.plane_res_l[id];
+   uint32_t trans_min = 0, trans_offset_blocks;
+   uint32_t trans_y_tile_min = 0, res_blocks = 0;
+   uint16_t trans_res_blocks = 0;
+
+   /* Keep Trans WM disabled for GEN9 */
+   if (IS_GEN9(dev_priv))
+   goto exit;
+
+   trans_min = SKL_TRANS_WM_MIN;
+
+   trans_offset_blocks = (trans_min + SKL_TRANS_WM_AMOUNT) << 16;
+
+   if (y_tile) {
+   trans_y_tile_min = 2 * y_tile_min;
+   res_blocks = max(trans_y_tile_min, selected_result) +
+   trans_offset_blocks;
+   } else {
+   res_blocks = selected_result + trans_offset_blocks;
+   }
+
+   trans_res_blocks = DIV_ROUND_UP(res_blocks, 1 << 16) + 1;
+
+   /* WA BUG:1938466 add one block for non y-tile planes */
+   if (!y_tile)
+   trans_res_blocks += 1;
+exit:
+   *out_blocks = trans_res_blocks;
+   *out_lines = 0;
+}
+
+
 static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
struct intel_crtc_state *cstate,
struct intel_plane_state *intel_pstate,
@@ -3709,6 +3753,9 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
*out_blocks = res_blocks;
*out_lines = res_lines;
 
+   if (level == 0)
+   skl_compute_plane_trans_wm(dev_priv, pipe_wm, intel_pstate,
+   selected_result, y_tile_minimum, y_tiled);
return 0;
 }
 
@@ -3778,11 +3825,13 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
 }
 
 static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
- struct skl_wm_level *trans_wm /* out */)
+ struct skl_wm_level *trans_wm, /* out */
+ struct skl_ddb_allocation *ddb)
 {
struct drm_crtc *crtc = cstate->base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane;
+   enum pipe pipe = to_intel_crtc(crtc)->pipe;
 
if (!cstate->base.active)
return;
@@ -3790,8 +3839,13 @@ static void skl_compute_transition_wm(struct 
intel_crtc_state *cstate,
/* Until we know more, just disable transition WMs */
for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) {
int i = skl_wm_plane_id(intel_plane);
+   uint16_t plane_ddb = skl_ddb_entry_size(>plane[pipe][i]);
+   uint16_t trans_res_blocks = trans_wm->plane_res_b[i];
 
-   trans_wm->plane_en[i] = false;
+   if ((plane_ddb > 0) && (trans_res_blocks > plane_ddb))
+   trans_wm->plane_en[i] = false;
+   else
+   trans_wm->plane_en[i] = true;
}
 }
 
@@ -3822,7 +3876,7 @@ static int skl_build_pipe_wm(struct intel_crtc_state 
*cstate,
 
pipe_wm->linetime = skl_compute_linetime_wm(cstate);
 
-   skl_compute_transition_wm(cstate, _wm->trans_wm);
+   skl_compute_transition_wm(cstate, 

[Intel-gfx] [PATCH v2 8/9] drm/i915/bxt: set chicken bit as IPC y-tile WA

2016-09-08 Thread Kumar, Mahesh
From: Mahesh Kumar 

It implements the WA to enable IDLE_WAKEMEM bit of CHICKEN_DCPR_1
register for Broxton platform. When IPC is enabled & Y-tile is
enabled in any of the enabled plane, above bit should be set.
Without this WA system observes random hang.

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 drivers/gpu/drm/i915/i915_reg.h  |  3 +++
 drivers/gpu/drm/i915/intel_display.c | 50 
 3 files changed, 55 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7964c0f..c94eedb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1619,6 +1619,8 @@ struct skl_wm_values {
unsigned dirty_pipes;
/* any WaterMark memory workaround Required */
enum watermark_memory_wa mem_wa;
+   /* IPC Y-tiled WA related member */
+   u32 y_plane_mask;
struct skl_ddb_allocation ddb;
uint32_t wm_linetime[I915_MAX_PIPES];
uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 75b5b52..210d9b0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5658,6 +5658,9 @@ enum {
 #define PLANE_NV12_BUF_CFG(pipe, plane)\
_MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), 
_PLANE_NV12_BUF_CFG_2(pipe))
 
+#define CHICKEN_DCPR_1 _MMIO(0x46430)
+#define IDLE_WAKEMEM_MASK  (1 << 13)
+
 /* SKL new cursor registers */
 #define _CUR_BUF_CFG_A 0x7017c
 #define _CUR_BUF_CFG_B 0x7117c
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index a6c3caa..c75685d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12429,6 +12429,8 @@ int intel_plane_atomic_calc_changes(struct 
drm_crtc_state *crtc_state,
bool is_crtc_enabled = crtc_state->active;
bool turn_off, turn_on, visible, was_visible;
struct drm_framebuffer *fb = plane_state->fb;
+   struct intel_atomic_state *intel_state =
+   to_intel_atomic_state(plane_state->state);
int ret;
 
if (INTEL_GEN(dev) >= 9 && plane->type != DRM_PLANE_TYPE_CURSOR) {
@@ -12515,6 +12517,15 @@ int intel_plane_atomic_calc_changes(struct 
drm_crtc_state *crtc_state,
!needs_scaling(old_plane_state))
pipe_config->disable_lp_wm = true;
 
+   if (fb && (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+   fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) {
+   intel_state->wm_results.y_plane_mask |=
+   (1 << drm_plane_index(plane));
+   } else {
+   intel_state->wm_results.y_plane_mask &=
+   ~(1 << drm_plane_index(plane));
+   }
+
return 0;
 }
 
@@ -13985,6 +13996,10 @@ static int intel_atomic_check(struct drm_device *dev,
if (ret)
return ret;
 
+   /* Copy the Y-tile WA related states */
+   intel_state->wm_results.y_plane_mask =
+   dev_priv->wm.skl_results.y_plane_mask;
+
for_each_crtc_in_state(state, crtc, crtc_state, i) {
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc_state);
@@ -14226,6 +14241,32 @@ static void intel_update_crtcs(struct drm_atomic_state 
*state,
}
 }
 
+/*
+ * GEN9 IPC WA for Y-tiled
+ */
+void bxt_set_ipc_wa(struct drm_i915_private *dev_priv, bool enable)
+{
+   u32 val;
+
+   if (!IS_BROXTON(dev_priv) || !i915.enable_ipc)
+   return;
+
+   val = I915_READ(CHICKEN_DCPR_1);
+   /*
+* If WA is already enabled or disabled
+* no need to re-enable or disable it.
+*/
+   if ((enable && (val & IDLE_WAKEMEM_MASK)) ||
+   (!enable && !(val & IDLE_WAKEMEM_MASK)))
+   return;
+
+   if (enable)
+   val |= IDLE_WAKEMEM_MASK;
+   else
+   val &= ~IDLE_WAKEMEM_MASK;
+   I915_WRITE(CHICKEN_DCPR_1, val);
+}
+
 static void skl_update_crtcs(struct drm_atomic_state *state,
 unsigned int *crtc_vblank_mask)
 {
@@ -14241,6 +14282,12 @@ static void skl_update_crtcs(struct drm_atomic_state 
*state,
enum pipe pipe;
 
/*
+* If IPC WA need to be enabled, enable it now
+*/
+   if (intel_state->wm_results.y_plane_mask)
+   bxt_set_ipc_wa(dev_priv, true);
+
+   /*
 * Whenever the number of active pipes changes, we need to make sure we
 * update the pipes in the right order so that their ddb allocations
 * never overlap with eachother inbetween CRTC updates. Otherwise we'll
@@ -14283,6 +14330,9 @@ static void 

[Intel-gfx] [PATCH v2 2/9] drm/i915/skl+: use linetime latency instead of ddb size

2016-09-08 Thread Kumar, Mahesh
From: Mahesh Kumar 

This patch make changes to use linetime latency instead of allocated
DDB size during plane watermark calculation in switch case, This is
required to implement new DDB allocation algorithm.

In New Algorithm DDB is allocated based on WM values, because of which
number of DDB blocks will not be available during WM calculation,
So this "linetime latency" is suggested by SV/HW team to use during
switch-case for WM blocks selection.

Changes since v1:
 - Rebase on top of Paulo's patch series

Signed-off-by: Mahesh Kumar 
---
 drivers/gpu/drm/i915/intel_pm.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 3fdec4d..cfd9b7d1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3622,10 +3622,15 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
selected_result = max(method2, y_tile_minimum);
} else {
+   uint32_t linetime_us = 0;
+
+   linetime_us = DIV_ROUND_UP(width * 1000,
+   skl_pipe_pixel_rate(cstate));
+
if ((cpp * cstate->base.adjusted_mode.crtc_htotal / 512 < 1) &&
(plane_bytes_per_line / 512 < 1))
selected_result = method2;
-   else if ((ddb_allocation / plane_blocks_per_line) >= 1)
+   if (latency >= linetime_us)
selected_result = min(method1, method2);
else
selected_result = method1;
-- 
2.8.3

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


[Intel-gfx] [PATCH] FOR_UPSTREAM [VPG]: drm/i915/skl+: Implement Transition WM

2016-08-29 Thread Kumar, Mahesh
This patch enables Transition WM for SKL+ platforms.

Transition WM are used if IPC is enabled, to decide, number of blocks
to be fetched before reducing the priority of display to fetch from
memory.

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 57 ++---
 1 file changed, 53 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9f69050..f4f387f 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2861,6 +2861,8 @@ bool ilk_disable_lp_wm(struct drm_device *dev)
 #define SKL_DDB_SIZE   896 /* in blocks */
 #define BXT_DDB_SIZE   512
 #define SKL_SAGV_BLOCK_TIME30 /* µs */
+#define SKL_TRANS_WM_AMOUNT10
+#define SKL_TRANS_WM_MIN   14
 
 /*
  * Return the index of a plane in the SKL DDB and wm result arrays.  Primary
@@ -3579,6 +3581,41 @@ static uint32_t skl_adjusted_plane_pixel_rate(const 
struct intel_crtc_state *cst
return pixel_rate;
 }
 
+static void skl_compute_plane_trans_wm(const struct drm_i915_private *dev_priv,
+   struct skl_pipe_wm *pipe_wm,
+   struct intel_plane_state *intel_pstate,
+   uint32_t y_tile_min,
+   bool y_tile)
+{
+   struct drm_plane_state *pstate = _pstate->base;
+   int id = skl_wm_plane_id(to_intel_plane(pstate->plane));
+   uint16_t *out_blocks = _wm->trans_wm.plane_res_b[id];
+   uint8_t *out_lines = _wm->trans_wm.plane_res_l[id];
+   uint16_t res_blocks = pipe_wm->wm[0].plane_res_b[id];
+   uint32_t trans_min = 0, trans_offset_blocks;
+   uint16_t trans_y_tile_min = 0;
+   uint16_t trans_res_blocks;
+
+
+   if (IS_GEN9(dev_priv))
+   trans_min = SKL_TRANS_WM_MIN;
+
+   trans_offset_blocks = trans_min + SKL_TRANS_WM_AMOUNT;
+
+   if (y_tile) {
+   trans_y_tile_min = 2 * y_tile_min;
+   trans_res_blocks = max(trans_y_tile_min, res_blocks) +
+   trans_offset_blocks;
+   } else {
+   trans_res_blocks = res_blocks + trans_offset_blocks;
+   /* WA BUG:1938466 add one block for non y-tile planes */
+   trans_res_blocks += 1;
+   }
+
+   *out_blocks = trans_res_blocks;
+   *out_lines = 0;
+}
+
 static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
struct intel_crtc_state *cstate,
struct intel_plane_state *intel_pstate,
@@ -3600,6 +3637,8 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
struct skl_wm_level *result = _wm->wm[level];
uint16_t *out_blocks = >plane_res_b[id];
uint8_t *out_lines = >plane_res_l[id];
+   uint32_t y_tile_minimum = 0;
+   bool y_tile = false;
 
if (latency == 0 || !cstate->base.active || !intel_pstate->base.visible)
return 0;
@@ -3627,7 +3666,6 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
uint32_t min_scanlines = 4;
-   uint32_t y_tile_minimum;
if (intel_rotation_90_or_270(pstate->rotation)) {
int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
drm_format_plane_cpp(fb->pixel_format, 1) :
@@ -3646,6 +3684,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
}
y_tile_minimum = plane_blocks_per_line * min_scanlines;
selected_result = max(method2, y_tile_minimum);
+   y_tile = true;
} else {
linetime_us = DIV_ROUND_UP(width * 1000,
skl_pipe_pixel_rate(cstate));
@@ -3669,6 +3708,9 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
*out_blocks = res_blocks;
*out_lines = res_lines;
 
+   if (level == 0)
+   skl_compute_plane_trans_wm(dev_priv, pipe_wm, intel_pstate,
+   y_tile_minimum, y_tile);
return 0;
 }
 
@@ -3738,11 +3780,13 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
 }
 
 static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
- struct skl_wm_level *trans_wm /* out */)
+ struct skl_wm_level *trans_wm,
+ struct skl_ddb_allocation *ddb)
 {
struct drm_crtc *crtc = cstate->base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane;
+   enum pipe p

[Intel-gfx] [PATCH 2/7] drm/i915/skl+: use linetime latency instead of ddb size

2016-08-29 Thread Kumar, Mahesh
This patch make changes to use linetime latency instead of allocated
DDB size during plane watermark calculation in switch case, This is
required to implement new DDB allocation algorithm.

In New Algorithm DDB is allocated based on WM values, because of which
number of DDB blocks will not be available during WM calculation,
So this "linetime latency" is suggested by SV/HW team to use during
switch-case for WM blocks selection.

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index aba6fd0..b2f17eb 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3554,6 +3554,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
uint8_t cpp;
uint32_t width = 0, height = 0;
uint32_t plane_pixel_rate;
+   uint32_t linetime_us = 0;
 
if (latency == 0 || !cstate->base.active || 
!intel_pstate->base.visible) {
*enabled = false;
@@ -3603,7 +3604,9 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
y_tile_minimum = plane_blocks_per_line * min_scanlines;
selected_result = max(method2, y_tile_minimum);
} else {
-   if ((ddb_allocation / plane_blocks_per_line) >= 1)
+   linetime_us = DIV_ROUND_UP(width * 1000,
+   skl_pipe_pixel_rate(cstate));
+   if (latency >= linetime_us)
selected_result = min(method1, method2);
else
selected_result = method1;
-- 
2.8.3

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


[Intel-gfx] [PATCH 4/7] drm/i915/skl: New ddb allocation algorithm

2016-08-29 Thread Kumar, Mahesh
This patch implements new DDB allocation algorithm as per HW team
suggestion. This algo takecare of scenario where we allocate less DDB
for the planes with lower relative pixel rate, but they require more DDB
to work.
It also takes care of enabling same watermark level for each
plane, for efficient power saving.

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 129 +---
 1 file changed, 67 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5fa02cb..9f69050 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3331,6 +3331,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
 
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ struct skl_pipe_wm *pipe_wm,
  struct skl_ddb_allocation *ddb /* out */)
 {
struct drm_atomic_state *state = cstate->base.state;
@@ -3346,8 +3347,11 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
uint16_t *minimum = cstate->wm.skl.minimum_blocks;
uint16_t *y_minimum = cstate->wm.skl.minimum_y_blocks;
unsigned int total_data_rate;
+   uint16_t total_min_blocks = 0;
+   uint16_t total_level_ddb = 0;
int num_active;
-   int id, i;
+   int max_level, level;
+   int id, i, ret = 0;
 
if (WARN_ON(!state))
return 0;
@@ -3363,6 +3367,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
alloc_size = skl_ddb_entry_size(alloc);
if (alloc_size == 0) {
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+   memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
return 0;
}
 
@@ -3396,19 +3401,42 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
}
 
for (i = 0; i < PLANE_CURSOR; i++) {
-   alloc_size -= minimum[i];
-   alloc_size -= y_minimum[i];
+   total_min_blocks += minimum[i];
+   total_min_blocks += y_minimum[i];
}
 
-   /*
-* 2. Distribute the remaining space in proportion to the amount of
-* data each plane needs to fetch from memory.
-*
-* FIXME: we may not allocate every single block here.
-*/
+   for (level = ilk_wm_max_level(dev); level >= 0; level--) {
+   total_level_ddb = 0;
+   for (i = 0; i < PLANE_CURSOR; i++) {
+   /*
+* TODO: We should calculate watermark values for Y/UV
+* plane both in case of NV12 format and use both values
+* for ddb calculation, As NV12 is disabled as of now.
+* using only single plane value here.
+*/
+   uint16_t min = minimum[i] + y_minimum[i];
+   uint16_t plane_level_ddb_wm =
+   max(pipe_wm->wm[level].plane_res_b[i], min);
+   total_level_ddb += plane_level_ddb_wm;
+   }
+
+   if (total_level_ddb <= alloc_size)
+   break;
+   }
+
+   if ((level < 0) || (total_min_blocks > alloc_size)) {
+   DRM_DEBUG_KMS("Requested display configuration exceeds system 
DDB limitations");
+   DRM_DEBUG_KMS("minimum required %d/%d\n", (level < 0) ?
+   total_level_ddb : total_min_blocks, alloc_size);
+   ret = -EINVAL;
+   goto exit;
+   }
+   max_level = level;
+   alloc_size -= total_level_ddb;
+
total_data_rate = skl_get_total_relative_data_rate(cstate);
if (total_data_rate == 0)
-   return 0;
+   goto exit;
 
start = alloc->start;
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
@@ -3423,7 +3451,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 * promote the expression to 64 bits to avoid overflowing, the
 * result is < available as data_rate / total_data_rate < 1
 */
-   plane_blocks = minimum[id];
+   plane_blocks = max(pipe_wm->wm[max_level].plane_res_b[id],
+   minimum[id]);
plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
total_data_rate);
 
@@ -3437,6 +3466,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 
/*
 * allocation for y_plane part of planar format:
+* TODO: Once we start calculating watermark values for Y/UV
+* plane both consider it for initial allowed wm blocks.
 */
y_data_rate = cstate-&

[Intel-gfx] [PATCH 5/7] drm/i915: Decode system memory bandwidth

2016-08-29 Thread Kumar, Mahesh
This patch adds support to decode system memory bandwidth
which will be used for arbitrated display memory percentage
calculation in GEN9 based system.

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 96 +
 drivers/gpu/drm/i915/i915_drv.h | 18 
 drivers/gpu/drm/i915/i915_reg.h | 25 +++
 3 files changed, 139 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 47fe072..5ece036 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -996,6 +996,96 @@ static void intel_sanitize_options(struct drm_i915_private 
*dev_priv)
DRM_DEBUG_DRIVER("use GPU sempahores? %s\n", yesno(i915.semaphores));
 }
 
+static void
+intel_get_memdev_info(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   uint32_t val = 0;
+   uint32_t mem_speed = 0;
+   uint8_t dram_type;
+   uint32_t dram_channel;
+   uint8_t num_channel;
+   bool rank_valid = false;
+
+   if (!IS_GEN9(dev_priv))
+   goto exit;
+
+   val = I915_READ(P_CR_MC_BIOS_REQ_0_0_0);
+   mem_speed = div_u64((uint64_t) (val & REQ_DATA_MASK) *
+   MEMORY_FREQ_MULTIPLIER, 1000);
+
+   if (mem_speed == 0)
+   goto exit;
+
+   dev_priv->memdev_info.valid = true;
+   dev_priv->memdev_info.mem_speed = mem_speed;
+   dram_type = (val >> DRAM_TYPE_SHIFT) & DRAM_TYPE_MASK;
+   dram_channel = (val >> DRAM_CHANNEL_SHIFT) & DRAM_CHANNEL_MASK;
+   num_channel = hweight32(dram_channel);
+
+   /*
+* The lpddr3 and lpddr4 technologies can have 1-4 channels and the
+* channels are 32bits wide; while ddr3l technologies can have 1-2
+* channels and the channels are 64 bits wide. But SV team found that in
+* case of single 64 bit wide DDR3L dimms two bits were set and system
+* with two DDR3L 64bit dimm all four bits were set.
+*/
+
+   switch (dram_type) {
+   case DRAM_TYPE_LPDDR3:
+   case DRAM_TYPE_LPDDR4:
+   dev_priv->memdev_info.data_width = 4;
+   dev_priv->memdev_info.num_channel = num_channel;
+   break;
+   case DRAM_TYPE_DDR3L:
+   dev_priv->memdev_info.data_width = 8;
+   dev_priv->memdev_info.num_channel = num_channel / 2;
+   break;
+   default:
+   dev_priv->memdev_info.data_width = 4;
+   dev_priv->memdev_info.num_channel = num_channel;
+   }
+
+   /*
+* Now read each DUNIT8/9/10/11 to check the rank of each dimms.
+* all the dimms should have same rank as in first valid Dimm
+*/
+#define D_CR_DRP0_DUNIT_INVALID0x
+
+   dev_priv->memdev_info.rank_valid = true;
+   if (I915_READ(D_CR_DRP0_DUNIT8) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT8);
+   rank_valid = true;
+   } else if (I915_READ(D_CR_DRP0_DUNIT9) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT9);
+   rank_valid = true;
+   } else if (I915_READ(D_CR_DRP0_DUNIT10) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT10);
+   rank_valid = true;
+   } else if (I915_READ(D_CR_DRP0_DUNIT11) != D_CR_DRP0_DUNIT_INVALID) {
+   val = I915_READ(D_CR_DRP0_DUNIT11);
+   rank_valid = true;
+   }
+#undef D_CR_DRP0_DUNIT_INVALID
+
+   if (rank_valid) {
+   dev_priv->memdev_info.rank_valid = true;
+   dev_priv->memdev_info.rank = (val & DRAM_RANK_MASK);
+   }
+
+   DRM_DEBUG_DRIVER("valid:%s speed-%d width-%d num_channel-%d\n",
+   dev_priv->memdev_info.valid ? "true" : "false",
+   dev_priv->memdev_info.mem_speed,
+   dev_priv->memdev_info.data_width,
+   dev_priv->memdev_info.num_channel);
+   DRM_DEBUG_DRIVER("rank_valid:%s rank-%d\n",
+   dev_priv->memdev_info.rank_valid ? "true" : "false",
+   dev_priv->memdev_info.rank);
+   return;
+exit:
+   dev_priv->memdev_info.valid = false;
+}
+
 /**
  * i915_driver_init_hw - setup state requiring device access
  * @dev_priv: device private
@@ -1099,6 +1189,12 @@ static int i915_driver_init_hw(struct drm_i915_private 
*dev_priv)
DRM_DEBUG_DRIVER("can't enable MSI");
}
 
+   /*
+* Fill the memdev structure to get the system raw bandwidth
+* This will be used by WM algorithm, to implement GEN9 based WA
+*/
+   intel_get_memdev_info(dev);
+
return 0;
 
 out_ggtt:
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/

[Intel-gfx] [PATCH 0/7] Implement New DDB allocation algorithm

2016-08-29 Thread Kumar, Mahesh
This series implements new DDB allocation algorithm to solve the cases,
where we have sufficient DDB available to enable multiple planes, But
due to the current algorithm not dividing it properly among planes, we
end-up failing the flip.
It also takes care of enabling same watermark level for each
plane, for efficient power saving.
This series also implements Transition Watermarks and Gen-9 related
arbitrated display bandwidth Workarounds.

There are two steps in current WM programming.

1. Calculate minimum number of blocks required  for a WM level to be
enabled. For 1440x2560 panel we need 41 blocks as minimum number of
blocks to enable WM0. This is the step which doesn't use vertical size.
It only depends on Pipe drain rate and plane horizontal size as per the
current Bspec algorithm.
So all the plane below have minimum  number of blocks required to enable
WM0 as 41
Plane 1  - 1440x2560-Min blocks to enable WM0 = 41
Plane 2  - 1440x2560-Min blocks to enable WM0 = 41
Plane 3  - 1440x48  -Min blocks to enable WM0 = 41
Plane 4  - 1440x96  -Min blocks to enable WM0 = 41

2. Number of blocks allotted by the driver
Driver allocates  12 for Plane 3   &  16 for plane 4

Total Dbuf Available = 508
Dbuf Available after 32 blocks for cursor = 508 - (32)  = 476
allocate minimum blocks for each plane 8 * 4 = 32
remaining blocks = 476 - 32 = 444
Relative Data Rate for Planes
   Plane 1  =  1440 * 2560 * 3  =  11059200
   Plane 2  =  1440 * 2560 * 3  =  11059200
   Plane 3  =  1440 * 48   * 3  =  207360
   Plane 4  =  1440 * 96   * 3  =  414720
   Total Relative BW=  22740480

-   Allocate Buffer
buffer allocation = (Plane relative data rate / total data rate)
* total remaming DDB + minimum plane DDB
 Plane 1  buffer allocation = (11059200 / 22740480) * 444 + 8 = 223
 Plane 2  buffer allocation = (11059200 / 22740480) * 444 + 8 = 223
 Plane 3  buffer allocation = (207360   / 22740480) * 444 + 8 = 12
 Plane 4  buffer allocation = (414720   / 22740480) * 444 + 8 = 16

In this case it forced driver to disable Plane 3 & 4. Driver need to use
more efficient way to allocate buffer that is optimum for power.

New Algorithm suggested by HW team is:

1. Calculate minimum buffer allocations for each plane and for each
watermark level

2. Add minimum buffer allocations required for enabling WM7
for all the planes

Level 0 =  41 + 41 + 41 + 41  = 164
Level 1 =  42 + 42 + 42 + 42  = 168
Level 2 =  42 + 42 + 42 + 42  = 168
Level 3 =  94 + 94 + 94 + 94 =  376
Level 4 =  94 + 94 + 94 + 94 =  376
Level 5 =  94 + 94 + 94 + 94 =  376
Level 6 =  94 + 94 + 94 + 94 =  376
Level 7 =  94 + 94 + 94 + 94 =  376

3. Check to see how many buffer allocation are left and enable
the best case. In this case since we have 476 blocks we can enable
WM0-7 on all 4 planes.
Let's say if we have only 200 block available then the best cases
allocation is to enable Level2 which requires 168 blocks

Kumar, Mahesh (7):
  drm/i915/hsw+: set intel_crtc active once pipe is active
  drm/i915/skl+: use linetime latency instead of ddb size
  drm/i915/skl: pass pipe_wm in skl_compute_(wm_level/plane_wm)
functions
  drm/i915/skl: New ddb allocation algorithm
  drm/i915: Decode system memory bandwidth
  FOR_UPSTREAM [VPG]: drm/i915/skl+: Implement Transition WM
  drm/i915/gen9: WM memory bandwidth related workaround

 drivers/gpu/drm/i915/i915_drv.c  |  96 +
 drivers/gpu/drm/i915/i915_drv.h  |  27 +++
 drivers/gpu/drm/i915/i915_reg.h  |  25 +++
 drivers/gpu/drm/i915/intel_display.c |   4 +-
 drivers/gpu/drm/i915/intel_drv.h |  11 ++
 drivers/gpu/drm/i915/intel_pm.c  | 366 +++
 6 files changed, 447 insertions(+), 82 deletions(-)

-- 
2.8.3

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


[Intel-gfx] [PATCH] drm/i915/gen9: WM memory bandwidth related workaround

2016-08-29 Thread Kumar, Mahesh
This patch implemnets Workariunds related to display arbitrated memory
bandwidth. These WA are applicabe for all gen-9 based platforms.

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |   9 +++
 drivers/gpu/drm/i915/intel_drv.h |  11 +++
 drivers/gpu/drm/i915/intel_pm.c  | 145 +++
 3 files changed, 165 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d0123f8..095af6c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1055,6 +1055,13 @@ enum intel_sbi_destination {
SBI_MPHY,
 };
 
+/* SKL+ Watermark arbitrated display bandwidth Workarounds */
+enum watermark_memory_wa {
+   WATERMARK_WA_NONE,
+   WATERMARK_WA_X_TILED,
+   WATERMARK_WA_Y_TILED,
+};
+
 #define QUIRK_PIPEA_FORCE (1<<0)
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)
 #define QUIRK_INVERT_BRIGHTNESS (1<<2)
@@ -1604,6 +1611,8 @@ struct skl_ddb_allocation {
 
 struct skl_wm_values {
unsigned dirty_pipes;
+   /* any WaterMark memory workaround Required */
+   enum watermark_memory_wa mem_wa;
struct skl_ddb_allocation ddb;
uint32_t wm_linetime[I915_MAX_PIPES];
uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 570a7ca..f2c38cc 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1807,6 +1807,17 @@ intel_atomic_get_crtc_state(struct drm_atomic_state 
*state,
return to_intel_crtc_state(crtc_state);
 }
 
+static inline struct intel_crtc_state *
+intel_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+   struct drm_crtc_state *crtc_state;
+
+   crtc_state = drm_atomic_get_existing_crtc_state(state, >base);
+
+   return to_intel_crtc_state(crtc_state);
+}
+
 static inline struct intel_plane_state *
 intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
  struct intel_plane *plane)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ac0d0ca..e9cd6ac 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3624,6 +3624,8 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
 {
struct drm_plane_state *pstate = _pstate->base;
struct drm_framebuffer *fb = pstate->fb;
+   struct intel_atomic_state *intel_state =
+   to_intel_atomic_state(cstate->base.state);
uint32_t latency = dev_priv->wm.skl_latency[level];
uint32_t method1, method2;
uint32_t plane_bytes_per_line, plane_blocks_per_line;
@@ -3639,10 +3641,17 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
uint8_t *out_lines = >plane_res_l[id];
uint32_t y_tile_minimum = 0;
bool y_tile = false;
+   enum watermark_memory_wa mem_wa;
 
if (latency == 0 || !cstate->base.active || !intel_pstate->base.visible)
return 0;
 
+   mem_wa = intel_state ? intel_state->wm_results.mem_wa : 
WATERMARK_WA_NONE;
+   if (mem_wa != WATERMARK_WA_NONE) {
+   if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
+   latency += 15;
+   }
+
width = drm_rect_width(_pstate->base.src) >> 16;
height = drm_rect_height(_pstate->base.src) >> 16;
 
@@ -3682,6 +3691,9 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
WARN(1, "Unsupported pixel depth for rotation");
}
}
+   if (mem_wa == WATERMARK_WA_Y_TILED)
+   min_scanlines *= 2;
+
y_tile_minimum = plane_blocks_per_line * min_scanlines;
selected_result = max(method2, y_tile_minimum);
y_tile = true;
@@ -4065,6 +4077,15 @@ skl_include_affected_pipes(struct drm_atomic_state 
*state)
intel_state->wm_results.dirty_pipes = ~0;
}
 
+   /*
+* If Watermark workaround is changed we need to recalculate
+* watermark values for all active pipes
+*/
+   if (intel_state->wm_results.mem_wa != dev_priv->wm.skl_hw.mem_wa) {
+   realloc_pipes = ~0;
+   intel_state->wm_results.dirty_pipes = ~0;
+   }
+
for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
struct intel_crtc_state *cstate;
 
@@ -4081,6 +4102,128 @@ skl_include_affected_pipes(struct drm_atomic_state 
*state)
 }
 
 static void
+skl_set_memory_bandwidth_wm_wa(struct drm_atomic_state *state)
+{
+   struct drm_device *dev = state->dev;
+   struct drm_i915_private *dev_priv = to_i915(dev);
+   

[Intel-gfx] [PATCH 3/7] drm/i915/skl: pass pipe_wm in skl_compute_(wm_level/plane_wm) functions

2016-08-29 Thread Kumar, Mahesh
This patch make use of plane_wm variable directly instead of passing
skl_plane_wm struct. this way reduces number of argument requirement
in watermark calculation functions.

It also gives more freedom of decision making to implement Bspec WM
workarounds.

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b2f17eb..5fa02cb 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3540,9 +3540,7 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
struct intel_plane_state *intel_pstate,
uint16_t ddb_allocation,
int level,
-   uint16_t *out_blocks, /* out */
-   uint8_t *out_lines, /* out */
-   bool *enabled /* out */)
+   struct skl_pipe_wm *pipe_wm)
 {
struct drm_plane_state *pstate = _pstate->base;
struct drm_framebuffer *fb = pstate->fb;
@@ -3555,6 +3553,11 @@ static int skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
uint32_t width = 0, height = 0;
uint32_t plane_pixel_rate;
uint32_t linetime_us = 0;
+   int id = skl_wm_plane_id(to_intel_plane(pstate->plane));
+   struct skl_wm_level *result = _wm->wm[level];
+   uint16_t *out_blocks = >plane_res_b[id];
+   uint8_t *out_lines = >plane_res_l[id];
+   bool *enabled = >plane_en[id];
 
if (latency == 0 || !cstate->base.active || 
!intel_pstate->base.visible) {
*enabled = false;
@@ -3655,7 +3658,7 @@ skl_compute_wm_level(const struct drm_i915_private 
*dev_priv,
 struct skl_ddb_allocation *ddb,
 struct intel_crtc_state *cstate,
 int level,
-struct skl_wm_level *result)
+struct skl_pipe_wm *pipe_wm)
 {
struct drm_atomic_state *state = cstate->base.state;
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
@@ -3666,12 +3669,6 @@ skl_compute_wm_level(const struct drm_i915_private 
*dev_priv,
enum pipe pipe = intel_crtc->pipe;
int ret;
 
-   /*
-* We'll only calculate watermarks for planes that are actually
-* enabled, so make sure all other planes are set as disabled.
-*/
-   memset(result, 0, sizeof(*result));
-
for_each_intel_plane_mask(_priv->drm,
  intel_plane,
  cstate->base.plane_mask) {
@@ -3709,9 +3706,7 @@ skl_compute_wm_level(const struct drm_i915_private 
*dev_priv,
   intel_pstate,
   ddb_blocks,
   level,
-  >plane_res_b[i],
-  >plane_res_l[i],
-  >plane_en[i]);
+  pipe_wm);
if (ret)
return ret;
}
@@ -3759,9 +3754,15 @@ static int skl_build_pipe_wm(struct intel_crtc_state 
*cstate,
int level, max_level = ilk_wm_max_level(dev);
int ret;
 
+   /*
+* We'll only calculate watermarks for planes that are actually
+* enabled, so make sure all other planes are set as disabled.
+*/
+   memset(pipe_wm, 0, sizeof(*pipe_wm));
+
for (level = 0; level <= max_level; level++) {
ret = skl_compute_wm_level(dev_priv, ddb, cstate,
-  level, _wm->wm[level]);
+  level, pipe_wm);
if (ret)
return ret;
}
-- 
2.8.3

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


[Intel-gfx] [PATCH 1/7] drm/i915/hsw+: set intel_crtc active once pipe is active

2016-08-29 Thread Kumar, Mahesh
Set the intel_crtc->active flag after pipe/crtc is actually active in
haswell_crtc_enable function.

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index e4e6141..7258883 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5427,8 +5427,6 @@ static void haswell_crtc_enable(struct intel_crtc_state 
*pipe_config,
 
intel_color_set_csc(_config->base);
 
-   intel_crtc->active = true;
-
if (intel_crtc->config->has_pch_encoder)
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
else
@@ -5475,6 +5473,8 @@ static void haswell_crtc_enable(struct intel_crtc_state 
*pipe_config,
assert_vblank_disabled(crtc);
drm_crtc_vblank_on(crtc);
 
+   intel_crtc->active = true;
+
intel_encoders_enable(crtc, pipe_config, old_state);
 
if (intel_crtc->config->has_pch_encoder) {
-- 
2.8.3

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


Re: [Intel-gfx] [PATCH] drm/i915/skl: Correct other-pipe watermark update condition check (v2)

2015-10-27 Thread Kumar, Mahesh

Yes, it doesn't solve all warnings.
Other than fbdev restore, there is one warning which I faced during 
DPMS/Hot-plug, which is due to calculation of watermarks twice. Once for 
first CRTC "Pipe-A" (during which it consider/calculates watermark for 
other pipe "Pipe-B" as well & stores in structure 
"intel_crtc->wm.active.skl") & Now in same atomic_commit, when it 
calculate watermark for second CRTC "Pipe-B" , that time watermark for 
other-pipe (in this case pipe-A) already have calculated values so it 
gives !wm_changed warning.


Hoping 2-stage watermark programming will take care of this, as in that 
case, If I'm not misunderstood  final results should be stored after 
calculation for all pipes.


Regards,
-Mahesh

On 10/23/2015 10:11 PM, Matt Roper wrote:

From: "Kumar, Mahesh" <mahesh1.ku...@intel.com>

If ddb allocation for planes in current CRTC is changed, that doesn't
lead to ddb allocation change for other CRTCs, because our DDB allocation
is not dynamic according to plane parameters, ddb is allocated according
to number of CRTC enabled, & divided equally among CTRC's.

In current condition check during Watermark calculation, if number of
plane/ddb allocation changes for current CRTC, Watermark for other pipes
are recalculated. But there is no change in DDB allocation of other pipe
so watermark is also not changed, This leads to warning messages.
WARN_ON(!wm_changed)

This patch corrects this and check if DDB allocation for pipes is changed,
then only recalculate watermarks.

v2 (by Matt): Rebased to latest -nightly and fixed a typo

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
Reviewed-by(v1): Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.ro...@intel.com>
---
I don't think this solves all the !wm_changed warnings (I still see one during
fbdev restore following various igt tests), but it seems like a move in the
right direction so I figured I'd go ahead and rebase Mahesh' patch so it can
get merged.

  drivers/gpu/drm/i915/intel_pm.c | 12 +---
  1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0fb0459..0467e34 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3064,14 +3064,12 @@ static bool skl_ddb_allocation_changed(const struct 
skl_ddb_allocation *new_ddb,
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
const struct skl_ddb_allocation *cur_ddb = _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(_ddb->plane[pipe][PLANE_CURSOR], _ddb->plane[pipe][PLANE_CURSOR],

-   sizeof(new_ddb->plane[pipe][PLANE_CURSOR])))
+   /*
+* If ddb allocation of pipes changed, it may require recalculation of
+* watermarks
+*/
+   if (memcmp(new_ddb->pipe, cur_ddb->pipe, sizeof(new_ddb->pipe)))
return true;
  
  	return false;


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


[Intel-gfx] [PATCH] drm/i915/skl: Correct other-pipe watermark update condition check

2015-09-21 Thread Kumar, Mahesh
If ddb allocation for planes in current CRTC is changed, that doesn't
lead to ddb allocation change for other CRTCs, because our DDB allocation
is not dynamic according to plane parameters, ddb is allocated according
to number of CRTC enabled, & divided equally among CTRC's.

In current condition check during Watermark calculation, if number of
plane/ddb allocation changes for current CRTC, Watermark for other pipes
are recalculated. But there is no change in DDB allocation of other pipe
so watermark is also not changed, This leads to warning messages.
WARN_ON(!wm_changed)

This patch corrects this and check if DDB allocation for pipes is changed,
then only recalculate watermarks.

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 62de97e..a1ed920 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3127,14 +3127,12 @@ static bool skl_ddb_allocation_changed(const struct 
skl_ddb_allocation *new_ddb,
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
const struct skl_ddb_allocation *cur_ddb = _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(_ddb->cursor[pipe], _ddb->cursor[pipe],
-   sizeof(new_ddb->cursor[pipe])))
+   /*
+* If ddb allocation of pipes chenged, it may require recalculation of
+* watermarks
+*/
+   if (memcmp(new_ddb->pipe, cur_ddb->pipe, sizeof(new_ddb->pipe)))
return true;
 
return false;
-- 
1.9.1

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


[Intel-gfx] [PATCH] drm/i915/skl+: Fix Watermark calculation for Broxton

2015-09-21 Thread Kumar, Mahesh
In case of Y-Tiling, "plane_blocks_per_line" calculation is different
than X/None-Tiling case.
This patch corrects this calculation according to Bspec.
plane blocks per line = Plane memory format is Y tile ?
ceiling[4 * plane bytes per line / 512]/4 :
ceiling[plane bytes per line / 512]
As per BSpec Don't increment selected "result_blocks" & "result_lines"
in case of BROXTON.

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a1ed920..5cfb5d9 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3247,7 +3247,13 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
 latency);
 
plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel;
-   plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+
+   if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
+   p_params->tiling == I915_FORMAT_MOD_Yf_TILED) {
+   plane_blocks_per_line = DIV_ROUND_UP(4 * plane_bytes_per_line, 
512);
+   plane_blocks_per_line /= 4;
+   } else
+   plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
 
if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
p_params->tiling == I915_FORMAT_MOD_Yf_TILED) {
@@ -3277,7 +3283,7 @@ static bool skl_compute_plane_wm(const struct 
drm_i915_private *dev_priv,
res_blocks = selected_result + 1;
res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
 
-   if (level >= 1 && level <= 7) {
+   if (level >= 1 && level <= 7 && !IS_BROXTON(dev_priv->dev)) {
if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
p_params->tiling == I915_FORMAT_MOD_Yf_TILED)
res_lines += 4;
-- 
1.9.1

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


[Intel-gfx] [PATCH 1/2] drm/i915/skl: Avoid using un-initialized bits_per_pixel

2015-09-03 Thread Kumar, Mahesh
Don't rely on fb->bits_per_pixel as intel_framebuffer_init is not
filling bits_per_pixel field of fb-struct for YUV pixel format.
This leads to divide by zero error during watermark calculation.

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
Cc: Konduru, Chandra <chandra.kond...@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ea49661..1b90f03 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3170,7 +3170,8 @@ static void skl_compute_wm_pipe_parameters(struct 
drm_crtc *crtc,
if (fb) {
p->plane[0].enabled = true;
p->plane[0].bytes_per_pixel = fb->pixel_format == 
DRM_FORMAT_NV12 ?
-   drm_format_plane_cpp(fb->pixel_format, 1) : 
fb->bits_per_pixel / 8;
+   drm_format_plane_cpp(fb->pixel_format, 1) :
+   drm_format_plane_cpp(fb->pixel_format, 0);
p->plane[0].y_bytes_per_pixel = fb->pixel_format == 
DRM_FORMAT_NV12 ?
drm_format_plane_cpp(fb->pixel_format, 0) : 0;
p->plane[0].tiling = fb->modifier[0];
-- 
1.9.1

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


[Intel-gfx] [PATCH 2/2] drm/i915/skl+: Add YUV pixel format in Capability list

2015-09-03 Thread Kumar, Mahesh
GEN >= 9 supports YUV format for all planes, but it's not exported in
Capability list of primary plane. Add YUV formats in skl_primary_formats
list.

Testcase: igt/kms_universal_plane.c

Signed-off-by: Kumar, Mahesh <mahesh1.ku...@intel.com>
Cc: Konduru, Chandra <chandra.kond...@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 0377520..5ab8a1a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -72,6 +72,10 @@ static const uint32_t skl_primary_formats[] = {
DRM_FORMAT_ABGR,
DRM_FORMAT_XRGB2101010,
DRM_FORMAT_XBGR2101010,
+   DRM_FORMAT_YUYV,
+   DRM_FORMAT_YVYU,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_VYUY,
 };
 
 /* Cursor formats */
-- 
1.9.1

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


Re: [Intel-gfx] [PATCH V2] drm/i915/skl+: Add YUV pixel format in Capability list

2015-08-24 Thread Kumar, Mahesh

Ok..., Will resubmit the patch with suggested changes.

Regards,
-Mahesh

On 8/24/2015 3:53 PM, Jindal, Sonika wrote:

Can you please add the test case name to the commit message?
Also, this should be split into two patches one addressing the divide by zero 
error and another one to add plane formats.

Regards,
Sonika

-Original Message-
From: Intel-gfx [mailto:intel-gfx-boun...@lists.freedesktop.org] On Behalf Of 
Kumar, Mahesh
Sent: Friday, July 17, 2015 7:21 PM
To: intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH V2] drm/i915/skl+: Add YUV pixel format in 
Capability list

GEN = 9 supports YUV format for all planes, but it's not exported in 
Capability list of primary plane. Add YUV formats in skl_primary_formats list.
Don't rely on fb-bits_per_pixel as intel_framebuffer_init is not filling 
bits_per_pixel field of fb-struct for YUV pixel format.
This leads to divide by zero error during watermark calculation.

V2: Don't break NV12 case.

Signed-off-by: Kumar, Mahesh mahesh1.ku...@intel.com
Cc: Konduru, Chandra chandra.kond...@intel.com
---

  IGT changes made for testcase will be sent in separate patch.

  drivers/gpu/drm/i915/intel_display.c | 4 
  drivers/gpu/drm/i915/intel_pm.c  | 3 ++-
  2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index af0bcfe..d31704a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -72,6 +72,10 @@ static const uint32_t skl_primary_formats[] = {
DRM_FORMAT_ABGR,
DRM_FORMAT_XRGB2101010,
DRM_FORMAT_XBGR2101010,
+   DRM_FORMAT_YUYV,
+   DRM_FORMAT_YVYU,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_VYUY,
  };
  
  /* Cursor formats */

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c 
index 5eeddc9..5768f8c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3164,7 +3164,8 @@ static void skl_compute_wm_pipe_parameters(struct 
drm_crtc *crtc,
if (fb) {
p-plane[0].enabled = true;
p-plane[0].bytes_per_pixel = fb-pixel_format == 
DRM_FORMAT_NV12 ?
-   drm_format_plane_cpp(fb-pixel_format, 1) : 
fb-bits_per_pixel / 8;
+   drm_format_plane_cpp(fb-pixel_format, 1) :
+   drm_format_plane_cpp(fb-pixel_format, 0);
p-plane[0].y_bytes_per_pixel = fb-pixel_format == 
DRM_FORMAT_NV12 ?
drm_format_plane_cpp(fb-pixel_format, 0) : 0;
p-plane[0].tiling = fb-modifier[0];
--
1.9.1

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


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


[Intel-gfx] [PATCH v2] kms_universal_plane: subtest for yuv pixel format in primary plane

2015-08-20 Thread Kumar, Mahesh
This test commit YUV framebuffer in primay plane. I'm using empty FB,
because this fulfills the purpose of testing YUV.

V2: Revert chnages for MAX_PLANE count as per nabendu's comment. These
changes are already floating for review.

Signed-off-by: Kumar, Mahesh mahesh1.ku...@intel.com
---
 lib/igt_fb.c|  4 +++
 tests/kms_universal_plane.c | 82 +
 2 files changed, 86 insertions(+)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 134dbd2..e570bfa 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -66,6 +66,10 @@ static struct format_desc_struct {
DF(XRGB,RGB24,  32, 24),
DF(XRGB2101010, RGB30,  32, 30),
DF(ARGB,ARGB32, 32, 32),
+   DF(YUYV,INVALID,16, 16),
+   DF(YVYU,INVALID,16, 16),
+   DF(UYVY,INVALID,16, 16),
+   DF(VYUY,INVALID,16, 16),
 };
 #undef DF
 
diff --git a/tests/kms_universal_plane.c b/tests/kms_universal_plane.c
index 635cc79..ed4b134 100644
--- a/tests/kms_universal_plane.c
+++ b/tests/kms_universal_plane.c
@@ -57,6 +57,12 @@ typedef struct {
struct igt_fb red_fb, blue_fb;
 } pageflip_test_t;
 
+typedef struct {
+   data_t *data;
+   struct igt_fb fullsize_fb, undersize_fb;
+} primary_yuv_test_t;
+
+
 static void
 functional_test_init(functional_test_t *test, igt_output_t *output, enum pipe 
pipe)
 {
@@ -430,6 +436,77 @@ sanity_test_pipe(data_t *data, enum pipe pipe, 
igt_output_t *output)
 }
 
 static void
+primary_yuv_test_init(primary_yuv_test_t *test, igt_output_t *output, enum 
pipe pipe)
+{
+   data_t *data = test-data;
+   drmModeModeInfo *mode;
+
+   igt_output_set_pipe(output, pipe);
+
+   mode = igt_output_get_mode(output);
+   igt_create_fb(data-drm_fd, mode-hdisplay, mode-vdisplay,
+   DRM_FORMAT_YUYV,
+   LOCAL_DRM_FORMAT_MOD_NONE,
+   test-fullsize_fb);
+   igt_create_fb(data-drm_fd, 300, 300,
+   DRM_FORMAT_YVYU,
+   LOCAL_DRM_FORMAT_MOD_NONE,
+   test-undersize_fb);
+}
+
+static void
+primary_yuv_test_fini(primary_yuv_test_t *test, igt_output_t *output)
+{
+   igt_remove_fb(test-data-drm_fd, test-fullsize_fb);
+   igt_remove_fb(test-data-drm_fd, test-undersize_fb);
+
+   igt_output_set_pipe(output, PIPE_ANY);
+   igt_display_commit2(test-data-display, COMMIT_LEGACY);
+}
+
+/*
+ * YUV pixel format test for primary plane
+ * Display Full frame in primay then 300x300 frame
+ */
+
+static void
+primary_yuv_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
+{
+   primary_yuv_test_t test = { .data = data };
+   igt_plane_t *primary;
+
+   igt_skip_on(pipe = data-display.n_pipes);
+
+   igt_output_set_pipe(output, pipe);
+
+   primary_yuv_test_init(test, output, pipe);
+
+   primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
+
+   /* Use legacy API to set a mode with a Fullsize FB */
+   igt_plane_set_fb(primary, test.fullsize_fb);
+   igt_display_commit2(data-display, COMMIT_LEGACY);
+
+   /* Disable the primary plane */
+   igt_plane_set_fb(primary, NULL);
+   igt_display_commit2(data-display, COMMIT_UNIVERSAL);
+
+   /* Use Universal API to set a mode with a Fullsize FB */
+   igt_plane_set_fb(primary, test.fullsize_fb);
+   igt_display_commit2(data-display, COMMIT_UNIVERSAL);
+
+   /* Use Universal API to set a mode with a Undersize FB */
+   igt_plane_set_fb(primary, test.undersize_fb);
+   igt_display_commit2(data-display, COMMIT_UNIVERSAL);
+
+   /* Disable the primary plane */
+   igt_plane_set_fb(primary, NULL);
+
+   primary_yuv_test_fini(test, output);
+
+}
+
+static void
 pageflip_test_init(pageflip_test_t *test, igt_output_t *output, enum pipe pipe)
 {
data_t *data = test-data;
@@ -663,6 +740,11 @@ run_tests_for_pipe(data_t *data, enum pipe pipe)
  kmstest_pipe_name(pipe))
for_each_connected_output(data-display, output)
cursor_leak_test_pipe(data, pipe, output);
+
+   igt_subtest_f(primary-plane-pipe-%s-yuv,
+ kmstest_pipe_name(pipe))
+   for_each_connected_output(data-display, output)
+   primary_yuv_test_pipe(data, pipe, output);
 }
 
 static data_t data;
-- 
1.9.1

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


[Intel-gfx] [PATCH] kms_universal_plane: subtest for yuv pixel format in primary plane

2015-07-20 Thread Kumar, Mahesh
This test commit YUV framebuffer in primay plane. I'm using empty FB,
because this fulfills the purpose of testing YUV.

Increase IGT_MAX_PLANES to 5 and add enum for IGT_PLANE_4, as in Broxton
we have 4Plane+1cursor plane.

Signed-off-by: Kumar, Mahesh mahesh1.ku...@intel.com
---
 lib/igt_fb.c|  4 +++
 lib/igt_kms.c   |  1 +
 lib/igt_kms.h   |  3 +-
 tests/kms_universal_plane.c | 82 +
 4 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 134dbd2..e570bfa 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -66,6 +66,10 @@ static struct format_desc_struct {
DF(XRGB,RGB24,  32, 24),
DF(XRGB2101010, RGB30,  32, 30),
DF(ARGB,ARGB32, 32, 32),
+   DF(YUYV,INVALID,16, 16),
+   DF(YVYU,INVALID,16, 16),
+   DF(UYVY,INVALID,16, 16),
+   DF(VYUY,INVALID,16, 16),
 };
 #undef DF
 
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 0bb16b4..781ffa5 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -213,6 +213,7 @@ const char *kmstest_plane_name(enum igt_plane plane)
[IGT_PLANE_1] = plane1,
[IGT_PLANE_2] = plane2,
[IGT_PLANE_3] = plane3,
+   [IGT_PLANE_4] = plane4,
[IGT_PLANE_CURSOR] = cursor,
};
 
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 09c08aa..14c8b28 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -53,6 +53,7 @@ enum igt_plane {
 IGT_PLANE_PRIMARY = IGT_PLANE_1,
 IGT_PLANE_2,
 IGT_PLANE_3,
+IGT_PLANE_4,
 IGT_PLANE_CURSOR,
 };
 
@@ -205,7 +206,7 @@ struct igt_pipe {
igt_display_t *display;
enum pipe pipe;
bool enabled;
-#define IGT_MAX_PLANES 4
+#define IGT_MAX_PLANES 5
int n_planes;
igt_plane_t planes[IGT_MAX_PLANES];
uint64_t background; /* Background color MSB BGR 16bpc LSB */
diff --git a/tests/kms_universal_plane.c b/tests/kms_universal_plane.c
index 635cc79..ed4b134 100644
--- a/tests/kms_universal_plane.c
+++ b/tests/kms_universal_plane.c
@@ -57,6 +57,12 @@ typedef struct {
struct igt_fb red_fb, blue_fb;
 } pageflip_test_t;
 
+typedef struct {
+   data_t *data;
+   struct igt_fb fullsize_fb, undersize_fb;
+} primary_yuv_test_t;
+
+
 static void
 functional_test_init(functional_test_t *test, igt_output_t *output, enum pipe 
pipe)
 {
@@ -430,6 +436,77 @@ sanity_test_pipe(data_t *data, enum pipe pipe, 
igt_output_t *output)
 }
 
 static void
+primary_yuv_test_init(primary_yuv_test_t *test, igt_output_t *output, enum 
pipe pipe)
+{
+   data_t *data = test-data;
+   drmModeModeInfo *mode;
+
+   igt_output_set_pipe(output, pipe);
+
+   mode = igt_output_get_mode(output);
+   igt_create_fb(data-drm_fd, mode-hdisplay, mode-vdisplay,
+   DRM_FORMAT_YUYV,
+   LOCAL_DRM_FORMAT_MOD_NONE,
+   test-fullsize_fb);
+   igt_create_fb(data-drm_fd, 300, 300,
+   DRM_FORMAT_YVYU,
+   LOCAL_DRM_FORMAT_MOD_NONE,
+   test-undersize_fb);
+}
+
+static void
+primary_yuv_test_fini(primary_yuv_test_t *test, igt_output_t *output)
+{
+   igt_remove_fb(test-data-drm_fd, test-fullsize_fb);
+   igt_remove_fb(test-data-drm_fd, test-undersize_fb);
+
+   igt_output_set_pipe(output, PIPE_ANY);
+   igt_display_commit2(test-data-display, COMMIT_LEGACY);
+}
+
+/*
+ * YUV pixel format test for primary plane
+ * Display Full frame in primay then 300x300 frame
+ */
+
+static void
+primary_yuv_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
+{
+   primary_yuv_test_t test = { .data = data };
+   igt_plane_t *primary;
+
+   igt_skip_on(pipe = data-display.n_pipes);
+
+   igt_output_set_pipe(output, pipe);
+
+   primary_yuv_test_init(test, output, pipe);
+
+   primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
+
+   /* Use legacy API to set a mode with a Fullsize FB */
+   igt_plane_set_fb(primary, test.fullsize_fb);
+   igt_display_commit2(data-display, COMMIT_LEGACY);
+
+   /* Disable the primary plane */
+   igt_plane_set_fb(primary, NULL);
+   igt_display_commit2(data-display, COMMIT_UNIVERSAL);
+
+   /* Use Universal API to set a mode with a Fullsize FB */
+   igt_plane_set_fb(primary, test.fullsize_fb);
+   igt_display_commit2(data-display, COMMIT_UNIVERSAL);
+
+   /* Use Universal API to set a mode with a Undersize FB */
+   igt_plane_set_fb(primary, test.undersize_fb);
+   igt_display_commit2(data-display, COMMIT_UNIVERSAL);
+
+   /* Disable the primary plane */
+   igt_plane_set_fb(primary, NULL);
+
+   primary_yuv_test_fini(test, output);
+
+}
+
+static void
 pageflip_test_init(pageflip_test_t *test

[Intel-gfx] [PATCH V2] drm/i915/skl+: Add YUV pixel format in Capability list

2015-07-17 Thread Kumar, Mahesh
GEN = 9 supports YUV format for all planes, but it's not exported in
Capability list of primary plane. Add YUV formats in skl_primary_formats
list.
Don't rely on fb-bits_per_pixel as intel_framebuffer_init is not
filling bits_per_pixel field of fb-struct for YUV pixel format.
This leads to divide by zero error during watermark calculation.

V2: Don't break NV12 case.

Signed-off-by: Kumar, Mahesh mahesh1.ku...@intel.com
Cc: Konduru, Chandra chandra.kond...@intel.com
---

 IGT changes made for testcase will be sent in separate patch.

 drivers/gpu/drm/i915/intel_display.c | 4 
 drivers/gpu/drm/i915/intel_pm.c  | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index af0bcfe..d31704a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -72,6 +72,10 @@ static const uint32_t skl_primary_formats[] = {
DRM_FORMAT_ABGR,
DRM_FORMAT_XRGB2101010,
DRM_FORMAT_XBGR2101010,
+   DRM_FORMAT_YUYV,
+   DRM_FORMAT_YVYU,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_VYUY,
 };
 
 /* Cursor formats */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5eeddc9..5768f8c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3164,7 +3164,8 @@ static void skl_compute_wm_pipe_parameters(struct 
drm_crtc *crtc,
if (fb) {
p-plane[0].enabled = true;
p-plane[0].bytes_per_pixel = fb-pixel_format == 
DRM_FORMAT_NV12 ?
-   drm_format_plane_cpp(fb-pixel_format, 1) : 
fb-bits_per_pixel / 8;
+   drm_format_plane_cpp(fb-pixel_format, 1) :
+   drm_format_plane_cpp(fb-pixel_format, 0);
p-plane[0].y_bytes_per_pixel = fb-pixel_format == 
DRM_FORMAT_NV12 ?
drm_format_plane_cpp(fb-pixel_format, 0) : 0;
p-plane[0].tiling = fb-modifier[0];
-- 
1.9.1

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


[Intel-gfx] [PATCH] drm/i915/skl+: Add YUV pixel format in Capability list

2015-07-14 Thread Kumar, Mahesh
GEN = 9 supports YUV format for all planes, but it's not exported in
Capability list of primary plane. Add YUV formats in skl_primary_formats
list.
Don't rely on fb-bits_per_pixel as intel_framebuffer_init is not
filling bits_per_pixel field of fb-struct for YUV pixel format.
This leads to divide by zero error during watermark calculation.

Signed-off-by: Kumar, Mahesh mahesh1.ku...@intel.com
Cc: Konduru, Chandra chandra.kond...@intel.com
---
 drivers/gpu/drm/i915/intel_display.c | 4 
 drivers/gpu/drm/i915/intel_pm.c  | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bb58cb6..f4b27af 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -72,6 +72,10 @@ static const uint32_t skl_primary_formats[] = {
DRM_FORMAT_ABGR,
DRM_FORMAT_XRGB2101010,
DRM_FORMAT_XBGR2101010,
+   DRM_FORMAT_YUYV,
+   DRM_FORMAT_YVYU,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_VYUY,
 };
 
 /* Cursor formats */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index f2be1ce..1d13b7e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3156,8 +3156,8 @@ static void skl_compute_wm_pipe_parameters(struct 
drm_crtc *crtc,
/* For planar: Bpp is for uv plane, y_Bpp is for y plane */
if (fb) {
p-plane[0].enabled = true;
-   p-plane[0].bytes_per_pixel = fb-pixel_format == 
DRM_FORMAT_NV12 ?
-   drm_format_plane_cpp(fb-pixel_format, 1) : 
fb-bits_per_pixel / 8;
+   p-plane[0].bytes_per_pixel =
+   drm_format_plane_cpp(fb-pixel_format, 1);
p-plane[0].y_bytes_per_pixel = fb-pixel_format == 
DRM_FORMAT_NV12 ?
drm_format_plane_cpp(fb-pixel_format, 0) : 0;
p-plane[0].tiling = fb-modifier[0];
-- 
1.9.1

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


[Intel-gfx] [PATCH] drm/i915/skl: Add check for minimum allocable Display Data Blocks

2015-02-09 Thread Kumar, Mahesh
Fifo Underrun is observed when allocating  minimum allocable blocks
for any plane, This patch calculate  checks for upper  lower DDB
bound for each plane according to total allocated DDB for that Pipe.

Signed-off-by: Kumar, Mahesh mahesh1.ku...@intel.com
---
 drivers/gpu/drm/i915/i915_drv.h |  2 ++
 drivers/gpu/drm/i915/intel_pm.c | 48 +
 2 files changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 26ffe8b..fe51a5a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1536,6 +1536,8 @@ 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];
+   uint16_t min_alloc[I915_MAX_PIPES][I915_MAX_PLANES];
+   uint16_t max_alloc[I915_MAX_PIPES][I915_MAX_PLANES];
 };
 
 struct skl_wm_values {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 3c64810..d4d8994 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2482,6 +2482,43 @@ skl_get_total_relative_data_rate(struct intel_crtc 
*intel_crtc,
 }
 
 static void
+skl_calculate_allocable_blocks(struct intel_crtc *intel_crtc,
+   const struct skl_pipe_wm_parameters *params,
+   uint16_t alloc_size, struct skl_ddb_allocation *ddb)
+{
+   uint16_t min;
+   uint16_t total_min_alloc = 0;
+   enum pipe pipe = intel_crtc-pipe;
+   int plane;
+
+   for (plane = 0; plane  intel_num_planes(intel_crtc); plane++) {
+   const struct intel_plane_wm_parameters *p;
+
+   p = params-plane[plane];
+   ddb-min_alloc[pipe][plane] = 0;
+
+   if (!p-enabled)
+   continue;
+
+   /*
+* TODO: Calculate PlaneMinAlloc according to X/Y-Tiling
+* calculation, for now use X-Tiling PlaneMinAlloc
+*/
+
+   min = 8;
+
+   ddb-min_alloc[pipe][plane] = min;
+   total_min_alloc += min;
+
+   }
+
+   for (plane = 0; plane  intel_num_planes(intel_crtc); plane++) {
+   ddb-max_alloc[pipe][plane] = alloc_size - total_min_alloc +
+   ddb-min_alloc[pipe][plane];
+   }
+}
+
+static void
 skl_allocate_pipe_ddb(struct drm_crtc *crtc,
  const struct intel_wm_config *config,
  const struct skl_pipe_wm_parameters *params,
@@ -2519,6 +2556,8 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
 
start = alloc-start;
+
+   skl_calculate_allocable_blocks(intel_crtc, params, alloc_size, ddb);
for (plane = 0; plane  intel_num_planes(intel_crtc); plane++) {
const struct intel_plane_wm_parameters *p;
unsigned int data_rate;
@@ -2537,6 +2576,15 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
plane_blocks = div_u64((uint64_t)alloc_size * data_rate,
   total_data_rate);
 
+   /*
+* Limit plane_blocks if out of limit
+*/
+
+   if (plane_blocks  ddb-max_alloc[pipe][plane])
+   plane_blocks = ddb-max_alloc[pipe][plane];
+   if (plane_blocks  ddb-min_alloc[pipe][plane])
+   plane_blocks = ddb-min_alloc[pipe][plane];
+
ddb-plane[pipe][plane].start = start;
ddb-plane[pipe][plane].end = start + plane_blocks;
 
-- 
2.3.0

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


  1   2   >