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 |
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
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 --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