osd: fix hotplug hdmi causes system crash [1/1]

PD#SWPL-7009

Problem:
hotplug hdmi causes system crash
when unplug hdmi display mode is null, hwc hasn't received
event and post frame normal but osd vsync lost, which caused
wait hw vsync timeout(1s), and fd leak.

Solution:
when process every frame, if display mode is null, exit frame process
just process fence.

Verify:
verified on Raven, franklin

Change-Id: Icbe7cd76776e46a6ed79c6cee3ea05772cc5f9d2
Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
This commit is contained in:
Pengcheng Chen
2019-04-10 12:21:38 +08:00
committed by Tao Zeng
parent dd62dac8c7
commit 799ba4c6f7

View File

@@ -1275,7 +1275,8 @@ static int sync_render_single_fence(u32 index, u32 yres,
kthread_queue_work(&buffer_toggle_worker[output_index], kthread_queue_work(&buffer_toggle_worker[output_index],
&buffer_toggle_work[output_index]); &buffer_toggle_work[output_index]);
request->out_fen_fd = out_fence_fd; request->out_fen_fd = out_fence_fd;
__close_fd(current->files, request->in_fen_fd); if (request->in_fen_fd >= 0)
__close_fd(current->files, request->in_fen_fd);
return out_fence_fd; return out_fence_fd;
} }
@@ -1342,8 +1343,10 @@ static int sync_render_layers_fence(u32 index, u32 yres,
fence_map->layer_map[index].in_fd, fence_map->layer_map[index].in_fd,
fence_map->layer_map[index].out_fd); fence_map->layer_map[index].out_fd);
request->out_fen_fd = out_fence_fd; request->out_fen_fd = out_fence_fd;
__close_fd(current->files, in_fence_fd); if (in_fence_fd >= 0)
__close_fd(current->files, request->shared_fd); __close_fd(current->files, in_fence_fd);
if (request->shared_fd >= 0)
__close_fd(current->files, request->shared_fd);
return out_fence_fd; return out_fence_fd;
} }
@@ -2184,8 +2187,16 @@ void osd_wait_vsync_hw(void)
if (pxp_mode) if (pxp_mode)
timeout = msecs_to_jiffies(50); timeout = msecs_to_jiffies(50);
else else {
timeout = msecs_to_jiffies(1000); struct vinfo_s *vinfo;
vinfo = get_current_vinfo();
if (vinfo && (!strcmp(vinfo->name, "invalid") ||
!strcmp(vinfo->name, "null"))) {
timeout = msecs_to_jiffies(1);
} else
timeout = msecs_to_jiffies(1000);
}
wait_event_interruptible_timeout( wait_event_interruptible_timeout(
osd_vsync_wq, vsync_hit, timeout); osd_vsync_wq, vsync_hit, timeout);
} }
@@ -4211,6 +4222,14 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map)
if (index >= OSD2) if (index >= OSD2)
goto out; goto out;
vinfo = get_current_vinfo();
if (vinfo && (!strcmp(vinfo->name, "invalid") ||
!strcmp(vinfo->name, "null")))
goto out;
osd_hw.vinfo_width[output_index] = vinfo->width;
osd_hw.vinfo_height[output_index] = vinfo->height;
if (timeline_created[output_index]) { /* out fence created success. */ if (timeline_created[output_index]) { /* out fence created success. */
ret = osd_wait_buf_ready(fence_map); ret = osd_wait_buf_ready(fence_map);
if (ret < 0) if (ret < 0)
@@ -4232,15 +4251,6 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map)
AFBC_EN | BLOCK_SPLIT | AFBC_EN | BLOCK_SPLIT |
YUV_TRANSFORM | SUPER_BLOCK_ASPECT; YUV_TRANSFORM | SUPER_BLOCK_ASPECT;
} }
vinfo = get_current_vinfo();
if (vinfo) {
if ((strcmp(vinfo->name, "invalid")) &&
(strcmp(vinfo->name, "null"))) {
osd_hw.vinfo_width[output_index] = vinfo->width;
osd_hw.vinfo_height[output_index] =
vinfo->height;
}
}
/* Todo: */ /* Todo: */
if (fence_map->ext_addr && fence_map->width if (fence_map->ext_addr && fence_map->width
&& fence_map->height) { && fence_map->height) {
@@ -4442,17 +4452,17 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map)
osd_wait_vsync_hw(); osd_wait_vsync_hw();
} }
} }
#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT
if (ret)
osd_ext_clone_pan(index);
#endif
out:
if (timeline_created[output_index]) { if (timeline_created[output_index]) {
if (ret) if (ret)
osd_timeline_increase(output_index); osd_timeline_increase(output_index);
else else
osd_log_err("------NOT signal out_fence ERROR\n"); osd_log_err("------NOT signal out_fence ERROR\n");
} }
#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT
if (ret)
osd_ext_clone_pan(index);
#endif
out:
if (fence_map->in_fence) if (fence_map->in_fence)
osd_put_fenceobj(fence_map->in_fence); osd_put_fenceobj(fence_map->in_fence);
} }
@@ -4654,15 +4664,17 @@ static void _osd_pan_display_layers_fence(
int ret; int ret;
int start_index = 0; int start_index = 0;
int backup_en = 0; int backup_en = 0;
int osd_count; int osd_count = 0;
/* osd_count need -1 when VIU2 enable */ /* osd_count need -1 when VIU2 enable */
struct layer_fence_map_s *layer_map = NULL; struct layer_fence_map_s *layer_map = NULL;
if (vinfo && (strcmp(vinfo->name, "invalid") && if (vinfo && (!strcmp(vinfo->name, "invalid") ||
strcmp(vinfo->name, "null"))) { !strcmp(vinfo->name, "null")))
osd_hw.vinfo_width[output_index] = vinfo->width; /* vout is null, release fence */
osd_hw.vinfo_height[output_index] = vinfo->field_height; goto out;
}
osd_hw.vinfo_width[output_index] = vinfo->width;
osd_hw.vinfo_height[output_index] = vinfo->field_height;
memcpy(&osd_hw.disp_info[output_index], &fence_map->disp_info, memcpy(&osd_hw.disp_info[output_index], &fence_map->disp_info,
sizeof(struct display_flip_info_s)); sizeof(struct display_flip_info_s));
if (output_index == VIU1) { if (output_index == VIU1) {
@@ -4708,6 +4720,7 @@ static void _osd_pan_display_layers_fence(
/* set hw regs */ /* set hw regs */
if (osd_hw.osd_display_debug != OSD_DISP_DEBUG) if (osd_hw.osd_display_debug != OSD_DISP_DEBUG)
osd_setting_blend(output_index); osd_setting_blend(output_index);
out:
/* signal out fence */ /* signal out fence */
if (timeline_created[output_index]) { if (timeline_created[output_index]) {
if (osd_hw.osd_debug.osd_single_step_mode) { if (osd_hw.osd_debug.osd_single_step_mode) {
@@ -10669,12 +10682,14 @@ void osd_page_flip(struct osd_plane_map_s *plane_map)
else if (output_index == VIU2) else if (output_index == VIU2)
vinfo = get_current_vinfo2(); vinfo = get_current_vinfo2();
#endif #endif
vinfo = get_current_vinfo();
if (vinfo && (strcmp(vinfo->name, "invalid") && if (vinfo && (!strcmp(vinfo->name, "invalid") ||
strcmp(vinfo->name, "null"))) { !strcmp(vinfo->name, "null"))) {
osd_hw.vinfo_width[output_index] = vinfo->width; return;
osd_hw.vinfo_height[output_index] = vinfo->height;
} }
osd_hw.vinfo_width[output_index] = vinfo->width;
osd_hw.vinfo_height[output_index] = vinfo->height;
osd_hw.osd_afbcd[index].enable = osd_hw.osd_afbcd[index].enable =
(plane_map->afbc_inter_format & AFBC_EN) >> 31; (plane_map->afbc_inter_format & AFBC_EN) >> 31;
if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) { if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {