From 0e60e3e2e4f2526210c54017457a5b0590f580d6 Mon Sep 17 00:00:00 2001 From: Brian Zhu Date: Thu, 7 Mar 2019 17:35:36 +0800 Subject: [PATCH] vpp: support 3D with afbc format [1/1] PD#TV-3042 Problem: 3D function did not support afbc format before Solution: Add the support case which format is afbc. Verify: x301 Change-Id: I38189bfa78eec6ac811fb81631514d7d7b8b3d62 Signed-off-by: Brian Zhu b8d9145 vpp: add interface to force non-afbc path [1/1] c807fc4 vpp: tm2: add vd2 function for tm2 [2/2] eea348a vpp: tm2: add vpp and sr support [1/2] f08c28c video: Some interlace stream will stuck when pts rebound [1/1] 53b2624 amlvideo: reset video_inuse when amlvideo stop [1/1] 17cdaf3 amvideo: set black_threshold_height default 48 [1/1] 1cd025d vpp: set default aspect when the ratecontrol is zero [1/1] 58a2e8f vpp: Modify vframe epoll event [1/1] 94b0dc8 vpp: Modify vframe epoll event [1/1] e98d6d3 video: enable pts calculation when hold video state changes [1/1] 43d30c4 vpp: add histgram test interface for vpp slt test [1/1] 2677784 amvecm: optimize amvecm update in vsync [1/1] af78b0f vpp: increase the afbc burst len as 4 for txlx [1/1] 1ace6fc vpp: hold the vpp setting when meet the non-dw afbc frame [1/1] e8a3758 vpp: 3d: disable crop when 3d playback or hdmi in [1/1] 4e6774d vpp: add black_threshold to disable video when window is too small[1/1] 3ae164f vpp: including crop info when AFBC switch to normal frame [1/1] c67657f vpp: add the pic_mode backup to check difference [1/1] 33b1aee video: timming gets error when switching channels [1/1] 233779e vpp: add log switch in vpp_set_filters [1/1] b00582b vpp: config the vd1 canvas1 correctly when 3D enabled [1/1] 607bc19 vpp: support 3D with afbc format [1/1] vpp: config the vd1 canvas1 correctly when 3D enabled [1/1] PD#TV-3086 Problem: 3D display abnormal. The vd1 canvas1 was incorrect. Solution: When enabled 3D function, config vd1 canvas1 correctly Verify: x301 Change-Id: I201cda2f33badf1af54ab4f177a17f761c7cea8d Signed-off-by: Brian Zhu vpp: add log switch in vpp_set_filters [1/1] PD#SWPL-5942 Problem: Too many log when DI process called the vpp_set_filters with AFBC. Solution: Add log switch to disable it. Verify: verified on X301 Change-Id: I34c8573bed78e49d27ec386279e929e617bf76d5 Signed-off-by: Brian Zhu video: timming gets error when switching channels [1/1] PD#TV-3062 Problem: When switching channels, Hisense platform needs hold video, and the timming obtained at this time is wrong Solution: because we have add hold video function, so get width and height interface give the last video frame width and height, and so on change the video Verify: X301 Change-Id: I331a4589dcb5f5785dce7eea6d8cd03c92d733d2 Signed-off-by: Xiaoming Sui vpp: add the pic_mode backup to check difference [1/1] PD#TV-2929 Problem: The pic_mode in cur_dispbuf was changed but not be detected. Solution: Add global pic_mode variable to check if the pic_mode in cur_dispbuf is changed. If so, force vpp_set_filters. Verify: verified on x301 Change-Id: I5b95f512ad0823b031989f05526f114694887f2b Signed-off-by: Brian Zhu vpp: including crop info when AFBC switch to normal frame [1/1] PD#SWPL-6347 Problem: When AFBC switch to normal frame, excluding the crop information, the pps parameters are calculated with wrong input size. Solution: 1.Add the crop information, when afbc swicth to normal frame. 2.check ratio of compress_width/width, sync to crop value Verify: verified on x301 Change-Id: Ib943f8a11263ce577952e589bc172d8b7bafd954 Signed-off-by: Brian Zhu Signed-off-by: Luan Yuan vpp: add black_threshold to disable video when window is too small [1/1] PD#TV-3641 Problem: Add new interface to disable video when window is too small Solution: Add the black_threshold interface to control the threshold size. And set the default value is width=20, height=30. Verify: verified by x301 Change-Id: Ifeb376c2e2edbb5706b2cdc2d08421bd0086b01e Signed-off-by: Brian Zhu vpp: 3d: disable crop when 3d playback or hdmi in [1/1] PD#TV-3962 Problem: 3D mode does not support crop function Solution: Remove crop when 3D display. Verify: Verified on x301 Change-Id: Id35dd662886be24e3ec78d070e3a70f513f89b16 Signed-off-by: Brian Zhu vpp: hold the vpp setting when meet the non-dw afbc frame [1/1] PD#SWPL-7513 Problem: When meet the non-dw afbc frame, vpp can not display with scaling down as expected. Solution: Hold the current vpp setting and wait provider to switch non-afbc. Verify: x301 Change-Id: I3c0e678d2da42376f3a77e334b8c5ce48460273b Signed-off-by: Brian Zhu vpp: increase the afbc burst len as 4 for txlx [1/1] PD#TV-3132 Problem: When playing 4K afbc and scaling down to small window, the vskip is 1 and DDR freq is also lower, the display will flicker caused by DDR bandwidth issue. Solution: Increase the afbc mif burst len from 2 to 4. And enable the dmc adjustment in that case. Verify: r311, verify pass Change-Id: Ia431a93f6083fd584b7e2eb14f777c5a5e7c20e7 Signed-off-by: Brian Zhu amvecm: optimize amvecm update in vsync [1/1] PD#SWPL-6475 Problem: hdmi input signal, video flicker Solution: optimize amvecm update in vsync Verify: verify on TL1 Change-Id: I3379333053fc52b8a33747ca83b1d6d68ea874ab Signed-off-by: MingLiang Dong vpp: add histgram test interface for vpp slt test [1/1] PD#GH-31 Problem: Need pattern to filter the error vpp modules in SLT test Solution: Using clipping and histgram function to create the test pattern and get the histgram data. Verify: verified on w400 Change-Id: I52680c96f568980f71ac8c27c4b66352fea96651 Signed-off-by: Brian Zhu video: enable pts calculation when hold video state changes [1/1] PD#TV-3999 Problem: dtmb individual channel switching speed is slow, it takes about 16s Solution: enable pts calculation when hold video state changes. Verify: X301 Change-Id: I4c8eda3af3df894d8116461abf63c3dda45c8ce3 Signed-off-by: Rui Wang vpp: Modify vframe epoll event [1/1] PD#SWPL-8850 Problem: too many print when channel change. Solution: Modify vframe epoll event flow to avoid same event. Verify: verify on marconi. Change-Id: Id709439f24d3cad82df6082c477cacce1a9b9cc7 Signed-off-by: qiyao.zhou vpp: Modify vframe epoll event [1/1] PD#SWPL-8850 Problem: too many print when channel change. Solution: Modify vframe epoll event flow to avoid same event. Verify: verify on marconi. Change-Id: Iefbd190c0280276bf941c48bf99706a0f2573df1 Signed-off-by: qiyao.zhou vpp: set default aspect when the ratecontrol is zero [1/1] PD#TV-5266 Problem: Vpp used the wrong aspect ratio in 3D, screen mode = normal and aspect ratio is 0 in ratecontrol variable. Solution: When the aspect ratio is 0, set the default value as (height << 8) / width Verify: Verified by x301 Change-Id: I34f7cd3ce5ed1818d3090ebb4be934225038625e Signed-off-by: Brian Zhu amvideo: set black_threshold_height default 48 [1/1] PD#OTT-1836 Problem: disable video when window is too small Solution: set black_threshold_height default 48 Verify: U212 Change-Id: I9ed7deb54baef1c44bb9cc0c1a4d699140663864 Signed-off-by: jintao xu amlvideo: reset video_inuse when amlvideo stop [1/1] PD#TV-6189 Problem: video_inuse always is 1 when codec server crash Solution: reset video_inuse when amlvideo stop Verify: TL1 Change-Id: I5b1b808668e3b2fb78781a4ea1ccbaefc3507d2b Signed-off-by: Lifeng Cao video: Some interlace stream will stuck when pts rebound [1/1] PD#TV-6236 Problem: Some interlace stream di has buffer count more than 16 If video pts rebound in this stream. The condition that (abs(omx_pts_set_index - next_vf->omx_index) <= 16) is not true. So this frame can not toggle always. Solution: Delete this condition that (abs(omx_pts_set_index - next_vf->omx_index) <= 16) Verify: verify TL1 Change-Id: I7e8c12ec72d086b0516f7c7490b492e16e36e8fe Signed-off-by: Lifeng Cao vpp: tm2: add vpp and sr support [1/2] PD#SWPL-6615 Problem: Need vpp and sr supprt for sm2 Solution: add support for tm2 Verify: test pass on tm2 skt Change-Id: I0ae2cb178fcbe047cdfec6b4e200424178993e6e Signed-off-by: Brian Zhu vpp: tm2: add vd2 function for tm2 [2/2] PD#SWPL-6615 Problem: Need vd2 function Solution: add vd2 function for tm2: 1.vd2 pps scaler 2.disable vd2 afbc Verify: test pass on tm2 skt Change-Id: I7af5de741b90e443ee065218aecb823ef06d66a7 Signed-off-by: Brian Zhu Signed-off-by: Luan Yuan vpp: add interface to force non-afbc path [1/1] PD#SWPL-7035 Problem: When DI switched to use VD AFBC, need vpp force to non-afbc first. Otherwise, display willl flash. Solution: Provide new interface to request the vpp release afbc hardware first. Then return the current afbc status. Verify: verified on x301 Change-Id: Ibb2b897db7d2f2c40006433d63709988992c84f1 Signed-off-by: Brian Zhu --- .../amlogic/media/enhancement/amvecm/amcsc.c | 9 - .../video_processor/video_dev/amlvideo.c | 2 + .../video_processor/video_dev/amlvideo.h | 1 + drivers/amlogic/media/video_sink/video.c | 1074 ++++++++++++++--- drivers/amlogic/media/video_sink/video_priv.h | 1 + drivers/amlogic/media/video_sink/vpp.c | 451 +++---- .../amlogic/media/registers/regs/vpp_regs.h | 2 + include/linux/amlogic/media/vfm/vframe.h | 1 + include/linux/amlogic/media/video_sink/vpp.h | 16 +- 9 files changed, 1140 insertions(+), 417 deletions(-) diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc.c b/drivers/amlogic/media/enhancement/amvecm/amcsc.c index 1b1391130b1b0..eacb845c0107e 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amcsc.c +++ b/drivers/amlogic/media/enhancement/amvecm/amcsc.c @@ -6360,15 +6360,6 @@ static void video_process( pr_csc("saturation offset = %d.\n", saturation_offset); cur_csc_type = csc_type; - - if (vf) { - if ((cur_csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB) && - (cur_csc_type != 0xffff) && - (vf->source_type == VFRAME_SOURCE_TYPE_HDMI)) { - amvecm_wakeup_queue(); - pr_csc("wake up hdr status queue.\n"); - } - } } } diff --git a/drivers/amlogic/media/video_processor/video_dev/amlvideo.c b/drivers/amlogic/media/video_processor/video_dev/amlvideo.c index e2490735ce5fd..bc424e7ee36ac 100644 --- a/drivers/amlogic/media/video_processor/video_dev/amlvideo.c +++ b/drivers/amlogic/media/video_processor/video_dev/amlvideo.c @@ -780,6 +780,8 @@ static int amlvideo_close(struct file *file) mutex_lock(&dev->mutex); dev->users--; mutex_unlock(&dev->mutex); + if (dev->inst == 0) + video_inuse = 0; AMLVIDEO_DBG("amlvideo close"); return 0; } diff --git a/drivers/amlogic/media/video_processor/video_dev/amlvideo.h b/drivers/amlogic/media/video_processor/video_dev/amlvideo.h index 4789a1cb2d606..090e294576de8 100644 --- a/drivers/amlogic/media/video_processor/video_dev/amlvideo.h +++ b/drivers/amlogic/media/video_processor/video_dev/amlvideo.h @@ -104,6 +104,7 @@ struct vivi_fh { enum v4l2_buf_type type; }; +extern bool video_inuse; extern bool omx_secret_mode; extern void get_ppmgr_buf_info(char **start, unsigned int *size); diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 7ac8a48f6032a..266fff1f8b6d1 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -85,6 +85,7 @@ MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_DEFAULT_LEVEL_DESC, LOG_MASK_DESC); #endif #include #include +#include #include "../common/vfm/vfm.h" #include @@ -158,6 +159,7 @@ static bool omx_drop_done; static bool video_start_post; static bool videopeek; static bool nopostvideostart; +static int hold_property_changed; static struct video_frame_detect_s video_frame_detect; static long long time_setomxpts; static long long time_setomxpts_last; @@ -224,6 +226,9 @@ static struct vframe_s local_pip; static struct device *amvideo_dev; static struct device *amvideo_poll_dev; +static u32 cur_width; +static u32 cur_height; + #define DRIVER_NAME "amvideo" #define MODULE_NAME "amvideo" #define DEVICE_NAME "amvideo" @@ -279,6 +284,8 @@ static u32 frame_detect_fps = 60000; static u32 frame_detect_receive_count; static u32 frame_detect_drop_count; +static u32 vpp_hold_setting_cnt; + #ifdef FIQ_VSYNC #define BRIDGE_IRQ INT_TIMER_C #define BRIDGE_IRQ_SET() WRITE_CBUS_REG(ISA_TIMERC, 1) @@ -449,9 +456,21 @@ static DEFINE_MUTEX(video_layer_mutex); static u32 layer_cap; static struct disp_info_s glayer_info[MAX_VD_LAYERS]; +static struct vframe_pic_mode_s gPic_info[MAX_VD_LAYERS]; static u32 reference_zorder = 128; +/* default value 20 30 */ +static s32 black_threshold_width = 20; +static s32 black_threshold_height = 48; + +static struct vframe_s hist_test_vf; +static bool hist_test_flag; +static unsigned long hist_buffer_addr; +static u32 hist_print_count; + +static atomic_t gAfbc_request = ATOMIC_INIT(0); + #define MAX_ZOOM_RATIO 300 #define VPP_PREBLEND_VD_V_END_LIMIT 2304 @@ -1105,7 +1124,7 @@ static u32 last_toggle_count; static u32 toggle_same_count; /* video_inuse */ -static u32 video_inuse; +u32 video_inuse; void set_freerun_mode(int mode) { @@ -1162,6 +1181,65 @@ static int noneseamless_play_clone_rate = 5; #define CONFIG_AM_VOUT +static s32 is_afbc_for_vpp(u8 id) +{ + s32 ret = -1; + u32 val; + + if ((id >= MAX_VD_LAYERS) + || legacy_vpp) + return ret; + + if (id == 0) + val = READ_VCBUS_REG( + VD1_AFBCD0_MISC_CTRL); + else + val = READ_VCBUS_REG( + VD2_AFBCD1_MISC_CTRL); + + if ((val & (1 << 10)) && (val & (1 << 12)) + && !(val & (1 << 9))) + ret = 1; + else + ret = 0; + return ret; +} + +s32 di_request_afbc_hw(u8 id, bool on) +{ + u32 cur_afbc_request; + u32 next_request = 0; + s32 ret = -1; + + if (id >= MAX_VD_LAYERS) + return ret; + + if (!glayer_info[id].afbc_support || legacy_vpp) + return ret; + + next_request = 1 << id; + cur_afbc_request = atomic_read(&gAfbc_request); + if (on) { + if (cur_afbc_request & next_request) + return is_afbc_for_vpp(id); + + atomic_add(next_request, &gAfbc_request); + ret = 1; + } else { + if ((cur_afbc_request & next_request) == 0) + return is_afbc_for_vpp(id); + + atomic_sub(next_request, &gAfbc_request); + ret = 1; + } + if (id == 0) + video_property_changed = 1; + else + pip_property_changed = 1; + return ret; +} +EXPORT_SYMBOL(di_request_afbc_hw); + void safe_disble_videolayer(void) { #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER_PPSCALER @@ -1237,6 +1315,13 @@ static inline struct vframe_s *video_vf_peek(void) { struct vframe_s *vf = vf_peek(RECEIVER_NAME); + if (hist_test_flag) { + if (cur_dispbuf != &hist_test_vf) + vf = &hist_test_vf; + else + vf = NULL; + } + if (vf && vf->disp_pts && vf->disp_pts_us64) { vf->pts = vf->disp_pts; vf->pts_us64 = vf->disp_pts_us64; @@ -1249,9 +1334,15 @@ static inline struct vframe_s *video_vf_peek(void) static inline struct vframe_s *video_vf_get(void) { struct vframe_s *vf = NULL; + int frame_width, frame_height; - vf = vf_get(RECEIVER_NAME); + if (hist_test_flag) { + if (cur_dispbuf != &hist_test_vf) + vf = &hist_test_vf; + return vf; + } + vf = vf_get(RECEIVER_NAME); if (vf) { if (vf->disp_pts && vf->disp_pts_us64) { vf->pts = vf->disp_pts; @@ -1259,6 +1350,13 @@ static inline struct vframe_s *video_vf_get(void) vf->disp_pts = 0; vf->disp_pts_us64 = 0; } + if (vf->type & VIDTYPE_COMPRESS) { + frame_width = vf->compWidth; + frame_height = vf->compHeight; + } else { + frame_width = vf->width; + frame_height = vf->height; + } video_notify_flag |= VIDEO_NOTIFY_PROVIDER_GET; atomic_set(&vf->use_cnt, 1); /*always to 1,for first get from vfm provider */ @@ -1280,36 +1378,35 @@ static inline struct vframe_s *video_vf_get(void) } if (((process_3d_type & MODE_FORCE_3D_TO_2D_LR) || (process_3d_type & MODE_FORCE_3D_LR) - || (process_3d_type & MODE_FORCE_3D_FA_LR) - ) + || (process_3d_type & MODE_FORCE_3D_FA_LR)) && (!(vf->type & VIDTYPE_MVC)) && (vf->trans_fmt != TVIN_TFMT_3D_FP)) { vf->trans_fmt = TVIN_TFMT_3D_DET_LR; vf->left_eye.start_x = 0; vf->left_eye.start_y = 0; - vf->left_eye.width = vf->width / 2; - vf->left_eye.height = vf->height; + vf->left_eye.width = frame_width / 2; + vf->left_eye.height = frame_height; - vf->right_eye.start_x = vf->width / 2; + vf->right_eye.start_x = frame_width / 2; vf->right_eye.start_y = 0; - vf->right_eye.width = vf->width / 2; + vf->right_eye.width = frame_width / 2; + vf->right_eye.height = frame_height; } if (((process_3d_type & MODE_FORCE_3D_TO_2D_TB) || (process_3d_type & MODE_FORCE_3D_TB) - || (process_3d_type & MODE_FORCE_3D_FA_TB) - ) + || (process_3d_type & MODE_FORCE_3D_FA_TB)) && (!(vf->type & VIDTYPE_MVC)) && (vf->trans_fmt != TVIN_TFMT_3D_FP)) { vf->trans_fmt = TVIN_TFMT_3D_TB; vf->left_eye.start_x = 0; vf->left_eye.start_y = 0; - vf->left_eye.width = vf->width; - vf->left_eye.height = vf->height/2; + vf->left_eye.width = frame_width; + vf->left_eye.height = frame_height/2; vf->right_eye.start_x = 0; - vf->right_eye.start_y = vf->height/2; - vf->right_eye.width = vf->width; - vf->right_eye.height = vf->height/2; + vf->right_eye.start_y = frame_height/2; + vf->right_eye.width = frame_width; + vf->right_eye.height = frame_height/2; } receive_frame_count++; #endif @@ -1333,6 +1430,9 @@ static inline void video_vf_put(struct vframe_s *vf) { struct vframe_provider_s *vfp = vf_get_provider(RECEIVER_NAME); + if (vf == &hist_test_vf) + return; + if (vfp && vf && atomic_dec_and_test(&vf->use_cnt)) { vf_put(vf, RECEIVER_NAME); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION @@ -1745,6 +1845,7 @@ static void zoom_get_horz_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls, u32 *le, u32 *rs, u32 *re) { u32 crop_sx, crop_ex, crop_sy, crop_ey; + int frame_width, frame_height; struct disp_info_s *layer = &glayer_info[0]; if (!vf) @@ -1755,18 +1856,26 @@ static void zoom_get_horz_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls, crop_ey = layer->crop_bottom; crop_ex = layer->crop_right; + if (vf->type & VIDTYPE_COMPRESS) { + frame_width = vf->compWidth; + frame_height = vf->compHeight; + } else { + frame_width = vf->width; + frame_height = vf->height; + } + switch (vpp_3d_mode) { case VPP_3D_MODE_LR: /*half width,double height */ *ls = zoom_start_x_lines; *le = zoom_end_x_lines; - *rs = *ls + (vf->width >> 1); - *re = *le + (vf->width >> 1); + *rs = *ls + (frame_width >> 1); + *re = *le + (frame_width >> 1); if (process_3d_type & MODE_3D_OUT_LR) { *ls = zoom_start_x_lines; *le = zoom_end_x_lines >> 1; - *rs = *ls + (vf->width >> 1); - *re = *le + (vf->width >> 1); + *rs = *ls + (frame_width >> 1); + *re = *le + (frame_width >> 1); } break; case VPP_3D_MODE_TB: @@ -1799,17 +1908,29 @@ static void zoom_get_vert_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls, u32 *le, u32 *rs, u32 *re) { u32 crop_sx, crop_ex, crop_sy, crop_ey, height; + int frame_width, frame_height; struct disp_info_s *layer = &glayer_info[0]; + if (!vf) + return; + crop_sy = layer->crop_top; crop_sx = layer->crop_left; crop_ey = layer->crop_bottom; crop_ex = layer->crop_right; + if (vf->type & VIDTYPE_COMPRESS) { + frame_width = vf->compWidth; + frame_height = vf->compHeight; + } else { + frame_width = vf->width; + frame_height = vf->height; + } + if (vf->type & VIDTYPE_INTERLACE) - height = vf->height >> 1; + height = frame_height >> 1; else - height = vf->height; + height = frame_height; switch (vpp_3d_mode) { case VPP_3D_MODE_TB: @@ -1919,7 +2040,8 @@ static void zoom_get_vert_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls, } #endif -static void zoom_display_horz(struct vframe_s *vf, int hscale) +static void zoom_display_horz( + struct vframe_s *vf, int hscale, bool no_compress) { u32 ls = 0, le = 0, rs = 0, re = 0; #ifdef TV_REVERSE @@ -1959,7 +2081,8 @@ static void zoom_display_horz(struct vframe_s *vf, int hscale) (((zoom_end_x_lines / 2 - zoom_start_x_lines / 2 + 1) >> hscale) << VD1_FMT_CHROMA_WIDTH_BIT)); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { + if (!no_compress && + vf && (vf->type & VIDTYPE_COMPRESS)) { int l_aligned; int r_aligned; int h_skip = cur_frame_par->hscale_skip_count + 1; @@ -1995,17 +2118,22 @@ static void zoom_display_horz(struct vframe_s *vf, int hscale) #ifdef TV_REVERSE if (reverse) { content_w = zoom_end_x_lines - zoom_start_x_lines + 1; - content_l = (r_aligned - zoom_end_x_lines - 1) + - (zoom_start_x_lines - l_aligned); + content_l = (r_aligned - zoom_end_x_lines - 1); content_r = content_l + content_w - 1; VSYNC_WR_MPEG_REG(AFBC_PIXEL_HOR_SCOPE, (((content_l << 16)) | content_r) / h_skip); } else #endif { - VSYNC_WR_MPEG_REG(AFBC_PIXEL_HOR_SCOPE, - (((zoom_start_x_lines - l_aligned) << 16) | - (zoom_end_x_lines - l_aligned)) / h_skip); + if (((process_3d_type & MODE_3D_FA) + || (process_3d_type & MODE_FORCE_3D_FA_LR)) + && (cur_frame_par->vpp_3d_mode == 1)) { + /* do nothing*/ + } else { + VSYNC_WR_MPEG_REG(AFBC_PIXEL_HOR_SCOPE, + (((zoom_start_x_lines - l_aligned) << 16) | + (zoom_end_x_lines - l_aligned)) / h_skip); + } } VSYNC_WR_MPEG_REG(AFBC_SIZE_IN, (VSYNC_RD_MPEG_REG(AFBC_SIZE_IN) & 0xffff) | @@ -2134,10 +2262,11 @@ static void vd2_zoom_display_horz(struct vframe_s *vf, int hscale) << VD1_FMT_CHROMA_WIDTH_BIT)); } -static void zoom_display_vert(struct vframe_s *vf) +static void zoom_display_vert( + struct vframe_s *vf, int vscale, bool no_compress) { - u32 ls, le, rs, re; + u32 ls = 0, le = 0, rs = 0, re = 0; if (process_3d_type & MODE_3D_ENABLE) { zoom_get_vert_pos(vf, @@ -2237,12 +2366,13 @@ static void zoom_display_vert(struct vframe_s *vf) } } - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { + if (!no_compress && + vf && (vf->type & VIDTYPE_COMPRESS)) { int t_aligned; int b_aligned; int ori_t_aligned; int ori_b_aligned; - int v_skip = cur_frame_par->vscale_skip_count + 1; + int v_skip = vscale + 1; int c_skip = 2; /* After TL1, afbc supports 420/422/444*/ @@ -2259,10 +2389,27 @@ static void zoom_display_vert(struct vframe_s *vf) VSYNC_WR_MPEG_REG(AFBC_VD_CFMT_H, (b_aligned - t_aligned) / c_skip / v_skip); - VSYNC_WR_MPEG_REG(AFBC_MIF_VER_SCOPE, - ((t_aligned / 4) << 16) | - ((b_aligned / 4) - 1)); - + if (((process_3d_type & MODE_3D_FA) + || (process_3d_type & MODE_FORCE_3D_FA_TB)) + && (cur_frame_par->vpp_3d_mode == 2)) { + int block_h; + + block_h = ori_b_aligned - ori_t_aligned; + block_h = block_h / 8; + if (toggle_3d_fa_frame == OUT_FA_B_FRAME) { + VSYNC_WR_MPEG_REG(AFBC_MIF_VER_SCOPE, + (((ori_t_aligned / 4) + block_h) << 16) | + ((ori_b_aligned / 4) - 1)); + } else { + VSYNC_WR_MPEG_REG(AFBC_MIF_VER_SCOPE, + ((ori_t_aligned / 4) << 16) | + ((ori_t_aligned / 4) + block_h - 1)); + } + } else { + VSYNC_WR_MPEG_REG(AFBC_MIF_VER_SCOPE, + ((t_aligned / 4) << 16) | + ((b_aligned / 4) - 1)); + } VSYNC_WR_MPEG_REG(AFBC_PIXEL_VER_SCOPE, ((zoom_start_y_lines - t_aligned) << 16) | (zoom_end_y_lines - t_aligned)); @@ -2525,7 +2672,7 @@ static void vsync_video_pattern(void) } #endif -static inline void vd1_path_select(bool afbc) +static inline void vd1_path_select(bool afbc, bool di_afbc) { u32 misc_off = cur_dev->vpp_off; @@ -2539,13 +2686,13 @@ static inline void vd1_path_select(bool afbc) /* vd1 -> dolby -> vpp top */ (0 << 14) | /* axi sel: vd1 mif or afbc */ - ((afbc ? 1 : 0) << 12) | + (((afbc || di_afbc) ? 1 : 0) << 12) | /* data sel: vd1 & afbc0 (not osd4) */ (0 << 11) | /* data sel: afbc0 or vd1 */ ((afbc ? 1 : 0) << 10) | /* afbc0 to vd1 (not di) */ - (0 << 9) | + ((di_afbc ? 1 : 0) << 9) | /* vd1 mif to vpp (not di) */ (0 << 8) | /* afbc0 gclk ctrl */ @@ -2589,7 +2736,7 @@ static inline void vd1_path_select(bool afbc) } } -static inline void vd2_path_select(bool afbc) +static inline void vd2_path_select(bool afbc, bool di_afbc) { u32 misc_off = cur_dev->vpp_off; @@ -2603,13 +2750,13 @@ static inline void vd2_path_select(bool afbc) /* TODO: vd2 -> dolby -> vpp top ?? */ (0 << 14) | /* axi sel: vd2 mif */ - ((afbc ? 1 : 0) << 12) | + (((afbc || di_afbc) ? 1 : 0) << 12) | /* data sel: vd2 & afbc1 (not osd4) */ (0 << 11) | /* data sel: afbc1 */ ((afbc ? 1 : 0) << 10) | /* afbc1 to vd2 (not di) */ - (0 << 9) | + ((di_afbc ? 1 : 0) << 9) | /* vd2 mif to vpp (not di) */ (0 << 8) | /* afbc1 gclk ctrl */ @@ -3026,6 +3173,7 @@ static inline void proc_vd2_vsc_phase_per_vsync( static void pip_toggle_frame(struct vframe_s *vf) { u32 first_picture = 0; + bool force_toggle = false; if (vf == NULL) return; @@ -3102,15 +3250,31 @@ static void pip_toggle_frame(struct vframe_s *vf) #endif } + if (cur_pipbuf && + (cur_pipbuf->ratio_control & + DISP_RATIO_ADAPTED_PICMODE)) { + if (vf && (cur_pipbuf->ratio_control + == vf->ratio_control) + && memcmp(&cur_pipbuf->pic_mode, + &vf->pic_mode, + sizeof(struct vframe_pic_mode_s))) + force_toggle = true; + else if (memcmp(&cur_pipbuf->pic_mode, + &gPic_info[1], + sizeof(struct vframe_pic_mode_s))) + force_toggle = true; + } + if (pip_property_changed) { - first_picture = 1; + force_toggle = true; pip_property_changed = 0; } if (cur_pipbuf != vf) vf->type_backup = vf->type; /* enable new config on the new frames */ - if ((first_picture) || (cur_pipbuf && + if (first_picture || force_toggle || + (cur_pipbuf && ((cur_pipbuf->bufWidth != vf->bufWidth) || (cur_pipbuf->width != vf->width) || (cur_pipbuf->height != vf->height) || @@ -3128,15 +3292,13 @@ static void pip_toggle_frame(struct vframe_s *vf) &pip_frame_parms[1] : &pip_frame_parms[0]; update_layer_info(1); - if (legacy_vpp || is_meson_tl1_cpu()) - iret = vpp_set_filters_no_scaler( - &glayer_info[1], vf, - nextpip_frame_par, vinfo); - else - iret = vpp_set_filters( - &glayer_info[1], vf, - nextpip_frame_par, vinfo, - true); + iret = vpp_set_filters( + &glayer_info[1], vf, + nextpip_frame_par, vinfo, + true, 1); + + memcpy(&gPic_info[1], &vf->pic_mode, + sizeof(struct vframe_pic_mode_s)); if (iret == VppFilter_Success_and_Changed) pip_property_changed = 1; @@ -3172,6 +3334,8 @@ static void pip_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) 0, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; u32 u, v; u32 type, bit_mode = 0; + u8 burst_len = 1; + u32 canvas_w; if (!vf || !frame_par) { pr_err("pip_set_dcu vf is NULL\n"); @@ -3185,9 +3349,11 @@ static void pip_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) type &= ~VIDTYPE_COMPRESS; if (type & VIDTYPE_COMPRESS) { + if (!legacy_vpp || is_meson_txlx_cpu()) + burst_len = 2; r = (3 << 24) | (vpp_hold_line << 16) | - ((legacy_vpp ? 1 : 2) << 14) | /* burst1 */ + (burst_len << 14) | /* burst1 */ (vf->bitdepth & BITDEPTH_MASK); if (frame_par->hscale_skip_count) @@ -3296,12 +3462,25 @@ static void pip_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) VD2_AFBCDEC_IQUANT_ENABLE, 0); } - vd2_path_select(true); + vd2_path_select(true, false); VSYNC_WR_MPEG_REG(VD2_IF0_GEN_REG + cur_dev->viu_off, 0); return; } + /* vd mif burst len is 2 as default */ + burst_len = 2; + if (vf->canvas0Addr != (u32)-1) + canvas_w = canvas_get_width( + vf->canvas0Addr & 0xff); + else + canvas_w = vf->canvas0_config[0].width; + + if (canvas_w % 32) + burst_len = 0; + else if (canvas_w % 64) + burst_len = 1; + if ((vf->bitdepth & BITDEPTH_Y10) && (!frame_par->nocomp)) { if (vf->type & VIDTYPE_VIU_444) { @@ -3315,11 +3494,14 @@ static void pip_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) } else { bit_mode = 0; } - vd2_path_select(false); + vd2_path_select(false, false); if (!legacy_vpp) { VSYNC_WR_MPEG_REG_BITS( G12_VD2_IF0_GEN_REG3, (bit_mode & 0x3), 8, 2); + VSYNC_WR_MPEG_REG_BITS( + G12_VD2_IF0_GEN_REG3, + (burst_len & 0x3), 1, 2); } else { VSYNC_WR_MPEG_REG_BITS( VD2_IF0_GEN_REG3 + cur_dev->viu_off, @@ -3576,6 +3758,13 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) frame_count++; toggle_count++; + if (vf && !(vf->type & VIDTYPE_COMPRESS) + && glayer_info[0].need_no_compress) { + atomic_sub(1, &gAfbc_request); + glayer_info[0].need_no_compress = false; + force_toggle = true; + } + if (vf->type & VIDTYPE_MVC) is_mvc = true; @@ -3688,6 +3877,13 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) timestamp_vpts_inc(-1); } } + if (vf->type & VIDTYPE_COMPRESS) { + cur_width = vf->compWidth; + cur_height = vf->compHeight; + } else { + cur_width = vf->width; + cur_height = vf->height; + } video_vf_put(vf); ATRACE_COUNTER(__func__, __LINE__); return; @@ -3754,11 +3950,11 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) if (video_property_changed) { property_changed_true = 2; video_property_changed = 0; - first_picture = 1; + force_toggle = true; } if (property_changed_true > 0) { property_changed_true--; - first_picture = 1; + force_toggle = true; } if ((debug_flag & DEBUG_FLAG_BLACKOUT) @@ -3768,7 +3964,7 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) /* switch buffer */ post_canvas = vf->canvas0Addr; - if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) && + if (!glayer_info[0].need_no_compress && (vf->type & VIDTYPE_COMPRESS)) { VSYNC_WR_MPEG_REG(AFBC_HEAD_BADDR, vf->compHeadAddr>>4); VSYNC_WR_MPEG_REG(AFBC_BODY_BADDR, vf->compBodyAddr>>4); @@ -3793,7 +3989,7 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) vf->plane_num, &disp_canvas_index[rdma_canvas_id][0]); } - if (is_mvc) { + if (is_mvc || process_3d_type) { if (vf->canvas1Addr != (u32)-1) { canvas_copy(vf->canvas1Addr & 0xff, disp_canvas_index[rdma_canvas_id][3]); @@ -3834,18 +4030,22 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) disp_canvas[rdma_canvas_id][0]); } if (cur_frame_par - && (process_3d_type & MODE_3D_ENABLE) - && (process_3d_type & MODE_3D_TO_2D_R) - && (cur_frame_par->vpp_2pic_mode == VPP_SELECT_PIC1) - && is_mvc) { + && (process_3d_type & MODE_3D_ENABLE) + && (process_3d_type & MODE_3D_TO_2D_R) + && (cur_frame_par->vpp_2pic_mode + == VPP_SELECT_PIC1)) { VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS0 + cur_dev->viu_off, - disp_canvas[rdma_canvas_id][1]); + disp_canvas[rdma_canvas_id][1]); VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS1 + cur_dev->viu_off, - disp_canvas[rdma_canvas_id][1]); - VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS0 + cur_dev->viu_off, - disp_canvas[rdma_canvas_id][1]); - VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 + cur_dev->viu_off, - disp_canvas[rdma_canvas_id][1]); + disp_canvas[rdma_canvas_id][1]); + if (is_mvc) { + VSYNC_WR_MPEG_REG( + VD2_IF0_CANVAS0 + cur_dev->viu_off, + disp_canvas[rdma_canvas_id][1]); + VSYNC_WR_MPEG_REG( + VD2_IF0_CANVAS1 + cur_dev->viu_off, + disp_canvas[rdma_canvas_id][1]); + } } next_rdma_canvas_id = rdma_canvas_id ? 0 : 1; #else @@ -3854,7 +4054,7 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) disp_canvas_index[1]); canvas_copy((vf->canvas0Addr >> 16) & 0xff, disp_canvas_index[2]); - if (is_mvc) { + if (is_mvc || process_3d_type) { canvas_copy(vf->canvas1Addr & 0xff, disp_canvas_index[3]); canvas_copy((vf->canvas1Addr >> 8) & 0xff, @@ -3918,14 +4118,20 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) vf->type_backup = vf->type; } - if (cur_dispbuf && vf && + if (cur_dispbuf && (cur_dispbuf->ratio_control & - DISP_RATIO_ADAPTED_PICMODE) && - (cur_dispbuf->ratio_control == - vf->ratio_control) && - memcmp(&cur_dispbuf->pic_mode, &vf->pic_mode, - sizeof(struct vframe_pic_mode_s))) - force_toggle = true; + DISP_RATIO_ADAPTED_PICMODE)) { + if (vf && (cur_dispbuf->ratio_control + == vf->ratio_control) + && memcmp(&cur_dispbuf->pic_mode, + &vf->pic_mode, + sizeof(struct vframe_pic_mode_s))) + force_toggle = true; + else if (memcmp(&cur_dispbuf->pic_mode, + &gPic_info[0], + sizeof(struct vframe_pic_mode_s))) + force_toggle = true; + } if ((last_process_3d_type != process_3d_type) || (last_el_status != vf_with_el)) @@ -3946,8 +4152,12 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) int iret; last_process_3d_type = process_3d_type; - atomic_inc(&video_sizechange); - wake_up_interruptible(&amvideo_sizechange_wait); + if (!cur_dispbuf || + ((cur_dispbuf->width != vf->width) || + (cur_dispbuf->height != vf->height))) { + atomic_inc(&video_sizechange); + wake_up_interruptible(&amvideo_sizechange_wait); + } amlog_mask(LOG_MASK_FRAMEINFO, "%s %dx%d ar=0x%x\n", ((vf->type & VIDTYPE_TYPEMASK) == @@ -3969,13 +4179,33 @@ static void vsync_toggle_frame(struct vframe_s *vf, int line) &glayer_info[0], vf, next_frame_par, vinfo, (is_dolby_vision_on() && - is_dolby_vision_stb_mode())); + is_dolby_vision_stb_mode()), 1); - if (iret == VppFilter_Success_and_Changed) + memcpy(&gPic_info[0], &vf->pic_mode, + sizeof(struct vframe_pic_mode_s)); + + if ((iret == VppFilter_Success_and_Changed) + || (iret == VppFilter_Changed_but_Hold)) video_property_changed = 1; - /* apply new vpp settings */ - frame_par_ready_to_set = 1; + if (iret == VppFilter_Changed_but_Hold) { + video_notify_flag |= + VIDEO_NOTIFY_NEED_NO_COMP; + vpp_hold_setting_cnt++; + if (debug_flag & DEBUG_FLAG_BLACKOUT) + pr_info("toggle_frame vpp hold setting cnt: %d\n", + vpp_hold_setting_cnt); + } else {/* apply new vpp settings */ + if ((next_frame_par->vscale_skip_count <= 1) + && (vf->type & VIDTYPE_SUPPORT_COMPRESS)) { + video_notify_flag |= + VIDEO_NOTIFY_NEED_NO_COMP; + if (debug_flag & DEBUG_FLAG_BLACKOUT) + pr_info("disable no compress mode\n"); + } + vpp_hold_setting_cnt = 0; + frame_par_ready_to_set = 1; + } if (((vf->width > 1920) && (vf->height > 1088)) || ((vf->type & VIDTYPE_COMPRESS) && @@ -4096,6 +4326,7 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) u32 u, v; u32 type, bit_mode = 0; bool is_mvc = false; + u8 burst_len = 1; if (vf == NULL) { pr_info("viu_set_dcu vf NULL, return\n"); @@ -4112,9 +4343,11 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) type &= ~VIDTYPE_COMPRESS; if (type & VIDTYPE_COMPRESS) { + if (!legacy_vpp || is_meson_txlx_cpu()) + burst_len = 2; r = (3 << 24) | (vpp_hold_line << 16) | - ((legacy_vpp ? 1 : 2) << 14) | /* burst1 */ + (burst_len << 14) | /* burst1 */ (vf->bitdepth & BITDEPTH_MASK); if (frame_par->hscale_skip_count) @@ -4214,15 +4447,30 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) AFBCDEC_IQUANT_ENABLE, 0); } - vd1_path_select(true); + vd1_path_select(true, false); VSYNC_WR_MPEG_REG( VD1_IF0_GEN_REG + cur_dev->viu_off, 0); return; } else { + u32 canvas_w; + + /* vd mif burst len is 2 as default */ + burst_len = 2; + if (vf->canvas0Addr != (u32)-1) + canvas_w = canvas_get_width( + vf->canvas0Addr & 0xff); + else + canvas_w = vf->canvas0_config[0].width; + + if (canvas_w % 32) + burst_len = 0; + else if (canvas_w % 64) + burst_len = 1; + if ((vf->bitdepth & BITDEPTH_Y10) && - (!frame_par->nocomp)) { + (!frame_par->nocomp)) { if (vf->type & VIDTYPE_VIU_444) { bit_mode = 2; } else { @@ -4238,10 +4486,17 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) VSYNC_WR_MPEG_REG_BITS( G12_VD1_IF0_GEN_REG3, (bit_mode & 0x3), 8, 2); - if (is_mvc) + VSYNC_WR_MPEG_REG_BITS( + G12_VD1_IF0_GEN_REG3, + (burst_len & 0x3), 1, 2); + if (is_mvc) { VSYNC_WR_MPEG_REG_BITS( G12_VD2_IF0_GEN_REG3, (bit_mode & 0x3), 8, 2); + VSYNC_WR_MPEG_REG_BITS( + G12_VD2_IF0_GEN_REG3, + (burst_len & 0x3), 1, 2); + } } else { VSYNC_WR_MPEG_REG_BITS( VD1_IF0_GEN_REG3 + @@ -4263,8 +4518,14 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) DI_POST_WR_REG_BITS(DI_IF0_GEN_REG3, (bit_mode & 0x3), 8, 2); #endif - vd1_path_select(false); - VSYNC_WR_MPEG_REG(AFBC_ENABLE, 0); + if (glayer_info[0].need_no_compress + || (vf->type & VIDTYPE_PRE_DI_AFBC)) { + vd1_path_select(false, true); + } else { + vd1_path_select(false, false); + VSYNC_WR_MPEG_REG( + AFBC_ENABLE, 0); + } } } @@ -4629,6 +4890,7 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) 0, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; u32 u, v; u32 type, bit_mode = 0; + u8 burst_len = 1; if (!vf) { pr_err("vd2_set_dcu vf is NULL\n"); @@ -4643,9 +4905,11 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) vf->width; if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { if (type & VIDTYPE_COMPRESS) { + if (!legacy_vpp || is_meson_txlx_cpu()) + burst_len = 2; r = (3 << 24) | (vpp_hold_line << 16) | - ((legacy_vpp ? 1 : 2) << 14) | /* burst1 */ + (burst_len << 14) | /* burst1 */ (vf->bitdepth & BITDEPTH_MASK); if (frame_par->hscale_skip_count) @@ -4755,13 +5019,28 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) VD2_AFBCDEC_IQUANT_ENABLE, 0); } - vd2_path_select(true); + vd2_path_select(true, false); VSYNC_WR_MPEG_REG(VD2_IF0_GEN_REG + cur_dev->viu_off, 0); return; } else { + u32 canvas_w; + + /* vd mif burst len is 2 as default */ + burst_len = 2; + if (vf->canvas0Addr != (u32)-1) + canvas_w = canvas_get_width( + vf->canvas0Addr & 0xff); + else + canvas_w = vf->canvas0_config[0].width; + + if (canvas_w % 32) + burst_len = 0; + else if (canvas_w % 64) + burst_len = 1; + if ((vf->bitdepth & BITDEPTH_Y10) && - (!frame_par->nocomp)) { + (!frame_par->nocomp)) { if (vf->type & VIDTYPE_VIU_444) { bit_mode = 2; } else { @@ -4773,11 +5052,14 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) } else { bit_mode = 0; } - vd2_path_select(false); + vd2_path_select(false, false); if (!legacy_vpp) { VSYNC_WR_MPEG_REG_BITS( G12_VD2_IF0_GEN_REG3, (bit_mode & 0x3), 8, 2); + VSYNC_WR_MPEG_REG_BITS( + G12_VD2_IF0_GEN_REG3, + (burst_len & 0x3), 1, 2); } else { VSYNC_WR_MPEG_REG_BITS( VD2_IF0_GEN_REG3 + cur_dev->viu_off, @@ -5289,11 +5571,14 @@ static inline bool vpts_expire(struct vframe_s *cur_vf, systime = timestamp_pcrscr_get(); pts = next_vf->pts; - if (((pts == 0) && (cur_dispbuf != &vf_local)) + if (((pts == 0) && ((cur_dispbuf != &vf_local) + || (hold_property_changed == 1))) || (freerun_mode == FREERUN_DUR)) { pts = timestamp_vpts_get() + (cur_vf ? DUR2PTS(cur_vf->duration) : 0); + if (hold_property_changed == 1) + hold_property_changed = 0; } /* check video PTS discontinuity */ else if ((enable_video_discontinue_report) && @@ -5364,7 +5649,6 @@ static inline bool vpts_expire(struct vframe_s *cur_vf, } else if (omx_run && omx_secret_mode && (omx_pts + omx_pts_interval_upper < next_vf->pts) - && (abs(omx_pts_set_index - next_vf->omx_index) <= 16) && (omx_pts_set_index >= next_vf->omx_index)) { pr_info("omx, omx_pts=%d omx_pts_set_index=%d pts=%d omx_index=%d\n", omx_pts, @@ -5564,6 +5848,13 @@ static void vsync_notify(void) video_notify_flag &= ~(VIDEO_NOTIFY_PROVIDER_GET | VIDEO_NOTIFY_PROVIDER_PUT); } + if (video_notify_flag & VIDEO_NOTIFY_NEED_NO_COMP) { + /* FIXME: can not use fixed provider name */ + vf_notify_provider_by_name("vdin0", + VFRAME_EVENT_RECEIVER_NEED_NO_COMP, + (void *)&vpp_hold_setting_cnt); + video_notify_flag &= ~VIDEO_NOTIFY_NEED_NO_COMP; + } #ifdef CONFIG_CLK81_DFS check_and_set_clk81(); #endif @@ -6065,6 +6356,158 @@ static int vpp_zorder_check(void) return force_flush; } +static bool black_threshold_check(u8 id) +{ + struct disp_info_s *layer = NULL; + bool ret = false; + + if (id >= MAX_VD_LAYERS) + return ret; + + if ((black_threshold_width <= 0) + || (black_threshold_height <= 0)) + return ret; + + layer = &glayer_info[id]; + if ((layer->layer_top == 0) + && (layer->layer_left == 0) + && (layer->layer_width <= 1) + && (layer->layer_height <= 1)) + /* special case to do full screen display */ + return ret; + + if ((layer->layer_width <= black_threshold_width) + || (layer->layer_height <= black_threshold_height)) + ret = true; + return ret; +} + +#ifdef TV_3D_FUNCTION_OPEN +inline void switch_3dView_per_vsync(void) +{ + u32 start_aligned, end_aligned, block_len; + u32 FA_enable = process_3d_type & MODE_3D_OUT_FA_MASK; + + if (FA_enable && (toggle_3d_fa_frame == OUT_FA_A_FRAME)) { + VSYNC_WR_MPEG_REG_BITS(VPP_MISC + + cur_dev->vpp_off, 1, 14, 1); + /* VPP_VD1_PREBLEND disable */ + VSYNC_WR_MPEG_REG_BITS(VPP_MISC + + cur_dev->vpp_off, 1, 10, 1); + /* VPP_VD1_POSTBLEND disable */ + VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_PSEL + + cur_dev->viu_off, 0x4000000); + VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL + + cur_dev->viu_off, 0x4000000); + VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL + + cur_dev->viu_off, 0x4000000); + VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL + + cur_dev->viu_off, 0x4000000); + if (cur_dispbuf->type & VIDTYPE_COMPRESS) { + if ((process_3d_type & MODE_FORCE_3D_FA_LR) + && (cur_frame_par->vpp_3d_mode == 1)) { + start_aligned = ori_start_x_lines; + end_aligned = ori_end_x_lines + 1; + block_len = + (end_aligned - start_aligned) / 2; + block_len = block_len / + (cur_frame_par->hscale_skip_count + 1); + VSYNC_WR_MPEG_REG(AFBC_PIXEL_HOR_SCOPE, + (start_aligned << 16) | + (start_aligned + block_len - 1)); + } + if ((process_3d_type & MODE_FORCE_3D_FA_TB) + && (cur_frame_par->vpp_3d_mode == 2)) { + start_aligned = + round_down(ori_start_y_lines, 4); + end_aligned = + round_up(ori_end_y_lines + 1, 4); + block_len = end_aligned - start_aligned; + block_len = block_len / 8; + VSYNC_WR_MPEG_REG(AFBC_MIF_VER_SCOPE, + ((start_aligned / 4) << 16) | + ((start_aligned / 4) + block_len - 1)); + } + } + } else if (FA_enable && + (toggle_3d_fa_frame == OUT_FA_B_FRAME)) { + VSYNC_WR_MPEG_REG_BITS(VPP_MISC + + cur_dev->vpp_off, 1, 14, 1); + /* VPP_VD1_PREBLEND disable */ + VSYNC_WR_MPEG_REG_BITS(VPP_MISC + + cur_dev->vpp_off, 1, 10, 1); + /* VPP_VD1_POSTBLEND disable */ + VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_PSEL + + cur_dev->viu_off, 0); + VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL + + cur_dev->viu_off, 0); + VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL + + cur_dev->viu_off, 0); + VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL + + cur_dev->viu_off, 0); + if (cur_dispbuf->type & VIDTYPE_COMPRESS) { + if ((process_3d_type & MODE_FORCE_3D_FA_LR) + && (cur_frame_par->vpp_3d_mode == 1)) { + start_aligned = ori_start_x_lines; + end_aligned = ori_end_x_lines + 1; + block_len = + (end_aligned - start_aligned) / 2; + block_len = block_len / + (cur_frame_par->hscale_skip_count + 1); + VSYNC_WR_MPEG_REG(AFBC_PIXEL_HOR_SCOPE, + ((start_aligned + block_len) << 16) | + (end_aligned - 1)); + } + if ((process_3d_type & MODE_FORCE_3D_FA_TB) + && (cur_frame_par->vpp_3d_mode == 2)) { + start_aligned = + round_down(ori_start_y_lines, 4); + end_aligned = + round_up(ori_end_y_lines + 1, 4); + block_len = end_aligned - start_aligned; + block_len = block_len / 8; + VSYNC_WR_MPEG_REG(AFBC_MIF_VER_SCOPE, + (((start_aligned / 4) + block_len) << 16) | + ((end_aligned / 4) - 1)); + } + } + } else if (FA_enable && + (toggle_3d_fa_frame == OUT_FA_BANK_FRAME)) { + /* output a banking frame */ + VSYNC_WR_MPEG_REG_BITS(VPP_MISC + + cur_dev->vpp_off, 0, 14, 1); + /* VPP_VD1_PREBLEND disable */ + VSYNC_WR_MPEG_REG_BITS(VPP_MISC + + cur_dev->vpp_off, 0, 10, 1); + /* VPP_VD1_POSTBLEND disable */ + } + + if ((process_3d_type & MODE_3D_OUT_TB) + || (process_3d_type & MODE_3D_OUT_LR)) { + if (cur_frame_par->vpp_2pic_mode & + VPP_PIC1_FIRST) { + VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_PSEL + + cur_dev->viu_off, 0x4000000); + VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL + + cur_dev->viu_off, 0x4000000); + VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL + + cur_dev->viu_off, 0); + VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL + + cur_dev->viu_off, 0); + } else { + VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_PSEL + + cur_dev->viu_off, 0); + VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL + + cur_dev->viu_off, 0); + VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL + + cur_dev->viu_off, 0x4000000); + VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL + + cur_dev->viu_off, 0x4000000); + } + } +} +#endif + #ifdef FIQ_VSYNC void vsync_fisr_in(void) #else @@ -6093,10 +6536,19 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) static struct vframe_s *pause_vf; int force_flush = 0; static u32 interrupt_count; + u32 next_afbc_request = atomic_read(&gAfbc_request); + + glayer_info[0].need_no_compress = + (next_afbc_request & 1) ? true : false; + glayer_info[1].need_no_compress = + (next_afbc_request & 2) ? true : false; if (debug_flag & DEBUG_FLAG_VSYNC_DONONE) return IRQ_HANDLED; + if (!hist_test_flag && (cur_dispbuf == &hist_test_vf)) + cur_dispbuf = NULL; + if (frame_detect_flag == 1 && receive_frame_count && frame_detect_time && @@ -6271,18 +6723,32 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) if (is_meson_txlx_cpu() && dmc_adjust) { bool force_adjust = false; + u32 vf_width = 0, vf_height = 0; struct vframe_s *chk_vf; chk_vf = (vf != NULL) ? vf : cur_dispbuf; if (chk_vf) force_adjust = (chk_vf->type & VIDTYPE_VIU_444) ? true : false; - if (chk_vf) + if (chk_vf) { + if (cur_frame_par && + cur_frame_par->nocomp) { + vf_width = chk_vf->width; + vf_height = chk_vf->height; + } else if ((chk_vf->type & VIDTYPE_COMPRESS) + && cur_frame_par + && cur_frame_par->vscale_skip_count) { + vf_width = chk_vf->compWidth; + vf_height = chk_vf->compHeight; + } else { + vf_width = chk_vf->width; + vf_height = chk_vf->height; + } dmc_adjust_for_mali_vpu( - chk_vf->width, - chk_vf->height, + vf_width, + vf_height, force_adjust); - else + } else dmc_adjust_for_mali_vpu( 0, 0, force_adjust); } @@ -6601,20 +7067,6 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) set_hdr_to_frame(vf); #endif -#if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) - refresh_on_vs(vf); - if (amvecm_on_vs( - (cur_dispbuf != &vf_local) - ? cur_dispbuf : NULL, - vf, CSC_FLAG_CHECK_OUTPUT, - cur_frame_par ? - cur_frame_par->supsc1_hori_ratio : - 0, - cur_frame_par ? - cur_frame_par->supsc1_vert_ratio : - 0) == 1) - break; -#endif /* *two special case: *case1:4k display case,input buffer not enough & @@ -6663,6 +7115,22 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) video_3d_format = vf->trans_fmt; } } + +#if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) + refresh_on_vs(vf); + if (amvecm_on_vs( + (cur_dispbuf != &vf_local) + ? cur_dispbuf : NULL, + vf, CSC_FLAG_CHECK_OUTPUT, + cur_frame_par ? + cur_frame_par->supsc1_hori_ratio : + 0, + cur_frame_par ? + cur_frame_par->supsc1_vert_ratio : + 0) == 1) + break; +#endif + vsync_toggle_frame(vf, __LINE__); toggle_frame = vf; @@ -7003,75 +7471,10 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) cur_dev->viu_off, 1, 20, 1); /* HFORMATTER_EN */ } - if (process_3d_type & MODE_3D_OUT_FA_MASK) { - if (toggle_3d_fa_frame == OUT_FA_A_FRAME) { - VSYNC_WR_MPEG_REG_BITS(VPP_MISC + - cur_dev->vpp_off, 1, 14, 1); - /* VPP_VD1_PREBLEND disable */ - VSYNC_WR_MPEG_REG_BITS(VPP_MISC + - cur_dev->vpp_off, 1, 10, 1); - /* VPP_VD1_POSTBLEND disable */ - VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_PSEL + - cur_dev->viu_off, 0x4000000); - VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL + - cur_dev->viu_off, 0x4000000); - VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL + - cur_dev->viu_off, 0x4000000); - VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL + - cur_dev->viu_off, 0x4000000); - } else if (OUT_FA_B_FRAME == - toggle_3d_fa_frame) { - VSYNC_WR_MPEG_REG_BITS(VPP_MISC + - cur_dev->vpp_off, 1, 14, 1); - /* VPP_VD1_PREBLEND disable */ - VSYNC_WR_MPEG_REG_BITS(VPP_MISC + - cur_dev->vpp_off, 1, 10, 1); - /* VPP_VD1_POSTBLEND disable */ - VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_PSEL + - cur_dev->viu_off, 0); - VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL + - cur_dev->viu_off, 0); - VSYNC_WR_MPEG_REG( - VD2_IF0_LUMA_PSEL + - cur_dev->viu_off, 0); - VSYNC_WR_MPEG_REG( - VD2_IF0_CHROMA_PSEL + - cur_dev->viu_off, 0); - } else if (toggle_3d_fa_frame == - OUT_FA_BANK_FRAME) { - /* output a banking frame */ - VSYNC_WR_MPEG_REG_BITS(VPP_MISC + - cur_dev->vpp_off, 0, 14, 1); - /* VPP_VD1_PREBLEND disable */ - VSYNC_WR_MPEG_REG_BITS(VPP_MISC + - cur_dev->vpp_off, 0, 10, 1); - /* VPP_VD1_POSTBLEND disable */ - } - } - if ((process_3d_type & MODE_3D_OUT_TB) - || (process_3d_type & MODE_3D_OUT_LR)) { - if (cur_frame_par && - (cur_frame_par->vpp_2pic_mode & - VPP_PIC1_FIRST)) { - VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_PSEL + - cur_dev->viu_off, 0x4000000); - VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL + - cur_dev->viu_off, 0x4000000); - VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL + - cur_dev->viu_off, 0); - VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL + - cur_dev->viu_off, 0); - } else { - VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_PSEL + - cur_dev->viu_off, 0); - VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL + - cur_dev->viu_off, 0); - VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL + - cur_dev->viu_off, 0x4000000); - VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL + - cur_dev->viu_off, 0x4000000); - } - } + +#ifdef TV_3D_FUNCTION_OPEN + switch_3dView_per_vsync(); +#endif /* vertical phase */ vphase = &cur_frame_par->VPP_vf_ini_phase_ [vpp_phase_table[vin_type] @@ -7301,11 +7704,14 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) cur_frame_par->VPP_hd_start_lines_; zoom_end_x_lines = cur_frame_par->VPP_hd_end_lines_; zoom_display_horz(cur_dispbuf, - cur_frame_par->hscale_skip_count); + cur_frame_par->hscale_skip_count, + cur_frame_par->nocomp); zoom_start_y_lines = zoom_start_y; zoom_end_y_lines = zoom_end_y; - zoom_display_vert(cur_dispbuf); + zoom_display_vert(cur_dispbuf, + cur_frame_par->vscale_skip_count, + cur_frame_par->nocomp); if (is_dolby_vision_enable() && cur_dispbuf2) { zoom2_start_x_lines = ori2_start_x_lines; zoom2_end_x_lines = ori2_end_x_lines; @@ -7742,7 +8148,8 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) spin_unlock_irqrestore(&video2_onoff_lock, flags); } - if (video_global_output == 0) { + if ((video_global_output == 0) + || black_threshold_check(0)) { video_enabled = 0; vpp_misc_set &= ~(VPP_VD1_PREBLEND | VPP_VD2_PREBLEND | @@ -7765,7 +8172,8 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) VPP_PREBLEND_EN); #ifdef VIDEO_PIP - if (pip_global_output == 0) { + if ((pip_global_output == 0) + || black_threshold_check(1)) { video2_enabled = 0; vpp_misc_set &= ~(VPP_VD2_PREBLEND | VPP_VD2_POSTBLEND); @@ -8149,7 +8557,7 @@ int get_current_vscale_skip_count(struct vframe_s *vf) &glayer_info[0], vf, &frame_par, vinfo, (is_dolby_vision_on() && - is_dolby_vision_stb_mode())); + is_dolby_vision_stb_mode()), 0); ret = frame_par.vscale_skip_count; if (cur_frame_par && (process_3d_type & MODE_3D_ENABLE)) ret |= (cur_frame_par->vpp_3d_mode<<8); @@ -8183,6 +8591,7 @@ static void video_vf_unreg_provider(void) first_frame_toggled = 0; videopeek = 0; nopostvideostart = false; + hold_property_changed = 0; atomic_set(&video_unreg_flag, 1); while (atomic_read(&video_inirq_flag) > 0) @@ -8468,6 +8877,7 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) /*alternative mode,passing two buffer in one frame */ if (platform_type == 1) { if ((process_3d_type & MODE_3D_FA) && + cur_dispbuf && !cur_dispbuf->trans_fmt) vf_notify_receiver_by_name("deinterlace", VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE, @@ -10763,14 +11173,21 @@ static ssize_t video_hold_store(struct class *cla, const char *buf, size_t count) { int r; + unsigned int value; + cur_width = 0; + cur_height = 0; if (debug_flag & DEBUG_FLAG_BLACKOUT) pr_info("%s(%s)\n", __func__, buf); - r = kstrtoint(buf, 0, &hold_video); + r = kstrtoint(buf, 0, &value); if (r < 0) return -EINVAL; + if (value == 0 && hold_video == 1) + hold_property_changed = 1; + + hold_video = value; return count; } @@ -10928,6 +11345,8 @@ static ssize_t frame_width_show(struct class *cla, struct class_attribute *attr, char *buf) { + if (hold_video == 1) + return sprintf(buf, "%d\n", cur_width); if (cur_dispbuf) { if (cur_dispbuf->type & VIDTYPE_COMPRESS) return sprintf(buf, "%d\n", cur_dispbuf->compWidth); @@ -10941,6 +11360,8 @@ static ssize_t frame_width_show(struct class *cla, static ssize_t frame_height_show(struct class *cla, struct class_attribute *attr, char *buf) { + if (hold_video == 1) + return sprintf(buf, "%d\n", cur_height); if (cur_dispbuf) { if (cur_dispbuf->type & VIDTYPE_COMPRESS) return sprintf(buf, "%d\n", cur_dispbuf->compHeight); @@ -11557,6 +11978,238 @@ static ssize_t video_zorder_store( return count; } +static ssize_t black_threshold_show( + struct class *cla, + struct class_attribute *attr, + char *buf) +{ + return sprintf(buf, "width: %d, height: %d\n", + black_threshold_width, + black_threshold_height); +} + +static ssize_t black_threshold_store( + struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ + int parsed[2]; + + if (likely(parse_para(buf, 2, parsed) == 2)) { + black_threshold_width = parsed[0]; + black_threshold_height = parsed[1]; + } + return strnlen(buf, count); +} + +static int free_alloced_hist_test_buffer(void) +{ + if (hist_buffer_addr) { + codec_mm_free_for_dma("hist-test", hist_buffer_addr); + hist_buffer_addr = 0; + } + return 0; +} + +static int alloc_hist_test_buffer(u32 size) +{ + int ret = -ENOMEM; + int flags = CODEC_MM_FLAGS_DMA | + CODEC_MM_FLAGS_FOR_VDECODER; + + if (!hist_buffer_addr) { + hist_buffer_addr = codec_mm_alloc_for_dma( + "hist-test", + PAGE_ALIGN(size)/PAGE_SIZE, 0, flags); + } + if (hist_buffer_addr) + ret = 0; + return ret; +} + +static ssize_t hist_test_show( + struct class *cla, + struct class_attribute *attr, + char *buf) +{ +#define VI_HIST_MAX_MIN (0x2e03) +#define VI_HIST_SPL_VAL (0x2e04) +#define VI_HIST_SPL_PIX_CNT (0x2e05) +#define VI_HIST_CHROMA_SUM (0x2e06) + ssize_t len = 0; + u32 hist_result[4]; + + if (hist_test_flag) { + hist_result[0] = READ_VCBUS_REG(VI_HIST_MAX_MIN); + hist_result[1] = READ_VCBUS_REG(VI_HIST_SPL_VAL); + hist_result[2] = READ_VCBUS_REG(VI_HIST_SPL_PIX_CNT); + hist_result[3] = READ_VCBUS_REG(VI_HIST_CHROMA_SUM); + + len += + sprintf(buf + len, "\n======time %d =====\n", + hist_print_count + 1); + len += + sprintf(buf + len, "hist_max_min: 0x%08x\n", + hist_result[0]); + len += + sprintf(buf + len, "hist_spl_val: 0x%08x\n", + hist_result[1]); + len += + sprintf(buf + len, "hist_spl_pix_cnt: 0x%08x\n", + hist_result[2]); + len += + sprintf(buf + len, "hist_chroma_sum: 0x%08x\n", + hist_result[3]); + msleep(50); + hist_print_count++; + } else { + len += + sprintf(buf + len, "no hist data\n"); + } + return len; +} + +static ssize_t hist_test_store( + struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ +#define VI_HIST_CTRL (0x2e00) +#define VI_HIST_H_START_END (0x2e01) +#define VI_HIST_V_START_END (0x2e02) +#define VI_HIST_PIC_SIZE (0x2e28) +#define VIU_EOTF_CTL (0x31d0) +#define XVYCC_LUT_CTL (0x3165) +#define XVYCC_INV_LUT_CTL (0x3164) +#define XVYCC_VD1_RGB_CTRST (0x3170) + int parsed[3]; + int frame_width = 0, frame_height = 0; + int pat_val = 0, canvas_width; + u32 hist_dst_w, hist_dst_h; + const struct vinfo_s *ginfo = get_current_vinfo(); + struct disp_info_s *layer = &glayer_info[0]; + + if (likely(parse_para(buf, 3, parsed) == 3)) { + frame_width = parsed[0]; + frame_height = parsed[1]; + pat_val = parsed[2]; + } + + if (cur_dispbuf + && (cur_dispbuf != &vf_local) + && (cur_dispbuf != &hist_test_vf)) + pat_val = 0; + if (!frame_width || !frame_height) + pat_val = 0; + + if (legacy_vpp) + pat_val = 0; + + if (pat_val > 0 && pat_val <= 0x3fffffff) { + if (!hist_test_flag) { + memset(&hist_test_vf, 0, sizeof(hist_test_vf)); + canvas_width = (frame_width + 31) & (~31); + if (!alloc_hist_test_buffer( + canvas_width * frame_height * 3)) { + hist_test_vf.canvas0Addr = + DISPLAY_CANVAS_BASE_INDEX + 5; + hist_test_vf.canvas1Addr = + DISPLAY_CANVAS_BASE_INDEX + 5; + canvas_config( + DISPLAY_CANVAS_BASE_INDEX + 5, + (unsigned int)hist_buffer_addr, + canvas_width * 3, + frame_height, + CANVAS_ADDR_NOWRAP, + CANVAS_BLKMODE_LINEAR); + hist_test_vf.width = frame_width; + hist_test_vf.height = frame_height; + hist_test_vf.type = VIDTYPE_VIU_444 | + VIDTYPE_VIU_SINGLE_PLANE | + VIDTYPE_VIU_FIELD | VIDTYPE_PIC; + /* indicate the vframe is a full range frame */ + hist_test_vf.signal_type = + /* HD default 709 limit */ + (1 << 29) /* video available */ + | (5 << 26) /* unspecified */ + | (1 << 25) /* full */ + | (1 << 24) /* color available */ + | (1 << 16) /* bt709 */ + | (1 << 8) /* bt709 */ + | (1 << 0); /* bt709 */ + hist_test_vf.duration_pulldown = 0; + hist_test_vf.index = 0; + hist_test_vf.pts = 0; + hist_test_vf.pts_us64 = 0; + hist_test_vf.ratio_control = 0; + hist_test_flag = true; + WRITE_VCBUS_REG(VIU_EOTF_CTL, 0); + WRITE_VCBUS_REG(XVYCC_LUT_CTL, 0); + WRITE_VCBUS_REG(XVYCC_INV_LUT_CTL, 0); + WRITE_VCBUS_REG(VPP_VADJ_CTRL, 0); + WRITE_VCBUS_REG(VPP_GAINOFF_CTRL0, 0); + WRITE_VCBUS_REG(VPP_VE_ENABLE_CTRL, 0); + WRITE_VCBUS_REG(XVYCC_VD1_RGB_CTRST, 0); + if (ginfo) { + if (ginfo->width > + (layer->layer_width + + layer->layer_left)) + hist_dst_w = + layer->layer_width + + layer->layer_left; + else + hist_dst_w = + ginfo->width; + if (ginfo->field_height > + (layer->layer_height + + layer->layer_top)) + hist_dst_h = + layer->layer_height + + layer->layer_top; + else + hist_dst_h = + ginfo->field_height; + WRITE_VCBUS_REG( + VI_HIST_H_START_END, + hist_dst_w & 0xfff); + WRITE_VCBUS_REG( + VI_HIST_V_START_END, + (hist_dst_h - 2) & 0xfff); + WRITE_VCBUS_REG( + VI_HIST_PIC_SIZE, + (ginfo->width & 0xfff) | + (ginfo->field_height << 16)); + WRITE_VCBUS_REG(VI_HIST_CTRL, 0x3803); + } else { + WRITE_VCBUS_REG( + VI_HIST_H_START_END, 0); + WRITE_VCBUS_REG( + VI_HIST_V_START_END, 0); + WRITE_VCBUS_REG( + VI_HIST_PIC_SIZE, + (ginfo->width & 0xfff) | + (ginfo->field_height << 16)); + WRITE_VCBUS_REG(VI_HIST_CTRL, 0x3801); + } + } + } + WRITE_VCBUS_REG(VPP_VD1_CLIP_MISC0, pat_val); + WRITE_VCBUS_REG(VPP_VD1_CLIP_MISC1, pat_val); + WRITE_VCBUS_REG(DOLBY_PATH_CTRL, 0x3f); + msleep(50); + hist_print_count = 0; + } else if (hist_test_flag) { + hist_test_flag = false; + msleep(50); + free_alloced_hist_test_buffer(); + WRITE_VCBUS_REG(VPP_VD1_CLIP_MISC0, 0x3fffffff); + WRITE_VCBUS_REG(VPP_VD1_CLIP_MISC1, 0); + WRITE_VCBUS_REG(DOLBY_PATH_CTRL, 0xf); + safe_disble_videolayer(); + } + return strnlen(buf, count); +} + #ifdef VIDEO_PIP int _videopip_set_disable(u32 val) { @@ -12079,6 +12732,14 @@ static struct class_attribute amvideo_class_attrs[] = { 0664, video_zorder_show, video_zorder_store), + __ATTR(black_threshold, + 0664, + black_threshold_show, + black_threshold_store), + __ATTR(hist_test, + 0664, + hist_test_show, + hist_test_store), __ATTR_RO(frame_addr), __ATTR_RO(frame_canvas_width), __ATTR_RO(frame_canvas_height), @@ -12585,17 +13246,17 @@ static int __init video_early_init(void) WRITE_VCBUS_REG_BITS( VPP_MISC1, 0x100, 0, 9); } - if (is_meson_tl1_cpu()) { + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { /* force bypass dolby for TL1, no dolby function */ - WRITE_VCBUS_REG_BITS( - DOLBY_PATH_CTRL, 0xf, 0, 6); + if (is_meson_tl1_cpu()) + WRITE_VCBUS_REG_BITS( + DOLBY_PATH_CTRL, 0xf, 0, 6); /* disable latch for sr core0/1 scaler */ WRITE_VCBUS_REG_BITS( SRSHARP0_SHARP_SYNC_CTRL, 1, 0, 1); WRITE_VCBUS_REG_BITS( SRSHARP1_SHARP_SYNC_CTRL, 1, 8, 1); - } - if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12B)) + } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12B)) WRITE_VCBUS_REG_BITS( SRSHARP0_SHARP_SYNC_CTRL, 1, 0, 1); return 0; @@ -12852,10 +13513,28 @@ static int __init video_init(void) /* make vd1 below vd2 */ for (i = 0; i < MAX_VD_LAYERS; i++) { vpp_disp_info_init(&glayer_info[i], i); + memset(&gPic_info[i], 0, sizeof(struct vframe_pic_mode_s)); glayer_info[i].wide_mode = 1; glayer_info[i].zorder = reference_zorder - 2 + i; glayer_info[i].cur_sel_port = i; glayer_info[i].last_sel_port = i; + if (legacy_vpp) { + glayer_info[i].afbc_support = true; + glayer_info[i].pps_support = + (i == 0) ? true : false; + } else if (is_meson_tl1_cpu()) { + glayer_info[i].afbc_support = + (i == 0) ? true : false; + glayer_info[i].pps_support = + (i == 0) ? true : false; + } else if (is_meson_tm2_cpu()) { + glayer_info[i].afbc_support = + (i == 0) ? true : false; + glayer_info[i].pps_support = true; + } else { + glayer_info[i].afbc_support = true; + glayer_info[i].pps_support = true; + } } if (legacy_vpp) @@ -12871,6 +13550,13 @@ static int __init video_init(void) LAYER0_AFBC | LAYER0_SCALER | LAYER0_AVAIL; + else if (is_meson_tm2_cpu()) + layer_cap = + LAYER1_SCALER | + LAYER1_AVAIL | + LAYER0_AFBC | + LAYER0_SCALER | + LAYER0_AVAIL; else layer_cap = LAYER1_AFBC | diff --git a/drivers/amlogic/media/video_sink/video_priv.h b/drivers/amlogic/media/video_sink/video_priv.h index c445c7cc4397e..159be8968598d 100644 --- a/drivers/amlogic/media/video_sink/video_priv.h +++ b/drivers/amlogic/media/video_sink/video_priv.h @@ -50,6 +50,7 @@ #define VIDEO_NOTIFY_PROVIDER_PUT 0x04 #define VIDEO_NOTIFY_FRAME_WAIT 0x08 #define VIDEO_NOTIFY_POS_CHANGED 0x10 +#define VIDEO_NOTIFY_NEED_NO_COMP 0x20 struct video_dev_s { int vpp_off; diff --git a/drivers/amlogic/media/video_sink/vpp.c b/drivers/amlogic/media/video_sink/vpp.c index c381f6dcc5d0c..28094877a50c5 100644 --- a/drivers/amlogic/media/video_sink/vpp.c +++ b/drivers/amlogic/media/video_sink/vpp.c @@ -589,6 +589,9 @@ module_param(cur_skip_ratio, uint, 0444); static unsigned int cur_vf_type; MODULE_PARM_DESC(cur_vf_type, "cur_vf_type"); module_param(cur_vf_type, uint, 0444); +static unsigned int cur_freq_ratio; +MODULE_PARM_DESC(cur_freq_ratio, "cur_freq_ratio"); +module_param(cur_freq_ratio, uint, 0444); static unsigned int custom_ar; MODULE_PARM_DESC(custom_ar, "custom_ar"); @@ -598,6 +601,10 @@ static unsigned int force_use_ext_ar; MODULE_PARM_DESC(force_use_ext_ar, "force_use_ext_ar"); module_param(force_use_ext_ar, uint, 0664); +static unsigned int force_no_compress; +MODULE_PARM_DESC(force_no_compress, "force_no_compress"); +module_param(force_no_compress, uint, 0664); + /* *test on txlx: *Time_out = (V_out/V_screen_total)/FPS_out; @@ -629,6 +636,8 @@ static int vpp_process_speed_check( { u32 cur_ratio, bpp = 1; int min_ratio_1000 = 0; + int freq_ratio = 1; + u32 sync_duration_den = 1; u32 vtotal, htotal = 0, clk_in_pps = 0, clk_vpu = 0, clk_temp; u32 input_time_us = 0, display_time_us = 0, dummy_time_us = 0; u32 width_out = 0; @@ -647,6 +656,9 @@ static int vpp_process_speed_check( if (next_frame_par->vscale_skip_count < force_vskip_cnt) return SPEED_CHECK_VSKIP; + if (vinfo->sync_duration_den > 0) + sync_duration_den = vinfo->sync_duration_den; + if (vf->type & VIDTYPE_PRE_INTERLACE) { if (is_meson_txlx_cpu()) clk_in_pps = 250000000; @@ -694,13 +706,22 @@ static int vpp_process_speed_check( if (clk_temp) dummy_time_us = (vtotal * htotal - height_out * width_out) / clk_temp; - display_time_us = 1000000 * vinfo->sync_duration_den / + display_time_us = 1000000 * sync_duration_den / vinfo->sync_duration_num; if (display_time_us > dummy_time_us) display_time_us = display_time_us - dummy_time_us; if (input_time_us > display_time_us) return SPEED_CHECK_VSKIP; } + + if ((vinfo->sync_duration_num / sync_duration_den) > 60) + freq_ratio = vinfo->sync_duration_num / + sync_duration_den / 60; + + if (freq_ratio < 1) + freq_ratio = 1; + cur_freq_ratio = freq_ratio; + /* #if (MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8) */ if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) && !is_meson_mtvd_cpu()) { if ((width_in <= 0) || (height_in <= 0) || (height_out <= 0) @@ -723,7 +744,7 @@ static int vpp_process_speed_check( MESON_CPU_MAJOR_ID_GXBB) { cur_ratio = div_u64((u64)height_in * (u64)vinfo->height * - 1000, + 1000 * freq_ratio, height_out * max_height); /* di process first, need more a bit of ratio */ if (vf->type & VIDTYPE_PRE_INTERLACE) @@ -752,7 +773,7 @@ static int vpp_process_speed_check( (u64)vinfo->sync_duration_num * (u64)vtotal, height_out * - vinfo->sync_duration_den * + sync_duration_den * bypass_ratio) > clk_in_pps) return SPEED_CHECK_VSKIP; else @@ -766,7 +787,7 @@ static int vpp_process_speed_check( (u64)vinfo->sync_duration_num * (u64)vtotal, height_out * - vinfo->sync_duration_den * 256) + sync_duration_den * 256) > clk_in_pps) return SPEED_CHECK_VSKIP; /* 4K down scaling to non 4K > 30hz,*/ @@ -776,7 +797,7 @@ static int vpp_process_speed_check( && (height_in > 2048) && (height_out < 2048) && (vinfo->sync_duration_num > - (30 * vinfo->sync_duration_den)) + (30 * sync_duration_den)) && (get_cpu_type() != MESON_CPU_MAJOR_ID_GXTVBB) && (get_cpu_type() != @@ -789,7 +810,7 @@ static int vpp_process_speed_check( /*TODO vpu */ if (div_u64(VPP_SPEED_FACTOR * width_in * vinfo->sync_duration_num * height_screen, - vinfo->sync_duration_den * 256) + sync_duration_den * 256) > get_vpu_clk()) return SPEED_CHECK_HSKIP; else @@ -871,8 +892,11 @@ static int vpp_set_filters_internal( u32 vert_chroma_filter; struct filter_info_s *cur_filter; s32 vpp_zoom_center_x, vpp_zoom_center_y; + u32 crop_ratio = 1; + u32 crop_left, crop_right, crop_top, crop_bottom; u32 sar_width = 0, sar_height = 0; bool ext_sar = false; + bool no_compress = false; if (!input) return VppFilter_Fail; @@ -896,7 +920,8 @@ static int vpp_set_filters_internal( reverse = input->reverse; #endif - if (vf->type & VIDTYPE_MVC) { + if ((vf->type & VIDTYPE_MVC) || + (input->proc_3d_type & MODE_3D_ENABLE)) { video_source_crop_left = 0; video_source_crop_right = 0; video_source_crop_top = 0; @@ -908,20 +933,6 @@ static int vpp_set_filters_internal( video_source_crop_bottom = input->crop_bottom; } - if (likely(w_in > - (video_source_crop_left + video_source_crop_right))) { - w_in -= video_source_crop_left; - w_in -= video_source_crop_right; - h_crop_enable = true; - } - - if (likely(h_in > - (video_source_crop_top + video_source_crop_bottom))) { - h_in -= video_source_crop_top; - h_in -= video_source_crop_bottom; - v_crop_enable = true; - } - #ifndef TV_3D_FUNCTION_OPEN next_frame_par->vscale_skip_count = 0; next_frame_par->hscale_skip_count = 0; @@ -947,6 +958,25 @@ static int vpp_set_filters_internal( pr_info("sar_width=%d, sar_height = %d, %d\n", vf->sar_width, vf->sar_height, force_use_ext_ar); +RESTART_ALL: + crop_left = video_source_crop_left / crop_ratio; + crop_right = video_source_crop_right / crop_ratio; + crop_top = video_source_crop_top / crop_ratio; + crop_bottom = video_source_crop_bottom / crop_ratio; + + if (likely(w_in > + (crop_left + crop_right))) { + w_in -= crop_left; + w_in -= crop_right; + h_crop_enable = true; + } + + if (likely(h_in > + (crop_top + crop_bottom))) { + h_in -= crop_top; + h_in -= crop_bottom; + v_crop_enable = true; + } RESTART: aspect_factor = (vpp_flags & VPP_FLAG_AR_MASK) >> VPP_FLAG_AR_BITS; @@ -1268,8 +1298,8 @@ static int vpp_set_filters_internal( } if (v_crop_enable) { - next_frame_par->VPP_vd_start_lines_ += video_source_crop_top; - next_frame_par->VPP_vd_end_lines_ += video_source_crop_top; + next_frame_par->VPP_vd_start_lines_ += crop_top; + next_frame_par->VPP_vd_end_lines_ += crop_top; } if (vpp_flags & VPP_FLAG_INTERLACE_IN) @@ -1386,8 +1416,8 @@ static int vpp_set_filters_internal( } if (h_crop_enable) { - next_frame_par->VPP_hd_start_lines_ += video_source_crop_left; - next_frame_par->VPP_hd_end_lines_ += video_source_crop_left; + next_frame_par->VPP_hd_start_lines_ += crop_left; + next_frame_par->VPP_hd_end_lines_ += crop_left; } next_frame_par->VPP_line_in_length_ = @@ -1467,10 +1497,21 @@ static int vpp_set_filters_internal( } if ((vf->type & VIDTYPE_COMPRESS) && + !(vf->type & VIDTYPE_NO_DW) && (vf->canvas0Addr != 0) && - (next_frame_par->vscale_skip_count > 1) && (!next_frame_par->nocomp)) { - pr_info( + if ((vpp_flags & VPP_FLAG_FORCE_NO_COMPRESS) + || (next_frame_par->vscale_skip_count > 1) + || !input->afbc_support + || force_no_compress) + no_compress = true; + } else + no_compress = false; + + if (no_compress) { + if ((vpp_flags & VPP_FLAG_MORE_LOG) + && input->afbc_support) + pr_info( "layer%d: Try DW buffer for compressed frame scaling.\n", input->layer_id); @@ -1482,7 +1523,9 @@ static int vpp_set_filters_internal( h_in = height_in = vf->height; next_frame_par->hscale_skip_count = 0; next_frame_par->vscale_skip_count = 0; - goto RESTART; + if (vf->width && vf->compWidth) + crop_ratio = vf->compWidth / vf->width; + goto RESTART_ALL; } if ((skip_policy & 0xf0) && (skip_policy_check == true)) { @@ -1657,6 +1700,10 @@ static int vpp_set_filters_internal( next_frame_par->vscale_skip_count; } + if ((next_frame_par->vscale_skip_count > 1) + && (vf->type & VIDTYPE_COMPRESS) + && (vf->type & VIDTYPE_NO_DW)) + ret = VppFilter_Changed_but_Hold; return ret; } /* @@ -1812,10 +1859,12 @@ int vpp_set_super_scaler_regs( if (is_meson_txhd_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || - is_meson_sm1_cpu() || - (is_meson_tl1_cpu() && + is_meson_sm1_cpu()) + tmp_data = ((reg_srscl0_hsize & 0x1fff) << 16) | + (reg_srscl0_vsize & 0x1fff); + else if ((is_meson_tl1_cpu() || is_meson_tm2_cpu()) && ((scaler_path_sel == PPS_CORE0_CORE1) || - (scaler_path_sel == PPS_CORE0_POSTBLEND_CORE1)))) + (scaler_path_sel == PPS_CORE0_POSTBLEND_CORE1))) tmp_data = ((reg_srscl0_hsize & 0x1fff) << 16) | (reg_srscl0_vsize & 0x1fff); else @@ -2212,7 +2261,7 @@ static void vpp_set_super_scaler( sr_path = next_frame_par->supscl_path; /* path config */ - if (is_meson_tl1_cpu()) { + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { if (sr_path == CORE0_PPS_CORE1) { next_frame_par->sr0_position = 1; next_frame_par->sr1_position = 1; @@ -2325,7 +2374,15 @@ static void vpp_get_video_source_size( u32 process_3d_type, struct vframe_s *vf, struct vpp_frame_par_s *next_frame_par) { + int frame_width, frame_height; + if (vf->type & VIDTYPE_COMPRESS) { + frame_width = vf->compWidth; + frame_height = vf->compHeight; + } else { + frame_width = vf->width; + frame_height = vf->height; + } if ((process_3d_type & MODE_3D_AUTO) || (((process_3d_type & MODE_3D_TO_2D_R) || (process_3d_type & MODE_3D_TO_2D_L) || @@ -2369,8 +2426,8 @@ static void vpp_get_video_source_size( break; case TVIN_TFMT_3D_DET_CHESSBOARD: default: - *src_width = vf->width; - *src_height = vf->height; + *src_width = frame_width; + *src_height = frame_height; next_frame_par->vpp_3d_mode = VPP_3D_MODE_NULL; next_frame_par->vpp_3d_scale = 0; next_frame_par->vpp_2pic_mode = 0; @@ -2381,15 +2438,15 @@ static void vpp_get_video_source_size( (process_3d_type & MODE_FORCE_3D_LR)) { next_frame_par->vpp_3d_mode = VPP_3D_MODE_LR; if (process_3d_type & MODE_3D_TO_2D_MASK) { - *src_width = vf->width >> 1; - *src_height = vf->height; + *src_width = frame_width >> 1; + *src_height = frame_height; } else if (process_3d_type & MODE_3D_OUT_LR) { - *src_width = vf->width; - *src_height = vf->height; + *src_width = frame_width; + *src_height = frame_height; next_frame_par->vpp_2pic_mode = 1; } else { - *src_width = vf->width >> 1; - *src_height = vf->height << 1; + *src_width = frame_width >> 1; + *src_height = frame_height << 1; next_frame_par->vpp_2pic_mode = 1; } @@ -2397,38 +2454,38 @@ static void vpp_get_video_source_size( (process_3d_type & MODE_FORCE_3D_TB)) { next_frame_par->vpp_3d_mode = VPP_3D_MODE_TB; if (process_3d_type & MODE_3D_TO_2D_MASK) { - *src_width = vf->width; - *src_height = vf->height >> 1; + *src_width = frame_width; + *src_height = frame_height >> 1; } else if (process_3d_type & MODE_3D_OUT_LR) { - *src_width = vf->width << 1; - *src_height = vf->height >> 1; + *src_width = frame_width << 1; + *src_height = frame_height >> 1; next_frame_par->vpp_2pic_mode = 1; } else { - *src_width = vf->width; - *src_height = vf->height; + *src_width = frame_width; + *src_height = frame_height; next_frame_par->vpp_2pic_mode = 1; } if (process_3d_type & MODE_3D_MVC) { - *src_width = vf->width; - *src_height = vf->height << 1; + *src_width = frame_width; + *src_height = frame_height << 1; next_frame_par->vpp_2pic_mode = 2; next_frame_par->vpp_3d_mode = VPP_3D_MODE_FA; } } else if (process_3d_type & MODE_3D_LA) { next_frame_par->vpp_3d_mode = VPP_3D_MODE_LA; - *src_height = vf->height - 1; - *src_width = vf->width; + *src_height = frame_height - 1; + *src_width = frame_width; next_frame_par->vpp_2pic_mode = 0; next_frame_par->vpp_3d_scale = 1; if (process_3d_type & MODE_3D_TO_2D_MASK) { next_frame_par->vscale_skip_count = 1; next_frame_par->vpp_3d_scale = 0; } else if (process_3d_type & MODE_3D_OUT_TB) { - *src_height = vf->height << 1; + *src_height = frame_height << 1; next_frame_par->vscale_skip_count = 1; next_frame_par->vpp_3d_scale = 0; } else if (process_3d_type & MODE_3D_OUT_LR) { - *src_width = vf->width << 1; + *src_width = frame_width << 1; next_frame_par->vscale_skip_count = 1; next_frame_par->vpp_3d_scale = 0; } @@ -2440,37 +2497,37 @@ static void vpp_get_video_source_size( if (process_3d_type & MODE_3D_TO_2D_MASK) { if (process_3d_type & MODE_FORCE_3D_FA_TB) { next_frame_par->vpp_3d_mode = VPP_3D_MODE_TB; - *src_width = vf->width; - *src_height = vf->height >> 1; + *src_width = frame_width; + *src_height = frame_height >> 1; } if (process_3d_type & MODE_FORCE_3D_FA_LR) { next_frame_par->vpp_3d_mode = VPP_3D_MODE_LR; - *src_width = vf->width >> 1; - *src_height = vf->height; + *src_width = frame_width >> 1; + *src_height = frame_height; } if (process_3d_type & MODE_3D_MVC) { - *src_width = vf->width; - *src_height = vf->height; + *src_width = frame_width; + *src_height = frame_height; next_frame_par->vpp_3d_mode = VPP_3D_MODE_FA; } if (vf->trans_fmt == TVIN_TFMT_3D_FP) { next_frame_par->vpp_3d_mode = VPP_3D_MODE_TB; - *src_width = vf->width; + *src_width = frame_width; *src_height = vf->left_eye.height; } next_frame_par->vpp_2pic_mode = 0; } else if (process_3d_type & MODE_3D_OUT_LR) { - *src_width = vf->width << 1; - *src_height = vf->height; + *src_width = frame_width << 1; + *src_height = frame_height; next_frame_par->vpp_2pic_mode = 2; } else { - *src_width = vf->width; - *src_height = vf->height << 1; + *src_width = frame_width; + *src_height = frame_height << 1; next_frame_par->vpp_2pic_mode = 2; } } else { - *src_width = vf->width; - *src_height = vf->height; + *src_width = frame_width; + *src_height = frame_height; next_frame_par->vpp_3d_mode = VPP_3D_MODE_NULL; next_frame_par->vpp_2pic_mode = 0; next_frame_par->vpp_3d_scale = 0; @@ -2497,8 +2554,8 @@ static void vpp_get_video_source_size( } /*avoid dividing 0 error */ if (*src_width == 0 || *src_height == 0) { - *src_width = vf->width; - *src_height = vf->height; + *src_width = frame_width; + *src_height = frame_height; } } #endif @@ -2538,6 +2595,9 @@ static int vpp_set_filters_no_scaler_internal( bool reverse = false; #endif int ret = VppFilter_Success; + u32 crop_ratio = 1; + u32 crop_left, crop_right, crop_top, crop_bottom; + bool no_compress = false; if (!input) return VppFilter_Fail; @@ -2553,7 +2613,8 @@ static int vpp_set_filters_no_scaler_internal( reverse = input->reverse; #endif - if (vf->type & VIDTYPE_MVC) { + if ((vf->type & VIDTYPE_MVC) || + (input->proc_3d_type & MODE_3D_ENABLE)) { video_source_crop_left = 0; video_source_crop_right = 0; video_source_crop_top = 0; @@ -2565,20 +2626,6 @@ static int vpp_set_filters_no_scaler_internal( video_source_crop_bottom = input->crop_bottom; } - if (likely(w_in > - (video_source_crop_left + video_source_crop_right))) { - w_in -= video_source_crop_left; - w_in -= video_source_crop_right; - h_crop_enable = true; - } - - if (likely(h_in > - (video_source_crop_top + video_source_crop_bottom))) { - h_in -= video_source_crop_top; - h_in -= video_source_crop_bottom; - v_crop_enable = true; - } - next_frame_par->vscale_skip_count = 0; next_frame_par->hscale_skip_count = 0; next_frame_par->nocomp = false; @@ -2592,6 +2639,26 @@ static int vpp_set_filters_no_scaler_internal( else vskip_step = 1; +RESTART_ALL: + crop_left = video_source_crop_left / crop_ratio; + crop_right = video_source_crop_right / crop_ratio; + crop_top = video_source_crop_top / crop_ratio; + crop_bottom = video_source_crop_bottom / crop_ratio; + + if (likely(w_in > + (crop_left + crop_right))) { + w_in -= crop_left; + w_in -= crop_right; + h_crop_enable = true; + } + + if (likely(h_in > + (crop_top + crop_bottom))) { + h_in -= crop_top; + h_in -= crop_bottom; + v_crop_enable = true; + } + RESTART: /* don't use input->wide_mode */ wide_mode = vpp_flags & VPP_FLAG_WIDEMODE_MASK; @@ -2678,8 +2745,8 @@ static int vpp_set_filters_no_scaler_internal( } if (v_crop_enable) { - next_frame_par->VPP_vd_start_lines_ += video_source_crop_top; - next_frame_par->VPP_vd_end_lines_ += video_source_crop_top; + next_frame_par->VPP_vd_start_lines_ += crop_top; + next_frame_par->VPP_vd_end_lines_ += crop_top; } if (vpp_flags & VPP_FLAG_INTERLACE_IN) @@ -2791,8 +2858,8 @@ static int vpp_set_filters_no_scaler_internal( } if (h_crop_enable) { - next_frame_par->VPP_hd_start_lines_ += video_source_crop_left; - next_frame_par->VPP_hd_end_lines_ += video_source_crop_left; + next_frame_par->VPP_hd_start_lines_ += crop_left; + next_frame_par->VPP_hd_end_lines_ += crop_left; } next_frame_par->VPP_line_in_length_ = @@ -2846,10 +2913,21 @@ static int vpp_set_filters_no_scaler_internal( } if ((vf->type & VIDTYPE_COMPRESS) && + !(vf->type & VIDTYPE_NO_DW) && (vf->canvas0Addr != 0) && - (next_frame_par->vscale_skip_count > 1) && (!next_frame_par->nocomp)) { - pr_info( + if ((vpp_flags & VPP_FLAG_FORCE_NO_COMPRESS) + || (next_frame_par->vscale_skip_count > 1) + || !input->afbc_support + || force_no_compress) + no_compress = true; + } else + no_compress = false; + + if (no_compress) { + if ((vpp_flags & VPP_FLAG_MORE_LOG) + && input->afbc_support) + pr_info( "layer%d: Try DW buffer for compressed frame scaling.\n", input->layer_id); @@ -2861,7 +2939,9 @@ static int vpp_set_filters_no_scaler_internal( h_in = height_in = vf->height; next_frame_par->hscale_skip_count = 0; next_frame_par->vscale_skip_count = 0; - goto RESTART; + if (vf->width && vf->compWidth) + crop_ratio = vf->compWidth / vf->width; + goto RESTART_ALL; } if ((skip_policy & 0xf0) && (skip_policy_check == true)) { @@ -2899,6 +2979,10 @@ static int vpp_set_filters_no_scaler_internal( next_frame_par->VPP_line_in_length_ >>= 1; } + if ((next_frame_par->vscale_skip_count > 1) + && (vf->type & VIDTYPE_COMPRESS) + && (vf->type & VIDTYPE_NO_DW)) + ret = VppFilter_Changed_but_Hold; return ret; } @@ -2907,7 +2991,7 @@ int vpp_set_filters( struct vframe_s *vf, struct vpp_frame_par_s *next_frame_par, const struct vinfo_s *vinfo, - bool bypass_sr) + bool bypass_sr, u32 op_flag) { u32 src_width = 0; u32 src_height = 0; @@ -2933,34 +3017,46 @@ int vpp_set_filters( next_frame_par->VPP_post_blend_vd_h_start_ = 0; next_frame_par->VPP_postproc_misc_ = 0x200; -#ifdef TV_3D_FUNCTION_OPEN next_frame_par->vscale_skip_count = 0; next_frame_par->hscale_skip_count = 0; + + if (vf->type & VIDTYPE_COMPRESS) { + src_width = vf->compWidth; + src_height = vf->compHeight; + } else { + src_width = vf->width; + src_height = vf->height; + } + +#ifdef TV_3D_FUNCTION_OPEN /* *check 3d mode change in display buffer or 3d type *get the source size according to 3d mode */ - if (process_3d_type & MODE_3D_ENABLE) { - vpp_get_video_source_size(&src_width, &src_height, - process_3d_type, vf, next_frame_par); - } else { - if (vf->type & VIDTYPE_COMPRESS) { - src_width = vf->compWidth; - src_height = vf->compHeight; + if (local_input.layer_id == 0) { + if (process_3d_type & MODE_3D_ENABLE) { + vpp_get_video_source_size( + &src_width, &src_height, + process_3d_type, + vf, next_frame_par); } else { - src_width = vf->width; - src_height = vf->height; + next_frame_par->vpp_3d_mode = + VPP_3D_MODE_NULL; + next_frame_par->vpp_2pic_mode = 0; + next_frame_par->vpp_3d_scale = 0; } + next_frame_par->trans_fmt = vf->trans_fmt; + get_vpp_3d_mode(process_3d_type, + next_frame_par->trans_fmt, + &next_frame_par->vpp_3d_mode); + if (local_input.vpp_3d_scale) + next_frame_par->vpp_3d_scale = 1; + } else { next_frame_par->vpp_3d_mode = VPP_3D_MODE_NULL; next_frame_par->vpp_2pic_mode = 0; next_frame_par->vpp_3d_scale = 0; + next_frame_par->trans_fmt = vf->trans_fmt; } - next_frame_par->trans_fmt = vf->trans_fmt; - get_vpp_3d_mode(process_3d_type, - next_frame_par->trans_fmt, - &next_frame_par->vpp_3d_mode); - if (local_input.vpp_3d_scale) - next_frame_par->vpp_3d_scale = 1; amlog_mask(LOG_MASK_VPP, "%s: src_width %u,src_height %u.\n", __func__, src_width, src_height); #endif @@ -2985,6 +3081,18 @@ int vpp_set_filters( aspect_ratio = (vf->ratio_control & DISP_RATIO_ASPECT_RATIO_MASK) >> DISP_RATIO_ASPECT_RATIO_BIT; + if (!aspect_ratio) { + u32 sar_width, sar_height; + + if (vf->type & VIDTYPE_COMPRESS) { + sar_width = vf->compWidth; + sar_height = vf->compHeight; + } else { + sar_width = vf->width; + sar_height = vf->height; + } + aspect_ratio = (sar_height << 8) / sar_width; + } /* the height from vdin afbc will be half */ /* so need no interlace in */ if ((vf->type & VIDTYPE_INTERLACE) @@ -2996,15 +3104,6 @@ int vpp_set_filters( if (vf->type & VIDTYPE_VSCALE_DISABLE) vpp_flags |= VPP_FLAG_VSCALE_DISABLE; -#ifndef TV_3D_FUNCTION_OPEN - if (vf->type & VIDTYPE_COMPRESS) { - src_width = vf->compWidth; - src_height = vf->compHeight; - } else { - src_width = vf->width; - src_height = vf->height; - } -#endif if ((vf->ratio_control & DISP_RATIO_ADAPTED_PICMODE) && !disable_adapted) { @@ -3036,6 +3135,9 @@ int vpp_set_filters( } } + if (!local_input.pps_support) + wide_mode = VIDEO_WIDEOPTION_NORMAL; + /* don't restore the wide mode */ /* input->wide_mode = wide_mode; */ vpp_flags |= wide_mode | (aspect_ratio << VPP_FLAG_AR_BITS); @@ -3043,15 +3145,30 @@ int vpp_set_filters( if (vinfo->field_height != vinfo->height) vpp_flags |= VPP_FLAG_INTERLACE_OUT; + if (op_flag & 1) + vpp_flags |= VPP_FLAG_MORE_LOG; + + if (local_input.need_no_compress) + vpp_flags |= VPP_FLAG_FORCE_NO_COMPRESS; + next_frame_par->VPP_post_blend_vd_v_end_ = vinfo->field_height - 1; next_frame_par->VPP_post_blend_vd_h_end_ = vinfo->width - 1; next_frame_par->VPP_post_blend_h_size_ = vinfo->width; - ret = vpp_set_filters_internal( - &local_input, src_width, src_height, - vinfo->width, vinfo->height, - vinfo, vpp_flags, next_frame_par, vf); - + if (local_input.pps_support) + ret = vpp_set_filters_internal( + &local_input, src_width, src_height, + vinfo->width, vinfo->height, + vinfo, vpp_flags, next_frame_par, vf); + else + ret = vpp_set_filters_no_scaler_internal( + &local_input, src_width, src_height, + vinfo->width, vinfo->height, + vinfo, vpp_flags, next_frame_par, vf); + + /* bypass sr since the input w/h may be wrong */ + if (ret == VppFilter_Changed_but_Hold) + bypass_sr = true; /*config super scaler after set next_frame_par is calc ok for pps*/ if (local_input.layer_id == 0) vpp_set_super_scaler( @@ -3062,90 +3179,6 @@ int vpp_set_filters( return ret; } -int vpp_set_filters_no_scaler( - struct disp_info_s *input, - struct vframe_s *vf, - struct vpp_frame_par_s *next_frame_par, - const struct vinfo_s *vinfo) -{ - u32 src_width = 0; - u32 src_height = 0; - u32 vpp_flags = 0; - u32 aspect_ratio = 0; - u32 wide_mode; - int ret = VppFilter_Fail; - struct disp_info_s local_input; - - if (!input) - return ret; - - WARN_ON(vinfo == NULL); - - /* use local var to avoid the input data be overwriten */ - memcpy(&local_input, input, sizeof(struct disp_info_s)); - /* wide_mode = local_input.wide_mode; */ - wide_mode = VIDEO_WIDEOPTION_NORMAL; - next_frame_par->VPP_post_blend_vd_v_start_ = 0; - next_frame_par->VPP_post_blend_vd_h_start_ = 0; - - next_frame_par->VPP_postproc_misc_ = 0x200; - next_frame_par->vscale_skip_count = 0; - next_frame_par->hscale_skip_count = 0; - if (vf->type & VIDTYPE_COMPRESS) { - src_width = vf->compWidth; - src_height = vf->compHeight; - } else { - src_width = vf->width; - src_height = vf->height; - } -#ifdef TV_3D_FUNCTION_OPEN - next_frame_par->vpp_3d_mode = VPP_3D_MODE_NULL; - next_frame_par->vpp_2pic_mode = 0; - next_frame_par->vpp_3d_scale = 0; - next_frame_par->trans_fmt = vf->trans_fmt; -#endif - - if (vf->type & VIDTYPE_INTERLACE) - vpp_flags = VPP_FLAG_INTERLACE_IN; - - if ((vf->ratio_control & DISP_RATIO_ADAPTED_PICMODE) - && !disable_adapted) { - if (vf->pic_mode.provider == PIC_MODE_PROVIDER_WSS) { - /* from wss, need add global setting */ - local_input.crop_top += vf->pic_mode.vs; - local_input.crop_left += vf->pic_mode.hs; - local_input.crop_bottom += vf->pic_mode.ve; - local_input.crop_right += vf->pic_mode.he; - } else { - /* from PQ database, final setting */ - local_input.crop_top = vf->pic_mode.vs; - local_input.crop_left = vf->pic_mode.hs; - local_input.crop_bottom = vf->pic_mode.ve; - local_input.crop_right = vf->pic_mode.he; - } - } - - aspect_ratio = - (vf->ratio_control & DISP_RATIO_ASPECT_RATIO_MASK) - >> DISP_RATIO_ASPECT_RATIO_BIT; - - /* don't restore the wide mode */ - /* input->wide_mode = wide_mode; */ - vpp_flags |= wide_mode | (aspect_ratio << VPP_FLAG_AR_BITS); - - if (vinfo->field_height != vinfo->height) - vpp_flags |= VPP_FLAG_INTERLACE_OUT; - - next_frame_par->VPP_post_blend_vd_v_end_ = vinfo->field_height - 1; - next_frame_par->VPP_post_blend_vd_h_end_ = vinfo->width - 1; - next_frame_par->VPP_post_blend_h_size_ = vinfo->width; - - ret = vpp_set_filters_no_scaler_internal( - &local_input, src_width, src_height, - vinfo->width, vinfo->height, - vinfo, vpp_flags, next_frame_par, vf); - return ret; -} s32 vpp_set_nonlinear_factor( struct disp_info_s *info, u32 f) { @@ -3187,8 +3220,11 @@ void vpp_super_scaler_support(void) is_meson_sm1_cpu()) { sr_support |= SUPER_CORE0_SUPPORT; sr_support &= ~SUPER_CORE1_SUPPORT; - } else if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() || - is_meson_txlx_cpu() || is_meson_tl1_cpu()) { + } else if (is_meson_gxtvbb_cpu() + || is_meson_txl_cpu() + || is_meson_txlx_cpu() + || is_meson_tl1_cpu() + || is_meson_tm2_cpu()) { sr_support |= SUPER_CORE0_SUPPORT; sr_support |= SUPER_CORE1_SUPPORT; } else { @@ -3204,7 +3240,8 @@ void vpp_super_scaler_support(void) is_meson_sm1_cpu()) { sr_reg_offt = 0xc00; sr_reg_offt2 = 0x00; - } else if (is_meson_tl1_cpu()) { + } else if (is_meson_tl1_cpu() + || is_meson_tm2_cpu()) { sr_reg_offt = 0xc00; sr_reg_offt2 = 0xc80; } else { diff --git a/include/linux/amlogic/media/registers/regs/vpp_regs.h b/include/linux/amlogic/media/registers/regs/vpp_regs.h index af2df43290630..41d9f1b67b38b 100644 --- a/include/linux/amlogic/media/registers/regs/vpp_regs.h +++ b/include/linux/amlogic/media/registers/regs/vpp_regs.h @@ -192,6 +192,8 @@ #define VPP_CLIP_MISC0 0x1dd9 #define VPP_CLIP_MISC1 0x1dda +#define VPP_VD1_CLIP_MISC0 0x1de1 +#define VPP_VD1_CLIP_MISC1 0x1de2 #define VPP2_MISC 0x1e26 #define VPP2_OFIFO_SIZE 0x1e27 diff --git a/include/linux/amlogic/media/vfm/vframe.h b/include/linux/amlogic/media/vfm/vframe.h index 8214dcff58243..faf3d7a6e6307 100644 --- a/include/linux/amlogic/media/vfm/vframe.h +++ b/include/linux/amlogic/media/vfm/vframe.h @@ -49,6 +49,7 @@ #define VIDTYPE_COMB_MODE 0x2000000 #define VIDTYPE_NO_DW 0x4000000 #define VIDTYPE_SUPPORT_COMPRESS 0x8000000 +#define VIDTYPE_PRE_DI_AFBC 0x10000000 #define DISP_RATIO_FORCECONFIG 0x80000000 #define DISP_RATIO_FORCE_NORMALWIDE 0x40000000 diff --git a/include/linux/amlogic/media/video_sink/vpp.h b/include/linux/amlogic/media/video_sink/vpp.h index f61c44dacc4a0..a09e4701848eb 100644 --- a/include/linux/amlogic/media/video_sink/vpp.h +++ b/include/linux/amlogic/media/video_sink/vpp.h @@ -34,6 +34,8 @@ extern bool super_scaler; #define VPP_FLAG_AR_BITS 8 #define VPP_FLAG_PORTRAIT_MODE 0x00040000 #define VPP_FLAG_VSCALE_DISABLE 0x00080000 +#define VPP_FLAG_MORE_LOG 0x00100000 +#define VPP_FLAG_FORCE_NO_COMPRESS 0x00200000 #define IDX_H (2 << 8) #define IDX_V_Y (1 << 13) @@ -52,6 +54,7 @@ enum vppfilter_state_e { VppFilter_Fail = -1, VppFilter_Success = 0, VppFilter_Success_and_Changed, + VppFilter_Changed_but_Hold, }; enum f2v_vphase_type_e { @@ -187,6 +190,11 @@ struct disp_info_s { u32 zorder; u32 cur_sel_port; u32 last_sel_port; + + bool afbc_support; + bool pps_support; + + bool need_no_compress; }; enum select_scaler_path_e { @@ -285,13 +293,7 @@ extern int vpp_set_filters( struct vframe_s *vf, struct vpp_frame_par_s *next_frame_par, const struct vinfo_s *vinfo, - bool bypass_sr); - -extern int vpp_set_filters_no_scaler( - struct disp_info_s *input, - struct vframe_s *vf, - struct vpp_frame_par_s *next_frame_par, - const struct vinfo_s *vinfo); + bool bypass_sr, u32 op_flag); extern s32 vpp_set_nonlinear_factor( struct disp_info_s *info, u32 f);