From 42b54ce57d6bc4bc80e3f044a72828880601f276 Mon Sep 17 00:00:00 2001 From: Pengcheng Chen Date: Sun, 28 Apr 2019 18:40:25 +0800 Subject: [PATCH] osd: afbc decode error when loop viu1 to vdin [1/1] PD#TV-5024 Problem: afbc decode error when loop viu1 to vdin. Solution: set osd hold line to max if vinfo is dummy_panel Verify: Tl1 X301 Change-Id: I0ebb312d381accb1890233164f071a095310d2f1 Signed-off-by: Pengcheng Chen --- drivers/amlogic/media/osd/osd_fb.c | 4 ++++ drivers/amlogic/media/osd/osd_hw.c | 42 +++++++++++++++++++++++++++++++------- drivers/amlogic/media/osd/osd_hw.h | 3 +++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/drivers/amlogic/media/osd/osd_fb.c b/drivers/amlogic/media/osd/osd_fb.c index 4d91c97..c4349b0 100644 --- a/drivers/amlogic/media/osd/osd_fb.c +++ b/drivers/amlogic/media/osd/osd_fb.c @@ -1956,6 +1956,10 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd, switch (cmd) { case VOUT_EVENT_MODE_CHANGE: set_osd_logo_freescaler(); + if (!strcmp(vinfo->name, "dummy_panel")) + osd_set_hold_line(MAX_HOLD_LINE); + else + osd_set_hold_line(DEFAULT_HOLD_LINE); if (osd_hw.osd_meson_dev.cpu_id == __MESON_CPU_MAJOR_ID_G12B && is_meson_rev_b()) set_reset_rdma_trigger_line(); diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index 59d5a86..418264d 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -1908,7 +1908,8 @@ static bool mali_afbc_get_error(void) status = VSYNCOSD_RD_MPEG_REG(VPU_MAFBC_IRQ_RAW_STATUS); if (status & 0x3c) { - osd_log_dbg(MODULE_BASE, "afbc error happened\n"); + osd_log_dbg(MODULE_BASE, + "afbc error happened,status=0x%x\n", status); osd_hw.afbc_err_cnt++; error = true; } @@ -3686,6 +3687,25 @@ void osd_set_dimm_info(u32 index, u32 osd_dimm_layer, u32 osd_dimm_color) osd_hw.dim_color[index] = osd_dimm_color; } +void osd_set_hold_line(int hold_line) +{ + int i; + unsigned int data32 = 0, val = 0; + + for (i = 0; i <= osd_hw.osd_meson_dev.viu1_osd_count; i++) { + if (osd_hw.powered[i]) { + data32 = VSYNCOSD_RD_MPEG_REG + (hw_osd_reg_array[i].osd_fifo_ctrl_stat); + val = (data32 >> 5) & 0x1f; + if (val != hold_line) { + VSYNCOSD_WR_MPEG_REG_BITS + (hw_osd_reg_array[i].osd_fifo_ctrl_stat, + hold_line & 0x1f, 5, 5); + } + } + } +} + int osd_get_capbility(u32 index) { u32 capbility = 0; @@ -4223,7 +4243,7 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) if (index >= OSD2) goto out; vinfo = get_current_vinfo(); - if (vinfo && (!strcmp(vinfo->name, "invalid") || + if (!vinfo || (!strcmp(vinfo->name, "invalid") || !strcmp(vinfo->name, "null"))) goto out; @@ -4668,7 +4688,7 @@ static void _osd_pan_display_layers_fence( /* osd_count need -1 when VIU2 enable */ struct layer_fence_map_s *layer_map = NULL; - if (vinfo && (!strcmp(vinfo->name, "invalid") || + if (!vinfo || (!strcmp(vinfo->name, "invalid") || !strcmp(vinfo->name, "null"))) /* vout is null, release fence */ goto out; @@ -8934,7 +8954,10 @@ static void osd_update_fifo(u32 index) { u32 data32; - data32 = osd_hw.urgent[index] & 1; + data32 = VSYNCOSD_RD_MPEG_REG( + hw_osd_reg_array[index].osd_fifo_ctrl_stat); + data32 |= osd_hw.urgent[index] & 1; + #if 0 data32 |= 4 << 5; /* hold_fifo_lines */ /* burst_len_sel: 3=64, g12a = 5 */ @@ -8957,6 +8980,7 @@ static void osd_update_fifo(u32 index) data32 |= 2 << 22; /* bit 28:24, fifo_lim */ data32 |= 2 << 24; + #endif VSYNCOSD_WR_MPEG_REG( hw_osd_reg_array[index].osd_fifo_ctrl_stat, data32); remove_from_update_list(index, OSD_FIFO); @@ -9374,6 +9398,7 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, void osd_init_viu2(void) { u32 idx, data32; + struct vinfo_s *vinfo; set_viu2_rgb2yuv(1); @@ -9386,7 +9411,11 @@ void osd_init_viu2(void) * set DDR request priority to be urgent */ data32 = 1; - data32 |= 4 << 5; /* hold_fifo_lines */ + vinfo = get_current_vinfo2(); + if (vinfo && (!strcmp(vinfo->name, "dummy_panel"))) { + data32 |= MAX_HOLD_LINE << 5; /* hold_fifo_lines */ + } else + data32 |= DEFAULT_HOLD_LINE << 5; /* hold_fifo_lines */ /* burst_len_sel: 3=64, g12a = 5 */ if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) { data32 |= 1 << 10; @@ -10682,8 +10711,7 @@ void osd_page_flip(struct osd_plane_map_s *plane_map) else if (output_index == VIU2) vinfo = get_current_vinfo2(); #endif - vinfo = get_current_vinfo(); - if (vinfo && (!strcmp(vinfo->name, "invalid") || + if (!vinfo || (!strcmp(vinfo->name, "invalid") || !strcmp(vinfo->name, "null"))) { return; } diff --git a/drivers/amlogic/media/osd/osd_hw.h b/drivers/amlogic/media/osd/osd_hw.h index f86f0b29..2e1217e 100644 --- a/drivers/amlogic/media/osd/osd_hw.h +++ b/drivers/amlogic/media/osd/osd_hw.h @@ -23,6 +23,8 @@ #include "osd_sync.h" #include "osd_drm.h" +#define MAX_HOLD_LINE 0x1f +#define DEFAULT_HOLD_LINE 0x04 //#define REG_OFFSET (0x20) #define OSD_RELATIVE_BITS 0x33330 #include "osd_rdma.h" @@ -219,4 +221,5 @@ void osd_set_dimm_info(u32 index, u32 osd_dimm_layer, u32 osd_dimm_color); u32 osd_get_line_n_rdma(void); void osd_set_line_n_rdma(u32 line_n_rdma); u32 get_output_device_id(u32 index); +void osd_set_hold_line(int hold_line); #endif -- 2.7.4