mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-29 10:08:59 +00:00
7d7aa2fd92
This change makes the names of Broadcom targets consistent by using the common notation based on SoC/CPU ID (which is used internally anyway), bcmXXXX instead of brcmXXXX. This is even used for target TITLE in make menuconfig already, only the short target name used brcm so far. Despite, since subtargets range from bcm2708 to bcm2711, it seems appropriate to use bcm27xx instead of bcm2708 (again, as already done for BOARDNAME). This also renames the packages brcm2708-userland and brcm2708-gpu-fw. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de> Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
186 lines
6.1 KiB
Diff
186 lines
6.1 KiB
Diff
From 0d592a7685e41d0bb1816a4fedb11d3570474417 Mon Sep 17 00:00:00 2001
|
|
From: Boris Brezillon <boris.brezillon@bootlin.com>
|
|
Date: Thu, 6 Dec 2018 15:24:38 +0100
|
|
Subject: [PATCH] drm/vc4: Take margin setup into account when updating
|
|
planes
|
|
|
|
Commit 666e73587f90f42d90385c1bea1009a650bf73f4 upstream.
|
|
|
|
Applyin margins is just a matter of scaling all planes appropriately
|
|
and adjusting the CRTC X/Y offset to account for the
|
|
left/right/top/bottom borders.
|
|
|
|
Create a vc4_plane_margins_adj() function doing that and call it from
|
|
vc4_plane_setup_clipping_and_scaling() so that we are ready to attach
|
|
margins properties to the HDMI connector.
|
|
|
|
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
|
|
Reviewed-by: Eric Anholt <eric@anholt.net>
|
|
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
|
|
Link: https://patchwork.freedesktop.org/patch/msgid/20181206142439.10441-5-boris.brezillon@bootlin.com
|
|
---
|
|
drivers/gpu/drm/vc4/vc4_crtc.c | 43 +++++++++++++++++++++++++++
|
|
drivers/gpu/drm/vc4/vc4_drv.h | 3 ++
|
|
drivers/gpu/drm/vc4/vc4_plane.c | 51 +++++++++++++++++++++++++++++++++
|
|
3 files changed, 97 insertions(+)
|
|
|
|
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
|
|
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
|
|
@@ -48,6 +48,13 @@ struct vc4_crtc_state {
|
|
struct drm_mm_node mm;
|
|
bool feed_txp;
|
|
bool txp_armed;
|
|
+
|
|
+ struct {
|
|
+ unsigned int left;
|
|
+ unsigned int right;
|
|
+ unsigned int top;
|
|
+ unsigned int bottom;
|
|
+ } margins;
|
|
};
|
|
|
|
static inline struct vc4_crtc_state *
|
|
@@ -623,6 +630,37 @@ static enum drm_mode_status vc4_crtc_mod
|
|
return MODE_OK;
|
|
}
|
|
|
|
+void vc4_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_crtc_get_margins() might be called before
|
|
+ * vc4_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_crtc_atomic_check(struct drm_crtc *crtc,
|
|
struct drm_crtc_state *state)
|
|
{
|
|
@@ -670,6 +708,10 @@ static int vc4_crtc_atomic_check(struct
|
|
vc4_state->feed_txp = false;
|
|
}
|
|
|
|
+ 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;
|
|
}
|
|
|
|
@@ -971,6 +1013,7 @@ static struct drm_crtc_state *vc4_crtc_d
|
|
|
|
old_vc4_state = to_vc4_crtc_state(crtc->state);
|
|
vc4_state->feed_txp = old_vc4_state->feed_txp;
|
|
+ vc4_state->margins = old_vc4_state->margins;
|
|
|
|
__drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base);
|
|
return &vc4_state->base;
|
|
--- a/drivers/gpu/drm/vc4/vc4_drv.h
|
|
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
|
|
@@ -705,6 +705,9 @@ bool vc4_crtc_get_scanoutpos(struct drm_
|
|
const struct drm_display_mode *mode);
|
|
void vc4_crtc_handle_vblank(struct vc4_crtc *crtc);
|
|
void vc4_crtc_txp_armed(struct drm_crtc_state *state);
|
|
+void vc4_crtc_get_margins(struct drm_crtc_state *state,
|
|
+ unsigned int *right, unsigned int *left,
|
|
+ unsigned int *top, unsigned int *bottom);
|
|
|
|
/* vc4_debugfs.c */
|
|
int vc4_debugfs_init(struct drm_minor *minor);
|
|
--- a/drivers/gpu/drm/vc4/vc4_plane.c
|
|
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
|
|
@@ -258,6 +258,52 @@ static u32 vc4_get_scl_field(struct drm_
|
|
}
|
|
}
|
|
|
|
+static int vc4_plane_margins_adj(struct drm_plane_state *pstate)
|
|
+{
|
|
+ struct vc4_plane_state *vc4_pstate = to_vc4_plane_state(pstate);
|
|
+ unsigned int left, right, top, bottom, adjhdisplay, adjvdisplay;
|
|
+ struct drm_crtc_state *crtc_state;
|
|
+
|
|
+ crtc_state = drm_atomic_get_new_crtc_state(pstate->state,
|
|
+ pstate->crtc);
|
|
+
|
|
+ vc4_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);
|
|
+ vc4_pstate->crtc_x = DIV_ROUND_CLOSEST(vc4_pstate->crtc_x *
|
|
+ adjhdisplay,
|
|
+ crtc_state->mode.hdisplay);
|
|
+ vc4_pstate->crtc_x += left;
|
|
+ if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - left)
|
|
+ vc4_pstate->crtc_x = crtc_state->mode.hdisplay - left;
|
|
+
|
|
+ adjvdisplay = crtc_state->mode.vdisplay - (top + bottom);
|
|
+ vc4_pstate->crtc_y = DIV_ROUND_CLOSEST(vc4_pstate->crtc_y *
|
|
+ adjvdisplay,
|
|
+ crtc_state->mode.vdisplay);
|
|
+ vc4_pstate->crtc_y += top;
|
|
+ if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - top)
|
|
+ vc4_pstate->crtc_y = crtc_state->mode.vdisplay - top;
|
|
+
|
|
+ vc4_pstate->crtc_w = DIV_ROUND_CLOSEST(vc4_pstate->crtc_w *
|
|
+ adjhdisplay,
|
|
+ crtc_state->mode.hdisplay);
|
|
+ vc4_pstate->crtc_h = DIV_ROUND_CLOSEST(vc4_pstate->crtc_h *
|
|
+ adjvdisplay,
|
|
+ crtc_state->mode.vdisplay);
|
|
+
|
|
+ if (!vc4_pstate->crtc_w || !vc4_pstate->crtc_h)
|
|
+ return -EINVAL;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
|
|
{
|
|
struct drm_plane *plane = state->plane;
|
|
@@ -269,6 +315,7 @@ static int vc4_plane_setup_clipping_and_
|
|
int num_planes = fb->format->num_planes;
|
|
u32 h_subsample = 1;
|
|
u32 v_subsample = 1;
|
|
+ int ret;
|
|
int i;
|
|
|
|
for (i = 0; i < num_planes; i++)
|
|
@@ -292,6 +339,10 @@ static int vc4_plane_setup_clipping_and_
|
|
vc4_state->crtc_w = state->crtc_w;
|
|
vc4_state->crtc_h = state->crtc_h;
|
|
|
|
+ ret = vc4_plane_margins_adj(state);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
vc4_state->x_scaling[0] = vc4_get_scaling_mode(vc4_state->src_w[0],
|
|
vc4_state->crtc_w);
|
|
vc4_state->y_scaling[0] = vc4_get_scaling_mode(vc4_state->src_h[0],
|