From 6bd92608dfce55e530522bbd5c1df0c78b5e323a Mon Sep 17 00:00:00 2001 From: Zhang Yubing Date: Tue, 20 Dec 2022 17:44:10 +0800 Subject: [PATCH] drm/rockchip: drv: get acm and csc info when boot Signed-off-by: Zhang Yubing Change-Id: I03dd5370a86d7a998bd8543c3eb09b1b7a8746c6 --- drivers/gpu/drm/rockchip/rockchip_drm_logo.c | 70 +++++++++++++++++++- drivers/gpu/drm/rockchip/rockchip_drm_logo.h | 3 + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 57 ++++++++++++++++ 3 files changed, 128 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c index 369a3dc76302..2c44fa94f6b1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_logo.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_logo.c @@ -376,6 +376,69 @@ get_framebuffer_by_node(struct drm_device *drm_dev, struct device_node *node) return rockchip_drm_logo_fb_alloc(drm_dev, &mode_cmd, private->logo); } +static void of_parse_post_csc_info(struct device_node *route, struct rockchip_drm_mode_set *set) +{ + int val; + + if (!of_property_read_u32(route, "post-csc,enable", &val)) + set->csc.csc_enable = val; + else + set->csc.csc_enable = 0; + + if (!set->csc.csc_enable) + return; + + if (!of_property_read_u32(route, "post-csc,hue", &val)) + set->csc.hue = val; + else + set->csc.hue = 256; + + if (!of_property_read_u32(route, "post-csc,saturation", &val)) + set->csc.saturation = val; + else + set->csc.saturation = 256; + + if (!of_property_read_u32(route, "post-csc,contrast", &val)) + set->csc.contrast = val; + else + set->csc.contrast = 256; + + if (!of_property_read_u32(route, "post-csc,brightness", &val)) + set->csc.brightness = val; + else + set->csc.brightness = 256; + + if (!of_property_read_u32(route, "post-csc,r-gain", &val)) + set->csc.r_gain = val; + else + set->csc.r_gain = 256; + + if (!of_property_read_u32(route, "post-csc,g-gain", &val)) + set->csc.g_gain = val; + else + set->csc.g_gain = 256; + + if (!of_property_read_u32(route, "post-csc,b-gain", &val)) + set->csc.b_gain = val; + else + set->csc.b_gain = 256; + + if (!of_property_read_u32(route, "post-csc,r-offset", &val)) + set->csc.r_offset = val; + else + set->csc.r_offset = 256; + + if (!of_property_read_u32(route, "post-csc,g-offset", &val)) + set->csc.g_offset = val; + else + set->csc.g_offset = 256; + + if (!of_property_read_u32(route, "post-csc,b-offset", &val)) + set->csc.b_offset = val; + else + set->csc.b_offset = 256; +} + static struct rockchip_drm_mode_set * of_parse_display_resource(struct drm_device *drm_dev, struct device_node *route) { @@ -470,6 +533,8 @@ of_parse_display_resource(struct drm_device *drm_dev, struct device_node *route) else set->hue = 50; + of_parse_post_csc_info(route, set); + set->force_output = of_property_read_bool(route, "force-output"); if (!of_property_read_u32(route, "cubic_lut,offset", &val)) { @@ -746,7 +811,7 @@ static int setup_initial_state(struct drm_device *drm_dev, if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->loader_protect) - priv->crtc_funcs[pipe]->loader_protect(crtc, true, NULL); + priv->crtc_funcs[pipe]->loader_protect(crtc, true, &set->csc); } if (!set->fb) { @@ -994,7 +1059,8 @@ void rockchip_drm_show_logo(struct drm_device *drm_dev) unset); if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->loader_protect) - priv->crtc_funcs[pipe]->loader_protect(crtc, true, NULL); + priv->crtc_funcs[pipe]->loader_protect(crtc, true, + &set->csc); priv->crtc_funcs[pipe]->crtc_close(crtc); if (priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->loader_protect) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_logo.h b/drivers/gpu/drm/rockchip/rockchip_drm_logo.h index 1b0b239e86d8..7e1b1d2dfdf4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_logo.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_logo.h @@ -7,12 +7,15 @@ #ifndef ROCKCHIP_DRM_LOGO_H #define ROCKCHIP_DRM_LOGO_H +#include "rockchip_drm_vop.h" + struct rockchip_drm_mode_set { struct list_head head; struct drm_framebuffer *fb; struct rockchip_drm_sub_dev *sub_dev; struct drm_crtc *crtc; struct drm_display_mode *mode; + struct post_csc csc; int clock; int hdisplay; int vdisplay; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index eb03d91fd5b1..31e4e17619d1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -5878,6 +5878,57 @@ static void vop2_crtc_disable_line_flag_event(struct drm_crtc *crtc) spin_unlock_irqrestore(&vop2->irq_lock, flags); } +static int vop2_crtc_get_inital_acm_info(struct drm_crtc *crtc) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + struct vop2 *vop2 = vp->vop2; + struct post_acm *acm = &vp->acm_info; + s16 *lut_y; + s16 *lut_h; + s16 *lut_s; + u32 value; + int i; + + value = readl(vop2->acm_regs + RK3528_ACM_CTRL); + acm->acm_enable = value & 0x1; + value = readl(vop2->acm_regs + RK3528_ACM_DELTA_RANGE); + acm->y_gain = value & 0x3ff; + acm->h_gain = (value >> 10) & 0x3ff; + acm->s_gain = (value >> 20) & 0x3ff; + + lut_y = &acm->gain_lut_hy[0]; + lut_h = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH]; + lut_s = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH * 2]; + for (i = 0; i < ACM_GAIN_LUT_HY_LENGTH; i++) { + value = readl(vop2->acm_regs + RK3528_ACM_YHS_DEL_HY_SEG0 + (i << 2)); + lut_y[i] = value & 0xff; + lut_h[i] = (value >> 8) & 0xff; + lut_s[i] = (value >> 16) & 0xff; + } + + lut_y = &acm->gain_lut_hs[0]; + lut_h = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH]; + lut_s = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH * 2]; + for (i = 0; i < ACM_GAIN_LUT_HS_LENGTH; i++) { + value = readl(vop2->acm_regs + RK3528_ACM_YHS_DEL_HS_SEG0 + (i << 2)); + lut_y[i] = value & 0xff; + lut_h[i] = (value >> 8) & 0xff; + lut_s[i] = (value >> 16) & 0xff; + } + + lut_y = &acm->delta_lut_h[0]; + lut_h = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH]; + lut_s = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH * 2]; + for (i = 0; i < ACM_DELTA_LUT_H_LENGTH; i++) { + value = readl(vop2->acm_regs + RK3528_ACM_YHS_DEL_HGAIN_SEG0 + (i << 2)); + lut_y[i] = value & 0x3ff; + lut_h[i] = (value >> 12) & 0xff; + lut_s[i] = (value >> 20) & 0x3ff; + } + + return 0; +} + static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data) { struct vop2_video_port *vp = to_vop2_video_port(crtc); @@ -5942,6 +5993,12 @@ static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data) ext_pll->vp_mask |= BIT(vp->id); } drm_crtc_vblank_on(crtc); + if (is_vop3(vop2)) { + if (vp_data->feature & (VOP_FEATURE_POST_ACM)) + vop2_crtc_get_inital_acm_info(crtc); + if (data && (vp_data->feature & VOP_FEATURE_POST_CSC)) + memcpy(&vp->csc_info, data, sizeof(struct post_csc)); + } if (private->cubic_lut[vp->id].enable) { dma_addr_t cubic_lut_mst; struct loader_cubic_lut *cubic_lut = &private->cubic_lut[vp->id];