Loading drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +72 −35 Original line number Diff line number Diff line Loading @@ -59,11 +59,17 @@ struct mdss_mdp_cmd_ctx mdss_mdp_cmd_ctx_list[MAX_SESSIONS]; static int mdss_mdp_cmd_do_notifier(struct mdss_mdp_cmd_ctx *ctx); static bool __mdss_mdp_cmd_panel_power_off(struct mdss_mdp_cmd_ctx *ctx) static bool __mdss_mdp_cmd_is_panel_power_off(struct mdss_mdp_cmd_ctx *ctx) { return mdss_panel_is_power_off(ctx->panel_power_state); } static bool __mdss_mdp_cmd_is_panel_power_on_interactive( struct mdss_mdp_cmd_ctx *ctx) { return mdss_panel_is_power_on_interactive(ctx->panel_power_state); } static inline u32 mdss_mdp_cmd_line_count(struct mdss_mdp_ctl *ctl) { struct mdss_mdp_mixer *mixer; Loading Loading @@ -216,7 +222,7 @@ static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx) struct mdss_data_type *mdata = mdss_mdp_get_mdata(); int irq_en, rc; if (__mdss_mdp_cmd_panel_power_off(ctx)) if (__mdss_mdp_cmd_is_panel_power_off(ctx)) return; mutex_lock(&ctx->clk_mtx); Loading Loading @@ -692,6 +698,45 @@ static int mdss_mdp_cmd_set_stream_size(struct mdss_mdp_ctl *ctl) return rc; } static int mdss_mdp_cmd_panel_on(struct mdss_mdp_ctl *ctl, struct mdss_mdp_ctl *sctl) { struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL; int rc = 0; ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data; if (!ctx) { pr_err("invalid ctx\n"); return -ENODEV; } if (sctl) sctx = (struct mdss_mdp_cmd_ctx *) sctl->priv_data; if (!__mdss_mdp_cmd_is_panel_power_on_interactive(ctx)) { rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_LINK_READY, NULL); WARN(rc, "intf %d link ready error (%d)\n", ctl->intf_num, rc); rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL); WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc); rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_ON, NULL); WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc); ctx->panel_power_state = MDSS_PANEL_POWER_ON; if (sctx) sctx->panel_power_state = MDSS_PANEL_POWER_ON; mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_REGISTER_RECOVERY_HANDLER, (void *)&ctx->intf_recovery); } else { pr_err("%s: Panel already on\n", __func__); } return rc; } /* * There are 3 partial update possibilities * left only ==> enable left pingpong_done Loading @@ -708,7 +753,6 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) { struct mdss_mdp_ctl *sctl = NULL; struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL; int rc; ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data; if (!ctx) { Loading @@ -733,24 +777,13 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) PERF_HW_MDP_STATE, PERF_STATUS_BUSY); } if (__mdss_mdp_cmd_panel_power_off(ctx)) { rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_LINK_READY, NULL); WARN(rc, "intf %d link ready error (%d)\n", ctl->intf_num, rc); rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL); WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc); rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_ON, NULL); WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc); ctx->panel_power_state = MDSS_PANEL_POWER_ON; if (sctx) sctx->panel_power_state = MDSS_PANEL_POWER_ON; mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_REGISTER_RECOVERY_HANDLER, (void *)&ctx->intf_recovery); } /* * Turn on the panel, if not already. This is because the panel is * turned on only when we send the first frame and not during cmd * start. This is to ensure that no artifacts are seen on the panel. */ if (__mdss_mdp_cmd_is_panel_power_off(ctx)) mdss_mdp_cmd_panel_on(ctl, sctl); MDSS_XLOG(ctl->num, ctl->roi.x, ctl->roi.y, ctl->roi.w, ctl->roi.h); Loading Loading @@ -863,12 +896,7 @@ int mdss_mdp_cmd_intfs_stop(struct mdss_mdp_ctl *ctl, int session, mdss_mdp_cmd_clk_off(ctx); flush_work(&ctx->pp_done_work); ctx->panel_power_state = panel_power_state; if (panel_power_state != MDSS_PANEL_POWER_OFF) { pr_debug("%s: panel always on\n", __func__); goto end; } mdss_mdp_cmd_tearcheck_setup(ctl, false); mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num, NULL, NULL); Loading @@ -877,7 +905,6 @@ int mdss_mdp_cmd_intfs_stop(struct mdss_mdp_ctl *ctl, int session, memset(ctx, 0, sizeof(*ctx)); end: pr_debug("%s:-\n", __func__); return 0; Loading @@ -900,6 +927,13 @@ static int mdss_mdp_cmd_stop_sub(struct mdss_mdp_ctl *ctl, if (ctx->panel_power_state == panel_power_state) return 0; /* * If the panel will be left on, then we do not need to turn off * interface clocks since we may continue to get display updates. */ if (mdss_panel_is_power_on(panel_power_state)) return 0; list_for_each_entry_safe(handle, tmp, &ctx->vsync_handlers, list) mdss_mdp_cmd_remove_vsync_handler(ctl, handle); MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled, Loading Loading @@ -945,12 +979,11 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state) ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_OFF, (void *) (long int) panel_power_state); WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret); if (panel_power_state != MDSS_PANEL_POWER_DOZE) mdss_mdp_cmd_tearcheck_setup(ctl, false); } if (panel_power_state != MDSS_PANEL_POWER_OFF) { ctx->panel_power_state = panel_power_state; if (mdss_panel_is_power_on(panel_power_state)) { pr_debug("%s: cmd_stop with panel always on\n", __func__); goto end; } Loading @@ -974,6 +1007,7 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, int session) { struct mdss_mdp_cmd_ctx *ctx; struct mdss_mdp_ctl *sctl = NULL; struct mdss_mdp_mixer *mixer; int ret; Loading @@ -986,10 +1020,11 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, return ret; } sctl = mdss_mdp_get_split_ctl(ctl); ctx = &mdss_mdp_cmd_ctx_list[session]; if (ctx->ref_cnt) { if (ctx->panel_power_state != MDSS_PANEL_POWER_OFF) { pr_debug("%s: ctl_start with panel always on\n", if (mdss_panel_is_power_on(ctx->panel_power_state)) { pr_debug("%s: cmd_start with panel always on\n", __func__); /* * It is possible that the resume was called from the Loading @@ -1000,7 +1035,9 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, * tearcheck logic. */ mdss_mdp_cmd_restore(ctl); return 0; /* Turn on panel so that it can exit low power mode */ return mdss_mdp_cmd_panel_on(ctl, sctl); } else { pr_err("Intf %d already in use\n", session); return -EBUSY; Loading Loading
drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +72 −35 Original line number Diff line number Diff line Loading @@ -59,11 +59,17 @@ struct mdss_mdp_cmd_ctx mdss_mdp_cmd_ctx_list[MAX_SESSIONS]; static int mdss_mdp_cmd_do_notifier(struct mdss_mdp_cmd_ctx *ctx); static bool __mdss_mdp_cmd_panel_power_off(struct mdss_mdp_cmd_ctx *ctx) static bool __mdss_mdp_cmd_is_panel_power_off(struct mdss_mdp_cmd_ctx *ctx) { return mdss_panel_is_power_off(ctx->panel_power_state); } static bool __mdss_mdp_cmd_is_panel_power_on_interactive( struct mdss_mdp_cmd_ctx *ctx) { return mdss_panel_is_power_on_interactive(ctx->panel_power_state); } static inline u32 mdss_mdp_cmd_line_count(struct mdss_mdp_ctl *ctl) { struct mdss_mdp_mixer *mixer; Loading Loading @@ -216,7 +222,7 @@ static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx) struct mdss_data_type *mdata = mdss_mdp_get_mdata(); int irq_en, rc; if (__mdss_mdp_cmd_panel_power_off(ctx)) if (__mdss_mdp_cmd_is_panel_power_off(ctx)) return; mutex_lock(&ctx->clk_mtx); Loading Loading @@ -692,6 +698,45 @@ static int mdss_mdp_cmd_set_stream_size(struct mdss_mdp_ctl *ctl) return rc; } static int mdss_mdp_cmd_panel_on(struct mdss_mdp_ctl *ctl, struct mdss_mdp_ctl *sctl) { struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL; int rc = 0; ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data; if (!ctx) { pr_err("invalid ctx\n"); return -ENODEV; } if (sctl) sctx = (struct mdss_mdp_cmd_ctx *) sctl->priv_data; if (!__mdss_mdp_cmd_is_panel_power_on_interactive(ctx)) { rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_LINK_READY, NULL); WARN(rc, "intf %d link ready error (%d)\n", ctl->intf_num, rc); rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL); WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc); rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_ON, NULL); WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc); ctx->panel_power_state = MDSS_PANEL_POWER_ON; if (sctx) sctx->panel_power_state = MDSS_PANEL_POWER_ON; mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_REGISTER_RECOVERY_HANDLER, (void *)&ctx->intf_recovery); } else { pr_err("%s: Panel already on\n", __func__); } return rc; } /* * There are 3 partial update possibilities * left only ==> enable left pingpong_done Loading @@ -708,7 +753,6 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) { struct mdss_mdp_ctl *sctl = NULL; struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL; int rc; ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data; if (!ctx) { Loading @@ -733,24 +777,13 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) PERF_HW_MDP_STATE, PERF_STATUS_BUSY); } if (__mdss_mdp_cmd_panel_power_off(ctx)) { rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_LINK_READY, NULL); WARN(rc, "intf %d link ready error (%d)\n", ctl->intf_num, rc); rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL); WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc); rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_ON, NULL); WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc); ctx->panel_power_state = MDSS_PANEL_POWER_ON; if (sctx) sctx->panel_power_state = MDSS_PANEL_POWER_ON; mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_REGISTER_RECOVERY_HANDLER, (void *)&ctx->intf_recovery); } /* * Turn on the panel, if not already. This is because the panel is * turned on only when we send the first frame and not during cmd * start. This is to ensure that no artifacts are seen on the panel. */ if (__mdss_mdp_cmd_is_panel_power_off(ctx)) mdss_mdp_cmd_panel_on(ctl, sctl); MDSS_XLOG(ctl->num, ctl->roi.x, ctl->roi.y, ctl->roi.w, ctl->roi.h); Loading Loading @@ -863,12 +896,7 @@ int mdss_mdp_cmd_intfs_stop(struct mdss_mdp_ctl *ctl, int session, mdss_mdp_cmd_clk_off(ctx); flush_work(&ctx->pp_done_work); ctx->panel_power_state = panel_power_state; if (panel_power_state != MDSS_PANEL_POWER_OFF) { pr_debug("%s: panel always on\n", __func__); goto end; } mdss_mdp_cmd_tearcheck_setup(ctl, false); mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num, NULL, NULL); Loading @@ -877,7 +905,6 @@ int mdss_mdp_cmd_intfs_stop(struct mdss_mdp_ctl *ctl, int session, memset(ctx, 0, sizeof(*ctx)); end: pr_debug("%s:-\n", __func__); return 0; Loading @@ -900,6 +927,13 @@ static int mdss_mdp_cmd_stop_sub(struct mdss_mdp_ctl *ctl, if (ctx->panel_power_state == panel_power_state) return 0; /* * If the panel will be left on, then we do not need to turn off * interface clocks since we may continue to get display updates. */ if (mdss_panel_is_power_on(panel_power_state)) return 0; list_for_each_entry_safe(handle, tmp, &ctx->vsync_handlers, list) mdss_mdp_cmd_remove_vsync_handler(ctl, handle); MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled, Loading Loading @@ -945,12 +979,11 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state) ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_OFF, (void *) (long int) panel_power_state); WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret); if (panel_power_state != MDSS_PANEL_POWER_DOZE) mdss_mdp_cmd_tearcheck_setup(ctl, false); } if (panel_power_state != MDSS_PANEL_POWER_OFF) { ctx->panel_power_state = panel_power_state; if (mdss_panel_is_power_on(panel_power_state)) { pr_debug("%s: cmd_stop with panel always on\n", __func__); goto end; } Loading @@ -974,6 +1007,7 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, int session) { struct mdss_mdp_cmd_ctx *ctx; struct mdss_mdp_ctl *sctl = NULL; struct mdss_mdp_mixer *mixer; int ret; Loading @@ -986,10 +1020,11 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, return ret; } sctl = mdss_mdp_get_split_ctl(ctl); ctx = &mdss_mdp_cmd_ctx_list[session]; if (ctx->ref_cnt) { if (ctx->panel_power_state != MDSS_PANEL_POWER_OFF) { pr_debug("%s: ctl_start with panel always on\n", if (mdss_panel_is_power_on(ctx->panel_power_state)) { pr_debug("%s: cmd_start with panel always on\n", __func__); /* * It is possible that the resume was called from the Loading @@ -1000,7 +1035,9 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, * tearcheck logic. */ mdss_mdp_cmd_restore(ctl); return 0; /* Turn on panel so that it can exit low power mode */ return mdss_mdp_cmd_panel_on(ctl, sctl); } else { pr_err("Intf %d already in use\n", session); return -EBUSY; Loading