drm/msm/sde: modify pitch verification condition for linear format
This change modifies the pitch verification logic for
linear format to allow if user space requests greater pitch
than driver calculated pitch
Change-Id: I20bb0365397dcfa06007f0bb80fcd6211f1d9db2
Signed-off-by: Narendra Muppalla <NarendraM@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
index c95fb47..2b736e5 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
@@ -918,10 +918,12 @@
* @pixel_format: DRM pixel format
* @width: Desired fb width
* @height: Desired fb height
+ * @pitch: Desired fb pitch
*/
static int _sde_encoder_phys_wb_init_internal_fb(
struct sde_encoder_phys_wb *wb_enc,
- uint32_t pixel_format, uint32_t width, uint32_t height)
+ uint32_t pixel_format, uint32_t width,
+ uint32_t height, uint32_t pitch)
{
struct drm_device *dev;
struct drm_framebuffer *fb;
@@ -951,9 +953,11 @@
mode_cmd.pixel_format = pixel_format;
mode_cmd.width = width;
mode_cmd.height = height;
+ mode_cmd.pitches[0] = pitch;
size = sde_format_get_framebuffer_size(pixel_format,
- mode_cmd.width, mode_cmd.height, 0, 0);
+ mode_cmd.width, mode_cmd.height,
+ mode_cmd.pitches, NULL, 0);
if (!size) {
SDE_DEBUG("not creating zero size buffer\n");
return -EINVAL;
@@ -1314,7 +1318,7 @@
/* create internal buffer for disable logic */
if (_sde_encoder_phys_wb_init_internal_fb(wb_enc,
- DRM_FORMAT_RGB888, 2, 1)) {
+ DRM_FORMAT_RGB888, 2, 1, 6)) {
SDE_ERROR("failed to init internal fb\n");
goto fail_wb_init;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_formats.c b/drivers/gpu/drm/msm/sde/sde_formats.c
index 04c9e79..3acf4c9 100644
--- a/drivers/gpu/drm/msm/sde/sde_formats.c
+++ b/drivers/gpu/drm/msm/sde/sde_formats.c
@@ -701,7 +701,8 @@
const struct sde_format *fmt,
const uint32_t width,
const uint32_t height,
- struct sde_hw_fmt_layout *layout)
+ struct sde_hw_fmt_layout *layout,
+ const uint32_t *pitches)
{
int i;
@@ -751,6 +752,17 @@
}
}
+ /*
+ * linear format: allow user allocated pitches if they are greater than
+ * the requirement.
+ * ubwc format: pitch values are computed uniformly across
+ * all the components based on ubwc specifications.
+ */
+ for (i = 0; i < layout->num_planes && i < SDE_MAX_PLANES; ++i) {
+ if (pitches && layout->plane_pitch[i] < pitches[i])
+ layout->plane_pitch[i] = pitches[i];
+ }
+
for (i = 0; i < SDE_MAX_PLANES; i++)
layout->total_size += layout->plane_size[i];
@@ -761,7 +773,8 @@
const struct sde_format *fmt,
const uint32_t w,
const uint32_t h,
- struct sde_hw_fmt_layout *layout)
+ struct sde_hw_fmt_layout *layout,
+ const uint32_t *pitches)
{
if (!layout || !fmt) {
DRM_ERROR("invalid pointer\n");
@@ -776,7 +789,7 @@
if (SDE_FORMAT_IS_UBWC(fmt) || SDE_FORMAT_IS_TILE(fmt))
return _sde_format_get_plane_sizes_ubwc(fmt, w, h, layout);
- return _sde_format_get_plane_sizes_linear(fmt, w, h, layout);
+ return _sde_format_get_plane_sizes_linear(fmt, w, h, layout, pitches);
}
int sde_format_get_block_size(const struct sde_format *fmt,
@@ -801,6 +814,7 @@
const uint32_t format,
const uint32_t width,
const uint32_t height,
+ const uint32_t *pitches,
const uint64_t *modifiers,
const uint32_t modifiers_len)
{
@@ -811,7 +825,10 @@
if (!fmt)
return 0;
- if (sde_format_get_plane_sizes(fmt, width, height, &layout))
+ if (!pitches)
+ return -EINVAL;
+
+ if (sde_format_get_plane_sizes(fmt, width, height, &layout, pitches))
layout.total_size = 0;
return layout.total_size;
@@ -917,7 +934,7 @@
/* Can now check the pitches given vs pitches expected */
for (i = 0; i < layout->num_planes; ++i) {
- if (layout->plane_pitch[i] != fb->pitches[i]) {
+ if (layout->plane_pitch[i] > fb->pitches[i]) {
DRM_ERROR("plane %u expected pitch %u, fb %u\n",
i, layout->plane_pitch[i], fb->pitches[i]);
return -EINVAL;
@@ -959,7 +976,7 @@
/* Populate the plane sizes etc via get_format */
ret = sde_format_get_plane_sizes(layout->format, fb->width, fb->height,
- layout);
+ layout, fb->pitches);
if (ret)
return ret;
@@ -1063,7 +1080,7 @@
num_base_fmt_planes = drm_format_num_planes(fmt->base.pixel_format);
ret = sde_format_get_plane_sizes(fmt, cmd->width, cmd->height,
- &layout);
+ &layout, cmd->pitches);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/msm/sde/sde_formats.h b/drivers/gpu/drm/msm/sde/sde_formats.h
index 2333a72..58065ab 100644
--- a/drivers/gpu/drm/msm/sde/sde_formats.h
+++ b/drivers/gpu/drm/msm/sde/sde_formats.h
@@ -64,6 +64,8 @@
* @w: width of the buffer
* @h: height of the buffer
* @layout: layout of the buffer
+ * @pitches: array of size [SDE_MAX_PLANES] to populate
+ * pitch for each plane
*
* Return: size of the buffer
*/
@@ -71,7 +73,8 @@
const struct sde_format *fmt,
const uint32_t w,
const uint32_t h,
- struct sde_hw_fmt_layout *layout);
+ struct sde_hw_fmt_layout *layout,
+ const uint32_t *pitches);
/**
* sde_format_get_block_size - get block size of given format when
@@ -137,6 +140,8 @@
* @format: DRM pixel format
* @width: pixel width
* @height: pixel height
+ * @pitches: array of size [SDE_MAX_PLANES] to populate
+ * pitch for each plane
* @modifiers: array to populate with drm modifiers, can be NULL
* @modifiers_len: length of modifers array
*
@@ -146,6 +151,7 @@
const uint32_t format,
const uint32_t width,
const uint32_t height,
+ const uint32_t *pitches,
const uint64_t *modifiers,
const uint32_t modifiers_len);
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 42af245..da1761d 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -1135,7 +1135,7 @@
}
ret = sde_format_get_plane_sizes(fbo->fmt, fbo->width, fbo->height,
- &fbo->layout);
+ &fbo->layout, fbo->layout.plane_pitch);
if (ret) {
SDE_ERROR("failed to get plane sizes\n");
goto done;