drm/msm/sde: add virtual writeback device and connector
Enable virtual writeback connector by allowing a property on the
connector to specify output frame buffer id, which takes in a
framebuffer object added via ADDFB2 ioctl. A new writeback
configure ioctl is added to configure connection state and
display modes of writeback connector.
Change-Id: Ifce411a3f0798e3af7dd7f19da27d67cdd849bfb
Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
Signed-off-by: Alan Kwong <akwong@codeaurora.org>
Signed-off-by: Clarence Ip <cip@codeaurora.org>
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
Signed-off-by: Narendra Muppalla <narendram@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde/sde_formats.c b/drivers/gpu/drm/msm/sde/sde_formats.c
index 5655a8a..6d9c574 100644
--- a/drivers/gpu/drm/msm/sde/sde_formats.c
+++ b/drivers/gpu/drm/msm/sde/sde_formats.c
@@ -363,6 +363,9 @@
uint32_t *v_sample,
uint32_t *h_sample)
{
+ if (!v_sample || !h_sample)
+ return;
+
switch (chroma_sample) {
case SDE_CHROMA_H2V1:
*v_sample = 1;
@@ -702,6 +705,69 @@
return ret;
}
+static void _sde_format_calc_offset_linear(struct sde_hw_fmt_layout *source,
+ u32 x, u32 y)
+{
+ if ((x == 0) && (y == 0))
+ return;
+
+ source->plane_addr[0] += y * source->plane_pitch[0];
+
+ if (source->num_planes == 1) {
+ source->plane_addr[0] += x * source->format->bpp;
+ } else {
+ uint32_t xoff, yoff;
+ uint32_t v_subsample = 1;
+ uint32_t h_subsample = 1;
+
+ _sde_get_v_h_subsample_rate(source->format->chroma_sample,
+ &v_subsample, &h_subsample);
+
+ xoff = x / h_subsample;
+ yoff = y / v_subsample;
+
+ source->plane_addr[0] += x;
+ source->plane_addr[1] += xoff +
+ (yoff * source->plane_pitch[1]);
+ if (source->num_planes == 2) /* pseudo planar */
+ source->plane_addr[1] += xoff;
+ else /* planar */
+ source->plane_addr[2] += xoff +
+ (yoff * source->plane_pitch[2]);
+ }
+}
+
+int sde_format_populate_layout_with_roi(
+ int mmu_id,
+ struct drm_framebuffer *fb,
+ struct sde_rect *roi,
+ struct sde_hw_fmt_layout *layout)
+{
+ int ret;
+
+ ret = sde_format_populate_layout(mmu_id, fb, layout);
+ if (ret || !roi)
+ return ret;
+
+ if (!roi->w || !roi->h || (roi->x + roi->w > fb->width) ||
+ (roi->y + roi->h > fb->height)) {
+ DRM_ERROR("invalid roi=[%d,%d,%d,%d], fb=[%u,%u]\n",
+ roi->x, roi->y, roi->w, roi->h,
+ fb->width, fb->height);
+ ret = -EINVAL;
+ } else if (SDE_FORMAT_IS_LINEAR(layout->format)) {
+ _sde_format_calc_offset_linear(layout, roi->x, roi->y);
+ layout->width = roi->w;
+ layout->height = roi->h;
+ } else if (roi->x || roi->y || (roi->w != fb->width) ||
+ (roi->h != fb->height)) {
+ DRM_ERROR("non-linear layout with roi not supported\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
int sde_format_check_modified_format(
const struct msm_kms *kms,
const struct msm_format *msm_fmt,