diff options
author | Álvaro Fernández Rojas <noltari@gmail.com> | 2020-03-16 20:41:03 +0100 |
---|---|---|
committer | Álvaro Fernández Rojas <noltari@gmail.com> | 2020-03-16 21:24:23 +0100 |
commit | 0f6d04457a64f2393b05f662dc8d381ea1963c66 (patch) | |
tree | 2d6a3c82d5e6d02b030b16df66da8bf9209b02ec /target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-Add-support-for-margins-to-fkms.patch | |
parent | d890f85e59617228b1e76e8cf45a9309904d9124 (diff) | |
download | upstream-0f6d04457a64f2393b05f662dc8d381ea1963c66.tar.gz upstream-0f6d04457a64f2393b05f662dc8d381ea1963c66.tar.bz2 upstream-0f6d04457a64f2393b05f662dc8d381ea1963c66.zip |
bcm27xx: sync 5.4 patches with RPi Foundation
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-Add-support-for-margins-to-fkms.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-Add-support-for-margins-to-fkms.patch | 328 |
1 files changed, 0 insertions, 328 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-Add-support-for-margins-to-fkms.patch b/target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-Add-support-for-margins-to-fkms.patch deleted file mode 100644 index 968eb3ff55..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0286-drm-vc4-Add-support-for-margins-to-fkms.patch +++ /dev/null @@ -1,328 +0,0 @@ -From 8a7170d2ad05ae00733e0535b281ce2e682c6f65 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson <dave.stevenson@raspberrypi.org> -Date: Fri, 19 Jul 2019 15:35:13 +0100 -Subject: [PATCH] drm/vc4: Add support for margins to fkms - -Allows for overscan to be configured under FKMS. -NB This is rescaling the planes, not reducing the size of the -display mode. - -Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 241 +++++++++++++++++++------ - 1 file changed, 190 insertions(+), 51 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -259,6 +259,23 @@ static inline struct vc4_crtc *to_vc4_cr - return container_of(crtc, struct vc4_crtc, base); - } - -+struct vc4_crtc_state { -+ struct drm_crtc_state base; -+ -+ struct { -+ unsigned int left; -+ unsigned int right; -+ unsigned int top; -+ unsigned int bottom; -+ } margins; -+}; -+ -+static inline struct vc4_crtc_state * -+to_vc4_crtc_state(struct drm_crtc_state *crtc_state) -+{ -+ return (struct vc4_crtc_state *)crtc_state; -+} -+ - struct vc4_fkms_encoder { - struct drm_encoder base; - bool hdmi_monitor; -@@ -367,17 +384,127 @@ static int vc4_plane_set_blank(struct dr - return ret; - } - -+static void vc4_fkms_crtc_get_margins(struct drm_crtc_state *state, -+ unsigned int *left, unsigned int *right, -+ unsigned int *top, unsigned int *bottom) -+{ -+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); -+ struct drm_connector_state *conn_state; -+ struct drm_connector *conn; -+ int i; -+ -+ *left = vc4_state->margins.left; -+ *right = vc4_state->margins.right; -+ *top = vc4_state->margins.top; -+ *bottom = vc4_state->margins.bottom; -+ -+ /* We have to interate over all new connector states because -+ * vc4_fkms_crtc_get_margins() might be called before -+ * vc4_fkms_crtc_atomic_check() which means margins info in -+ * vc4_crtc_state might be outdated. -+ */ -+ for_each_new_connector_in_state(state->state, conn, conn_state, i) { -+ if (conn_state->crtc != state->crtc) -+ continue; -+ -+ *left = conn_state->tv.margins.left; -+ *right = conn_state->tv.margins.right; -+ *top = conn_state->tv.margins.top; -+ *bottom = conn_state->tv.margins.bottom; -+ break; -+ } -+} -+ -+static int vc4_fkms_margins_adj(struct drm_plane_state *pstate, -+ struct set_plane *plane) -+{ -+ unsigned int left, right, top, bottom; -+ int adjhdisplay, adjvdisplay; -+ struct drm_crtc_state *crtc_state; -+ -+ crtc_state = drm_atomic_get_new_crtc_state(pstate->state, -+ pstate->crtc); -+ -+ vc4_fkms_crtc_get_margins(crtc_state, &left, &right, &top, &bottom); -+ -+ if (!left && !right && !top && !bottom) -+ return 0; -+ -+ if (left + right >= crtc_state->mode.hdisplay || -+ top + bottom >= crtc_state->mode.vdisplay) -+ return -EINVAL; -+ -+ adjhdisplay = crtc_state->mode.hdisplay - (left + right); -+ plane->dst_x = DIV_ROUND_CLOSEST(plane->dst_x * adjhdisplay, -+ (int)crtc_state->mode.hdisplay); -+ plane->dst_x += left; -+ if (plane->dst_x > (int)(crtc_state->mode.hdisplay - left)) -+ plane->dst_x = crtc_state->mode.hdisplay - left; -+ -+ adjvdisplay = crtc_state->mode.vdisplay - (top + bottom); -+ plane->dst_y = DIV_ROUND_CLOSEST(plane->dst_y * adjvdisplay, -+ (int)crtc_state->mode.vdisplay); -+ plane->dst_y += top; -+ if (plane->dst_y > (int)(crtc_state->mode.vdisplay - top)) -+ plane->dst_y = crtc_state->mode.vdisplay - top; -+ -+ plane->dst_w = DIV_ROUND_CLOSEST(plane->dst_w * adjhdisplay, -+ crtc_state->mode.hdisplay); -+ plane->dst_h = DIV_ROUND_CLOSEST(plane->dst_h * adjvdisplay, -+ crtc_state->mode.vdisplay); -+ -+ if (!plane->dst_w || !plane->dst_h) -+ return -EINVAL; -+ -+ return 0; -+} -+ - static void vc4_plane_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) - { - struct drm_plane_state *state = plane->state; -+ -+ /* -+ * Do NOT set now, as we haven't checked if the crtc is active or not. -+ * Set from vc4_plane_set_blank instead. -+ * -+ * If the CRTC is on (or going to be on) and we're enabled, -+ * then unblank. Otherwise, stay blank until CRTC enable. -+ */ -+ if (state->crtc->state->active) -+ vc4_plane_set_blank(plane, false); -+} -+ -+static void vc4_plane_atomic_disable(struct drm_plane *plane, -+ struct drm_plane_state *old_state) -+{ -+ struct drm_plane_state *state = plane->state; -+ struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); -+ -+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane disable %dx%d@%d +%d,%d\n", -+ plane->base.id, plane->name, -+ state->crtc_w, -+ state->crtc_h, -+ vc4_plane->mb.plane.vc_image_type, -+ state->crtc_x, -+ state->crtc_y); -+ vc4_plane_set_blank(plane, true); -+} -+ -+static bool plane_enabled(struct drm_plane_state *state) -+{ -+ return state->fb && state->crtc; -+} -+ -+static int vc4_plane_to_mb(struct drm_plane *plane, -+ struct mailbox_set_plane *mb, -+ struct drm_plane_state *state) -+{ - struct drm_framebuffer *fb = state->fb; - struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); - const struct drm_format_info *drm_fmt = fb->format; - const struct vc_image_format *vc_fmt = - vc4_get_vc_image_fmt(drm_fmt->format); -- struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); -- struct mailbox_set_plane *mb = &vc4_plane->mb; - int num_planes = fb->format->num_planes; - struct drm_display_mode *mode = &state->crtc->mode; - unsigned int rotation = SUPPORTED_ROTATIONS; -@@ -419,25 +546,7 @@ static void vc4_plane_atomic_update(stru - break; - } - -- /* FIXME: If the dest rect goes off screen then clip the src rect so we -- * don't have off-screen pixels. -- */ -- if (plane->type == DRM_PLANE_TYPE_CURSOR) { -- /* There is no scaling on the cursor plane, therefore the calcs -- * to alter the source crop as the cursor goes off the screen -- * are simple. -- */ -- if (mb->plane.dst_x + mb->plane.dst_w > mode->hdisplay) { -- mb->plane.dst_w = mode->hdisplay - mb->plane.dst_x; -- mb->plane.src_w = (mode->hdisplay - mb->plane.dst_x) -- << 16; -- } -- if (mb->plane.dst_y + mb->plane.dst_h > mode->vdisplay) { -- mb->plane.dst_h = mode->vdisplay - mb->plane.dst_y; -- mb->plane.src_h = (mode->vdisplay - mb->plane.dst_y) -- << 16; -- } -- } -+ vc4_fkms_margins_adj(state, &mb->plane); - - if (num_planes > 1) { - /* Assume this must be YUV */ -@@ -527,38 +636,19 @@ static void vc4_plane_atomic_update(stru - state->alpha, - state->normalized_zpos); - -- /* -- * Do NOT set now, as we haven't checked if the crtc is active or not. -- * Set from vc4_plane_set_blank instead. -- * -- * If the CRTC is on (or going to be on) and we're enabled, -- * then unblank. Otherwise, stay blank until CRTC enable. -- */ -- if (state->crtc->state->active) -- vc4_plane_set_blank(plane, false); -+ return 0; - } - --static void vc4_plane_atomic_disable(struct drm_plane *plane, -- struct drm_plane_state *old_state) -+static int vc4_plane_atomic_check(struct drm_plane *plane, -+ struct drm_plane_state *state) - { -- //struct vc4_dev *vc4 = to_vc4_dev(plane->dev); -- struct drm_plane_state *state = plane->state; - struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); - -- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane disable %dx%d@%d +%d,%d\n", -- plane->base.id, plane->name, -- state->crtc_w, -- state->crtc_h, -- vc4_plane->mb.plane.vc_image_type, -- state->crtc_x, -- state->crtc_y); -- vc4_plane_set_blank(plane, true); --} -+ if (!plane_enabled(state)) -+ return 0; -+ -+ return vc4_plane_to_mb(plane, &vc4_plane->mb, state); - --static int vc4_plane_atomic_check(struct drm_plane *plane, -- struct drm_plane_state *state) --{ -- return 0; - } - - /* Called during init to allocate the plane's atomic state. */ -@@ -909,8 +999,23 @@ vc4_crtc_mode_valid(struct drm_crtc *crt - static int vc4_crtc_atomic_check(struct drm_crtc *crtc, - struct drm_crtc_state *state) - { -- DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_check.\n", -- crtc->base.id); -+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); -+ struct drm_connector *conn; -+ struct drm_connector_state *conn_state; -+ int i; -+ -+ DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_check.\n", crtc->base.id); -+ -+ for_each_new_connector_in_state(state->state, conn, conn_state, i) { -+ if (conn_state->crtc != crtc) -+ continue; -+ -+ vc4_state->margins.left = conn_state->tv.margins.left; -+ vc4_state->margins.right = conn_state->tv.margins.right; -+ vc4_state->margins.top = conn_state->tv.margins.top; -+ vc4_state->margins.bottom = conn_state->tv.margins.bottom; -+ break; -+ } - return 0; - } - -@@ -1011,6 +1116,33 @@ static int vc4_page_flip(struct drm_crtc - return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx); - } - -+static struct drm_crtc_state * -+vc4_crtc_duplicate_state(struct drm_crtc *crtc) -+{ -+ struct vc4_crtc_state *vc4_state, *old_vc4_state; -+ -+ vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL); -+ if (!vc4_state) -+ return NULL; -+ -+ old_vc4_state = to_vc4_crtc_state(crtc->state); -+ vc4_state->margins = old_vc4_state->margins; -+ -+ __drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base); -+ return &vc4_state->base; -+} -+ -+static void -+vc4_crtc_reset(struct drm_crtc *crtc) -+{ -+ if (crtc->state) -+ __drm_atomic_helper_crtc_destroy_state(crtc->state); -+ -+ crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL); -+ if (crtc->state) -+ crtc->state->crtc = crtc; -+} -+ - static int vc4_fkms_enable_vblank(struct drm_crtc *crtc) - { - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -@@ -1038,8 +1170,8 @@ static const struct drm_crtc_funcs vc4_c - .set_property = NULL, - .cursor_set = NULL, /* handled by drm_mode_cursor_universal */ - .cursor_move = NULL, /* handled by drm_mode_cursor_universal */ -- .reset = drm_atomic_helper_crtc_reset, -- .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, -+ .reset = vc4_crtc_reset, -+ .atomic_duplicate_state = vc4_crtc_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, - .enable_vblank = vc4_fkms_enable_vblank, - .disable_vblank = vc4_fkms_disable_vblank, -@@ -1291,6 +1423,13 @@ vc4_fkms_connector_init(struct drm_devic - connector->interlace_allowed = 0; - } - -+ /* Create and attach TV margin props to this connector. */ -+ ret = drm_mode_create_tv_margin_properties(dev); -+ if (ret) -+ return ERR_PTR(ret); -+ -+ drm_connector_attach_tv_margin_properties(connector); -+ - connector->polled = (DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT); - |