diff mbox series

[v5,4/9] drm: mali-dp: Enable Mali-DP tiled buffer formats

Message ID 20181019105752.17741-5-alexandru-cosmin.gheorghe@arm.com (mailing list archive)
State New, archived
Headers show
Series Add method to describe tile/bit_level_packed formats | expand

Commit Message

Alexandru-Cosmin Gheorghe Oct. 19, 2018, 10:57 a.m. UTC
Enable the following formats
- DRM_FORMAT_X0L0: DP650
- DRM_FORMAT_X0L2: DP550, DP650

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
---
 drivers/gpu/drm/arm/malidp_hw.c     | 14 +++++++++++---
 drivers/gpu/drm/arm/malidp_planes.c | 23 +++++++++++++++++++++--
 2 files changed, 32 insertions(+), 5 deletions(-)

Comments

Brian Starkey Oct. 19, 2018, 1:17 p.m. UTC | #1
Hi Alex,

On Fri, Oct 19, 2018 at 11:57:47AM +0100, Alexandru Gheorghe wrote:
>Enable the following formats
>- DRM_FORMAT_X0L0: DP650
>- DRM_FORMAT_X0L2: DP550, DP650
>
>Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>

A couple of suggestions below, but with or without you can add my
r-b.

>---
> drivers/gpu/drm/arm/malidp_hw.c     | 14 +++++++++++---
> drivers/gpu/drm/arm/malidp_planes.c | 23 +++++++++++++++++++++--
> 2 files changed, 32 insertions(+), 5 deletions(-)
>
>diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
>index c94a4422e0e9..e01fc0e5b503 100644
>--- a/drivers/gpu/drm/arm/malidp_hw.c
>+++ b/drivers/gpu/drm/arm/malidp_hw.c
>@@ -77,12 +77,18 @@ static const struct malidp_format_id malidp500_de_formats[] = {
> 	{ DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) },	\
> 	{ DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) },	\
> 	{ DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) },	\
>-	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }
>+	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \
>+	{ DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}
>
> static const struct malidp_format_id malidp550_de_formats[] = {
> 	MALIDP_COMMON_FORMATS,
> };
>
>+static const struct malidp_format_id malidp650_de_formats[] = {
>+	MALIDP_COMMON_FORMATS,
>+	{ DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)},
>+};
>+
> static const struct malidp_layer malidp500_layers[] = {
> 	{ DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB },
> 	{ DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 },
>@@ -595,6 +601,8 @@ static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
> 	case DRM_FORMAT_BGR565:
> 	case DRM_FORMAT_UYVY:
> 	case DRM_FORMAT_YUYV:
>+	case DRM_FORMAT_X0L0:
>+	case DRM_FORMAT_X0L2:
> 		bytes_per_col = 32;
> 		break;
> 	/* 16 lines at 1.5 bytes per pixel */
>@@ -860,8 +868,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
> 					    MALIDP550_DC_IRQ_SE,
> 				.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
> 			},
>-			.pixel_formats = malidp550_de_formats,
>-			.n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
>+			.pixel_formats = malidp650_de_formats,
>+			.n_pixel_formats = ARRAY_SIZE(malidp650_de_formats),
> 			.bus_align_bytes = 16,
> 		},
> 		.query_hw = malidp650_query_hw,
>diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
>index 49c37f6dd63e..33bbc29da774 100644
>--- a/drivers/gpu/drm/arm/malidp_planes.c
>+++ b/drivers/gpu/drm/arm/malidp_planes.c
>@@ -196,13 +196,26 @@ static int malidp_de_plane_check(struct drm_plane *plane,
> 	ms->n_planes = fb->format->num_planes;
> 	for (i = 0; i < ms->n_planes; i++) {
> 		u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
>-		if (fb->pitches[i] & (alignment - 1)) {
>+
>+		if ((fb->pitches[i] * drm_format_info_block_height(fb->format, i))
>+				& (alignment - 1)) {
> 			DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
> 				      fb->pitches[i], i);
> 			return -EINVAL;
> 		}
> 	}
>
>+	if (fb->width % drm_format_info_block_width(fb->format, 0) ||
>+	    fb->height % drm_format_info_block_height(fb->format, 0)) {
>+		DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
>+		return -EINVAL;
>+	}
>+	if ((state->src_x >> 16) % drm_format_info_block_width(fb->format, 0) ||
>+	    (state->src_y >> 16) % drm_format_info_block_height(fb->format, 0)) {
>+		DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile sizes");
>+		return -EINVAL;
>+	}

Some local variables for block_w and block_h instead of all the
function calls might be easier to parse in this function.

>+
> 	if ((state->crtc_w > mp->hwdev->max_line_size) ||
> 	    (state->crtc_h > mp->hwdev->max_line_size) ||
> 	    (state->crtc_w < mp->hwdev->min_line_size) ||
>@@ -258,8 +271,14 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
> 		num_strides = (mp->hwdev->hw->features &
> 			       MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
>
>+	/*
>+	 * The drm convention for pitch is that it needs to cover width * cpp,
>+	 * but our hardware wants the pitch/stride to cover all rows included
>+	 * in a tile.
>+	 */
> 	for (i = 0; i < num_strides; ++i)
>-		malidp_hw_write(mp->hwdev, pitches[i],
>+		malidp_hw_write(mp->hwdev, pitches[i] *
>+				drm_format_info_block_height(mp->base.state->fb->format, i),
> 				mp->layer->base +
> 				mp->layer->stride_offset + i * 4);

Personally I think longer lines which don't break up the arguments (or
local variables again) would make this easier to read.

Cheers,
-Brian

> }
>-- 
>2.18.0
>
Alexandru-Cosmin Gheorghe Oct. 22, 2018, 10:08 a.m. UTC | #2
On Fri, Oct 19, 2018 at 02:17:22PM +0100, Brian Starkey wrote:
> Hi Alex,
> 
> On Fri, Oct 19, 2018 at 11:57:47AM +0100, Alexandru Gheorghe wrote:
> >Enable the following formats
> >- DRM_FORMAT_X0L0: DP650
> >- DRM_FORMAT_X0L2: DP550, DP650
> >
> >Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> 
> A couple of suggestions below, but with or without you can add my
> r-b.

Will address them in the next version.

> 
> >---
> >drivers/gpu/drm/arm/malidp_hw.c     | 14 +++++++++++---
> >drivers/gpu/drm/arm/malidp_planes.c | 23 +++++++++++++++++++++--
> >2 files changed, 32 insertions(+), 5 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
> >index c94a4422e0e9..e01fc0e5b503 100644
> >--- a/drivers/gpu/drm/arm/malidp_hw.c
> >+++ b/drivers/gpu/drm/arm/malidp_hw.c
> >@@ -77,12 +77,18 @@ static const struct malidp_format_id malidp500_de_formats[] = {
> >	{ DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) },	\
> >	{ DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) },	\
> >	{ DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) },	\
> >-	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }
> >+	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \
> >+	{ DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}
> >
> >static const struct malidp_format_id malidp550_de_formats[] = {
> >	MALIDP_COMMON_FORMATS,
> >};
> >
> >+static const struct malidp_format_id malidp650_de_formats[] = {
> >+	MALIDP_COMMON_FORMATS,
> >+	{ DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)},
> >+};
> >+
> >static const struct malidp_layer malidp500_layers[] = {
> >	{ DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB },
> >	{ DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 },
> >@@ -595,6 +601,8 @@ static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
> >	case DRM_FORMAT_BGR565:
> >	case DRM_FORMAT_UYVY:
> >	case DRM_FORMAT_YUYV:
> >+	case DRM_FORMAT_X0L0:
> >+	case DRM_FORMAT_X0L2:
> >		bytes_per_col = 32;
> >		break;
> >	/* 16 lines at 1.5 bytes per pixel */
> >@@ -860,8 +868,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
> >					    MALIDP550_DC_IRQ_SE,
> >				.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
> >			},
> >-			.pixel_formats = malidp550_de_formats,
> >-			.n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
> >+			.pixel_formats = malidp650_de_formats,
> >+			.n_pixel_formats = ARRAY_SIZE(malidp650_de_formats),
> >			.bus_align_bytes = 16,
> >		},
> >		.query_hw = malidp650_query_hw,
> >diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
> >index 49c37f6dd63e..33bbc29da774 100644
> >--- a/drivers/gpu/drm/arm/malidp_planes.c
> >+++ b/drivers/gpu/drm/arm/malidp_planes.c
> >@@ -196,13 +196,26 @@ static int malidp_de_plane_check(struct drm_plane *plane,
> >	ms->n_planes = fb->format->num_planes;
> >	for (i = 0; i < ms->n_planes; i++) {
> >		u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
> >-		if (fb->pitches[i] & (alignment - 1)) {
> >+
> >+		if ((fb->pitches[i] * drm_format_info_block_height(fb->format, i))
> >+				& (alignment - 1)) {
> >			DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
> >				      fb->pitches[i], i);
> >			return -EINVAL;
> >		}
> >	}
> >
> >+	if (fb->width % drm_format_info_block_width(fb->format, 0) ||
> >+	    fb->height % drm_format_info_block_height(fb->format, 0)) {
> >+		DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
> >+		return -EINVAL;
> >+	}
> >+	if ((state->src_x >> 16) % drm_format_info_block_width(fb->format, 0) ||
> >+	    (state->src_y >> 16) % drm_format_info_block_height(fb->format, 0)) {
> >+		DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile sizes");
> >+		return -EINVAL;
> >+	}
> 
> Some local variables for block_w and block_h instead of all the
> function calls might be easier to parse in this function.
> 
> >+
> >	if ((state->crtc_w > mp->hwdev->max_line_size) ||
> >	    (state->crtc_h > mp->hwdev->max_line_size) ||
> >	    (state->crtc_w < mp->hwdev->min_line_size) ||
> >@@ -258,8 +271,14 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
> >		num_strides = (mp->hwdev->hw->features &
> >			       MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
> >
> >+	/*
> >+	 * The drm convention for pitch is that it needs to cover width * cpp,
> >+	 * but our hardware wants the pitch/stride to cover all rows included
> >+	 * in a tile.
> >+	 */
> >	for (i = 0; i < num_strides; ++i)
> >-		malidp_hw_write(mp->hwdev, pitches[i],
> >+		malidp_hw_write(mp->hwdev, pitches[i] *
> >+				drm_format_info_block_height(mp->base.state->fb->format, i),
> >				mp->layer->base +
> >				mp->layer->stride_offset + i * 4);
> 
> Personally I think longer lines which don't break up the arguments (or
> local variables again) would make this easier to read.
> 
> Cheers,
> -Brian
> 
> >}
> >-- 
> >2.18.0
> >
diff mbox series

Patch

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c94a4422e0e9..e01fc0e5b503 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -77,12 +77,18 @@  static const struct malidp_format_id malidp500_de_formats[] = {
 	{ DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) },	\
 	{ DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) },	\
 	{ DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) },	\
