diff --git a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301.dts b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301.dts index 59e620f40..ed982ccfa 100644 --- a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301.dts +++ b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301.dts @@ -1487,6 +1487,7 @@ wb_sel = <0>;/*1:mtx ;0:gainoff*/ vlock_en = <1>;/*1:enable;0:disable*/ vlock_mode = <0x8>; + vrr_priority = <1>;/*1:game mode vrr always on;0:vrr on depend on vrr signal*/ /*vlock work mode: *bit0:auto ENC *bit1:auto PLL diff --git a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1.5g.dts b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1.5g.dts index 8135daed9..5614d7f0c 100644 --- a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1.5g.dts +++ b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1.5g.dts @@ -1489,6 +1489,7 @@ wb_sel = <0>;/*1:mtx ;0:gainoff*/ vlock_en = <1>;/*1:enable;0:disable*/ vlock_mode = <0x8>; + vrr_priority = <1>;/*1:game mode vrr always on;0:vrr on depend on vrr signal*/ /*vlock work mode: *bit0:auto ENC *bit1:auto PLL diff --git a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1.5g_R.dts b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1.5g_R.dts index 8a04af43b..a3dbb266f 100644 --- a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1.5g_R.dts +++ b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1.5g_R.dts @@ -1489,6 +1489,7 @@ wb_sel = <0>;/*1:mtx ;0:gainoff*/ vlock_en = <1>;/*1:enable;0:disable*/ vlock_mode = <0x8>; + vrr_priority = <1>;/*1:game mode vrr always on;0:vrr on depend on vrr signal*/ /*vlock work mode: *bit0:auto ENC *bit1:auto PLL diff --git a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1g.dts b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1g.dts index 77d47b948..93cb1b501 100644 --- a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1g.dts +++ b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1g.dts @@ -1491,6 +1491,7 @@ wb_sel = <0>;/*1:mtx ;0:gainoff*/ vlock_en = <1>;/*1:enable;0:disable*/ vlock_mode = <0x8>; + vrr_priority = <1>;/*1:game mode vrr always on;0:vrr on depend on vrr signal*/ /*vlock work mode: *bit0:auto ENC *bit1:auto PLL diff --git a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1g_R.dts b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1g_R.dts index eaf94b0a9..dbfeb9d0d 100644 --- a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1g_R.dts +++ b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_1g_R.dts @@ -1491,6 +1491,7 @@ wb_sel = <0>;/*1:mtx ;0:gainoff*/ vlock_en = <1>;/*1:enable;0:disable*/ vlock_mode = <0x8>; + vrr_priority = <1>;/*1:game mode vrr always on;0:vrr on depend on vrr signal*/ /*vlock work mode: *bit0:auto ENC *bit1:auto PLL diff --git a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_R.dts b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_R.dts index 12364233a..8feabbdc6 100644 --- a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_R.dts +++ b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_R.dts @@ -1487,6 +1487,7 @@ wb_sel = <0>;/*1:mtx ;0:gainoff*/ vlock_en = <1>;/*1:enable;0:disable*/ vlock_mode = <0x8>; + vrr_priority = <1>;/*1:game mode vrr always on;0:vrr on depend on vrr signal*/ /*vlock work mode: *bit0:auto ENC *bit1:auto PLL diff --git a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_linux.dts b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_linux.dts index d79e0f0a8..26ebec7de 100644 --- a/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_linux.dts +++ b/arch/arm/boot/dts/amlogic/t5w_t962d4_at301_linux.dts @@ -1486,6 +1486,7 @@ wb_sel = <0>;/*1:mtx ;0:gainoff*/ vlock_en = <1>;/*1:enable;0:disable*/ vlock_mode = <0x8>; + vrr_priority = <1>;/*1:game mode vrr always on;0:vrr on depend on vrr signal*/ /*vlock work mode: *bit0:auto ENC *bit1:auto PLL diff --git a/drivers/media/video_processor/video_composer/video_composer.c b/drivers/media/video_processor/video_composer/video_composer.c index 3a3c28e0d..be84dac76 100644 --- a/drivers/media/video_processor/video_composer/video_composer.c +++ b/drivers/media/video_processor/video_composer/video_composer.c @@ -56,6 +56,9 @@ #endif #include "videodisplay.h" +#ifdef CONFIG_AMLOGIC_MEDIA_VRR +#include +#endif #define VIDEO_COMPOSER_VERSION "1.0" #define VIDEO_COMPOSER_NAME_SIZE 32 @@ -4346,6 +4349,11 @@ static void video_composer_task(struct composer_dev *dev) vc_print(dev->index, PRINT_AXIS, "===============================\n"); +#ifdef CONFIG_AMLOGIC_MEDIA_VRR + vrr_crop_update_delay_line(frame_info->crop_y, frame_info->dst_y, + frame_info->dst_w, frame_info->dst_h, VRR_AXIS); +#endif + if (is_dec_vf) { /* copy to uvm vf */ vf_ext = vf->uvm_vf; diff --git a/drivers/media/video_sink/video.c b/drivers/media/video_sink/video.c index 8530a4325..f853e844c 100644 --- a/drivers/media/video_sink/video.c +++ b/drivers/media/video_sink/video.c @@ -150,6 +150,10 @@ MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_DEFAULT_LEVEL_DESC, LOG_MASK_DESC); #define RECEIVERPIP_NAME "videopip" #define RECEIVERPIP2_NAME "videopip2" +#ifdef CONFIG_AMLOGIC_MEDIA_VRR +#include +#endif + #define PARSE_MD_IN_ADVANCE 1 #ifdef CONFIG_AML_VSYNC_FIQ_ENABLE @@ -7452,7 +7456,11 @@ static ssize_t video_screen_mode_store(const struct class *cla, return -EINVAL; if (mode < VIDEO_WIDEOPTION_MAX && - mode != layer->wide_mode) { + mode != layer->wide_mode) { + if (mode == VIDEO_WIDEOPTION_NORMAL_NOSCALEUP) +#ifdef CONFIG_AMLOGIC_MEDIA_VRR + vrr_crop_update_delay_line(0, 0, 0, 0, VRR_DOT); +#endif if (debug_flag & DEBUG_FLAG_BASIC_INFO) pr_info("video_screen_mode sysfs:%d->%ld %s\n", layer->wide_mode, mode, current->comm); diff --git a/drivers/media/video_sink/video_func.c b/drivers/media/video_sink/video_func.c index 5b0454814..b682fa458 100644 --- a/drivers/media/video_sink/video_func.c +++ b/drivers/media/video_sink/video_func.c @@ -82,6 +82,9 @@ #if IS_ENABLED(CONFIG_AMLOGIC_DEBUG_IOTRACE) #include #endif +#ifdef CONFIG_AMLOGIC_MEDIA_VRR +#include +#endif #ifndef CONFIG_AMLOGIC_ZAPPER_CUT #if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) @@ -1084,6 +1087,9 @@ void _set_video_crop(struct disp_info_s *layer, int *p) new_b != last_b || new_r != last_r) { if (layer->layer_id == 0) { vd_layer[0].property_changed = true; +#ifdef CONFIG_AMLOGIC_MEDIA_VRR + vrr_crop_update_delay_line(layer->crop_top, 0, 0, 0, VRR_CROP); +#endif } else if (layer->layer_id == 1) { if (vd_layer[1].vpp_index == VPP0) vd_layer[1].property_changed = true; diff --git a/drivers/media/video_sink/vpp.c b/drivers/media/video_sink/vpp.c index efee5a1a9..0473eb2a4 100644 --- a/drivers/media/video_sink/vpp.c +++ b/drivers/media/video_sink/vpp.c @@ -58,9 +58,6 @@ #include "video_common.h" #include "video_safa_reg.h" -#ifdef CONFIG_AMLOGIC_MEDIA_VRR -#include -#endif #include "vpp_pq.h" #include "vpp_post_s5.h" @@ -2291,10 +2288,6 @@ RESTART: next_frame_par->crop_bottom = crop_bottom; } -#ifdef CONFIG_AMLOGIC_MEDIA_VRR - vrr_crop_update_delay_line(crop_top, vpp_index); -#endif - if (vpp_flags & VPP_FLAG_INTERLACE_IN) next_frame_par->VPP_vd_start_lines_ &= ~1; diff --git a/drivers/media/vrr/vrr_drv.c b/drivers/media/vrr/vrr_drv.c index 75222c84e..ae89eb5f7 100644 --- a/drivers/media/vrr/vrr_drv.c +++ b/drivers/media/vrr/vrr_drv.c @@ -54,9 +54,16 @@ unsigned int vrr_debug_print; u32 crop_line; u32 pre_line; +u32 dst_line; +u32 pre_dst_line; +u32 vrr_axis_y; +u32 pre_axis_y; unsigned int vrr_line_dly; u8 vrr_vpp_index; +unsigned int line_change_type; +unsigned int vrr_dot_line = 600; + #define VRR_MNT_MAX 5 static unsigned int vrr_mnt_table[VRR_MNT_MAX] = { VPU_VENCP_STAT, @@ -381,38 +388,41 @@ static void vrr_line_delay_update(struct aml_vrr_drv_s *vdrv) else temp = vrr_reg_getb(reg + offset, 8, 16); - vrr_line_dly = vdrv->line_dly + crop_line; + if (line_change_type == VRR_DOT) + vrr_line_dly = vrr_dot_line; + else if (line_change_type == VRR_AXIS) + vrr_line_dly = dst_line; + else + vrr_line_dly = vdrv->line_dly + crop_line; if (temp == vrr_line_dly) return; - if (crop_line > pre_line) { + if (crop_line > pre_line || dst_line > pre_dst_line) { if (vdrv->data->chip_type == VRR_CHIP_T3X) vrr_reg_setb(VENC_VRR_CTRL_T3X, vrr_line_dly, 16, 32); else vrr_reg_setb(reg, vrr_line_dly, 8, 16); - } else if (crop_line < pre_line) { + } else if (crop_line < pre_line || dst_line < pre_dst_line) { if (vdrv->data->chip_type == VRR_CHIP_T3X) - VSYNC_WRITE_VPP_REG_BITS_VPP_SEL(VENC_VRR_CTRL_T3X, - vrr_line_dly, 16, 32, vrr_vpp_index); + vrr_reg_setb(VENC_VRR_CTRL_T3X, + vrr_line_dly, 16, 32); else - VSYNC_WRITE_VPP_REG_BITS_VPP_SEL(reg, - vrr_line_dly, 8, 16, vrr_vpp_index); + vrr_reg_setb(reg, + vrr_line_dly, 8, 16); } if (vrr_debug_print & VRR_DBG_PR_NORMAL) VRRPR("[%d]: %s: %d->%d\n", vdrv->index, __func__, temp, vrr_line_dly); - - pre_line = crop_line; } -void vrr_crop_update_delay_line(u32 line, u8 vpp_index) +void vrr_crop_update_delay_line(u32 line, u16 axis_y, + u16 dst_w, u16 dst_h, u16 type) { struct aml_vrr_drv_s *vdrv = NULL; vdrv = aml_vrr_drv_active_sel(); - crop_line = line; if (!vdrv) { if (vrr_debug_print & VRR_DBG_PR_NORMAL) @@ -420,17 +430,67 @@ void vrr_crop_update_delay_line(u32 line, u8 vpp_index) return; } + if (!vdrv->vrr_dev) { + if (vrr_debug_print & VRR_DBG_PR_NORMAL) + VRRPR("%s no vrr_dev\n", __func__); + return; + } + + switch (type) { + case VRR_CROP: + crop_line = line; + if (crop_line != pre_line) + line_change_type = VRR_CROP; + + if (vrr_debug_print & VRR_DBG_PR_NORMAL) + VRRPR("%s crop:%d pre:%d\n", __func__, crop_line, pre_line); + break; + + case VRR_AXIS: + if (dst_h <= vdrv->vrr_dev->v_active && dst_h > 0 && axis_y > 0 && + vdrv->vrr_dev->v_active >= dst_h + axis_y) + dst_line = (vdrv->vrr_dev->v_active - dst_h - axis_y) + 200; + else if (dst_h <= vdrv->vrr_dev->v_active && dst_h > 0 && axis_y > 0 && + vdrv->vrr_dev->v_active < dst_h + axis_y) + dst_line = axis_y + 200; + else + dst_line = 200; + + if (dst_line != pre_dst_line) { + line_change_type = VRR_AXIS; + if (vrr_debug_print & VRR_DBG_PR_NORMAL) + VRRPR("%s y:%d w:%d h:%d ac:%d dst:%d pre:%d\n", + __func__, axis_y, dst_w, dst_h, vdrv->vrr_dev->v_active, + dst_line, pre_dst_line); + } + break; + + case VRR_DOT: + line_change_type = VRR_DOT; + if (vrr_debug_print & VRR_DBG_PR_NORMAL) + VRRPR("%s doy by dot change line!\n", __func__); + break; + + default: + break; + } + if (!vdrv->enable) { if (vrr_debug_print & VRR_DBG_PR_NORMAL) VRRPR("%s vrr not enable!", __func__); return; } - //crop_line = line; - vrr_vpp_index = vpp_index; - - if (crop_line != pre_line) + if (line_change_type) { vrr_line_delay_update(vdrv); + if (vrr_debug_print & VRR_DBG_PR_NORMAL) + VRRPR("%s type:%d crop:%d->%d dst:%d->%d\n", __func__, + type, pre_line, crop_line, pre_dst_line, dst_line); + } + + pre_line = crop_line; + pre_dst_line = dst_line; + pre_axis_y = vrr_axis_y; } static void vrr_drv_disable(struct aml_vrr_drv_s *vdrv) diff --git a/include/linux/amlogic/media/vrr/vrr.h b/include/linux/amlogic/media/vrr/vrr.h index f784f2ef3..eb4a07935 100644 --- a/include/linux/amlogic/media/vrr/vrr.h +++ b/include/linux/amlogic/media/vrr/vrr.h @@ -33,6 +33,7 @@ struct vrr_device_s { void *dev_data; unsigned int (*lfc_switch)(void *dev_data, int fps); int (*disable_cb)(void *dev_data); + unsigned int v_active; }; struct vrr_notifier_data_s { @@ -78,6 +79,15 @@ struct vrr_notifier_data_s { #define VRR_EVENT_LFC_OFF BIT(6) #define VRR_EVENT_GET_STATE BIT(7) +/* ********************************** + * LINE define + * ********************************** + */ +/* check different type change display scale */ +#define VRR_CROP 1 +#define VRR_AXIS 2 +#define VRR_DOT 3 + /* ************************************************************* */ #ifdef CONFIG_AMLOGIC_MEDIA_VRR int aml_vrr_state(void); @@ -130,7 +140,8 @@ static inline int aml_vrr_atomic_notifier_call_chain(unsigned long event, #endif bool frame_lock_type_vrr_lock(void); unsigned int vrr_check_frame_rate_min_hz(void); -void vrr_crop_update_delay_line(u32 line, u8 vpp_index); +void vrr_crop_update_delay_line(u32 line, u16 axis_y, +u16 dst_w, u16 dst_h, u16 type); struct aml_vrr_drv_s *aml_vrr_drv_active_sel(void); unsigned int vrr_instead_vlock(void);