media_module: fix vp9/h265 double write only(0x10) issue [1/1]

PD#SWPL-896

Problem:
1) vp9/h265 double write only mode doesn't work with mmu ucode
2) double write flag bug in decoder driver probe

Solution:
1) change code to support double write only mode with mmu ucode
2) fix double write flag bug

Verify:
QA verify

Change-Id: I544d49547238545303cd090541ff6effd1606863
Signed-off-by: Hui Zhang <hui.zhang@amlogic.com>
This commit is contained in:
Hui Zhang
2018-10-05 10:15:10 +08:00
committed by Dongjin Kim
parent e541f1aa96
commit f7b23df1a1
3 changed files with 59 additions and 47 deletions

View File

@@ -6546,13 +6546,12 @@ static int ammvdec_avs2_probe(struct platform_device *pdev)
pdata->threaded_irq_handler = avs2_threaded_irq_cb;
pdata->dump_state = avs2_dump_state;
memcpy(&BUF[0], &dec->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
memset(dec, 0, sizeof(struct AVS2Decoder_s));
memcpy(&dec->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
dec->index = pdev->id;
dec->m_ins_flag = 1;
if (pdata->use_vfm_path)
snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
@@ -6653,8 +6652,6 @@ static int ammvdec_avs2_probe(struct platform_device *pdev)
dec->buf_start = dec->cma_alloc_addr;
dec->buf_size = work_buf_size;
#endif
dec->m_ins_flag = 1;
dec->init_flag = 0;
dec->fatal_error = 0;
dec->show_frame_num = 0;

View File

@@ -1826,7 +1826,7 @@ static int get_dynamic_buf_num_margin(struct hevc_state_s *hevc)
static int get_double_write_mode(struct hevc_state_s *hevc)
{
u32 valid_dw_mode = get_valid_double_write_mode(hevc);
u32 dw;
u32 dw = hevc->double_write_mode;
if (valid_dw_mode == 0x100) {
int w = hevc->pic_w;
int h = hevc->pic_h;
@@ -2185,8 +2185,8 @@ static int init_mmu_buffers(struct hevc_state_s *hevc)
hevc_print(hevc, 0, "%s max_w %d max_h %d\n",
__func__, hevc->max_pic_w, hevc->max_pic_h);
}
if (hevc->mmu_enable) {
if (hevc->mmu_enable
&& ((get_double_write_mode(hevc) & 0x10) == 0)) {
hevc->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
hevc->index,
MAX_REF_PIC_NUM,
@@ -2841,7 +2841,7 @@ static void init_pic_list_hw(struct hevc_state_s *hevc)
break;
}
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) {
if (hevc->mmu_enable)
if (hevc->mmu_enable && ((dw_mode & 0x10) == 0))
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
hevc->m_PIC[i]->header_adr>>5);
else
@@ -2853,10 +2853,6 @@ static void init_pic_list_hw(struct hevc_state_s *hevc)
(hevc->m_PIC[i]->mc_canvas_y << 8) | 0x1);
if (dw_mode & 0x10) {
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) {
if (hevc->mmu_enable)
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
hevc->m_PIC[i]->header_adr>>5);
else
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
hevc->m_PIC[i]->mc_u_v_adr >> 5);
}
@@ -2871,7 +2867,7 @@ static void init_pic_list_hw(struct hevc_state_s *hevc)
return;
for (; i < MAX_REF_PIC_NUM; i++) {
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) {
if (hevc->mmu_enable)
if (hevc->mmu_enable && ((dw_mode & 0x10) == 0))
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
hevc->m_PIC[cur_pic_num-1]->header_adr>>5);
else
@@ -4404,7 +4400,6 @@ static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params)
hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
"[DBLK DEBUG] HEVC1 CFGB : 0x%x\n", data32);
}
data32 = (hevc->pic_w | hevc->pic_h << 16);
WRITE_VREG(HEVC_DBLK_CFG2, data32);
@@ -4473,11 +4468,28 @@ static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params)
data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
if (get_double_write_mode(hevc) == 0)
data32 |= 0x2; /*disable double write*/
else if (!hevc->mmu_enable && (get_double_write_mode(hevc) & 0x10))
else if (get_double_write_mode(hevc) & 0x10)
data32 |= 0x1; /*disable cm*/
}
WRITE_VREG(HEVC_SAO_CTRL1, data32);
} else {
unsigned int data;
data = (0x57 << 8) | /* 1st/2nd write both enable*/
(0x0 << 0); /* h265 video format*/
if (hevc->pic_w >= 1280)
data |= (0x1 << 4); /*dblk pipeline mode=1 for performance*/
data &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/
if (get_double_write_mode(hevc) == 0)
data |= (0x1 << 8); /*enable first write*/
else if (get_double_write_mode(hevc) & 0x10)
data |= (0x1 << 9); /*double write only*/
else
data |= ((0x1 << 8) |(0x1 << 9));
WRITE_VREG(HEVC_DBLK_CFGB, data);
hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
"[DBLK DEBUG] HEVC1 CFGB : 0x%x\n", data);
}
WRITE_VREG(HEVC_SAO_CTRL1, data32);
if (get_double_write_mode(hevc) & 0x10) {
/* [23:22] dw_v1_ctrl
*[21:20] dw_v0_ctrl
@@ -5076,7 +5088,8 @@ static inline void hevc_pre_pic(struct hevc_state_s *hevc,
hevc->ignore_bufmgr_error |= 0x2;
}
}
if (hevc->mmu_enable) {
if (hevc->mmu_enable
&& ((hevc->double_write_mode & 0x10) == 0)) {
if (!hevc->m_ins_flag) {
hevc->used_4k_num =
READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
@@ -5910,7 +5923,8 @@ static int H265_alloc_mmu(struct hevc_state_s *hevc, struct PIC_s *new_pic,
picture_size = compute_losless_comp_body_size(hevc, new_pic->width,
new_pic->height, !bit_depth_10);
cur_mmu_4k_number = ((picture_size+(1<<12)-1) >> 12);
if (hevc->double_write_mode & 0x10)
return 0;
/*hevc_print(hevc, 0,
"alloc_mmu cur_idx : %d picture_size : %d mmu_4k_number : %d\r\n",
cur_buf_idx, picture_size, cur_mmu_4k_number);*/
@@ -5953,7 +5967,9 @@ static void release_pic_mmu_buf(struct hevc_state_s *hevc,
__func__, pic->index,
pic->scatter_alloc);
if (hevc->mmu_enable && pic->scatter_alloc)
if (hevc->mmu_enable
&& ((hevc->double_write_mode & 0x10) == 0)
&& pic->scatter_alloc)
decoder_mmu_box_free_idx(hevc->mmu_box, pic->index);
pic->scatter_alloc = 0;
}
@@ -8000,7 +8016,8 @@ pic_done:
hevc->ignore_bufmgr_error |= 0x2;
}
}
if (hevc->mmu_enable) {
if (hevc->mmu_enable
&& ((hevc->double_write_mode & 0x10) == 0)) {
if (!hevc->m_ins_flag) {
hevc->used_4k_num =
READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
@@ -9947,7 +9964,7 @@ static void vh265_work(struct work_struct *work)
/* if (!hevc->ctx_valid)
hevc->ctx_valid = 1; */
decode_frame_count[hevc->index]++;
if (hevc->mmu_enable) {
if (hevc->mmu_enable && ((hevc->double_write_mode & 0x10) == 0)) {
hevc->used_4k_num =
READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
if (hevc->used_4k_num >= 0 &&
@@ -10737,6 +10754,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev)
pdata->dump_state = vh265_dump_state;
hevc->index = pdev->id;
hevc->m_ins_flag = 1;
if (pdata->use_vfm_path)
snprintf(pdata->vf_provider_name,
@@ -10821,8 +10839,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev)
hevc->dynamic_buf_num_margin = dynamic_buf_num_margin;
if (mmu_enable_force == 0) {
if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL
|| hevc->double_write_mode == 0x10)
if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL)
hevc->mmu_enable = 0;
else
hevc->mmu_enable = 1;
@@ -10860,7 +10877,6 @@ static int ammvdec_h265_probe(struct platform_device *pdev)
if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXTVBB) &&
(parser_sei_enable & 0x100) == 0)
parser_sei_enable = 7;
hevc->m_ins_flag = 1;
hevc->init_flag = 0;
hevc->uninit_list = 0;
hevc->fatal_error = 0;

View File

@@ -1218,9 +1218,9 @@ static int setup_frame_size(
WRITE_VREG(HEVC_PARSER_PICTURE_SIZE, (height << 16) | width);
#ifdef VP9_10B_HED_FB
WRITE_VREG(HEVC_ASSIST_PIC_SIZE_FB_READ, (height << 16) | width);
WRITE_VREG(HEVC_ASSIST_PIC_SIZE_FB_READ, (height << 16) | width);
#endif
if (pbi->mmu_enable) {
if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
ret = vp9_alloc_mmu(pbi,
cm->new_fb_idx,
params->p.width,
@@ -1337,7 +1337,7 @@ static int setup_frame_size_with_refs(
params->p.height = height;
WRITE_VREG(HEVC_PARSER_PICTURE_SIZE, (height << 16) | width);
if (pbi->mmu_enable) {
if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
/*if(cm->prev_fb_idx >= 0) release_unused_4k(cm->prev_fb_idx);
*cm->prev_fb_idx = cm->new_fb_idx;
*/
@@ -1591,6 +1591,8 @@ int vp9_alloc_mmu(
pr_err("error no mmu box!\n");
return -1;
}
if (pbi->double_write_mode & 0x10)
return 0;
if (bit_depth >= VPX_BITS_12) {
pbi->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW;
pr_err("fatal_error, un support bit depth 12!\n\n");
@@ -4684,7 +4686,7 @@ static void init_pic_list(struct VP9Decoder_s *pbi)
struct PIC_BUFFER_CONFIG_s *pic_config;
u32 header_size;
if (pbi->mmu_enable) {
if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
header_size = vvp9_mmu_compress_header_size();
/*alloc VP9 compress header first*/
for (i = 0; i < pbi->used_buf_num; i++) {
@@ -4747,11 +4749,8 @@ static void init_pic_list_hw(struct VP9Decoder_s *pbi)
if (pic_config->index < 0)
break;
if (pbi->mmu_enable) {
/*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
* pic_config->header_adr
* | (pic_config->mc_canvas_y << 8)|0x1);
*/
if (pbi->mmu_enable && ((pic_config->double_write_mode & 0x10) == 0)) {
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
pic_config->header_adr >> 5);
} else {
@@ -4767,14 +4766,10 @@ static void init_pic_list_hw(struct VP9Decoder_s *pbi)
* pic_config->mc_u_v_adr
* | (pic_config->mc_canvas_u_v << 8)| 0x1);
*/
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
pic_config->header_adr >> 5);
#else
if (pic_config->double_write_mode & 0x10) {
if (pbi->mmu_enable)
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
pic_config->header_adr>>5);
else
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
pic_config->dw_u_v_adr >> 5);
}
@@ -5098,8 +5093,7 @@ static void config_sao_hw(struct VP9Decoder_s *pbi, union param_u *params)
data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
if (get_double_write_mode(pbi) == 0)
data32 |= 0x2; /*disable double write*/
else if (!pbi->mmu_enable &&
get_double_write_mode(pbi) & 0x10)
else if (get_double_write_mode(pbi) & 0x10)
data32 |= 0x1; /*disable cm*/
} else { /* >= G12A dw write control */
unsigned int data;
@@ -5107,7 +5101,7 @@ static void config_sao_hw(struct VP9Decoder_s *pbi, union param_u *params)
data &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/
if (get_double_write_mode(pbi) == 0)
data |= (0x1 << 8); /*enable first write*/
else if (get_double_write_mode(pbi) == 0x10)
else if (get_double_write_mode(pbi) & 0x10)
data |= (0x1 << 9); /*double write only*/
else
data |= ((0x1 << 8) |(0x1 << 9));
@@ -6334,6 +6328,7 @@ static void set_canvas(struct VP9Decoder_s *pbi,
canvas_config_ex(pic_config->uv_canvas_index,
pic_config->dw_u_v_adr, canvas_w, canvas_h,
CANVAS_ADDR_NOWRAP, blkmode, 0x7);
#ifdef MULTI_INSTANCE_SUPPORT
pic_config->canvas_config[0].phy_addr =
pic_config->dw_y_adr;
@@ -6948,6 +6943,8 @@ static void debug_buffer_mgr_more(struct VP9Decoder_s *pbi)
static void vp9_recycle_mmu_buf_tail(struct VP9Decoder_s *pbi)
{
struct VP9_Common_s *const cm = &pbi->common;
if (pbi->double_write_mode & 0x10)
return;
if (cm->cur_fb_idx_mmu != INVALID_IDX) {
if (pbi->used_4k_num == -1)
pbi->used_4k_num =
@@ -6964,6 +6961,8 @@ static void vp9_recycle_mmu_buf_tail(struct VP9Decoder_s *pbi)
static void vp9_recycle_mmu_buf(struct VP9Decoder_s *pbi)
{
struct VP9_Common_s *const cm = &pbi->common;
if (pbi->double_write_mode & 0x10)
return;
if (cm->cur_fb_idx_mmu != INVALID_IDX) {
decoder_mmu_box_free_idx(pbi->mmu_box,
cm->cur_fb_idx_mmu);
@@ -7006,7 +7005,7 @@ int continue_decoding(struct VP9Decoder_s *pbi)
pbi->slice_idx++;
} else {
union param_u *params = &vp9_param;
if (pbi->mmu_enable) {
if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
ret = vp9_alloc_mmu(pbi,
cm->new_fb_idx,
params->p.width,
@@ -7133,7 +7132,7 @@ int continue_decoding(struct VP9Decoder_s *pbi)
WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DECODE_SLICE);
}
pbi->process_state = PROC_STATE_DECODESLICE;
if (pbi->mmu_enable) {
if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
if (pbi->last_put_idx < pbi->used_buf_num) {
struct RefCntBuffer_s *frame_bufs =
cm->buffer_pool->frame_bufs;
@@ -8225,7 +8224,7 @@ static int amvdec_vp9_mmu_init(struct VP9Decoder_s *pbi)
(pbi->max_pic_w * pbi->max_pic_h <= 1280*736)) {
buf_size = 4;
}
if (pbi->mmu_enable) {
if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
pbi->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
pbi->index, FRAME_BUFFERS,
buf_size * SZ_1M,
@@ -8306,7 +8305,7 @@ static int amvdec_vp9_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pdata);
#endif
pbi->double_write_mode = double_write_mode;
pbi->mmu_enable = !(pbi->double_write_mode == 0x10);
pbi->mmu_enable = 1;
if (amvdec_vp9_mmu_init(pbi) < 0) {
vfree(pbi);
mutex_unlock(&vvp9_mutex);
@@ -9355,7 +9354,7 @@ static int ammvdec_vp9_probe(struct platform_device *pdev)
pbi->vvp9_amstream_dec_info.rate = 30;*/
pbi->double_write_mode = double_write_mode;
}
pbi->mmu_enable = !(pbi->double_write_mode == 0x10);
pbi->mmu_enable = 1;
video_signal_type = pbi->video_signal_type;
#if 0
pbi->buf_start = pdata->mem_start;