-	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }
+	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \
+	{ DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}
 
 static const struct malidp_format_id malidp550_de_formats[] = {
 	MALIDP_COMMON_FORMATS,
 };
 
+static const struct malidp_format_id malidp650_de_formats[] = {
+	MALIDP_COMMON_FORMATS,
+	{ DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)},
+};
+
 static const struct malidp_layer malidp500_layers[] = {
 	{ DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB },
 	{ DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 },
@@ -595,6 +601,8 @@  static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
 	case DRM_FORMAT_BGR565:
 	case DRM_FORMAT_UYVY:
 	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_X0L0:
+	case DRM_FORMAT_X0L2:
 		bytes_per_col = 32;
 		break;
 	/* 16 lines at 1.5 bytes per pixel */
@@ -860,8 +868,8 @@  const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
 					    MALIDP550_DC_IRQ_SE,
 				.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
 			},
-			.pixel_formats = malidp550_de_formats,
-			.n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
+			.pixel_formats = malidp650_de_formats,
+			.n_pixel_formats = ARRAY_SIZE(malidp650_de_formats),
 			.bus_align_bytes = 16,
 		},
 		.query_hw = malidp650_query_hw,
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 49c37f6dd63e..33bbc29da774 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -196,13 +196,26 @@  static int malidp_de_plane_check(struct drm_plane *plane,
 	ms->n_planes = fb->format->num_planes;
 	for (i = 0; i < ms->n_planes; i++) {
 		u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
-		if (fb->pitches[i] & (alignment - 1)) {
+
+		if ((fb->pitches[i] * drm_format_info_block_height(fb->format, i))
+				& (alignment - 1)) {
 			DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
 				      fb->pitches[i], i);
 			return -EINVAL;
 		}
 	}
 
+	if (fb->width % drm_format_info_block_width(fb->format, 0) ||
+	    fb->height % drm_format_info_block_height(fb->format, 0)) {
+		DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
+		return -EINVAL;
+	}
+	if ((state->src_x >> 16) % drm_format_info_block_width(fb->format, 0) ||
+	    (state->src_y >> 16) % drm_format_info_block_height(fb->format, 0)) {
+		DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile sizes");
+		return -EINVAL;
+	}
+
 	if ((state->crtc_w > mp->hwdev->max_line_size) ||
 	    (state->crtc_h > mp->hwdev->max_line_size) ||
 	    (state->crtc_w < mp->hwdev->min_line_size) ||
@@ -258,8 +271,14 @@  static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
 		num_strides = (mp->hwdev->hw->features &
 			       MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
 
+	/*
+	 * The drm convention for pitch is that it needs to cover width * cpp,
+	 * but our hardware wants the pitch/stride to cover all rows included
+	 * in a tile.
+	 */
 	for (i = 0; i < num_strides; ++i)
-		malidp_hw_write(mp->hwdev, pitches[i],
+		malidp_hw_write(mp->hwdev, pitches[i] *
+				drm_format_info_block_height(mp->base.state->fb->format, i),
 				mp->layer->base +
 				mp->layer->stride_offset + i * 4);
 }