Loading drivers/video/msm/mdss/mdss_fb.c +128 −0 Original line number Diff line number Diff line Loading @@ -820,6 +820,122 @@ static void mdss_fb_shutdown(struct platform_device *pdev) unlock_fb_info(mfd->fbi); } static void mdss_fb_input_event_handler(struct input_handle *handle, unsigned int type, unsigned int code, int value) { struct msm_fb_data_type *mfd = handle->handler->private; int rc; if (type != EV_ABS) return; if (mfd->mdp.input_event_handler) { rc = mfd->mdp.input_event_handler(mfd); if (rc) pr_err("mdp input event handler failed\n"); } } static int mdss_fb_input_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) { int rc; struct input_handle *handle; handle = kzalloc(sizeof(*handle), GFP_KERNEL); if (!handle) return -ENOMEM; handle->dev = dev; handle->handler = handler; handle->name = handler->name; rc = input_register_handle(handle); if (rc) { pr_err("failed to register input handle, rc = %d\n", rc); goto error; } rc = input_open_device(handle); if (rc) { pr_err("failed to open input device, rc = %d\n", rc); goto error_unregister; } return 0; error_unregister: input_unregister_handle(handle); error: kfree(handle); return rc; } static void mdss_fb_input_disconnect(struct input_handle *handle) { input_close_device(handle); input_unregister_handle(handle); kfree(handle); } /* * Structure for specifying event parameters on which to receive callbacks. * This structure will trigger a callback in case of a touch event (specified by * EV_ABS) where there is a change in X and Y coordinates, */ static const struct input_device_id mdss_fb_input_ids[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT, .evbit = { BIT_MASK(EV_ABS) }, .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] = BIT_MASK(ABS_MT_POSITION_X) | BIT_MASK(ABS_MT_POSITION_Y) }, }, { }, }; static int mdss_fb_register_input_handler(struct msm_fb_data_type *mfd) { int rc; struct input_handler *handler; if (mfd->input_handler) return -EINVAL; handler = kzalloc(sizeof(*handler), GFP_KERNEL); if (!handler) return -ENOMEM; handler->event = mdss_fb_input_event_handler; handler->connect = mdss_fb_input_connect; handler->disconnect = mdss_fb_input_disconnect, handler->name = "mdss_fb", handler->id_table = mdss_fb_input_ids; handler->private = mfd; rc = input_register_handler(handler); if (rc) { pr_err("Unable to register the input handler\n"); kfree(handler); } else { mfd->input_handler = handler; } return rc; } static void mdss_fb_unregister_input_handler(struct msm_fb_data_type *mfd) { if (!mfd->input_handler) return; input_unregister_handler(mfd->input_handler); kfree(mfd->input_handler); } static int mdss_fb_probe(struct platform_device *pdev) { struct msm_fb_data_type *mfd = NULL; Loading Loading @@ -938,6 +1054,16 @@ static int mdss_fb_probe(struct platform_device *pdev) if (mfd->mdp.splash_init_fnc) mfd->mdp.splash_init_fnc(mfd); /* * Register with input driver for a callback for command mode panels. * When there is an input event, mdp clocks will be turned on to reduce * latency when a frame update happens. * Video mode panels are not handled today because clocks are always on. */ if (mfd->panel_info->type == MIPI_CMD_PANEL) if (mdss_fb_register_input_handler(mfd)) pr_err("failed to register input handler\n"); INIT_DELAYED_WORK(&mfd->idle_notify_work, __mdss_fb_idle_notify_work); return rc; Loading Loading @@ -981,6 +1107,8 @@ static int mdss_fb_remove(struct platform_device *pdev) if (mfd->key != MFD_KEY) return -EINVAL; mdss_fb_unregister_input_handler(mfd); if (mdss_fb_suspend_sub(mfd)) pr_err("msm_fb_remove: can't stop the device %d\n", mfd->index); Loading drivers/video/msm/mdss/mdss_fb.h +2 −0 Original line number Diff line number Diff line Loading @@ -219,6 +219,7 @@ struct msm_mdp_interface { void (*check_dsi_status)(struct work_struct *work, uint32_t interval); int (*configure_panel)(struct msm_fb_data_type *mfd, int mode, int dest_ctrl); int (*input_event_handler)(struct msm_fb_data_type *mfd); void *private1; }; Loading Loading @@ -341,6 +342,7 @@ struct msm_fb_data_type { u32 switch_new_mode; bool pending_switch; struct mutex switch_lock; struct input_handler *input_handler; }; static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd) Loading drivers/video/msm/mdss/mdss_mdp.h +3 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,7 @@ struct mdss_mdp_ctl_intfs_ops { int (*config_fps_fnc)(struct mdss_mdp_ctl *ctl, struct mdss_mdp_ctl *sctl, int new_fps); int (*restore_fnc)(struct mdss_mdp_ctl *ctl); int (*early_wake_up_fnc)(struct mdss_mdp_ctl *ctl); }; struct mdss_mdp_ctl { Loading Loading @@ -312,6 +313,8 @@ struct mdss_mdp_ctl { struct mdss_mdp_ctl_intfs_ops ops; bool force_ctl_start; u64 last_input_time; }; struct mdss_mdp_mixer { Loading drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +109 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #define STOP_TIMEOUT(hz) msecs_to_jiffies((1000 / hz) * (6 + 2)) #define POWER_COLLAPSE_TIME msecs_to_jiffies(100) #define CMD_MODE_IDLE_TIMEOUT msecs_to_jiffies(16 * 4) #define INPUT_EVENT_HANDLER_DELAY_USECS (16000 * 4) static DEFINE_MUTEX(cmd_clk_mtx); Loading @@ -52,6 +53,7 @@ struct mdss_mdp_cmd_ctx { struct work_struct gate_clk_work; struct delayed_work delayed_off_clk_work; struct work_struct pp_done_work; struct work_struct early_wakeup_clk_work; struct mutex autorefresh_mtx; atomic_t pp_done_cnt; Loading Loading @@ -312,11 +314,17 @@ err: * pending data transfer and turn off all the clocks/resources, * so after return from this event we must be in off * state. * * @MDP_RSRC_CTL_EVENT_EARLY_WAKE_UP: * This event happens at NORMAL priority from a work item. * Event signals that there will be a frame update soon and mdp should wake * up early to update the frame with little latency. */ enum mdp_rsrc_ctl_events { MDP_RSRC_CTL_EVENT_KICKOFF = 1, MDP_RSRC_CTL_EVENT_PP_DONE, MDP_RSRC_CTL_EVENT_STOP MDP_RSRC_CTL_EVENT_STOP, MDP_RSRC_CTL_EVENT_EARLY_WAKE_UP }; enum { Loading @@ -335,6 +343,8 @@ static char *get_sw_event_name(u32 sw_event) return "PP_DONE"; case MDP_RSRC_CTL_EVENT_STOP: return "STOP"; case MDP_RSRC_CTL_EVENT_EARLY_WAKE_UP: return "EARLY_WAKE_UP"; default: return "UNKNOWN"; } Loading Loading @@ -668,6 +678,51 @@ int mdss_mdp_resource_control(struct mdss_mdp_ctl *ctl, u32 sw_event) mdp5_data->resources_state = MDP_RSRC_CTL_STATE_OFF; } break; case MDP_RSRC_CTL_EVENT_EARLY_WAKE_UP: /* * 1. If the current state is ON, stay in ON and cancel any * pending GATE work item. * 2. If the current state is GATED, stay at GATED and cancel * any pending POWER-OFF work item. * 3. If the current state is POWER-OFF, Schedule a work item to * POWER-ON. */ if (mdp5_data->resources_state != MDP_RSRC_CTL_STATE_OFF) { if (cancel_work_sync(&ctx->gate_clk_work)) pr_debug("%s: %s - gate_work cancelled\n", __func__, get_sw_event_name(sw_event)); if (cancel_delayed_work_sync( &ctx->delayed_off_clk_work)) pr_debug("%s: %s - off work cancelled\n", __func__, get_sw_event_name(sw_event)); } else { mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_mdp_ctl_intf_event(ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)MDSS_DSI_CLK_ON, true); if (sctx) mdss_mdp_ctl_intf_event(sctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)MDSS_DSI_CLK_ON, true); mdss_mdp_cmd_clk_on(ctx); if (sctx) mdss_mdp_cmd_clk_on(sctx); mdp5_data->resources_state = MDP_RSRC_CTL_STATE_ON; /* * Schedule off work after cmd mode idle timeout is * reached. This is to prevent the case where early wake * up is called but no frame update is sent. */ schedule_delayed_work(&ctx->delayed_off_clk_work, CMD_MODE_IDLE_TIMEOUT); } break; default: pr_warn("%s unexpected event (%d)\n", __func__, sw_event); break; Loading Loading @@ -920,7 +975,7 @@ static void clk_ctrl_delayed_off_work(struct work_struct *work) if (mdp5_data->resources_state != MDP_RSRC_CTL_STATE_GATE) pr_warn("enter off from unexpected state\n"); pr_debug("%s: enter off from ON state\n", __func__); } /* first power off the slave DSI (if present) */ Loading Loading @@ -1845,6 +1900,56 @@ end: return ret; } static void early_wakeup_work(struct work_struct *work) { int rc = 0; struct mdss_mdp_cmd_ctx *ctx = container_of(work, typeof(*ctx), early_wakeup_clk_work); struct mdss_mdp_ctl *ctl; if (!ctx) { pr_err("%s: invalid ctx\n", __func__); return; } ATRACE_BEGIN(__func__); ctl = ctx->ctl; if (!ctl) { pr_err("%s: invalid ctl\n", __func__); goto fail; } rc = mdss_mdp_resource_control(ctl, MDP_RSRC_CTL_EVENT_EARLY_WAKE_UP); if (rc) pr_err("%s: failed to control resources\n", __func__); fail: ATRACE_END(__func__); } static int mdss_mdp_cmd_early_wake_up(struct mdss_mdp_ctl *ctl) { u64 curr_time; struct mdss_mdp_cmd_ctx *ctx; curr_time = ktime_to_us(ktime_get()); if ((curr_time - ctl->last_input_time) < INPUT_EVENT_HANDLER_DELAY_USECS) return 0; ctl->last_input_time = curr_time; ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX]; /* * Early wake up event is called from an interrupt context and * involves cancelling queued work items. So this will be * scheduled in a work item. */ schedule_work(&ctx->early_wakeup_clk_work); return 0; } static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_cmd_ctx *ctx, int pp_num, int pingpong_split_slave) Loading @@ -1868,6 +1973,7 @@ static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, INIT_DELAYED_WORK(&ctx->delayed_off_clk_work, clk_ctrl_delayed_off_work); INIT_WORK(&ctx->pp_done_work, pingpong_done_work); INIT_WORK(&ctx->early_wakeup_clk_work, early_wakeup_work); atomic_set(&ctx->pp_done_cnt, 0); ctx->autorefresh_off_pending = false; ctx->autorefresh_init = false; Loading Loading @@ -2041,6 +2147,7 @@ int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl) ctl->ops.remove_vsync_handler = mdss_mdp_cmd_remove_vsync_handler; ctl->ops.read_line_cnt_fnc = mdss_mdp_cmd_line_count; ctl->ops.restore_fnc = mdss_mdp_cmd_restore; ctl->ops.early_wake_up_fnc = mdss_mdp_cmd_early_wake_up; pr_debug("%s:-\n", __func__); return 0; Loading drivers/video/msm/mdss/mdss_mdp_overlay.c +12 −0 Original line number Diff line number Diff line Loading @@ -4802,6 +4802,17 @@ static int mdss_mdp_update_panel_info(struct msm_fb_data_type *mfd, return 0; } int mdss_mdp_input_event_handler(struct msm_fb_data_type *mfd) { int rc = 0; struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd); if (ctl->ops.early_wake_up_fnc) rc = ctl->ops.early_wake_up_fnc(ctl); return rc; } int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd) { struct device *dev = mfd->fbi->dev; Loading Loading @@ -4841,6 +4852,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd) mdp5_interface->get_sync_fnc = mdss_mdp_rotator_sync_pt_get; mdp5_interface->splash_init_fnc = mdss_mdp_splash_init; mdp5_interface->configure_panel = mdss_mdp_update_panel_info; mdp5_interface->input_event_handler = mdss_mdp_input_event_handler; if (mfd->panel_info->type == WRITEBACK_PANEL) { mdp5_interface->atomic_validate = Loading Loading
drivers/video/msm/mdss/mdss_fb.c +128 −0 Original line number Diff line number Diff line Loading @@ -820,6 +820,122 @@ static void mdss_fb_shutdown(struct platform_device *pdev) unlock_fb_info(mfd->fbi); } static void mdss_fb_input_event_handler(struct input_handle *handle, unsigned int type, unsigned int code, int value) { struct msm_fb_data_type *mfd = handle->handler->private; int rc; if (type != EV_ABS) return; if (mfd->mdp.input_event_handler) { rc = mfd->mdp.input_event_handler(mfd); if (rc) pr_err("mdp input event handler failed\n"); } } static int mdss_fb_input_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) { int rc; struct input_handle *handle; handle = kzalloc(sizeof(*handle), GFP_KERNEL); if (!handle) return -ENOMEM; handle->dev = dev; handle->handler = handler; handle->name = handler->name; rc = input_register_handle(handle); if (rc) { pr_err("failed to register input handle, rc = %d\n", rc); goto error; } rc = input_open_device(handle); if (rc) { pr_err("failed to open input device, rc = %d\n", rc); goto error_unregister; } return 0; error_unregister: input_unregister_handle(handle); error: kfree(handle); return rc; } static void mdss_fb_input_disconnect(struct input_handle *handle) { input_close_device(handle); input_unregister_handle(handle); kfree(handle); } /* * Structure for specifying event parameters on which to receive callbacks. * This structure will trigger a callback in case of a touch event (specified by * EV_ABS) where there is a change in X and Y coordinates, */ static const struct input_device_id mdss_fb_input_ids[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT, .evbit = { BIT_MASK(EV_ABS) }, .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] = BIT_MASK(ABS_MT_POSITION_X) | BIT_MASK(ABS_MT_POSITION_Y) }, }, { }, }; static int mdss_fb_register_input_handler(struct msm_fb_data_type *mfd) { int rc; struct input_handler *handler; if (mfd->input_handler) return -EINVAL; handler = kzalloc(sizeof(*handler), GFP_KERNEL); if (!handler) return -ENOMEM; handler->event = mdss_fb_input_event_handler; handler->connect = mdss_fb_input_connect; handler->disconnect = mdss_fb_input_disconnect, handler->name = "mdss_fb", handler->id_table = mdss_fb_input_ids; handler->private = mfd; rc = input_register_handler(handler); if (rc) { pr_err("Unable to register the input handler\n"); kfree(handler); } else { mfd->input_handler = handler; } return rc; } static void mdss_fb_unregister_input_handler(struct msm_fb_data_type *mfd) { if (!mfd->input_handler) return; input_unregister_handler(mfd->input_handler); kfree(mfd->input_handler); } static int mdss_fb_probe(struct platform_device *pdev) { struct msm_fb_data_type *mfd = NULL; Loading Loading @@ -938,6 +1054,16 @@ static int mdss_fb_probe(struct platform_device *pdev) if (mfd->mdp.splash_init_fnc) mfd->mdp.splash_init_fnc(mfd); /* * Register with input driver for a callback for command mode panels. * When there is an input event, mdp clocks will be turned on to reduce * latency when a frame update happens. * Video mode panels are not handled today because clocks are always on. */ if (mfd->panel_info->type == MIPI_CMD_PANEL) if (mdss_fb_register_input_handler(mfd)) pr_err("failed to register input handler\n"); INIT_DELAYED_WORK(&mfd->idle_notify_work, __mdss_fb_idle_notify_work); return rc; Loading Loading @@ -981,6 +1107,8 @@ static int mdss_fb_remove(struct platform_device *pdev) if (mfd->key != MFD_KEY) return -EINVAL; mdss_fb_unregister_input_handler(mfd); if (mdss_fb_suspend_sub(mfd)) pr_err("msm_fb_remove: can't stop the device %d\n", mfd->index); Loading
drivers/video/msm/mdss/mdss_fb.h +2 −0 Original line number Diff line number Diff line Loading @@ -219,6 +219,7 @@ struct msm_mdp_interface { void (*check_dsi_status)(struct work_struct *work, uint32_t interval); int (*configure_panel)(struct msm_fb_data_type *mfd, int mode, int dest_ctrl); int (*input_event_handler)(struct msm_fb_data_type *mfd); void *private1; }; Loading Loading @@ -341,6 +342,7 @@ struct msm_fb_data_type { u32 switch_new_mode; bool pending_switch; struct mutex switch_lock; struct input_handler *input_handler; }; static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd) Loading
drivers/video/msm/mdss/mdss_mdp.h +3 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,7 @@ struct mdss_mdp_ctl_intfs_ops { int (*config_fps_fnc)(struct mdss_mdp_ctl *ctl, struct mdss_mdp_ctl *sctl, int new_fps); int (*restore_fnc)(struct mdss_mdp_ctl *ctl); int (*early_wake_up_fnc)(struct mdss_mdp_ctl *ctl); }; struct mdss_mdp_ctl { Loading Loading @@ -312,6 +313,8 @@ struct mdss_mdp_ctl { struct mdss_mdp_ctl_intfs_ops ops; bool force_ctl_start; u64 last_input_time; }; struct mdss_mdp_mixer { Loading
drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +109 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #define STOP_TIMEOUT(hz) msecs_to_jiffies((1000 / hz) * (6 + 2)) #define POWER_COLLAPSE_TIME msecs_to_jiffies(100) #define CMD_MODE_IDLE_TIMEOUT msecs_to_jiffies(16 * 4) #define INPUT_EVENT_HANDLER_DELAY_USECS (16000 * 4) static DEFINE_MUTEX(cmd_clk_mtx); Loading @@ -52,6 +53,7 @@ struct mdss_mdp_cmd_ctx { struct work_struct gate_clk_work; struct delayed_work delayed_off_clk_work; struct work_struct pp_done_work; struct work_struct early_wakeup_clk_work; struct mutex autorefresh_mtx; atomic_t pp_done_cnt; Loading Loading @@ -312,11 +314,17 @@ err: * pending data transfer and turn off all the clocks/resources, * so after return from this event we must be in off * state. * * @MDP_RSRC_CTL_EVENT_EARLY_WAKE_UP: * This event happens at NORMAL priority from a work item. * Event signals that there will be a frame update soon and mdp should wake * up early to update the frame with little latency. */ enum mdp_rsrc_ctl_events { MDP_RSRC_CTL_EVENT_KICKOFF = 1, MDP_RSRC_CTL_EVENT_PP_DONE, MDP_RSRC_CTL_EVENT_STOP MDP_RSRC_CTL_EVENT_STOP, MDP_RSRC_CTL_EVENT_EARLY_WAKE_UP }; enum { Loading @@ -335,6 +343,8 @@ static char *get_sw_event_name(u32 sw_event) return "PP_DONE"; case MDP_RSRC_CTL_EVENT_STOP: return "STOP"; case MDP_RSRC_CTL_EVENT_EARLY_WAKE_UP: return "EARLY_WAKE_UP"; default: return "UNKNOWN"; } Loading Loading @@ -668,6 +678,51 @@ int mdss_mdp_resource_control(struct mdss_mdp_ctl *ctl, u32 sw_event) mdp5_data->resources_state = MDP_RSRC_CTL_STATE_OFF; } break; case MDP_RSRC_CTL_EVENT_EARLY_WAKE_UP: /* * 1. If the current state is ON, stay in ON and cancel any * pending GATE work item. * 2. If the current state is GATED, stay at GATED and cancel * any pending POWER-OFF work item. * 3. If the current state is POWER-OFF, Schedule a work item to * POWER-ON. */ if (mdp5_data->resources_state != MDP_RSRC_CTL_STATE_OFF) { if (cancel_work_sync(&ctx->gate_clk_work)) pr_debug("%s: %s - gate_work cancelled\n", __func__, get_sw_event_name(sw_event)); if (cancel_delayed_work_sync( &ctx->delayed_off_clk_work)) pr_debug("%s: %s - off work cancelled\n", __func__, get_sw_event_name(sw_event)); } else { mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_mdp_ctl_intf_event(ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)MDSS_DSI_CLK_ON, true); if (sctx) mdss_mdp_ctl_intf_event(sctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)MDSS_DSI_CLK_ON, true); mdss_mdp_cmd_clk_on(ctx); if (sctx) mdss_mdp_cmd_clk_on(sctx); mdp5_data->resources_state = MDP_RSRC_CTL_STATE_ON; /* * Schedule off work after cmd mode idle timeout is * reached. This is to prevent the case where early wake * up is called but no frame update is sent. */ schedule_delayed_work(&ctx->delayed_off_clk_work, CMD_MODE_IDLE_TIMEOUT); } break; default: pr_warn("%s unexpected event (%d)\n", __func__, sw_event); break; Loading Loading @@ -920,7 +975,7 @@ static void clk_ctrl_delayed_off_work(struct work_struct *work) if (mdp5_data->resources_state != MDP_RSRC_CTL_STATE_GATE) pr_warn("enter off from unexpected state\n"); pr_debug("%s: enter off from ON state\n", __func__); } /* first power off the slave DSI (if present) */ Loading Loading @@ -1845,6 +1900,56 @@ end: return ret; } static void early_wakeup_work(struct work_struct *work) { int rc = 0; struct mdss_mdp_cmd_ctx *ctx = container_of(work, typeof(*ctx), early_wakeup_clk_work); struct mdss_mdp_ctl *ctl; if (!ctx) { pr_err("%s: invalid ctx\n", __func__); return; } ATRACE_BEGIN(__func__); ctl = ctx->ctl; if (!ctl) { pr_err("%s: invalid ctl\n", __func__); goto fail; } rc = mdss_mdp_resource_control(ctl, MDP_RSRC_CTL_EVENT_EARLY_WAKE_UP); if (rc) pr_err("%s: failed to control resources\n", __func__); fail: ATRACE_END(__func__); } static int mdss_mdp_cmd_early_wake_up(struct mdss_mdp_ctl *ctl) { u64 curr_time; struct mdss_mdp_cmd_ctx *ctx; curr_time = ktime_to_us(ktime_get()); if ((curr_time - ctl->last_input_time) < INPUT_EVENT_HANDLER_DELAY_USECS) return 0; ctl->last_input_time = curr_time; ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX]; /* * Early wake up event is called from an interrupt context and * involves cancelling queued work items. So this will be * scheduled in a work item. */ schedule_work(&ctx->early_wakeup_clk_work); return 0; } static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_cmd_ctx *ctx, int pp_num, int pingpong_split_slave) Loading @@ -1868,6 +1973,7 @@ static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, INIT_DELAYED_WORK(&ctx->delayed_off_clk_work, clk_ctrl_delayed_off_work); INIT_WORK(&ctx->pp_done_work, pingpong_done_work); INIT_WORK(&ctx->early_wakeup_clk_work, early_wakeup_work); atomic_set(&ctx->pp_done_cnt, 0); ctx->autorefresh_off_pending = false; ctx->autorefresh_init = false; Loading Loading @@ -2041,6 +2147,7 @@ int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl) ctl->ops.remove_vsync_handler = mdss_mdp_cmd_remove_vsync_handler; ctl->ops.read_line_cnt_fnc = mdss_mdp_cmd_line_count; ctl->ops.restore_fnc = mdss_mdp_cmd_restore; ctl->ops.early_wake_up_fnc = mdss_mdp_cmd_early_wake_up; pr_debug("%s:-\n", __func__); return 0; Loading
drivers/video/msm/mdss/mdss_mdp_overlay.c +12 −0 Original line number Diff line number Diff line Loading @@ -4802,6 +4802,17 @@ static int mdss_mdp_update_panel_info(struct msm_fb_data_type *mfd, return 0; } int mdss_mdp_input_event_handler(struct msm_fb_data_type *mfd) { int rc = 0; struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd); if (ctl->ops.early_wake_up_fnc) rc = ctl->ops.early_wake_up_fnc(ctl); return rc; } int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd) { struct device *dev = mfd->fbi->dev; Loading Loading @@ -4841,6 +4852,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd) mdp5_interface->get_sync_fnc = mdss_mdp_rotator_sync_pt_get; mdp5_interface->splash_init_fnc = mdss_mdp_splash_init; mdp5_interface->configure_panel = mdss_mdp_update_panel_info; mdp5_interface->input_event_handler = mdss_mdp_input_event_handler; if (mfd->panel_info->type == WRITEBACK_PANEL) { mdp5_interface->atomic_validate = Loading