vpp: improve pre-link function in vpp [1/2]

PD#SWPL-118311

Problem:
1. vf->vf_ext may be freed when vpp used. It will occur crash.
So need switch to uvm src_vf.
2. change vskip policy for prelink mode
3. t5d revb need switch afbcd between DI and vd1.

Solution:
1. add uvm_vf in vframe to link to uvm src_vf
2. change vskip policy for prelink mode
3. change the afbcd setting flow in vpp side
4. add force urgent function for di pre-link

Verify:
Verified on t5m

Change-Id: Ifb65141a9ca3779f19f6b2131284ffc3461980af
Signed-off-by: Brian Zhu <brian.zhu@amlogic.com>
Signed-off-by: jintao xu <jintao.xu@amlogic.com>
Signed-off-by: qianqian.cai <qianqian.cai@amlogic.com>
This commit is contained in:
Brian Zhu
2023-04-14 03:17:57 +08:00
committed by gerrit autosubmit
parent b120d568fc
commit 041f547ceb
14 changed files with 666 additions and 145 deletions
@@ -44,6 +44,9 @@
#include <linux/amlogic/media/registers/cpu_version.h>
#include <linux/amlogic/media/vfm/amlogic_fbc_hook_v1.h>
#include "../../gdc/inc/api/gdc_api.h"
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
#include <linux/amlogic/media/di/di_interface.h>
#endif
#include "videodisplay.h"
#define VIDEO_COMPOSER_VERSION "1.0"
@@ -1605,6 +1608,14 @@ static struct output_axis output_axis_adjust(struct composer_dev *dev,
return axis;
}
bool vf_is_pre_link(struct vframe_s *vf)
{
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
if (vf && pvpp_check_vf(vf) > 0 && vf->vf_ext)
return true;
#endif
return false;
}
static struct vframe_s *get_vf_from_file(struct composer_dev *dev,
struct file *file_vf, bool need_dw)
@@ -1644,12 +1655,15 @@ static struct vframe_s *get_vf_from_file(struct composer_dev *dev,
di_vf->type_original);
if (!need_dw ||
(need_dw && di_vf->width != 0 &&
di_vf->canvas0_config[0].phy_addr != 0)) {
di_vf->canvas0_config[0].phy_addr != 0 &&
!vf_is_pre_link(di_vf))) {
vc_print(dev->index, PRINT_OTHER,
"use di vf.\n");
"use di vf\n");
/* link uvm vf into di_vf->vf_ext */
if (!di_vf->vf_ext)
di_vf->vf_ext = vf;
/* link uvm vf into vf->uvm_vf */
di_vf->uvm_vf = vf;
vf = di_vf;
}
}
@@ -1664,9 +1678,14 @@ static struct vframe_s *get_vf_from_file(struct composer_dev *dev,
"invalid fd: no uvm, no v4lvideo!!\n");
} else {
vf = &file_private_data->vf;
if (vf->vf_ext && (vf->flag &
VFRAME_FLAG_CONTAIN_POST_FRAME))
vf = vf->vf_ext;
if (need_dw && (vf->flag & VFRAME_FLAG_DOUBLE_FRAM) && vf->vf_ext) {
if (vf->width == 0 ||
vf->canvas0_config[0].phy_addr == 0 ||
vf_is_pre_link(vf)) {
vf = vf->vf_ext;
vc_print(dev->index, PRINT_OTHER, "use dec vf.\n");
}
}
}
}
return vf;
@@ -3299,26 +3318,31 @@ static void video_composer_task(struct composer_dev *dev)
vc_print(dev->index, PRINT_AXIS,
"===============================\n");
if (vf->flag & VFRAME_FLAG_DOUBLE_FRAM) {
vf_ext = vf->vf_ext;
if (vf_ext) {
vf_ext->axis[0] = vf->axis[0];
vf_ext->axis[1] = vf->axis[1];
vf_ext->axis[2] = vf->axis[2];
vf_ext->axis[3] = vf->axis[3];
vf_ext->crop[0] = vf->crop[0];
vf_ext->crop[1] = vf->crop[1];
vf_ext->crop[2] = vf->crop[2];
vf_ext->crop[3] = vf->crop[3];
vf_ext->zorder = vf->zorder;
vf_ext->flag |= VFRAME_FLAG_VIDEO_COMPOSER
| VFRAME_FLAG_VIDEO_COMPOSER_BYPASS;
} else {
vc_print(dev->index, PRINT_ERROR,
"vf_ext is null\n");
if (is_dec_vf) {
/* copy to uvm vf */
vf_ext = vf->uvm_vf;
} else if (is_v4l_vf) {
if (vf->flag & VFRAME_FLAG_DOUBLE_FRAM) {
vf_ext = vf->vf_ext;
if (!vf_ext)
vc_print(dev->index, PRINT_ERROR, "vf_ext is null\n");
}
}
if (vf_ext) {
vf_ext->axis[0] = vf->axis[0];
vf_ext->axis[1] = vf->axis[1];
vf_ext->axis[2] = vf->axis[2];
vf_ext->axis[3] = vf->axis[3];
vf_ext->crop[0] = vf->crop[0];
vf_ext->crop[1] = vf->crop[1];
vf_ext->crop[2] = vf->crop[2];
vf_ext->crop[3] = vf->crop[3];
vf_ext->zorder = vf->zorder;
vf_ext->flag |= VFRAME_FLAG_VIDEO_COMPOSER
| VFRAME_FLAG_VIDEO_COMPOSER_BYPASS;
}
if (is_repeat_vf) {
vf->repeat_count++;
vc_print(dev->index, PRINT_FENCE,
@@ -3443,6 +3467,7 @@ static int video_composer_thread(void *data)
dev->last_file = NULL;
dev->fake_vf.flag |= VFRAME_FLAG_FAKE_FRAME;
dev->fake_vf.vf_ext = NULL;
dev->fake_vf.uvm_vf = NULL;
dev->fake_back_vf = dev->fake_vf;
if (!kfifo_put(&dev->ready_q,
&dev->fake_back_vf))
@@ -30,7 +30,6 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/delay.h>
#include <linux/amlogic/media/video_processor/video_composer_ext.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
@@ -969,6 +969,8 @@ static struct vframe_s *vd_get_vf_from_buf(struct composer_dev *dev,
/* link uvm vf into di_vf->vf_ext */
if (!di_vf->vf_ext)
di_vf->vf_ext = vf;
/* link uvm vf into vf->uvm_vf */
di_vf->uvm_vf = vf;
vf = di_vf;
}
dmabuf_put_vframe(buf);
@@ -1314,6 +1316,7 @@ int video_display_setframe(int layer_index,
bool is_dec_vf = false, is_v4l_vf = false, is_repeat_vf = false;
struct vd_prepare_s *vd_prepare = NULL;
u64 phy_addr2 = 0;
struct vframe_s *vf_ext = NULL;
if (IS_ERR_OR_NULL(frame_info)) {
vc_print(layer_index, PRINT_ERROR,
@@ -1400,6 +1403,23 @@ int video_display_setframe(int layer_index,
return 0;
}
/* copy to uvm vf */
vf_ext = vf->uvm_vf;
if (vf_ext) {
vf_ext->axis[0] = vf->axis[0];
vf_ext->axis[1] = vf->axis[1];
vf_ext->axis[2] = vf->axis[2];
vf_ext->axis[3] = vf->axis[3];
vf_ext->crop[0] = vf->crop[0];
vf_ext->crop[1] = vf->crop[1];
vf_ext->crop[2] = vf->crop[2];
vf_ext->crop[3] = vf->crop[3];
vf_ext->zorder = vf->zorder;
vf_ext->flag |= VFRAME_FLAG_VIDEO_COMPOSER
| VFRAME_FLAG_VIDEO_COMPOSER_BYPASS;
vf_ext->disp_pts = 0;
}
if (!(is_dec_vf || is_v4l_vf)) {
vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
vf->plane_num = 1;
+79 -12
View File
@@ -1053,34 +1053,63 @@ static void video_vf_unreg_provider(void)
if (cur_dispbuf[0]) {
if (cur_dispbuf[0]->vf_ext &&
IS_DI_POSTWRTIE(cur_dispbuf[0]->type)) {
struct vframe_s *tmp =
(struct vframe_s *)cur_dispbuf[0]->vf_ext;
struct vframe_s *tmp;
if (cur_dispbuf[0]->uvm_vf)
tmp = cur_dispbuf[0]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[0]->vf_ext;
memcpy(&tmp->pic_mode, &cur_dispbuf[0]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local_ext[0] = *tmp;
vf_local[0] = *cur_dispbuf[0];
vf_local[0].vf_ext = (void *)&vf_local_ext[0];
vf_local[0].uvm_vf = NULL;
vf_local_ext[0].ratio_control = vf_local[0].ratio_control;
} else if (cur_dispbuf[0]->vf_ext &&
is_pre_link_source(cur_dispbuf[0])) {
u32 tmp_rc;
struct vframe_s *tmp =
(struct vframe_s *)cur_dispbuf[0]->vf_ext;
struct vframe_s *tmp;
if (cur_dispbuf[0]->uvm_vf)
tmp = cur_dispbuf[0]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[0]->vf_ext;
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("video_unreg: prelink: cur_dispbuf:%p, vf->ext:%p, flag:%x\n",
pr_info("video_unreg: prelink: cur_dispbuf:%px vf_ext:%px uvm_vf:%px flag:%x\n",
cur_dispbuf[0], cur_dispbuf[0]->vf_ext,
cur_dispbuf[0]->flag);
cur_dispbuf[0]->uvm_vf, cur_dispbuf[0]->flag);
tmp_rc = cur_dispbuf[0]->ratio_control;
memcpy(&tmp->pic_mode, &cur_dispbuf[0]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local[0] = *tmp;
vf_local[0].ratio_control = tmp_rc;
vf_local[0].vf_ext = NULL;
vf_local[0].uvm_vf = NULL;
} else if (IS_DI_POST(cur_dispbuf[0]->type) &&
(cur_dispbuf[0]->vf_ext || cur_dispbuf[0]->uvm_vf)) {
u32 tmp_rc;
struct vframe_s *tmp;
if (cur_dispbuf[0]->uvm_vf)
tmp = cur_dispbuf[0]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[0]->vf_ext;
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("video_unreg: pre/post link: cur_dispbuf:%px vf_ext:%px uvm_vf:%px flag:%x\n",
cur_dispbuf[0], cur_dispbuf[0]->vf_ext,
cur_dispbuf[0]->uvm_vf, cur_dispbuf[0]->flag);
tmp_rc = cur_dispbuf[0]->ratio_control;
memcpy(&tmp->pic_mode, &cur_dispbuf[0]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local[0] = *tmp;
vf_local[0].ratio_control = tmp_rc;
vf_local[0].vf_ext = NULL;
vf_local[0].uvm_vf = NULL;
} else {
vf_local[0] = *cur_dispbuf[0];
vf_local[0].vf_ext = NULL;
vf_local[0].uvm_vf = NULL;
}
cur_dispbuf[0] = &vf_local[0];
cur_dispbuf[0]->video_angle = 0;
@@ -1283,35 +1312,65 @@ static void video_vf_light_unreg_provider(int need_keep_frame)
if (cur_dispbuf[0]) {
if (cur_dispbuf[0]->vf_ext &&
IS_DI_POSTWRTIE(cur_dispbuf[0]->type)) {
struct vframe_s *tmp =
(struct vframe_s *)cur_dispbuf[0]->vf_ext;
struct vframe_s *tmp;
if (cur_dispbuf[0]->uvm_vf)
tmp = cur_dispbuf[0]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[0]->vf_ext;
memcpy(&tmp->pic_mode, &cur_dispbuf[0]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local_ext[0] = *tmp;
vf_local[0] = *cur_dispbuf[0];
vf_local[0].vf_ext = (void *)&vf_local_ext[0];
vf_local[0].uvm_vf = NULL;
vf_local_ext[0].ratio_control = vf_local[0].ratio_control;
} else if (cur_dispbuf[0]->vf_ext &&
is_pre_link_source(cur_dispbuf[0])) {
u32 tmp_rc;
struct vframe_s *tmp =
(struct vframe_s *)cur_dispbuf[0]->vf_ext;
struct vframe_s *tmp;
if (cur_dispbuf[0]->uvm_vf)
tmp = cur_dispbuf[0]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[0]->vf_ext;
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("%s: prelink: cur_dispbuf:%p, vf->ext:%p, flag:%x\n",
pr_info("%s: prelink: cur_dispbuf:%px vf_ext:%px uvm_vf:%px flag:%x\n",
__func__,
cur_dispbuf[0], cur_dispbuf[0]->vf_ext,
cur_dispbuf[0]->flag);
cur_dispbuf[0]->uvm_vf, cur_dispbuf[0]->flag);
tmp_rc = cur_dispbuf[0]->ratio_control;
memcpy(&tmp->pic_mode, &cur_dispbuf[0]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local[0] = *tmp;
vf_local[0].ratio_control = tmp_rc;
vf_local[0].vf_ext = NULL;
vf_local[0].uvm_vf = NULL;
} else if (IS_DI_POST(cur_dispbuf[0]->type) &&
(cur_dispbuf[0]->vf_ext || cur_dispbuf[0]->uvm_vf)) {
u32 tmp_rc;
struct vframe_s *tmp;
if (cur_dispbuf[0]->uvm_vf)
tmp = cur_dispbuf[0]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[0]->vf_ext;
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("%s: pre/post link: cur_dispbuf:%px vf_ext:%px uvm_vf:%px flag:%x\n",
__func__,
cur_dispbuf[0], cur_dispbuf[0]->vf_ext,
cur_dispbuf[0]->uvm_vf, cur_dispbuf[0]->flag);
tmp_rc = cur_dispbuf[0]->ratio_control;
memcpy(&tmp->pic_mode, &cur_dispbuf[0]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local[0] = *tmp;
vf_local[0].ratio_control = tmp_rc;
vf_local[0].vf_ext = NULL;
vf_local[0].uvm_vf = NULL;
} else {
vf_local[0] = *cur_dispbuf[0];
vf_local[0].vf_ext = NULL;
vf_local[0].uvm_vf = NULL;
}
cur_dispbuf[0] = &vf_local[0];
}
@@ -8359,6 +8418,10 @@ static ssize_t vframe_states_show(struct class *cla,
ret += sprintf(buf + ret,
"vf_ext=%p\n",
vf->vf_ext);
if (vf->uvm_vf)
ret += sprintf(buf + ret,
"uvm_vf=%p\n",
vf->uvm_vf);
}
spin_unlock_irqrestore(&lock, flags);
@@ -8418,6 +8481,10 @@ static ssize_t vframe_states_show(struct class *cla,
ret += sprintf(buf + ret,
"vf_ext=%p\n",
vf->vf_ext);
if (vf->uvm_vf)
ret += sprintf(buf + ret,
"uvm_vf=%p\n",
vf->uvm_vf);
} else {
ret += sprintf(buf + ret, "vframe no states\n");
}
+214 -27
View File
@@ -55,6 +55,7 @@
#include <trace/events/meson_atrace.h>
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
#include <linux/amlogic/media/di/di.h>
#include <linux/amlogic/media/di/di_interface.h>
#endif
#include "vpp_pq.h"
#if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM)
@@ -75,6 +76,7 @@
/* local var */
static u32 blend_conflict_cnt;
static u32 stop_update;
static u32 stop_force_dmc;
/* 3d related */
static unsigned int last_process_3d_type;
@@ -1403,7 +1405,9 @@ void primary_swap_frame(struct video_layer_s *layer,
vf = vf1;
layer_info = &glayer_info[0];
if (layer->need_switch_vf && IS_DI_POST(vf->type)) {
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
if (layer->need_switch_vf && IS_DI_POST(vf->type) &&
dil_get_diff_ver_flag() == DI_DRV_DEINTERLACE) {
if ((vf1->flag & VFRAME_FLAG_DOUBLE_FRAM) &&
is_di_post_mode(vf1)) {
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
@@ -1420,7 +1424,7 @@ void primary_swap_frame(struct video_layer_s *layer,
layer->need_switch_vf = false;
}
}
#endif
if ((vf->flag & (VFRAME_FLAG_VIDEO_COMPOSER |
VFRAME_FLAG_VIDEO_DRM)) &&
!(vf->flag & VFRAME_FLAG_FAKE_FRAME) &&
@@ -1633,6 +1637,10 @@ s32 primary_render_frame(struct video_layer_s *layer,
di_in_p.dmode = EPVPP_DISPLAY_MODE_NR;
di_in_p.unreg_bypass = 0;
iret = pvpp_display(dispbuf, &di_in_p, NULL);
if (iret <= 0) {
vd_layer[0].property_changed = true;
vd_layer[0].prelink_bypass_check = true;
}
if (layer->global_debug & DEBUG_FLAG_PRELINK_MORE)
pr_info("do di callback iret:%d\n", iret);
} else {
@@ -1651,6 +1659,7 @@ s32 primary_render_frame(struct video_layer_s *layer,
if (layer->global_debug & DEBUG_FLAG_PRELINK)
pr_info("%s: unreg_bypass pre-link mode ret %d\n", __func__, iret);
layer->pre_link_en = false;
layer->prelink_bypass_check = false;
layer->prelink_skip_cnt = 0;
iret = pvpp_sw(false);
if (layer->global_debug & DEBUG_FLAG_PRELINK)
@@ -2053,6 +2062,7 @@ int update_video_recycle_buffer(u8 path_index)
}
for (i = 0; i < DISPBUF_TO_PUT_MAX; i++)
if (dispbuf_to_put[j][i] &&
(dispbuf_to_put[j][i]->flag & VFRAME_FLAG_DI_PW_VFM) &&
IS_DI_POSTWRTIE(dispbuf_to_put[j][i]->type))
to_put_buf[put_cnt++] = dispbuf_to_put[j][i];
#endif
@@ -2061,7 +2071,8 @@ int update_video_recycle_buffer(u8 path_index)
rdma_buf = cur_dispbuf[j];
if (rdma_buf &&
!IS_DI_POSTWRTIE(rdma_buf->type))
(!(rdma_buf->flag & VFRAME_FLAG_DI_PW_VFM) ||
!IS_DI_POSTWRTIE(rdma_buf->type)))
rdma_buf = NULL;
if (recycle_cnt[j] &&
@@ -2761,21 +2772,16 @@ static int video_early_proc(u8 layer_id, u8 fake_layer_id)
func_id = vd_layer[layer_id].func_path_id;
switch (func_id) {
case AMVIDEO:
amvideo_early_proc(AMVIDEO);
break;
return amvideo_early_proc(AMVIDEO);
case PIP1:
case PIP2:
path_index = func_id - AMVIDEO;
if (path_index < MAX_VD_LAYER)
pipx_early_proc(path_index);
break;
return pipx_early_proc(path_index);
case RENDER0:
case RENDER1:
case RENDER2:
path_index = func_id - RENDER0;
if (path_index < MAX_VD_LAYER)
recvx_early_proc(path_index);
break;
return recvx_early_proc(path_index);
default:
break;
}
@@ -3141,12 +3147,19 @@ static struct vframe_s *vdx_swap_frame(u8 layer_id,
}
if (vd_layer[layer_id].switch_vf &&
vd_layer[layer_id].dispbuf &&
vd_layer[layer_id].dispbuf->vf_ext)
vd_layer[layer_id].vf_ext =
(struct vframe_s *)vd_layer[layer_id].dispbuf->vf_ext;
else
vd_layer[layer_id].dispbuf &&
(vd_layer[layer_id].dispbuf->vf_ext ||
vd_layer[layer_id].dispbuf->uvm_vf)) {
/* select uvm_vf first */
if (vd_layer[layer_id].dispbuf->uvm_vf)
vd_layer[layer_id].vf_ext =
vd_layer[layer_id].dispbuf->uvm_vf;
else
vd_layer[layer_id].vf_ext =
(struct vframe_s *)vd_layer[layer_id].dispbuf->vf_ext;
} else {
vd_layer[layer_id].vf_ext = NULL;
}
/* vdx config */
if (gvideo_recv[0] &&
@@ -4753,8 +4766,8 @@ void release_di_buffer(int inst)
for (i = 0; i < recycle_cnt[inst]; i++) {
if (recycle_buf[inst][i] &&
IS_DI_POSTWRTIE(recycle_buf[inst][i]->type) &&
(recycle_buf[inst][i]->flag & VFRAME_FLAG_DI_PW_VFM)) {
recycle_buf[inst][i]->flag & VFRAME_FLAG_DI_PW_VFM &&
IS_DI_POSTWRTIE(recycle_buf[inst][i]->type)) {
di_release_count++;
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
dim_post_keep_cmd_release2(recycle_buf[inst][i]);
@@ -4881,7 +4894,9 @@ struct vframe_s *get_dispbuf(u8 layer_id)
}
layer = get_layer_by_layer_id(layer_id);
if (layer && layer->switch_vf && layer->vf_ext)
if (layer && dispbuf &&
!is_local_vf(dispbuf) &&
layer->switch_vf && layer->vf_ext)
dispbuf = layer->vf_ext;
return dispbuf;
}
@@ -4928,17 +4943,71 @@ static void pipx_vf_unreg_provider(u8 path_index)
if (cur_dispbuf[path_index]) {
if (cur_dispbuf[path_index]->vf_ext &&
IS_DI_POSTWRTIE(cur_dispbuf[path_index]->type)) {
struct vframe_s *tmp =
(struct vframe_s *)cur_dispbuf[path_index]->vf_ext;
struct vframe_s *tmp;
if (cur_dispbuf[path_index]->uvm_vf)
tmp = cur_dispbuf[path_index]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[path_index]->vf_ext;
memcpy(&tmp->pic_mode, &cur_dispbuf[path_index]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local_ext[path_index] = *tmp;
vf_local[path_index] = *cur_dispbuf[path_index];
vf_local[path_index].vf_ext = (void *)&vf_local_ext[path_index];
vf_local[path_index].uvm_vf = NULL;
vf_local_ext[path_index].ratio_control = vf_local[path_index].ratio_control;
} else if (cur_dispbuf[path_index]->vf_ext &&
is_pre_link_source(cur_dispbuf[path_index])) {
u32 tmp_rc;
struct vframe_s *tmp;
if (cur_dispbuf[path_index]->uvm_vf)
tmp = cur_dispbuf[path_index]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[path_index]->vf_ext;
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("%s %d: prelink: cur_dispbuf:%px vf_ext:%px uvm_vf:%px flag:%x\n",
__func__, path_index,
cur_dispbuf[path_index],
cur_dispbuf[path_index]->vf_ext,
cur_dispbuf[path_index]->uvm_vf,
cur_dispbuf[path_index]->flag);
tmp_rc = cur_dispbuf[path_index]->ratio_control;
memcpy(&tmp->pic_mode, &cur_dispbuf[path_index]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local[path_index] = *tmp;
vf_local[path_index].ratio_control = tmp_rc;
vf_local[path_index].vf_ext = NULL;
vf_local[path_index].uvm_vf = NULL;
} else if (IS_DI_POST(cur_dispbuf[path_index]->type) &&
(cur_dispbuf[path_index]->vf_ext || cur_dispbuf[path_index]->uvm_vf)) {
u32 tmp_rc;
struct vframe_s *tmp;
if (cur_dispbuf[path_index]->uvm_vf)
tmp = cur_dispbuf[path_index]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[path_index]->vf_ext;
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("%s %d: pre/post link: cur_dispbuf:%px vf_ext:%px uvm_vf:%px flag:%x\n",
__func__, path_index,
cur_dispbuf[path_index],
cur_dispbuf[path_index]->vf_ext,
cur_dispbuf[path_index]->uvm_vf,
cur_dispbuf[path_index]->flag);
tmp_rc = cur_dispbuf[path_index]->ratio_control;
memcpy(&tmp->pic_mode, &cur_dispbuf[path_index]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local[path_index] = *tmp;
vf_local[path_index].ratio_control = tmp_rc;
vf_local[path_index].vf_ext = NULL;
vf_local[path_index].uvm_vf = NULL;
} else {
vf_local[path_index] = *cur_dispbuf[path_index];
vf_local[path_index].vf_ext = NULL;
vf_local[path_index].uvm_vf = NULL;
}
cur_dispbuf[path_index] = &vf_local[path_index];
cur_dispbuf[path_index]->video_angle = 0;
@@ -5052,18 +5121,71 @@ static void pipx_vf_light_unreg_provider(u8 path_index, int need_keep_frame)
if (cur_dispbuf[path_index]) {
if (cur_dispbuf[path_index]->vf_ext &&
IS_DI_POSTWRTIE(cur_dispbuf[path_index]->type)) {
struct vframe_s *tmp =
(struct vframe_s *)cur_dispbuf[path_index]->vf_ext;
struct vframe_s *tmp;
if (cur_dispbuf[path_index]->uvm_vf)
tmp = cur_dispbuf[path_index]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[path_index]->vf_ext;
memcpy(&tmp->pic_mode, &cur_dispbuf[path_index]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local_ext[path_index] = *tmp;
vf_local[path_index] = *cur_dispbuf[path_index];
vf_local[path_index] .vf_ext = (void *)&vf_local_ext[path_index];
vf_local_ext[path_index].ratio_control =
vf_local[path_index] .ratio_control;
vf_local[path_index].vf_ext = (void *)&vf_local_ext[path_index];
vf_local[path_index].uvm_vf = NULL;
vf_local_ext[path_index].ratio_control = vf_local[path_index].ratio_control;
} else if (cur_dispbuf[path_index]->vf_ext &&
is_pre_link_source(cur_dispbuf[path_index])) {
u32 tmp_rc;
struct vframe_s *tmp;
if (cur_dispbuf[path_index]->uvm_vf)
tmp = cur_dispbuf[path_index]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[path_index]->vf_ext;
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("%s %d: prelink: cur_dispbuf:%px vf_ext:%px uvm_vf:%px flag:%x\n",
__func__, path_index,
cur_dispbuf[path_index],
cur_dispbuf[path_index]->vf_ext,
cur_dispbuf[path_index]->uvm_vf,
cur_dispbuf[path_index]->flag);
tmp_rc = cur_dispbuf[path_index]->ratio_control;
memcpy(&tmp->pic_mode, &cur_dispbuf[path_index]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local[path_index] = *tmp;
vf_local[path_index].ratio_control = tmp_rc;
vf_local[path_index].vf_ext = NULL;
vf_local[path_index].uvm_vf = NULL;
} else if (IS_DI_POST(cur_dispbuf[path_index]->type) &&
(cur_dispbuf[path_index]->vf_ext || cur_dispbuf[path_index]->uvm_vf)) {
u32 tmp_rc;
struct vframe_s *tmp;
if (cur_dispbuf[path_index]->uvm_vf)
tmp = cur_dispbuf[path_index]->uvm_vf;
else
tmp = (struct vframe_s *)cur_dispbuf[path_index]->vf_ext;
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("%s %d: pre/post link: cur_dispbuf:%px vf_ext:%px uvm_vf:%px flag:%x\n",
__func__, path_index,
cur_dispbuf[path_index],
cur_dispbuf[path_index]->vf_ext,
cur_dispbuf[path_index]->uvm_vf,
cur_dispbuf[path_index]->flag);
tmp_rc = cur_dispbuf[path_index]->ratio_control;
memcpy(&tmp->pic_mode, &cur_dispbuf[path_index]->pic_mode,
sizeof(struct vframe_pic_mode_s));
vf_local[path_index] = *tmp;
vf_local[path_index].ratio_control = tmp_rc;
vf_local[path_index].vf_ext = NULL;
vf_local[path_index].uvm_vf = NULL;
} else {
vf_local[path_index] = *cur_dispbuf[path_index];
vf_local[path_index] = *cur_dispbuf[path_index];
vf_local[path_index].vf_ext = NULL;
vf_local[path_index].uvm_vf = NULL;
}
cur_dispbuf[path_index] = &vf_local[path_index];
}
@@ -5256,6 +5378,68 @@ void di_prelink_state_changed_notify(void)
}
EXPORT_SYMBOL(di_prelink_state_changed_notify);
void di_prelink_force_dmc_priority(bool urgent, bool wait)
{
#define DI_READ_DMC_AM1_CHAN_CTRL 0x0064
#define DI_WRTIE_DMC_AM4_CHAN_CTRL 0x0070
bool valid = false;
if (stop_force_dmc)
return;
/* check priority adjustment function valid or not */
if (!legacy_vpp) {
if (cur_dev->display_module == OLD_DISPLAY_MODULE ||
video_is_meson_t5w_cpu())
valid = true;
}
if (!legacy_vpp) {
u32 sleep_time = 40;
if (!valid)
wait = false;
while (atomic_read(&video_inirq_flag) > 0 && wait)
schedule();
if (vinfo && wait) {
sleep_time = vinfo->sync_duration_den * 1000;
if (vinfo->sync_duration_num) {
sleep_time /= vinfo->sync_duration_num;
/* need two vsync */
sleep_time = (sleep_time + 1) * 2;
} else {
sleep_time = 40;
}
}
if (wait)
msleep(sleep_time);
else
sleep_time = 0;
if (cur_dev->display_module == OLD_DISPLAY_MODULE ||
video_is_meson_t5w_cpu()) {
WRITE_DMCREG
(DI_READ_DMC_AM1_CHAN_CTRL,
urgent ? 0xCFF403C4 : 0xCFF203C4);
WRITE_DMCREG
(DI_READ_DMC_AM1_CHAN_CTRL,
urgent ? 0xCFF403C4 : 0xCFF203C4);
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("%s: port:0x%x 0x%x to 0x%x (%s) wait:%s time %dms\n",
__func__,
DI_READ_DMC_AM1_CHAN_CTRL,
DI_WRTIE_DMC_AM4_CHAN_CTRL,
urgent ? 0xCFF403C4 : 0xCFF203C4,
urgent ? "super urgent" : "not urgent",
wait ? "true" : "false",
sleep_time);
}
}
}
EXPORT_SYMBOL(di_prelink_force_dmc_priority);
u32 get_playback_delay_duration(void)
{
u32 memc_delay = 0;
@@ -5535,3 +5719,6 @@ module_param(stop_update, uint, 0664);
MODULE_PARM_DESC(pre_vsync_count, "\n pre_vsync_count\n");
module_param(pre_vsync_count, uint, 0664);
MODULE_PARM_DESC(stop_force_dmc, "\n stop_force_dmc\n");
module_param(stop_force_dmc, uint, 0664);
+158 -57
View File
@@ -1301,7 +1301,8 @@ bool is_di_on(void)
bool ret = false;
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
if (DI_POST_REG_RD(DI_IF1_GEN_REG) & 0x1)
if ((dil_get_diff_ver_flag() == DI_DRV_DEINTERLACE) &&
(DI_POST_REG_RD(DI_IF1_GEN_REG) & 0x1))
ret = true;
#endif
return ret;
@@ -1312,7 +1313,8 @@ bool is_di_post_on(void)
bool ret = false;
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
if (DI_POST_REG_RD(DI_POST_CTRL) & 0x100)
if ((dil_get_diff_ver_flag() == DI_DRV_DEINTERLACE) &&
(DI_POST_REG_RD(DI_POST_CTRL) & 0x100))
ret = true;
#endif
return ret;
@@ -1323,7 +1325,8 @@ bool is_di_post_link_on(void)
bool ret = false;
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
if (DI_POST_REG_RD(DI_POST_CTRL) & 0x1000)
if ((dil_get_diff_ver_flag() == DI_DRV_DEINTERLACE) &&
(DI_POST_REG_RD(DI_POST_CTRL) & 0x1000))
ret = true;
#endif
return ret;
@@ -1333,8 +1336,11 @@ bool is_di_post_mode(struct vframe_s *vf)
{
bool ret = false;
if (vf && IS_DI_POST(vf->type))
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
if ((dil_get_diff_ver_flag() == DI_DRV_DEINTERLACE) &&
vf && IS_DI_POST(vf->type))
ret = true;
#endif
return ret;
}
@@ -2051,6 +2057,7 @@ static void vd1_set_dcu(struct video_layer_s *layer,
struct hw_afbc_reg_s *vd_afbc_reg = &layer->vd_afbc_reg;
bool di_post = false, di_pre_link = false;
u8 vpp_index = layer->vpp_index;
bool skip_afbc = false;
if (!vf) {
pr_info("%s vf NULL, return\n", __func__);
@@ -2058,9 +2065,30 @@ static void vd1_set_dcu(struct video_layer_s *layer,
}
type = vf->type;
#ifdef ENABLE_PRE_LINK
if (video_is_meson_t5d_revb_cpu() &&
!layer->vd1_vd2_mux &&
!is_local_vf(vf) &&
is_pre_link_on(layer, vf) &&
is_pre_link_source(vf)) {
struct vframe_s *dec_vf;
if (vf->uvm_vf)
dec_vf = vf->uvm_vf;
else
dec_vf = (struct vframe_s *)vf->vf_ext;
if (dec_vf && (dec_vf->type & VIDTYPE_COMPRESS)) {
type |= VIDTYPE_COMPRESS;
skip_afbc = true;
}
}
#endif
if (type & VIDTYPE_MVC)
is_mvc = true;
pr_debug("%s for vd%d %p, type:0x%x, flag:%x\n",
__func__, layer->layer_id, vf, type, vf->flag);
if (cur_dev->display_module != C3_DISPLAY_MODULE) {
if (layer->vd1_vd2_mux) {
vd_mif_reg = &vd_layer[1].vd_mif_reg;
@@ -2082,8 +2110,20 @@ static void vd1_set_dcu(struct video_layer_s *layer,
if (frame_par->nocomp)
type &= ~VIDTYPE_COMPRESS;
if (type & VIDTYPE_COMPRESS) {
/*
* not dead code,just for T5DB enable
*/
/*coverity[dead_error_line:SUPPRESS]*/
if (skip_afbc && (type & VIDTYPE_COMPRESS)) {
vd1_path_select(layer, true, false, di_post, di_pre_link);
cur_dev->rdma_func[vpp_index].rdma_wr_bits
(VD1_AFBCD0_MISC_CTRL,
/* vd1 afbc to di */
1, 1, 1);
cur_dev->rdma_func[vpp_index].rdma_wr
(vd_mif_reg->vd_if0_gen_reg, 0);
return;
} else if (type & VIDTYPE_COMPRESS) {
if (cur_dev->display_module == T7_DISPLAY_MODULE) {
if (conv_lbuf_len[layer->layer_id] == VIDEO_USE_4K_RAM)
r = 3;
@@ -9380,18 +9420,6 @@ int set_layer_display_canvas(struct video_layer_s *layer,
canvas_update_for_mif(layer, vf);
vpp_trace_vframe("swap_vf", (void *)vf, vf->type, vf->flag, layer_id, 0);
if (layer->global_debug & DEBUG_FLAG_PRINT_FRAME_DETAIL) {
struct canvas_s tmp;
canvas_read(cur_canvas_tbl[0], &tmp);
pr_info("%s %d: vf:%px, y:%02x, adr:0x%lx, canvas0Addr:%x, pnum:%d, type:%x, flag:%x, afbc:0x%lx-0x%lx, vf->vf_ext:%px, line:%d\n",
__func__, layer_id, vf,
cur_canvas_tbl[0], tmp.addr,
vf->canvas0Addr, vf->plane_num,
vf->type, vf->flag,
vf->compHeadAddr, vf->compBodyAddr,
vf->vf_ext, line);
}
if (layer_id == 0 &&
(is_mvc || process_3d_type))
canvas_update_for_3d(layer, vf,
@@ -9447,6 +9475,19 @@ int set_layer_display_canvas(struct video_layer_s *layer,
layer->next_canvas_id = layer->cur_canvas_id ? 0 : 1;
#endif
}
if (layer->global_debug & DEBUG_FLAG_PRINT_FRAME_DETAIL) {
struct canvas_s tmp;
canvas_read(cur_canvas_tbl[0], &tmp);
pr_info("%s %d: vf:%px, y:%02x, adr:0x%lx, canvas0:%x, pnum:%d, type:%x, flag:%x, afbc:0x%lx-0x%lx, vf_ext:%px uvm_vf:%px di_flag:%x size:%d %d, vframe size:%d line:%d\n",
__func__, layer_id, vf,
cur_canvas_tbl[0], tmp.addr,
vf->canvas0Addr, vf->plane_num,
vf->type, vf->flag,
vf->compHeadAddr, vf->compBodyAddr,
vf->vf_ext, vf->uvm_vf, vf->di_flag,
vf->compWidth, vf->width, (u32)sizeof(struct vframe_s), line);
}
return 0;
}
@@ -9565,14 +9606,20 @@ static bool update_pre_link_state(struct video_layer_s *layer,
return ret;
if (!layer->need_disable_prelink &&
is_pre_link_on(layer, vf) &&
layer->dispbuf &&
layer->dispbuf->di_instance_id != vf->di_instance_id &&
vf->di_instance_id == di_api_get_plink_instance_id()) {
layer->need_disable_prelink = true;
pr_info("Error: need trigger need_disable_prelink!!, disp:%px id:%d, vf:%px, id:%d\n",
layer->dispbuf, layer->dispbuf->di_instance_id,
vf, vf->di_instance_id);
is_pre_link_on(layer, vf)) {
if (layer->dispbuf &&
layer->dispbuf->di_instance_id !=
vf->di_instance_id &&
vf->di_instance_id ==
di_api_get_plink_instance_id())
layer->need_disable_prelink = true;
if (!IS_DI_POST(vf->type))
layer->need_disable_prelink = true;
if (layer->need_disable_prelink && (layer->global_debug & DEBUG_FLAG_PRELINK))
pr_info("warning: need trigger need_disable_prelink!!, disp:%px id:%d, vf:%px, id:%d type:0x%x\n",
layer->dispbuf,
layer->dispbuf ? layer->dispbuf->di_instance_id : -1,
vf, vf->di_instance_id, vf->type);
}
/* for new pipeline and front-end already unreg->reg */
if (layer->need_disable_prelink &&
@@ -9581,8 +9628,10 @@ static bool update_pre_link_state(struct video_layer_s *layer,
if (!layer->dispbuf ||
layer->dispbuf->di_instance_id !=
vf->di_instance_id) {
vf->di_instance_id ||
layer->last_di_instance != vf->di_instance_id) {
layer->need_disable_prelink = false;
layer->last_di_instance = -1;
trig_flag = true;
}
if (trig_flag && (layer->global_debug & DEBUG_FLAG_PRELINK))
@@ -9592,6 +9641,7 @@ static bool update_pre_link_state(struct video_layer_s *layer,
/* meet non pre-link vf and set need_disable_prelink as 0 */
if (is_local_vf(vf) || !vf->vf_ext) {
layer->need_disable_prelink = false;
layer->last_di_instance = -1;
} else if (vf->vf_ext) {
/* is_pre_link_source maybe invalid here */
/* check if vf is remained and same instance as before */
@@ -9607,13 +9657,23 @@ static bool update_pre_link_state(struct video_layer_s *layer,
if (layer->global_debug & DEBUG_FLAG_PRELINK)
pr_info("Disable/Bypass pre-link mode ret %d\n", iret);
}
ret = true;
/* just bypass prelink and not switch */
/* TODO: if need change the condition to IS_DI_PROCESSED */
if (!IS_DI_POST(vf->type) && !is_pre_link_source(vf))
ret = false;
else
ret = true;
if (layer->global_debug & DEBUG_FLAG_PRELINK_MORE) {
pr_info("warning: keeping need_disable_prelink: vf %px, type:%x, flag:%x\n",
vf, vf->type, vf->flag);
pr_info("is_pre_link_source:%d, is_pre_link_available:%d\n",
is_pre_link_source(vf) ? 1 : 0,
is_pre_link_available(vf) ? 1 : 0);
pr_info("warning: keeping need_disable_prelink: vf %px type:%x flag:%x di_instance_id:%d last_di_instance:%d\n",
vf, vf->type, vf->flag,
vf->di_instance_id, layer->last_di_instance);
if (!IS_DI_POST(vf->type))
pr_info("is not pre_link_source\n");
else
pr_info("is_pre_link_source:%d, is_pre_link_available:%d\n",
is_pre_link_source(vf) ? 1 : 0,
is_pre_link_available(vf) ? 1 : 0);
}
}
if (is_pre_link_on(layer, vf)) {
@@ -9626,15 +9686,25 @@ static bool update_pre_link_state(struct video_layer_s *layer,
__func__, iret);
iret = pvpp_sw(false);
layer->pre_link_en = false;
layer->prelink_bypass_check = false;
layer->last_di_instance = vf->di_instance_id;
layer->prelink_skip_cnt = 0;
}
if (!layer->dispbuf ||
(layer->dispbuf->di_instance_id !=
vf->di_instance_id))
layer->dispbuf->di_instance_id !=
vf->di_instance_id ||
layer->last_di_instance != vf->di_instance_id) {
layer->need_disable_prelink = false;
layer->last_di_instance = -1;
}
if (layer->global_debug & DEBUG_FLAG_PRELINK)
pr_info("Disable pre-link mode. need_disable_prelink:%d, iret:%d\n",
layer->need_disable_prelink ? 1 : 0, iret);
pr_info("Disable pre-link mode. need_disable_prelink:%d, iret:%d ret:%d\n",
layer->need_disable_prelink ? 1 : 0,
iret, ret ? 1 : 0);
if (layer->global_debug & DEBUG_FLAG_PRELINK_MORE)
pr_info("Disable pre-link mode. dispbuf->di_instance_id:%d, vf->di_instance_id:%d last_di_instance:%d\n",
layer->dispbuf ? layer->dispbuf->di_instance_id : -2,
vf->di_instance_id, layer->last_di_instance);
} else {
if (layer->next_frame_par->vscale_skip_count > 0 &&
is_pre_link_on(layer, vf) &&
@@ -9642,7 +9712,8 @@ static bool update_pre_link_state(struct video_layer_s *layer,
pr_info("Error, no vf_ext to switch for pre-link\n");
/* dynamic switch when di is in active */
if (layer->next_frame_par->vscale_skip_count > 0 &&
if ((layer->next_frame_par->vscale_skip_count > 0 ||
layer->prelink_bypass_check) &&
is_pre_link_on(layer, vf) && vf->vf_ext) {
memset(&di_in_p, 0, sizeof(struct pvpp_dis_para_in_s));
di_in_p.dmode = EPVPP_DISPLAY_MODE_BYPASS;
@@ -9654,6 +9725,8 @@ static bool update_pre_link_state(struct video_layer_s *layer,
pr_info("Bypass pre-link mode ret %d\n", iret);
ret = true;
layer->pre_link_en = false;
layer->prelink_bypass_check = false;
layer->last_di_instance = vf->di_instance_id;
layer->prelink_skip_cnt = 0;
} else {
pr_info("Bypass pre-link fail %d\n", iret);
@@ -9687,6 +9760,9 @@ static bool update_pre_link_state(struct video_layer_s *layer,
layer->pre_link_en = true;
layer->prelink_skip_cnt = 1;
} else {
/* force config in next frame swap */
if (ret == 0)
layer->force_config_cnt++;
layer->prelink_skip_cnt = 0;
ret = true;
}
@@ -9698,6 +9774,7 @@ static bool update_pre_link_state(struct video_layer_s *layer,
}
} else if (!is_pre_link_on(layer, vf) &&
!is_local_vf(vf) &&
!layer->next_frame_par->vscale_skip_count &&
is_pre_link_source(vf)) {
ret = true;
if (layer->global_debug & DEBUG_FLAG_PRELINK_MORE)
@@ -9708,17 +9785,31 @@ static bool update_pre_link_state(struct video_layer_s *layer,
/* is_pre_link_source maybe invalid here */
/* should be not run here */
if (layer->global_debug & DEBUG_FLAG_PRELINK)
pr_info("Warning: need disable pre-link and switch vf %px, vf->ext:%px\n",
vf, vf->vf_ext);
pr_info("Warning: need disable pre-link and switch vf %px vf_ext:%px uvm_vf:%px\n",
vf, vf->vf_ext, vf->uvm_vf);
ret = true;
layer->pre_link_en = false;
layer->prelink_bypass_check = false;
layer->last_di_instance = vf->di_instance_id;
layer->prelink_skip_cnt = 0;
} else if (!is_pre_link_on(layer, vf) &&
vf->vf_ext &&
!IS_DI_POSTWRTIE(vf->type)) {
/* Just test the exception case */
pr_info("Exception case: vf %px, vf->ext:%px, type:%x, flag:%x\n",
vf, vf->vf_ext, vf->type, vf->flag);
if (IS_DI_POST(vf->type) &&
layer->next_frame_par->vscale_skip_count > 0) {
ret = true;
} else if (vf->di_flag & DI_FLAG_DI_PVPPLINK) {
ret = true;
if (layer->global_debug & DEBUG_FLAG_PRELINK)
pr_info("can't enable pre-link, force switch: vf %px vf_ext:%px uvm_vf:%px type:%x flag:%x di_flag:%x\n",
vf, vf->vf_ext, vf->uvm_vf,
vf->type, vf->flag, vf->di_flag);
} else if (layer->global_debug & DEBUG_FLAG_PRELINK) {
pr_info("pre-link warning: vf %px vf_ext:%px uvm_vf:%px type:%x flag:%x\n",
vf, vf->vf_ext, vf->uvm_vf,
vf->type, vf->flag);
}
}
}
return ret;
@@ -9738,10 +9829,17 @@ s32 layer_swap_frame(struct vframe_s *vf, struct video_layer_s *layer,
bool is_mvc = false;
u8 layer_id;
bool aisr_update = false;
struct vframe_s *vf_ext = NULL;
if (!vf)
return vppfilter_fail;
if (IS_DI_PROCESSED(vf->type)) {
if (vf->uvm_vf)
vf_ext = vf->uvm_vf;
else
vf_ext = (struct vframe_s *)vf->vf_ext;
}
layer_id = layer->layer_id;
layer_info = &glayer_info[layer_id];
@@ -9774,7 +9872,7 @@ s32 layer_swap_frame(struct vframe_s *vf, struct video_layer_s *layer,
set_video_slice_policy(layer, vf);
set_mosaic_vframe_info(layer, layer_info, vf);
if (!vf->vf_ext) {
if (!vf_ext) {
if (layer->switch_vf) {
force_toggle = true;
if (layer->global_debug & DEBUG_FLAG_BASIC_INFO)
@@ -9784,10 +9882,9 @@ s32 layer_swap_frame(struct vframe_s *vf, struct video_layer_s *layer,
}
layer->switch_vf = false;
} else if (layer->switch_vf) {
struct vframe_s *tmp = (struct vframe_s *)vf->vf_ext;
memcpy(&tmp->pic_mode, &vf->pic_mode,
sizeof(struct vframe_pic_mode_s));
if (vf_ext)
memcpy(&vf_ext->pic_mode, &vf->pic_mode,
sizeof(struct vframe_pic_mode_s));
if (!layer->vf_ext)
force_toggle = true;
}
@@ -9801,8 +9898,7 @@ s32 layer_swap_frame(struct vframe_s *vf, struct video_layer_s *layer,
aisr_reshape_addr_set(layer, &layer->aisr_mif_setting);
set_layer_display_canvas
(layer,
layer->switch_vf ?
(struct vframe_s *)vf->vf_ext : vf,
(layer->switch_vf && vf_ext) ? vf_ext : vf,
layer->cur_frame_par, layer_info, __LINE__);
if (layer->global_debug & DEBUG_FLAG_TRACE_EVENT) {
@@ -9924,6 +10020,7 @@ s32 layer_swap_frame(struct vframe_s *vf, struct video_layer_s *layer,
if (ret != vppfilter_changed_but_hold &&
ret != vppfilter_changed_but_switch)
layer->new_vpp_setting = true;
if (layer->mosaic_mode) {
int i;
struct mosaic_frame_s *mosaic_frame;
@@ -9958,23 +10055,25 @@ s32 layer_swap_frame(struct vframe_s *vf, struct video_layer_s *layer,
layer->new_vpp_setting = true;
}
}
if (ret == vppfilter_success_and_switched && !vf->vf_ext &&
if (ret == vppfilter_success_and_switched && !vf_ext &&
(layer->global_debug & DEBUG_FLAG_BASIC_INFO))
pr_info
("Warning: layer%d: pending switch the display to vf_ext %px\n",
layer->layer_id, vf);
if (ret == vppfilter_success_and_switched && vf->vf_ext) {
if (ret == vppfilter_success_and_switched && vf_ext) {
/* first switch, need re-config vf ext canvas */
if (!layer->switch_vf) {
set_layer_display_canvas
(layer,
(struct vframe_s *)vf->vf_ext,
vf_ext,
layer->cur_frame_par,
layer_info, __LINE__);
if (layer->global_debug & DEBUG_FLAG_BASIC_INFO)
pr_info
("layer%d: switch to vf_ext %px->%px\n",
layer->layer_id, vf, vf->vf_ext);
("layer%d: switch to vf_ext %px->%px(%px %px)\n",
layer->layer_id, vf, vf_ext,
vf->vf_ext, vf->uvm_vf);
}
layer->switch_vf = true;
} else {
@@ -9987,8 +10086,9 @@ s32 layer_swap_frame(struct vframe_s *vf, struct video_layer_s *layer,
layer_info, __LINE__);
if (layer->global_debug & DEBUG_FLAG_BASIC_INFO)
pr_info
("layer%d: switch to orig vf %px->%px\n",
layer->layer_id, vf->vf_ext, vf);
("layer%d: switch to orig vf %px(%px %px)->%px\n",
layer->layer_id, vf_ext,
vf->vf_ext, vf->uvm_vf, vf);
}
layer->switch_vf = false;
}
@@ -10060,7 +10160,7 @@ s32 layer_swap_frame(struct vframe_s *vf, struct video_layer_s *layer,
}
}
if (layer->switch_vf)
layer->vf_ext = (struct vframe_s *)vf->vf_ext;
layer->vf_ext = vf_ext;
else
layer->vf_ext = NULL;
return ret;
@@ -13144,6 +13244,7 @@ int video_early_init(struct amvideo_device_data_s *p_amvideo)
vd_layer[i].keep_frame_id = 0xff;
vd_layer[i].disable_video = VIDEO_DISABLE_FORNEXT;
vd_layer[i].vpp_index = VPP0;
vd_layer[i].last_di_instance = -1;
/* clip config */
vd_layer[i].clip_setting.id = i;
+2 -1
View File
@@ -1130,7 +1130,8 @@ unsigned int vf_keep_current_locked(u8 layer_id,
if (IS_DI_PROCESSED(cur_buf->type)) {
ret = 2;
if (cur_buf->flag & VFRAME_FLAG_DOUBLE_FRAM) {
if (cur_buf->vf_ext &&
(cur_buf->flag & VFRAME_FLAG_DOUBLE_FRAM)) {
ret = video_keeper_frame_keep_locked
(layer_id, (struct vframe_s *)cur_buf->vf_ext,
cur_buf_el);
+36 -10
View File
@@ -551,6 +551,20 @@ static int lowlatency_vsync(u8 instance_id)
vd_layer[0].dispbuf != gvideo_recv[2]->cur_buf)
vd_layer[0].dispbuf = gvideo_recv[2]->cur_buf;
if (vd_layer[0].switch_vf &&
vd_layer[0].dispbuf &&
(vd_layer[0].dispbuf->vf_ext ||
vd_layer[0].dispbuf->uvm_vf)) {
/* select uvm_vf first */
if (vd_layer[0].dispbuf->uvm_vf)
vd_layer[0].vf_ext =
vd_layer[0].dispbuf->uvm_vf;
else
vd_layer[0].vf_ext =
(struct vframe_s *)vd_layer[0].dispbuf->vf_ext;
} else {
vd_layer[0].vf_ext = NULL;
}
/* vd1 config */
if (gvideo_recv[0] &&
gvideo_recv[0]->path_id == vd1_path_id) {
@@ -992,12 +1006,18 @@ static int lowlatency_vsync(u8 instance_id)
if (vd_layer[1].switch_vf &&
vd_layer[1].dispbuf &&
vd_layer[1].dispbuf->vf_ext)
vd_layer[1].vf_ext =
(struct vframe_s *)vd_layer[1].dispbuf->vf_ext;
else
(vd_layer[1].dispbuf->vf_ext ||
vd_layer[1].dispbuf->uvm_vf)) {
/* select uvm_vf first */
if (vd_layer[1].dispbuf->uvm_vf)
vd_layer[1].vf_ext =
vd_layer[1].dispbuf->uvm_vf;
else
vd_layer[1].vf_ext =
(struct vframe_s *)vd_layer[1].dispbuf->vf_ext;
} else {
vd_layer[1].vf_ext = NULL;
}
/* vd2 config */
if (gvideo_recv[0] &&
gvideo_recv[0]->path_id == vd2_path_id) {
@@ -1279,12 +1299,18 @@ static int lowlatency_vsync(u8 instance_id)
if (vd_layer[2].switch_vf &&
vd_layer[2].dispbuf &&
vd_layer[2].dispbuf->vf_ext)
vd_layer[2].vf_ext =
(struct vframe_s *)vd_layer[2].dispbuf->vf_ext;
else
(vd_layer[2].dispbuf->vf_ext ||
vd_layer[2].dispbuf->uvm_vf)) {
/* select uvm_vf first */
if (vd_layer[2].dispbuf->uvm_vf)
vd_layer[2].vf_ext =
vd_layer[2].dispbuf->uvm_vf;
else
vd_layer[2].vf_ext =
(struct vframe_s *)vd_layer[2].dispbuf->vf_ext;
} else {
vd_layer[2].vf_ext = NULL;
}
/* vd3 config */
if (gvideo_recv[0] &&
gvideo_recv[0]->path_id == vd3_path_id) {
+11 -4
View File
@@ -275,11 +275,18 @@ irqreturn_t vsync_isr_viux(u8 vpp_index, const struct vinfo_s *info)
if (vd_layer_vpp[vpp_id].switch_vf &&
vd_layer_vpp[vpp_id].dispbuf &&
vd_layer_vpp[vpp_id].dispbuf->vf_ext)
vd_layer_vpp[vpp_id].vf_ext =
(struct vframe_s *)vd_layer_vpp[vpp_id].dispbuf->vf_ext;
else
(vd_layer_vpp[vpp_id].dispbuf->vf_ext ||
vd_layer_vpp[vpp_id].dispbuf->uvm_vf)) {
/* select uvm_vf first */
if (vd_layer_vpp[vpp_id].dispbuf->uvm_vf)
vd_layer_vpp[vpp_id].vf_ext =
vd_layer_vpp[vpp_id].dispbuf->uvm_vf;
else
vd_layer_vpp[vpp_id].vf_ext =
(struct vframe_s *)vd_layer_vpp[vpp_id].dispbuf->vf_ext;
} else {
vd_layer_vpp[vpp_id].vf_ext = NULL;
}
/* vd2/3 config */
if (gvideo_recv_vpp[recv_id] &&
+6
View File
@@ -24,6 +24,10 @@
#include <linux/amlogic/media/amvecm/amvecm.h>
#include "video_reg_s5.h"
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
#define ENABLE_PRE_LINK
#endif
#define VIDEO_ENABLE_STATE_IDLE 0
#define VIDEO_ENABLE_STATE_ON_REQ 1
#define VIDEO_ENABLE_STATE_ON_PENDING 2
@@ -572,8 +576,10 @@ struct video_layer_s {
struct pip_alpha_scpxn_s alpha_win;
bool pre_link_en;
bool need_disable_prelink;
bool prelink_bypass_check;
bool mosaic_frame;
u8 prelink_skip_cnt;
s32 last_di_instance;
u32 slice_num;
u32 pi_enable;
u32 vd1s1_vd2_prebld_en;
+51 -3
View File
@@ -193,19 +193,67 @@ static void common_vf_unreg_provider(struct video_recv_s *ins)
ins->frame_count = 0;
if (ins->cur_buf) {
if (ins->cur_buf->vf_ext &&
if ((ins->cur_buf->vf_ext || ins->cur_buf->uvm_vf) &&
IS_DI_POSTWRTIE(ins->cur_buf->type)) {
struct vframe_s *tmp =
(struct vframe_s *)ins->cur_buf->vf_ext;
struct vframe_s *tmp;
if (ins->cur_buf->uvm_vf)
tmp = ins->cur_buf->uvm_vf;
else
tmp = (struct vframe_s *)ins->cur_buf->vf_ext;
memcpy(&tmp->pic_mode, &ins->cur_buf->pic_mode,
sizeof(struct vframe_pic_mode_s));
ins->local_buf_ext = *tmp;
ins->local_buf = *ins->cur_buf;
ins->local_buf.vf_ext = (void *)&ins->local_buf_ext;
ins->local_buf.uvm_vf = NULL;
ins->local_buf_ext.ratio_control = ins->local_buf.ratio_control;
} else if (ins->cur_buf->vf_ext &&
is_pre_link_source(ins->cur_buf)) {
u32 tmp_rc;
struct vframe_s *tmp;
if (ins->cur_buf->uvm_vf)
tmp = ins->cur_buf->uvm_vf;
else
tmp = (struct vframe_s *)ins->cur_buf->vf_ext;
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("common_vf_unreg: prelink: cur_buf:%px vf_ext:%px uvm_vf:%px final_vf:%px flag:%x\n",
ins->cur_buf, ins->cur_buf->vf_ext,
ins->cur_buf->uvm_vf, tmp,
ins->cur_buf->flag);
memcpy(&tmp->pic_mode, &ins->cur_buf->pic_mode,
sizeof(struct vframe_pic_mode_s));
tmp_rc = ins->cur_buf->ratio_control;
ins->local_buf = *tmp;
ins->local_buf.ratio_control = tmp_rc;
ins->local_buf.vf_ext = NULL;
ins->local_buf.uvm_vf = NULL;
} else if (IS_DI_POST(ins->cur_buf->type) &&
(ins->cur_buf->vf_ext || ins->cur_buf->uvm_vf)) {
u32 tmp_rc;
struct vframe_s *tmp;
if (ins->cur_buf->uvm_vf)
tmp = ins->cur_buf->uvm_vf;
else
tmp = (struct vframe_s *)ins->cur_buf->vf_ext;
if (debug_flag & DEBUG_FLAG_PRELINK)
pr_info("common_vf_unreg: pre/post link: cur_buf:%px vf_ext:%px uvm_vf:%px final_vf:%px flag:%x\n",
ins->cur_buf, ins->cur_buf->vf_ext,
ins->cur_buf->uvm_vf, tmp,
ins->cur_buf->flag);
memcpy(&tmp->pic_mode, &ins->cur_buf->pic_mode,
sizeof(struct vframe_pic_mode_s));
tmp_rc = ins->cur_buf->ratio_control;
ins->local_buf = *tmp;
ins->local_buf.ratio_control = tmp_rc;
ins->local_buf.vf_ext = NULL;
ins->local_buf.uvm_vf = NULL;
} else {
ins->local_buf = *ins->cur_buf;
ins->local_buf.vf_ext = NULL;
ins->local_buf.uvm_vf = NULL;
}
ins->cur_buf = &ins->local_buf;
}
+38 -8
View File
@@ -44,6 +44,9 @@
#if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM)
#include <linux/amlogic/media/amvecm/amvecm.h>
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
#include <linux/amlogic/media/di/di.h>
#endif
#include "video_priv.h"
#include "video_hw_s5.h"
@@ -982,6 +985,10 @@ static int vpp_process_speed_check
clk_in_pps = 250000000;
else
clk_in_pps = 333000000;
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
if (vf->di_flag & DI_FLAG_DI_PVPPLINK)
clk_in_pps = dim_get_vpuclkb_ext();
#endif
} else {
clk_in_pps = vpu_clk_get();
}
@@ -1055,6 +1062,12 @@ static int vpp_process_speed_check
height_out * width_out) / clk_temp;
display_time_us = 1000000 * sync_duration_den /
vinfo->sync_duration_num;
if (super_debug)
pr_info("%s:input_time_us=%d, display_time_us=%d, dummy_time_us=%d\n",
__func__,
input_time_us,
display_time_us,
dummy_time_us);
if (display_time_us > dummy_time_us)
display_time_us = display_time_us - dummy_time_us;
if (input_time_us > display_time_us)
@@ -1096,7 +1109,8 @@ static int vpp_process_speed_check
1000 * freq_ratio,
height_out * max_height);
/* di process first, need more a bit of ratio */
if (IS_DI_POST(vf->type))
if (IS_DI_POST(vf->type) &&
!(vf->di_flag & DI_FLAG_DI_PVPPLINK))
cur_ratio = (cur_ratio * 105) / 100;
if (!is_meson_t7_cpu() &&
next_frame_par->vscale_skip_count > 0 &&
@@ -1110,11 +1124,12 @@ static int vpp_process_speed_check
(vpp_flags & VPP_FLAG_FROM_TOGGLE_FRAME))
cur_skip_ratio = cur_ratio;
if (super_debug)
pr_info("%s:line=%d,cur_ratio=%d, min_ratio_1000=%d\n",
pr_info("%s:line=%d,cur_ratio=%d, min_ratio_1000=%d, type:%x\n",
__func__,
__LINE__,
cur_ratio,
min_ratio_1000);
min_ratio_1000,
vf->type);
if (cur_ratio > min_ratio_1000 &&
vf->source_type !=
VFRAME_SOURCE_TYPE_TUNER &&
@@ -1123,21 +1138,36 @@ static int vpp_process_speed_check
return SPEED_CHECK_VSKIP;
}
if (vf->type & VIDTYPE_VIU_422) {
/*TODO vpu */
clk_calc = div_u64((u64)VPP_SPEED_FACTOR *
u64 cur_vpp_speed_factor;
u32 cur_bypass_ratio;
if (IS_DI_POST(vf->type) &&
(vf->di_flag & DI_FLAG_DI_PVPPLINK)) {
cur_vpp_speed_factor = 0x100; //adjust factor for prelink
cur_bypass_ratio = bypass_ratio;
} else {
cur_vpp_speed_factor = VPP_SPEED_FACTOR;
cur_bypass_ratio = bypass_ratio;
}
clk_calc = div_u64((u64)cur_vpp_speed_factor *
(u64)width_in *
(u64)height_in *
(u64)vinfo->sync_duration_num *
(u64)vtotal,
height_out *
sync_duration_den *
bypass_ratio);
cur_bypass_ratio);
if (super_debug)
pr_info("%s:line=%d,clk_calc=%d, clk_in_pps=%d\n",
pr_info("%s:line=%d,clk_calc=%d, clk_in_pps=%d, vtotal=%d, sync_duration_num=%d, sync_duration_den=%d, cur_vpp_speed_factor=%lld, cur_bypass_ratio=%d\n",
__func__,
__LINE__,
clk_calc,
clk_in_pps);
clk_in_pps,
vtotal,
vinfo->sync_duration_num,
sync_duration_den,
cur_vpp_speed_factor,
cur_bypass_ratio);
if (height_out == 0 ||
clk_calc > clk_in_pps)
return SPEED_CHECK_VSKIP;
@@ -279,6 +279,7 @@ u32 di_api_get_plink_instance_id(void);
void di_disable_prelink_notify(bool async);
void di_prelink_state_changed_notify(void);
void di_prelink_force_dmc_priority(bool urgent, bool wait);
/*********************************************************
* @brief di_s_bypass_ch set channel bypass
+3
View File
@@ -763,6 +763,9 @@ struct vframe_s {
/* data address of userdata_param_t structure */
struct vf_ud_param_s vf_ud_param;
u32 afbce_num;
/* link to uvm src_vf */
struct vframe_s *uvm_vf;
} /*vframe_t */;
#define VC_FLAG_AI_SR 0x1