From: zhilei.wu Date: Tue, 20 Mar 2018 13:43:10 +0000 (+0800) Subject: dv: fixed core2 lut table error X-Git-Tag: khadas-vims-v0.9.6-release~2301 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f3aa7318d492af815192b682052c3519beadff5c;p=platform%2Fkernel%2Flinux-amlogic.git dv: fixed core2 lut table error PD#161010: dv: fixed core2 lut table error Change-Id: Ic0ebdf677869ab1325f17fda36e0869329be37b8 Signed-off-by: zhilei.wu --- diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c index 4519997..2a117b4 100644 --- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c +++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c @@ -170,10 +170,7 @@ module_param(dolby_vision_tunning_mode, uint, 0664); MODULE_PARM_DESC(dolby_vision_tunning_mode, "\n dolby_vision_tunning_mode\n"); #ifdef V2_4 -#define DV_LL_OUTPUT_BITS 12 -/* bit0 ~ bit7: output mode, bit8 ~ bit15: output bits */ -static unsigned int dv_ll_output_mode = - (DV_LL_OUTPUT_BITS << 8) | DOLBY_VISION_OUTPUT_MODE_HDR10; +static unsigned int dv_ll_output_mode = DOLBY_VISION_OUTPUT_MODE_HDR10; module_param(dv_ll_output_mode, uint, 0664); MODULE_PARM_DESC(dv_ll_output_mode, "\n dv_ll_output_mode\n"); @@ -250,6 +247,9 @@ static u32 core1_disp_vsize; static u32 vsync_count; #define FLAG_VSYNC_CNT 10 +static bool is_osd_off; +static bool force_reset_core2; + module_param(vtotal_add, uint, 0664); MODULE_PARM_DESC(vtotal_add, "\n vtotal_add\n"); module_param(vpotch, uint, 0664); @@ -780,8 +780,13 @@ MODULE_PARM_DESC(debug_dolby_frame, "\n debug_dolby_frame\n"); pr_info("DOLBY ERROR: " fmt, ## args) #define dump_enable \ ((debug_dolby_frame >= 0xffff) || (debug_dolby_frame == frame_count)) -#define is_graphics_output_off() 0 - /*(!(READ_VPP_REG(VPP_MISC) & (1<<12)))*/ +static int is_graphics_output_off(void) +{ + if (is_meson_g12a()) + return !(READ_VPP_REG(OSD1_BLEND_SRC_CTRL) & (1<<8)); + else + return (!(READ_VPP_REG(VPP_MISC) & (1<<12))); +} #define single_step_enable \ (((debug_dolby_frame >= 0xffff) || \ ((debug_dolby_frame + 1) == frame_count)) && \ @@ -841,7 +846,7 @@ static u32 stb_core_setting_update_flag = FLAG_CHANGE_ALL; static uint64_t stb_core1_lut[STB_DMA_TBL_SIZE]; static bool tv_mode; -static bool is_meson_gxm(void) +bool is_meson_gxm(void) { if (dv_meson_dev.cpu_id == _CPU_MAJOR_ID_GXM) return true; @@ -849,7 +854,7 @@ static bool is_meson_gxm(void) return false; } -static bool is_meson_txlx(void) +bool is_meson_txlx(void) { if (dv_meson_dev.cpu_id == _CPU_MAJOR_ID_TXLX) return true; @@ -857,7 +862,7 @@ static bool is_meson_txlx(void) return false; } -static bool is_meson_txlx_tvmode(void) +bool is_meson_txlx_tvmode(void) { if ((is_meson_txlx()) && (tv_mode == 1)) return true; @@ -865,7 +870,7 @@ static bool is_meson_txlx_tvmode(void) return false; } -static bool is_meson_txlx_stbmode(void) +bool is_meson_txlx_stbmode(void) { if ((is_meson_txlx()) && (tv_mode == 0)) return true; @@ -873,7 +878,7 @@ static bool is_meson_txlx_stbmode(void) return false; } -static bool is_meson_g12a(void) +bool is_meson_g12a(void) { if (dv_meson_dev.cpu_id == _CPU_MAJOR_ID_G12A) return true; @@ -1114,7 +1119,9 @@ static int stb_dolby_core1_set( if (dolby_vision_run_mode != 0xff) run_mode = dolby_vision_run_mode; else { - run_mode = (0x7 << 6) | (el_41_mode << 3) | bypass_flag; + run_mode = (0x7 << 6) | + ((el_41_mode ? 3 : 1) << 2) | + bypass_flag; if (dolby_vision_on_count < dolby_vision_run_mode_delay) { run_mode |= 1; VSYNC_WR_MPEG_REG(VPP_VD1_CLIP_MISC0, @@ -1137,7 +1144,11 @@ static int stb_dolby_core1_set( if (reset) VSYNC_WR_MPEG_REG(DOLBY_TV_REG_START + 1, run_mode); - VSYNC_WR_MPEG_REG(DOLBY_TV_SWAP_CTRL5, 0x6); + /* 962e work around to fix the uv swap issue when bl:el = 1:1 */ + if (el_41_mode) + VSYNC_WR_MPEG_REG(DOLBY_TV_SWAP_CTRL5, 0x6); + else + VSYNC_WR_MPEG_REG(DOLBY_TV_SWAP_CTRL5, 0xa); /* axi dma for reg table */ reg_size = prepare_stb_dolby_core1_reg( @@ -1424,14 +1435,17 @@ static int dolby_core1_set( if (dolby_vision_flags & FLAG_DISABLE_COMPOSER) composer_enable = 0; + if (dolby_vision_on_count + == dolby_vision_run_mode_delay) + reset = true; + if ((!dolby_vision_on || reset) && bl_enable) { VSYNC_WR_MPEG_REG(VIU_SW_RESET, 1 << 9); VSYNC_WR_MPEG_REG(VIU_SW_RESET, 0); reset = true; } - if ((dolby_vision_flags & FLAG_CERTIFICAION) - || (frame_count < 10)) + if (dolby_vision_flags & FLAG_CERTIFICAION) reset = true; if (stb_core_setting_update_flag & FLAG_CHANGE_TC) @@ -1570,14 +1584,17 @@ static int dolby_core1_set( VIU_MISC_CTRL1, 1, 16, 1); } else { - VSYNC_WR_MPEG_REG( - VPP_VD1_CLIP_MISC0, - (0x3ff << 20) | - (0x3ff << 10) | - 0x3ff); - VSYNC_WR_MPEG_REG( - VPP_VD1_CLIP_MISC1, - 0); + if (dolby_vision_on_count > + dolby_vision_run_mode_delay) { + VSYNC_WR_MPEG_REG( + VPP_VD1_CLIP_MISC0, + (0x3ff << 20) | + (0x3ff << 10) | + 0x3ff); + VSYNC_WR_MPEG_REG( + VPP_VD1_CLIP_MISC1, + 0); + } if (dolby_vision_core1_on && !bypass_core1) { if (is_meson_g12a()) @@ -1633,14 +1650,15 @@ static int dolby_core2_set( && (dolby_vision_flags & FLAG_DISABE_CORE_SETTING)) return 0; - if (!dolby_vision_on) { + + if (!dolby_vision_on || force_reset_core2) { VSYNC_WR_MPEG_REG(VIU_SW_RESET, (1 << 10)); VSYNC_WR_MPEG_REG(VIU_SW_RESET, 0); + force_reset_core2 = false; reset = true; } - if ((dolby_vision_flags & FLAG_CERTIFICAION) - || (frame_count < 10)) + if (dolby_vision_flags & FLAG_CERTIFICAION) reset = true; if (stb_core_setting_update_flag & FLAG_CHANGE_TC2) @@ -1649,8 +1667,7 @@ static int dolby_core2_set( VSYNC_WR_MPEG_REG(DOLBY_CORE2A_CLKGATE_CTRL, 0); VSYNC_WR_MPEG_REG(DOLBY_CORE2A_SWAP_CTRL0, 0); if (is_meson_gxm() || - is_meson_g12a() || - (dolby_vision_flags & FLAG_CERTIFICAION)) { + is_meson_g12a() || reset) { VSYNC_WR_MPEG_REG(DOLBY_CORE2A_SWAP_CTRL1, ((hsize + g_htotal_add) << 16) | (vsize + g_vtotal_add + g_vsize_add)); @@ -1663,8 +1680,10 @@ static int dolby_core2_set( (g_hpotch << 16) | g_vpotch); if (is_meson_txlx_stbmode() || force_stb_mode) VSYNC_WR_MPEG_REG(DOLBY_CORE2A_SWAP_CTRL5, 0xf8000000); - else + else if (is_meson_g12a()) VSYNC_WR_MPEG_REG(DOLBY_CORE2A_SWAP_CTRL5, 0xa8000000); + else + VSYNC_WR_MPEG_REG(DOLBY_CORE2A_SWAP_CTRL5, 0x0); VSYNC_WR_MPEG_REG(DOLBY_CORE2A_DMA_CTRL, 0x0); VSYNC_WR_MPEG_REG(DOLBY_CORE2A_REG_START + 2, 1); VSYNC_WR_MPEG_REG(DOLBY_CORE2A_REG_START + 1, 2); @@ -1679,10 +1698,12 @@ static int dolby_core2_set( for (i = 0; i < count; i++) if (reset || (p_core2_dm_regs[i] != - last_dm[i])) + last_dm[i])) { VSYNC_WR_MPEG_REG( DOLBY_CORE2A_REG_START + 6 + i, p_core2_dm_regs[i]); + set_lut = true; + } /* core2 metadata program done */ VSYNC_WR_MPEG_REG(DOLBY_CORE2A_REG_START + 3, 1); @@ -1751,11 +1772,8 @@ static int dolby_core3_set( FLAG_DISABE_CORE_SETTING)) return 0; - if (!dolby_vision_on) - reset = true; - - if ((dolby_vision_flags & FLAG_CERTIFICAION) - || (frame_count < 10)) + if (!dolby_vision_on || + (dolby_vision_flags & FLAG_CERTIFICAION)) reset = true; #ifdef V2_4 if (((cur_dv_mode == DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL) @@ -1831,8 +1849,7 @@ static int dolby_core3_set( memcmp(&p_core3_dm_regs[18], &last_dm[18], 32))) enable_rgb_to_yuv_matrix_for_dvll( - 1, &p_core3_dm_regs[18], - (dv_ll_output_mode >> 8) & 0xff); + 1, &p_core3_dm_regs[18], 12); #endif VSYNC_WR_MPEG_REG(DOLBY_CORE3_CLKGATE_CTRL, 0); @@ -1929,15 +1946,26 @@ static void apply_stb_core_settings( graphics_w = dv_cert_graphic_width; graphics_h = dv_cert_graphic_height; } + if (is_meson_txlx_package_962E() + || force_stb_mode) { + if ((vinfo->width >= 1920) && + (vinfo->height >= 1080) && + (vinfo->field_height >= 1080)) + dma_start_line = 0x400; + else + dma_start_line = 0x180; + /* adjust core2 setting to work around*/ + /* fixing with 1080p24hz and 480p60hz */ + if ((vinfo->width < 1280) && + (vinfo->height < 720) && + (vinfo->field_height < 720)) + g_vpotch = 0x60; + else + g_vpotch = 0x20; + } if (mask & 1) { - if (is_meson_txlx_stbmode() + if (is_meson_txlx_package_962E() || force_stb_mode) { - if ((vinfo->width >= 1920) && - (vinfo->height >= 1080) && - (vinfo->field_height >= 1080)) - dma_start_line = 0x400; - else - dma_start_line = 0x180; stb_dolby_core1_set( 27, 173, 256 * 5, (uint32_t *)&new_dovi_setting.dm_reg1, @@ -2407,9 +2435,7 @@ void enable_dolby_vision(int enable) VSYNC_WR_MPEG_REG_BITS( VPP_DOLBY_CTRL, 1, 1, 2); enable_rgb_to_yuv_matrix_for_dvll( - 1, ®[18], - (dv_ll_output_mode >> 8) - & 0xff); + 1, ®[18], 12); } else enable_rgb_to_yuv_matrix_for_dvll( 0, NULL, 12); @@ -2588,9 +2614,7 @@ void enable_dolby_vision(int enable) VPP_DOLBY_CTRL, 3, 6, 2); /* post matrix */ enable_rgb_to_yuv_matrix_for_dvll( - 1, ®[18], - (dv_ll_output_mode >> 8) - & 0xff); + 1, ®[18], 12); } else enable_rgb_to_yuv_matrix_for_dvll( 0, NULL, 12); @@ -2988,22 +3012,37 @@ static void dump_setting( p = (uint32_t *)&setting->comp_reg; for (i = 0; i < 173; i++) pr_info("%08x\n", p[i]); - pr_info("core1 swap\n"); - for (i = DOLBY_CORE1_CLKGATE_CTRL; - i <= DOLBY_CORE1_DMA_PORT; i++) - pr_info("[0x%4x] = 0x%x\n", - i, READ_VPP_REG(i)); - pr_info("core1 real reg\n"); - for (i = DOLBY_CORE1_REG_START; - i <= DOLBY_CORE1_REG_START + 5; i++) - pr_info("[0x%4x] = 0x%x\n", - i, READ_VPP_REG(i)); - pr_info("core1 composer real reg\n"); - for (i = 0; i < 173 ; i++) - pr_info("%08x\n", - READ_VPP_REG( - DOLBY_CORE1_REG_START - + 50 + i)); + if (is_meson_gxm()) { + pr_info("core1 swap\n"); + for (i = DOLBY_CORE1_CLKGATE_CTRL; + i <= DOLBY_CORE1_DMA_PORT; i++) + pr_info("[0x%4x] = 0x%x\n", + i, READ_VPP_REG(i)); + pr_info("core1 real reg\n"); + for (i = DOLBY_CORE1_REG_START; + i <= DOLBY_CORE1_REG_START + 5; + i++) + pr_info("[0x%4x] = 0x%x\n", + i, READ_VPP_REG(i)); + pr_info("core1 composer real reg\n"); + for (i = 0; i < 173 ; i++) + pr_info("%08x\n", + READ_VPP_REG( + DOLBY_CORE1_REG_START + + 50 + i)); + } else if (is_meson_txlx()) { + pr_info("core1 swap\n"); + for (i = DOLBY_TV_SWAP_CTRL0; + i <= DOLBY_TV_STATUS1; i++) + pr_info("[0x%4x] = 0x%x\n", + i, READ_VPP_REG(i)); + pr_info("core1 real reg\n"); + for (i = DOLBY_TV_REG_START; + i <= DOLBY_CORE1_REG_START + 5; + i++) + pr_info("[0x%4x] = 0x%x\n", + i, READ_VPP_REG(i)); + } } if ((debug_flag & 0x20) && dump_enable) { @@ -3596,8 +3635,8 @@ static int parse_sei_and_meta( pr_dolby_dbg("metadata parser init OK\n"); } } else { - if (p_funcs->metadata_parser_reset - (metadata_parser_reset_flag) == 0) + if (p_funcs->metadata_parser_reset( + metadata_parser_reset_flag) == 0) metadata_parser_reset_flag = 0; parser_ready = 1; } @@ -4001,53 +4040,53 @@ static bool send_hdmi_pkt( | (9 << 16) /* bt2020 */ | (0x10 << 8) /* bt2020-10 */ | (10 << 0);/* bt2020c */ + /* need invert to g,b,r */ if (hdr10_data.primaries[0][0] != - ((p_hdr->display_primaries_x_0_MSB << 8) - | p_hdr->display_primaries_x_0_LSB)) - flag = true; - hdr10_data.primaries[0][0] = - (p_hdr->display_primaries_x_0_MSB << 8) - | p_hdr->display_primaries_x_0_LSB; - - if (hdr10_data.primaries[0][1] != - ((p_hdr->display_primaries_y_0_MSB << 8) - | p_hdr->display_primaries_y_0_LSB)) - flag = true; - hdr10_data.primaries[0][1] = - (p_hdr->display_primaries_y_0_MSB << 8) - | p_hdr->display_primaries_y_0_LSB; - - if (hdr10_data.primaries[1][0] != ((p_hdr->display_primaries_x_1_MSB << 8) | p_hdr->display_primaries_x_1_LSB)) flag = true; - hdr10_data.primaries[1][0] = + hdr10_data.primaries[0][0] = (p_hdr->display_primaries_x_1_MSB << 8) | p_hdr->display_primaries_x_1_LSB; - if (hdr10_data.primaries[1][1] != + if (hdr10_data.primaries[0][1] != ((p_hdr->display_primaries_y_1_MSB << 8) | p_hdr->display_primaries_y_1_LSB)) flag = true; - hdr10_data.primaries[1][1] = + hdr10_data.primaries[0][1] = (p_hdr->display_primaries_y_1_MSB << 8) | p_hdr->display_primaries_y_1_LSB; - if (hdr10_data.primaries[2][0] != + if (hdr10_data.primaries[1][0] != ((p_hdr->display_primaries_x_2_MSB << 8) | p_hdr->display_primaries_x_2_LSB)) flag = true; - hdr10_data.primaries[2][0] = + hdr10_data.primaries[1][0] = (p_hdr->display_primaries_x_2_MSB << 8) | p_hdr->display_primaries_x_2_LSB; - if (hdr10_data.primaries[2][1] != + if (hdr10_data.primaries[1][1] != ((p_hdr->display_primaries_y_2_MSB << 8) | p_hdr->display_primaries_y_2_LSB)) flag = true; - hdr10_data.primaries[2][1] = + hdr10_data.primaries[1][1] = (p_hdr->display_primaries_y_2_MSB << 8) | p_hdr->display_primaries_y_2_LSB; + if (hdr10_data.primaries[2][0] != + ((p_hdr->display_primaries_x_0_MSB << 8) + | p_hdr->display_primaries_x_0_LSB)) + flag = true; + hdr10_data.primaries[2][0] = + (p_hdr->display_primaries_x_0_MSB << 8) + | p_hdr->display_primaries_x_0_LSB; + + if (hdr10_data.primaries[2][1] != + ((p_hdr->display_primaries_y_0_MSB << 8) + | p_hdr->display_primaries_y_0_LSB)) + flag = true; + hdr10_data.primaries[2][1] = + (p_hdr->display_primaries_y_0_MSB << 8) + | p_hdr->display_primaries_y_0_LSB; if (hdr10_data.white_point[0] != ((p_hdr->white_point_x_MSB << 8) @@ -4531,7 +4570,11 @@ int dolby_vision_parse_metadata( } else if (meta_flag_bl && meta_flag_el) { total_md_size = last_total_md_size; total_comp_size = last_total_comp_size; - el_flag = dovi_setting.el_flag; + if (is_dolby_vision_stb_mode()) + el_flag = dovi_setting.el_flag; + else + el_flag = ((struct tv_dovi_setting_s *) + tv_dovi_setting)->el_flag; meta_flag_bl = 0; } if ((src_format == FORMAT_DOVI) @@ -4734,18 +4777,15 @@ int dolby_vision_parse_metadata( if (is_graphics_output_off()) { graphic_min = 0; graphic_max = 0; + is_osd_off = true; } else { - graphic_min = - dolby_vision_graphic_min; -#ifdef V2_4 - if (dolby_vision_flags & FLAG_CERTIFICAION) - graphic_max = 500; - else - graphic_max = - dolby_vision_graphic_max; -#else + graphic_min = dolby_vision_graphic_min; graphic_max = dolby_vision_graphic_max; -#endif + /* force reset core2 when osd off->on */ + /* TODO: 962e need ? */ + if (is_osd_off) + force_reset_core2 = true; + is_osd_off = false; } if (dolby_vision_flags & FLAG_USE_SINK_MIN_MAX) { if (vinfo->vout_device->dv_info->ieeeoui == 0x00d046) { @@ -4837,19 +4877,70 @@ int dolby_vision_parse_metadata( && (vinfo->vout_device->dv_info ->block_flag == CORRECT)) { if (new_dovi_setting.vsvdb_len - != vinfo->vout_device->dv_info->length) + != vinfo->vout_device->dv_info->length + 1) new_dovi_setting.vsvdb_changed = 1; else if (memcmp(&new_dovi_setting.vsvdb_tbl[0], &vinfo->vout_device->dv_info->rawdata[0], - vinfo->vout_device->dv_info->length)) + vinfo->vout_device->dv_info->length + 1)) new_dovi_setting.vsvdb_changed = 1; memset(&new_dovi_setting.vsvdb_tbl[0], 0, sizeof(new_dovi_setting.vsvdb_tbl)); memcpy(&new_dovi_setting.vsvdb_tbl[0], &vinfo->vout_device->dv_info->rawdata[0], - vinfo->vout_device->dv_info->length); + vinfo->vout_device->dv_info->length + 1); new_dovi_setting.vsvdb_len = - vinfo->vout_device->dv_info->length; + vinfo->vout_device->dv_info->length + 1; + if (new_dovi_setting.vsvdb_changed + && new_dovi_setting.vsvdb_len) { + int k = 0; + + pr_dolby_dbg( + "new vsvdb[%d]:\n", + new_dovi_setting.vsvdb_len); + pr_dolby_dbg( + "---%02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x\n", + new_dovi_setting.vsvdb_tbl[k + 0], + new_dovi_setting.vsvdb_tbl[k + 1], + new_dovi_setting.vsvdb_tbl[k + 2], + new_dovi_setting.vsvdb_tbl[k + 3], + new_dovi_setting.vsvdb_tbl[k + 4], + new_dovi_setting.vsvdb_tbl[k + 5], + new_dovi_setting.vsvdb_tbl[k + 6], + new_dovi_setting.vsvdb_tbl[k + 7]); + k += 8; + pr_dolby_dbg( + "---%02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x\n", + new_dovi_setting.vsvdb_tbl[k + 0], + new_dovi_setting.vsvdb_tbl[k + 1], + new_dovi_setting.vsvdb_tbl[k + 2], + new_dovi_setting.vsvdb_tbl[k + 3], + new_dovi_setting.vsvdb_tbl[k + 4], + new_dovi_setting.vsvdb_tbl[k + 5], + new_dovi_setting.vsvdb_tbl[k + 6], + new_dovi_setting.vsvdb_tbl[k + 7]); + k += 8; + pr_dolby_dbg( + "---%02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x\n", + new_dovi_setting.vsvdb_tbl[k + 0], + new_dovi_setting.vsvdb_tbl[k + 1], + new_dovi_setting.vsvdb_tbl[k + 2], + new_dovi_setting.vsvdb_tbl[k + 3], + new_dovi_setting.vsvdb_tbl[k + 4], + new_dovi_setting.vsvdb_tbl[k + 5], + new_dovi_setting.vsvdb_tbl[k + 6], + new_dovi_setting.vsvdb_tbl[k + 7]); + k += 8; + pr_dolby_dbg( + "---%02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x\n", + new_dovi_setting.vsvdb_tbl[k + 0], + new_dovi_setting.vsvdb_tbl[k + 1], + new_dovi_setting.vsvdb_tbl[k + 2], + new_dovi_setting.vsvdb_tbl[k + 3], + new_dovi_setting.vsvdb_tbl[k + 4], + new_dovi_setting.vsvdb_tbl[k + 5], + new_dovi_setting.vsvdb_tbl[k + 6], + new_dovi_setting.vsvdb_tbl[k + 7]); + } } else { if (new_dovi_setting.vsvdb_len) new_dovi_setting.vsvdb_changed = 1; @@ -4961,19 +5052,20 @@ int dolby_vision_parse_metadata( dovi_setting_video_flag = video_frame; if (debug_dolby & 1) { if (el_flag) - pr_dolby_dbg("setting %d->%d(T:%d-%d): flag=%02x,md=%d,comp=%d\n", + pr_dolby_dbg("setting %d->%d(T:%d-%d): flag=%02x,md=%d,comp=%d, frame:%d\n", src_format, dst_format, dolby_vision_target_min, dolby_vision_target_max[src_format][dst_format], flag, - total_md_size, total_comp_size); + total_md_size, total_comp_size, + frame_count); else - pr_dolby_dbg("setting %d->%d(T:%d-%d): flag=%02x,md=%d\n", + pr_dolby_dbg("setting %d->%d(T:%d-%d): flag=%02x,md=%d, frame:%d\n", src_format, dst_format, dolby_vision_target_min, dolby_vision_target_max[src_format][dst_format], flag, - total_md_size); + total_md_size, frame_count); } dump_setting(&new_dovi_setting, frame_count, debug_dolby); el_mode = el_flag; @@ -4999,13 +5091,14 @@ int dolby_vision_wait_metadata(struct vframe_s *vf) int ret = 0; unsigned int mode; - if (single_step_enable) + if (single_step_enable) { if (dolby_vision_flags & FLAG_SINGLE_STEP) /* wait fake el for "step" */ return 1; - if (single_step_enable) - if (!(dolby_vision_flags & FLAG_SINGLE_STEP)) + else dolby_vision_flags |= FLAG_SINGLE_STEP; + } + if (dolby_vision_flags & FLAG_CERTIFICAION) { bool ott_mode = true; @@ -5244,9 +5337,10 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size) && !video_off_handled) { dolby_vision_set_toggle_flag(1); frame_count = 0; - pr_dolby_dbg("video off\n"); - if (debug_dolby) + if (debug_dolby & 2) { video_off_handled = 1; + pr_dolby_dbg("video off\n"); + } } if (last_dolby_vision_policy != dolby_vision_policy) { @@ -5594,6 +5688,11 @@ int register_dv_functions(const struct dolby_vision_func_s *func) pq_config_fake = (struct pq_config_s *)pq_config; dovi_setting = vmalloc(sizeof(dovi_setting)); tv_dovi_setting = (struct tv_dovi_setting_s *)dovi_setting; + /* adjust core2 setting to work around fixing with 1080p24hz */ + if (is_meson_txlx()) + g_vpotch = 0x20; + else + g_vpotch = 0x8; } return ret; } diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 71b11ab..4034d55 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -378,6 +378,7 @@ static u32 hdmiin_frame_check_cnt; CLEAR_VCBUS_REG_MASK(VPP_MISC + cur_dev->vpp_off, \ VPP_VD2_POSTBLEND | VPP_VD2_PREBLEND | \ (0x1ff << VPP_VD2_ALPHA_BIT)); \ + VIDEO_LAYER2_OFF(); \ VD2_MEM_POWER_OFF(); \ } while (0) #endif @@ -721,6 +722,7 @@ static const struct vinfo_s *vinfo; /* config */ static struct vframe_s *cur_dispbuf; static struct vframe_s *cur_dispbuf2; +static bool need_disable_vd2; void update_cur_dispbuf(void *buf) { cur_dispbuf = buf; @@ -1620,13 +1622,13 @@ static void zoom_display_horz(int hscale) (zoom_start_x_lines - l_aligned); content_r = content_l + content_w - 1; VSYNC_WR_MPEG_REG(AFBC_PIXEL_HOR_SCOPE, - (content_l << 16) | content_r); + (((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)); + (((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) | @@ -2018,6 +2020,10 @@ static void vframe_canvas_set(struct canvas_config_s *config, u32 planes, canvas_config_config(*canvas_index, cfg); } +/* for sdr/hdr/single dv switch with dual dv */ +static u32 last_el_status; +/* for dual dv switch with different el size */ +static u32 last_el_w; bool has_enhanced_layer(struct vframe_s *vf) { struct provider_aux_req_s req; @@ -2363,6 +2369,7 @@ static void vsync_toggle_frame(struct vframe_s *vf) (cur_dispbuf->ratio_control != vf->ratio_control) || ((cur_dispbuf->type_backup & VIDTYPE_INTERLACE) != (vf->type_backup & VIDTYPE_INTERLACE)) || + (last_el_status != vf_with_el) || (cur_dispbuf->type != vf->type) ))) { last_process_3d_type = process_3d_type; @@ -2419,6 +2426,7 @@ static void vsync_toggle_frame(struct vframe_s *vf) /* #endif */ } + last_el_status = vf_with_el; if (((vf->type & VIDTYPE_NO_VIDEO_ENABLE) == 0) && ((!property_changed_true) || (vf != cur_dispbuf))) { @@ -2437,6 +2445,8 @@ static void vsync_toggle_frame(struct vframe_s *vf) VD2_MEM_POWER_ON(); else if (vf_with_el) EnableVideoLayer2(); + else if (need_disable_vd2) + DisableVideoLayer2(); } } if (cur_dispbuf && (cur_dispbuf->type != vf->type)) { @@ -2449,7 +2459,7 @@ static void vsync_toggle_frame(struct vframe_s *vf) VD2_MEM_POWER_ON(); else if (vf_with_el) EnableVideoLayer2(); - else + else if (need_disable_vd2) DisableVideoLayer2(); } } @@ -2920,6 +2930,16 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) << VFORMATTER_PHASE_BIT) | VFORMATTER_EN); } + if ((is_meson_txlx_cpu() + || is_meson_g12a()) + && is_dolby_vision_on() + && is_dolby_vision_stb_mode() + && (vf->source_type == + VFRAME_SOURCE_TYPE_OTHERS)) + VSYNC_WR_MPEG_REG_BITS( + VIU_VD1_FMT_CTRL + cur_dev->viu_off, + 1, 29, 1); + /* LOOP/SKIP pattern */ pat = vpat[frame_par->vscale_skip_count]; @@ -3095,6 +3115,10 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) u32 type = vf->type, bit_mode = 0; pr_debug("set dcu for vd2 %p, type:0x%x\n", vf, type); + last_el_w = (vf->type + & VIDTYPE_COMPRESS) ? + vf->compWidth : + vf->width; if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { if (type & VIDTYPE_COMPRESS) { r = (3 << 24) | @@ -3366,6 +3390,16 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) /*is_dolby_vision_on()*/0); } } + + if ((is_meson_txlx_cpu() + || is_meson_g12a()) + && is_dolby_vision_on() + && is_dolby_vision_stb_mode() + && (vf->source_type == + VFRAME_SOURCE_TYPE_OTHERS)) + VSYNC_WR_MPEG_REG_BITS( + VIU_VD2_FMT_CTRL + cur_dev->viu_off, + 1, 29, 1); /* LOOP/SKIP pattern */ pat = vpat[frame_par->vscale_skip_count]; @@ -4041,9 +4075,9 @@ static int dolby_vision_need_wait(void) return 1; return 0; } - /* patch for 4k2k bandwidth issue, skiw mali and vpu mif */ -static void dmc_adjust_for_mali_vpu(unsigned int width, unsigned int height) +static void dmc_adjust_for_mali_vpu(unsigned int width, + unsigned int height, bool force_adjust) { if (toggle_count == last_toggle_count) toggle_same_count++; @@ -4053,9 +4087,9 @@ static void dmc_adjust_for_mali_vpu(unsigned int width, unsigned int height) } /*avoid 3840x2160 crop*/ if ((width >= 2000) && (height >= 1400) && - (dmc_config_state != 1) && - (toggle_same_count < 30)) { - if (is_dolby_vision_enable()) { + (((dmc_config_state != 1) && (toggle_same_count < 30)) + || force_adjust)) { + if (0) {/* if (is_dolby_vision_enable()) { */ /* vpu dmc */ WRITE_DMCREG( DMC_AM0_CHAN_CTRL, @@ -4081,6 +4115,19 @@ static void dmc_adjust_for_mali_vpu(unsigned int width, unsigned int height) DMC_AXI2_HOLD_CTRL, 0x08040804); } else { + /* vpu dmc */ + WRITE_DMCREG( + DMC_AM1_CHAN_CTRL, + 0x43028); + WRITE_DMCREG( + DMC_AM1_HOLD_CTRL, + 0x18101818); + WRITE_DMCREG( + DMC_AM3_CHAN_CTRL, + 0x85f403f4); + WRITE_DMCREG( + DMC_AM4_CHAN_CTRL, + 0x85f403f4); /* mali dmc */ WRITE_DMCREG( DMC_AXI1_HOLD_CTRL, @@ -4099,10 +4146,22 @@ static void dmc_adjust_for_mali_vpu(unsigned int width, unsigned int height) 0x8FF003C4); WRITE_DMCREG( DMC_AM1_CHAN_CTRL, - 0x8FF003C4); + 0x3028); + WRITE_DMCREG( + DMC_AM1_HOLD_CTRL, + 0x18101810); WRITE_DMCREG( DMC_AM2_CHAN_CTRL, 0x8FF003C4); + WRITE_DMCREG( + DMC_AM2_HOLD_CTRL, + 0x3028); + WRITE_DMCREG( + DMC_AM3_CHAN_CTRL, + 0x85f003f4); + WRITE_DMCREG( + DMC_AM4_CHAN_CTRL, + 0x85f003f4); /* mali dmc */ WRITE_DMCREG( @@ -4122,13 +4181,33 @@ static void dmc_adjust_for_mali_vpu(unsigned int width, unsigned int height) } } +static bool is_sc_enable_before_pps(struct vpp_frame_par_s *par) +{ + bool ret = false; + + if (par) { + if (par->supsc0_enable && + ((par->supscl_path == CORE0_PPS_CORE1) + || (par->supscl_path == CORE0_BEFORE_PPS))) + ret = true; + else if (par->supsc1_enable && + (par->supscl_path == CORE1_BEFORE_PPS)) + ret = true; + else if ((par->supsc0_enable || par->supsc1_enable) + && (par->supscl_path == CORE0_CORE1_PPS)) + ret = true; + } + return ret; +} + void correct_vd1_mif_size_for_DV(struct vpp_frame_par_s *par) { u32 aligned_mask = 0xfffffffe; u32 old_len; - - if ((is_dolby_vision_on() == true) && - (par->VPP_line_in_length_ > 0)) { + if ((is_dolby_vision_on() == true) + && (par->VPP_line_in_length_ > 0) + && !is_sc_enable_before_pps(par)) { + /* work around to skip the size check when sc enable */ if (cur_dispbuf2) { /* *if (cur_dispbuf2->type @@ -4185,9 +4264,10 @@ void correct_vd2_mif_size_for_DV( { int width_bl, width_el, line_in_length; int shift; - - if ((is_dolby_vision_on() == true) && - (par->VPP_line_in_length_ > 0)) { + if ((is_dolby_vision_on() == true) + && (par->VPP_line_in_length_ > 0) + && !is_sc_enable_before_pps(par)) { + /* work around to skip the size check when sc enable */ width_el = (cur_dispbuf2->type & VIDTYPE_COMPRESS) ? cur_dispbuf2->compWidth : @@ -4248,6 +4328,7 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) struct vframe_s *toggle_vf = NULL; struct vframe_s *toggle_frame = NULL; int video1_off_req = 0; + int video2_off_req = 0; struct vframe_s *cur_dispbuf_back = cur_dispbuf; static struct vframe_s *pause_vf; @@ -4343,16 +4424,31 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) vsync_enter_line_max = enc_line; if (is_meson_txlx_cpu() && dmc_adjust) { + bool force_adjust = false; + + if (vf) + force_adjust = + ((vf->type & (VIDTYPE_VIU_444 + | VIDTYPE_PIC)) + == (VIDTYPE_VIU_444 + | VIDTYPE_PIC)) ? true : false; + else if (cur_dispbuf) + force_adjust = + ((cur_dispbuf->type & (VIDTYPE_VIU_444 + | VIDTYPE_PIC)) + == (VIDTYPE_VIU_444 + | VIDTYPE_PIC)) ? true : false; if (vf) dmc_adjust_for_mali_vpu( - vf->width, vf->height); + vf->width, vf->height, force_adjust); else if (cur_dispbuf) dmc_adjust_for_mali_vpu( cur_dispbuf->width, - cur_dispbuf->height); + cur_dispbuf->height, + force_adjust); else dmc_adjust_for_mali_vpu( - 0, 0); + 0, 0, force_adjust); } #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA vsync_rdma_config_pre(); @@ -4827,16 +4923,20 @@ SET_FILTER: cur_dispbuf, 2, false); dolby_vision_set_toggle_flag(1); } +/* pause mode was moved to video display property */ +#if 0 /* force toggle in pause mode */ if (cur_dispbuf && (cur_dispbuf != &vf_local) && !toggle_vf - && is_dolby_vision_on()) { + && is_dolby_vision_on() + && !for_dolby_vision_certification()) { toggle_vf = cur_dispbuf; dolby_vision_parse_metadata( cur_dispbuf, 0, false); dolby_vision_set_toggle_flag(1); } +#endif if (cur_frame_par) { if (cur_frame_par->VPP_hd_start_lines_ >= cur_frame_par->VPP_hd_end_lines_) @@ -4888,6 +4988,22 @@ SET_FILTER: if (cur_dispbuf2) vd2_set_dcu(cur_frame_par, cur_dispbuf2); + } else if (cur_dispbuf2) { + u32 new_el_w = + (cur_dispbuf2->type + & VIDTYPE_COMPRESS) ? + cur_dispbuf2->compWidth : + cur_dispbuf2->width; + if (new_el_w != last_el_w) { + pr_info("reset vd2 dcu for el change, %d->%d, %p--%p\n", + last_el_w, new_el_w, + cur_dispbuf, cur_dispbuf2); + vd2_set_dcu(cur_frame_par, + cur_dispbuf2); + } + } else { + last_el_w = 0; + last_el_status = 0; } } { @@ -4912,10 +5028,10 @@ SET_FILTER: && cur_dispbuf && (cur_dispbuf->type & VIDTYPE_VIU_FIELD)) { VSYNC_WR_MPEG_REG_BITS(VIU_VD1_FMT_CTRL + - cur_dev->viu_off, 0, 20, 1); + cur_dev->viu_off, 1, 20, 1); /* HFORMATTER_EN */ VSYNC_WR_MPEG_REG_BITS(VIU_VD2_FMT_CTRL + - cur_dev->viu_off, 0, 20, 1); + cur_dev->viu_off, 1, 20, 1); /* HFORMATTER_EN */ } if (process_3d_type & MODE_3D_OUT_FA_MASK) { @@ -5402,7 +5518,7 @@ SET_FILTER: VPP_HSC_START_PHASE_STEP + cur_dev->vpp_off); v_phase_step = READ_VCBUS_REG( VPP_VSC_START_PHASE_STEP + cur_dev->vpp_off); - if ((vpp_filter->vpp_hsc_start_phase_step != h_phase_step) || + if ((vpp_filter->vpp_hf_start_phase_step != h_phase_step) || (vpp_filter->vpp_vsc_start_phase_step != v_phase_step)) { video_property_changed = true; /*pr_info("frame info register rdma write fail!\n");*/ @@ -5491,6 +5607,7 @@ SET_FILTER: if (debug_flag & DEBUG_FLAG_BLACKOUT) pr_info("VsyncDisableVideoLayer2\n"); + video2_off_req = 1; } spin_unlock_irqrestore(&video2_onoff_lock, flags); } @@ -5579,6 +5696,24 @@ SET_FILTER: vpp_misc_set); /*vpp_misc_set maybe have same,but need off.*/ + /* if vd1 off, disable vd2 also */ + if (video2_off_req || video1_off_req) { + if ((debug_flag & DEBUG_FLAG_BLACKOUT) + && video2_off_req) + pr_info("VD2 AFBC off now.\n"); + VSYNC_WR_MPEG_REG(VD2_AFBC_ENABLE, 0); + VSYNC_WR_MPEG_REG( + VD2_IF0_GEN_REG + cur_dev->viu_off, 0); + if (!legacy_vpp) { + VSYNC_WR_MPEG_REG( + VD2_BLEND_SRC_CTRL + cur_dev->vpp_off, 0); + } + last_el_w = 0; + last_el_status = 0; + if (cur_dispbuf2 && (cur_dispbuf2 == &vf_local2)) + cur_dispbuf2 = NULL; + need_disable_vd2 = false; + } if (video1_off_req) { /* * video layer off, swith off afbc, @@ -5587,19 +5722,26 @@ SET_FILTER: if (debug_flag & DEBUG_FLAG_BLACKOUT) pr_info("AFBC off now.\n"); VSYNC_WR_MPEG_REG(AFBC_ENABLE, 0); - VSYNC_WR_MPEG_REG(VD2_AFBC_ENABLE, 0); VSYNC_WR_MPEG_REG( VD1_IF0_GEN_REG + cur_dev->viu_off, 0); - VSYNC_WR_MPEG_REG( - VD2_IF0_GEN_REG + cur_dev->viu_off, 0); if (!legacy_vpp) { VSYNC_WR_MPEG_REG( VD1_BLEND_SRC_CTRL + cur_dev->vpp_off, 0); - VSYNC_WR_MPEG_REG( - VD2_BLEND_SRC_CTRL + cur_dev->vpp_off, 0); } - } - + if (is_dolby_vision_enable()) { + if (is_meson_txlx_stbmode() || + is_meson_gxm()) + VSYNC_WR_MPEG_REG_BITS( + VIU_MISC_CTRL1, + 1, 16, 1); /* bypass core1 */ + else if (is_meson_g12a()) + VSYNC_WR_MPEG_REG_BITS( + DOLBY_PATH_CTRL, + 1, 0, 1); + } + if (cur_dispbuf && (cur_dispbuf == &vf_local)) + cur_dispbuf = NULL; + } #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA cur_rdma_buf = cur_dispbuf; /* vsync_rdma_config(); */ @@ -5796,6 +5938,8 @@ static void video_vf_unreg_provider(void) cur_dispbuf = &vf_local; cur_dispbuf->video_angle = 0; } + if (cur_dispbuf2) + need_disable_vd2 = true; if (is_dolby_vision_enable()) { if (cur_dispbuf2 == &vf_local2) cur_dispbuf2 = NULL; @@ -6038,8 +6182,10 @@ int _video_set_disable(u32 val) video_property_changed = true; try_free_keep_video(0); } else { - if (cur_dispbuf && (cur_dispbuf != &vf_local)) + if (cur_dispbuf && (cur_dispbuf != &vf_local)) { EnableVideoLayer(); + video_property_changed = true; + } } return 0; diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c index 4d80346..ec37f99 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c @@ -1202,7 +1202,8 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, } /*ver1_12 and ver2 use Dolby VSIF*/ if ((hdev->RXCap.dv_info.ver == 2) || ((hdev->RXCap.dv_info.ver == 1) - && (hdev->RXCap.dv_info.length == 0xB))) { + && (hdev->RXCap.dv_info.length == 0xB)) + || (type == EOTF_T_LL_MODE)) { if (data == NULL) data = ¶ diff --git a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h index 1d4c11d3..9adc16b 100644 --- a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h +++ b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h @@ -28,6 +28,11 @@ extern void dolby_vision_update_pq_config( char *pq_config_buf); extern int dolby_vision_update_setting(void); extern bool is_dolby_vision_stb_mode(void); +extern bool is_meson_g12a(void); +extern bool is_meson_gxm(void); +extern bool is_meson_txlx(void); +extern bool is_meson_txlx_tvmode(void); +extern bool is_meson_txlx_stbmode(void); extern void tv_dolby_vision_crc_clear(int flag); extern char *tv_dolby_vision_get_crc(u32 *len); extern void tv_dolby_vision_insert_crc(bool print); diff --git a/include/linux/amlogic/media/registers/regs/viu_regs.h b/include/linux/amlogic/media/registers/regs/viu_regs.h index 565b4bb..20d5df4 100644 --- a/include/linux/amlogic/media/registers/regs/viu_regs.h +++ b/include/linux/amlogic/media/registers/regs/viu_regs.h @@ -27,6 +27,7 @@ #define VIU_MISC_CTRL1 0x1a07 #define D2D3_INTF_LENGTH 0x1a08 #define D2D3_INTF_CTRL0 0x1a09 +#define DOLBY_PATH_CTRL 0x1a0c #define VIU_OSD1_CTRL_STAT 0x1a10 #define VIU_OSD1_CTRL_STAT2 0x1a2d #define VIU_OSD1_COLOR_ADDR 0x1a11