From 41a8769edad35cbb62dd8418f977f4d3600a2251 Mon Sep 17 00:00:00 2001 From: "yujun.zhang" Date: Thu, 9 Nov 2023 18:11:04 +0800 Subject: [PATCH] drm: fix color space conversion of viu2 [1/1] PD#SWPL-145044 Problem: For viu2 on sm1 & g12b, green color screen if hdmitx gets connected until kernel has been started. Solution: Configure rgb to yuv conversion when mode is enabling and postblend is setting state. Verify: SM1 & G12B Test: DRM-OSD-129 Change-Id: I50d177f4445d83b147e8f161501256ef838d8fa8 Signed-off-by: yujun.zhang --- drivers/drm/meson_crtc.c | 2 + drivers/drm/meson_logo.h | 4 -- drivers/drm/meson_vpu_pipeline.h | 7 +++ drivers/drm/vpu-hw/meson_vpu_postblend.c | 70 +++++++++++++++++++++++- 4 files changed, 78 insertions(+), 5 deletions(-) diff --git a/drivers/drm/meson_crtc.c b/drivers/drm/meson_crtc.c index 849d229d2..d99764262 100644 --- a/drivers/drm/meson_crtc.c +++ b/drivers/drm/meson_crtc.c @@ -428,6 +428,7 @@ static void meson_crtc_atomic_print_state(struct drm_printer *p, drm_printf(p, "\t\tdv-hdr core state:[%d,%d]\n", cstate->crtc_dv_enable, cstate->crtc_hdr_enable); + drm_printf(p, "\t\tvmode=%u, preset_vmode:%u\n", cstate->vmode, cstate->preset_vmode); drm_printf(p, "\tmeson vpu pipeline state:\n"); drm_printf(p, "\t\tenable_blocks=%llu\n", @@ -684,6 +685,7 @@ static void am_meson_crtc_atomic_enable(struct drm_crtc *crtc, } meson_crtc_state->vmode = mode; + pipeline->subs[amcrtc->crtc_index].vmode = mode; memcpy(&pipeline->subs[amcrtc->crtc_index].mode, adjusted_mode, sizeof(struct drm_display_mode)); diff --git a/drivers/drm/meson_logo.h b/drivers/drm/meson_logo.h index 9bf895925..4a2859d3c 100644 --- a/drivers/drm/meson_logo.h +++ b/drivers/drm/meson_logo.h @@ -9,10 +9,6 @@ #define VMODE_NAME_LEN_MAX 64 -#define VPP0 0 -#define VPP1 1 -#define VPP2 2 - struct am_meson_logo { struct page *logo_page; void *vaddr; diff --git a/drivers/drm/meson_vpu_pipeline.h b/drivers/drm/meson_vpu_pipeline.h index 928e6fae5..4a51b21c7 100644 --- a/drivers/drm/meson_vpu_pipeline.h +++ b/drivers/drm/meson_vpu_pipeline.h @@ -72,6 +72,12 @@ enum slice_index { OSD3_SLICE1, }; +enum vpp_index { + VPP0, + VPP1, + VPP2, +}; + enum meson_vpu_blk_type { MESON_BLK_OSD = 0, MESON_BLK_AFBC, @@ -492,6 +498,7 @@ struct meson_vpu_sub_pipeline { struct meson_vpu_pipeline *pipeline; struct drm_display_mode mode; struct rdma_reg_ops *reg_ops; + enum vmode_e vmode; }; struct meson_vpu_pipeline_ops { diff --git a/drivers/drm/vpu-hw/meson_vpu_postblend.c b/drivers/drm/vpu-hw/meson_vpu_postblend.c index 959bbdaf3..645410801 100644 --- a/drivers/drm/vpu-hw/meson_vpu_postblend.c +++ b/drivers/drm/vpu-hw/meson_vpu_postblend.c @@ -726,6 +726,74 @@ static void postblend_hw_disable(struct meson_vpu_block *vblk, } #ifndef CONFIG_AMLOGIC_ZAPPER_CUT + +#define MATRIX_5x3_COEF_SIZE 24 + +static int RGB709_to_YUV709l_coeff[MATRIX_5x3_COEF_SIZE] = { + 0, 0, 0, /* pre offset */ + 186, 627, 63, + -102, -344, 448, + 448, -406, -40, + 0, 0, 0, /* 10'/11'/12' */ + 0, 0, 0, /* 20'/21'/22' */ + 64, 512, 512, /* offset */ + 0, 0, 0 /* mode, right_shift, clip_en */ +}; + +/* color conversion of viu2 on sm1, g12b */ +static void set_viu2_osd_matrix_rgb2yuv(bool on) +{ + int *m = RGB709_to_YUV709l_coeff; + + /* RGB -> 709 limit */ + /* VPP WRAP OSD3 matrix */ + meson_drm_write_reg(VIU2_OSD1_MATRIX_PRE_OFFSET0_1, + ((m[0] & 0xfff) << 16) | (m[1] & 0xfff)); + meson_drm_write_reg(VIU2_OSD1_MATRIX_PRE_OFFSET2, + m[2] & 0xfff); + meson_drm_write_reg(VIU2_OSD1_MATRIX_COEF00_01, + ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff)); + meson_drm_write_reg(VIU2_OSD1_MATRIX_COEF02_10, + ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff)); + meson_drm_write_reg(VIU2_OSD1_MATRIX_COEF11_12, + ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff)); + meson_drm_write_reg(VIU2_OSD1_MATRIX_COEF20_21, + ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff)); + meson_drm_write_reg(VIU2_OSD1_MATRIX_COEF22, + m[11] & 0x1fff); + + meson_drm_write_reg(VIU2_OSD1_MATRIX_OFFSET0_1, + ((m[18] & 0xfff) << 16) | (m[19] & 0xfff)); + meson_drm_write_reg(VIU2_OSD1_MATRIX_OFFSET2, + m[20] & 0xfff); + + meson_drm_write_reg_bits(VIU2_OSD1_MATRIX_EN_CTRL, on, 0, 1); +} + +static void g12b_postblend_set_state(struct meson_vpu_block *vblk, + struct meson_vpu_block_state *state, + struct meson_vpu_block_state *old_state) +{ + int crtc_index; + enum vmode_e mode; + + crtc_index = vblk->index; + mode = state->sub->vmode; + mode &= VMODE_MODE_BIT_MASK; + + postblend_set_state(vblk, state, old_state); + + /* viu2 on g12b or sm1 */ + if (crtc_index == VPP1) { + if (mode == VMODE_HDMI) + set_viu2_osd_matrix_rgb2yuv(true); + else + set_viu2_osd_matrix_rgb2yuv(false); + } + + MESON_DRM_BLOCK("g12b postblend set state done!\n"); +} + static void g12b_postblend_hw_disable(struct meson_vpu_block *vblk, struct meson_vpu_block_state *state) { @@ -1153,7 +1221,7 @@ struct meson_vpu_block_ops postblend_ops = { #ifndef CONFIG_AMLOGIC_ZAPPER_CUT struct meson_vpu_block_ops g12b_postblend_ops = { .check_state = postblend_check_state, - .update_state = postblend_set_state, + .update_state = g12b_postblend_set_state, .enable = postblend_hw_enable, .disable = g12b_postblend_hw_disable, .dump_register = postblend_dump_register,