From b0d79ebe7097de33e7958356eb89359c926005dd Mon Sep 17 00:00:00 2001 From: Damon Ding Date: Thu, 20 Mar 2025 09:24:06 +0800 Subject: [PATCH] drm/rockchip: logo: support to use the win scale to configure overscan parameters For some platforms, such as RK3576, use the win scale instead of the post scale to configure overscan parameters, because the sharp/post scale/split functions are mutually exclusice. Change-Id: If422749ed8defc553924f14f24ab173913b2dcad Signed-off-by: Damon Ding --- drivers/gpu/drm/rockchip/rockchip_drm_logo.c | 35 ++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c index b39036d9b3fd..1be914c14841 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c @@ -772,7 +772,8 @@ static void rockchip_drm_mode_fixup(struct drm_crtc_state *crtc_state, static int setup_initial_state(struct drm_device *drm_dev, struct drm_atomic_state *state, - struct rockchip_drm_mode_set *set) + struct rockchip_drm_mode_set *set, + struct device_node *route) { struct rockchip_drm_private *priv = drm_dev->dev_private; struct drm_connector *connector = set->sub_dev->connector; @@ -785,8 +786,11 @@ static int setup_initial_state(struct drm_device *drm_dev, const struct drm_connector_helper_funcs *funcs; int pipe = drm_crtc_index(crtc); bool is_crtc_enabled = true; + u32 overscan_by_win_scale = 0; int hdisplay, vdisplay; int fb_width, fb_height; + int overscan_w, overscan_h; + int crtc_x, crtc_y, crtc_w, crtc_h; int found = 0, match = 0; int num_modes; int ret = 0; @@ -938,6 +942,33 @@ static int setup_initial_state(struct drm_device *drm_dev, primary_state->crtc_w = hdisplay; primary_state->crtc_h = vdisplay; } + + /* + * For some platforms, such as RK3576, use the win scale instead + * of the post scale to configure overscan parameters, because the + * sharp/post scale/split functions are mutually exclusice. + */ + of_property_read_u32(route, "overscan,win_scale", &overscan_by_win_scale); + if (overscan_by_win_scale) { + overscan_w = primary_state->crtc_w * (200 - set->left_margin * 2) / 200; + overscan_h = primary_state->crtc_h * (200 - set->top_margin * 2) / 200; + + crtc_x = primary_state->crtc_x + overscan_w / 2; + crtc_y = primary_state->crtc_y + overscan_h / 2; + crtc_w = primary_state->crtc_w - overscan_w; + crtc_h = primary_state->crtc_h - overscan_h; + + primary_state->crtc_x = crtc_x; + primary_state->crtc_y = crtc_y; + primary_state->crtc_w = crtc_w; + primary_state->crtc_h = crtc_h; + + set->left_margin = 100; + set->right_margin = 100; + set->top_margin = 100; + set->bottom_margin = 100; + } + s = to_rockchip_crtc_state(crtc->state); s->output_type = connector->connector_type; @@ -1100,7 +1131,7 @@ void rockchip_drm_show_logo(struct drm_device *drm_dev) if (!set) continue; - if (setup_initial_state(drm_dev, state, set)) { + if (setup_initial_state(drm_dev, state, set, route)) { drm_framebuffer_put(set->fb); INIT_LIST_HEAD(&set->head); list_add_tail(&set->head, &mode_unset_list);