diff mbox series

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

Message ID 20181029171419.4512-4-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. 29, 2018, 5:14 p.m. UTC
Enable the following formats
- DRM_FORMAT_X0L0: DP650
- DRM_FORMAT_X0L2: DP550, DP650

Reviewed-by: Brian Starkey <brian.starkey@arm.com>
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 | 28 +++++++++++++++++++++++++---
 2 files changed, 36 insertions(+), 6 deletions(-)

Comments

Alexandru-Cosmin Gheorghe Nov. 1, 2018, 1:31 p.m. UTC | #1
Hi,

Liviu, can I merge this through drm-misc-next.

On Mon, Oct 29, 2018 at 05:14:38PM +0000, Alexandru-Cosmin Gheorghe wrote:
> Enable the following formats
> - DRM_FORMAT_X0L0: DP650
> - DRM_FORMAT_X0L2: DP550, DP650
> 
> Reviewed-by: Brian Starkey <brian.starkey@arm.com>
> 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 | 28 +++++++++++++++++++++++++---
>  2 files changed, 36 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
> index 7aad7dd80d8c..b9bed1138fa3 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[] = {
>  	/* id, base address, fb pointer address base, stride offset,
>  	 *	yuv2rgb matrix offset, mmu control register offset, rotation_features
> @@ -630,6 +636,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 */
> @@ -905,8 +913,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 837a24d56675..c9a6d3e0cada 100644
> --- a/drivers/gpu/drm/arm/malidp_planes.c
> +++ b/drivers/gpu/drm/arm/malidp_planes.c
> @@ -398,6 +398,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
>  	struct drm_framebuffer *fb;
>  	u16 pixel_alpha = state->pixel_blend_mode;
>  	int i, ret;
> +	unsigned int block_w, block_h;
>  
>  	if (!state->crtc || !state->fb)
>  		return 0;
> @@ -413,13 +414,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;
>  		}
>  	}
>  
> +	block_w = drm_format_info_block_width(fb->format, 0);
> +	block_h = drm_format_info_block_height(fb->format, 0);
> +	if (fb->width % block_w || fb->height % block_h) {
> +		DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
> +		return -EINVAL;
> +	}
> +	if ((state->src_x >> 16) % block_w || (state->src_y >> 16) % block_h) {
> +		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) ||
> @@ -492,10 +506,18 @@ 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;
>  
> -	for (i = 0; i < num_strides; ++i)
> -		malidp_hw_write(mp->hwdev, pitches[i],
> +	/*
> +	 * 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) {
> +		unsigned int block_h = drm_format_info_block_height(mp->base.state->fb->format, i);
> +
> +		malidp_hw_write(mp->hwdev, pitches[i] * block_h,
>  				mp->layer->base +
>  				mp->layer->stride_offset + i * 4);
> +	}
>  }
>  
>  static const s16
> -- 
> 2.19.1
Liviu Dudau Nov. 1, 2018, 3:24 p.m. UTC | #2
On Thu, Nov 01, 2018 at 01:31:06PM +0000, Alexandru-Cosmin Gheorghe wrote:
> Hi,
> 
> Liviu, can I merge this through drm-misc-next.

Yeah, that is fine with me.

Best regards,
Liviu

> 
> On Mon, Oct 29, 2018 at 05:14:38PM +0000, Alexandru-Cosmin Gheorghe wrote:
> > Enable the following formats
> > - DRM_FORMAT_X0L0: DP650
> > - DRM_FORMAT_X0L2: DP550, DP650
> > 
> > Reviewed-by: Brian Starkey <brian.starkey@arm.com>
> > 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 | 28 +++++++++++++++++++++++++---
> >  2 files changed, 36 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
> > index 7aad7dd80d8c..b9bed1138fa3 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[] = {
> >  	/* id, base address, fb pointer address base, stride offset,
> >  	 *	yuv2rgb matrix offset, mmu control register offset, rotation_features
> > @@ -630,6 +636,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 */
> > @@ -905,8 +913,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 837a24d56675..c9a6d3e0cada 100644
> > --- a/drivers/gpu/drm/arm/malidp_planes.c
> > +++ b/drivers/gpu/drm/arm/malidp_planes.c
> > @@ -398,6 +398,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
> >  	struct drm_framebuffer *fb;
> >  	u16 pixel_alpha = state->pixel_blend_mode;
> >  	int i, ret;
> > +	unsigned int block_w, block_h;
> >  
> >  	if (!state->crtc || !state->fb)
> >  		return 0;
> > @@ -413,13 +414,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;
> >  		}
> >  	}
> >  
> > +	block_w = drm_format_info_block_width(fb->format, 0);
> > +	block_h = drm_format_info_block_height(fb->format, 0);
> > +	if (fb->width % block_w || fb->height % block_h) {
> > +		DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
> > +		return -EINVAL;
> > +	}
> > +	if ((state->src_x >> 16) % block_w || (state->src_y >> 16) % block_h) {
> > +		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) ||
> > @@ -492,10 +506,18 @@ 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;
> >  
> > -	for (i = 0; i < num_strides; ++i)
> > -		malidp_hw_write(mp->hwdev, pitches[i],
> > +	/*
> > +	 * 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) {
> > +		unsigned int block_h = drm_format_info_block_height(mp->base.state->fb->format, i);
> > +
> > +		malidp_hw_write(mp->hwdev, pitches[i] * block_h,
> >  				mp->layer->base +
> >  				mp->layer->stride_offset + i * 4);
> > +	}
> >  }
> >  
> >  static const s16
> > -- 
> > 2.19.1
> 
> -- 
> Cheers,
> Alex G
diff mbox series

Patch

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index 7aad7dd80d8c..b9bed1138fa3 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[] = {
 	/* id, base address, fb pointer address base, stride offset,
 	 *	yuv2rgb matrix offset, mmu control register offset, rotation_features
@@ -630,6 +636,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 */
@@ -905,8 +913,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 837a24d56675..c9a6d3e0cada 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -398,6 +398,7 @@  static int malidp_de_plane_check(struct drm_plane *plane,
 	struct drm_framebuffer *fb;
 	u16 pixel_alpha = state->pixel_blend_mode;
 	int i, ret;
+	unsigned int block_w, block_h;
 
 	if (!state->crtc || !state->fb)
 		return 0;
@@ -413,13 +414,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;
 		}
 	}
 
+	block_w = drm_format_info_block_width(fb->format, 0);
+	block_h = drm_format_info_block_height(fb->format, 0);
+	if (fb->width % block_w || fb->height % block_h) {
+		DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
+		return -EINVAL;
+	}
+	if ((state->src_x >> 16) % block_w || (state->src_y >> 16) % block_h) {
+		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) ||
@@ -492,10 +506,18 @@  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;
 
-	for (i = 0; i < num_strides; ++i)
-		malidp_hw_write(mp->hwdev, pitches[i],
+	/*
+	 * 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) {
+		unsigned int block_h = drm_format_info_block_height(mp->base.state->fb->format, i);
+
+		malidp_hw_write(mp->hwdev, pitches[i] * block_h,
 				mp->layer->base +
 				mp->layer->stride_offset + i * 4);
+	}
 }
 
 static const s16