osd: afbc decode error when loop viu1 to vdin [1/1]
authorPengcheng Chen <pengcheng.chen@amlogic.com>
Sun, 28 Apr 2019 10:40:25 +0000 (18:40 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Sun, 5 May 2019 06:31:49 +0000 (23:31 -0700)
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 <pengcheng.chen@amlogic.com>
drivers/amlogic/media/osd/osd_fb.c
drivers/amlogic/media/osd/osd_hw.c
drivers/amlogic/media/osd/osd_hw.h

index 4d91c9706ba3ddf8e43353016e1c34c1998eec2e..c4349b09c4c42a871df13dcd2cebe0c67b7fbfef 100644 (file)
@@ -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();
index 59d5a8643b793c3658549586c7bd64a82f886d68..418264d7218b7fe818f0a65529b99e5d532e6b2c 100644 (file)
@@ -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;
        }
index f86f0b29b2f265d492e9dc1f7e41af0bf6c14ed0..2e1217e9eaf2f6054882e071ec78d03017709925 100644 (file)
@@ -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