Loading drivers/video/msm/mdss/mdss_fb.c +1 −1 Original line number Diff line number Diff line Loading @@ -807,7 +807,7 @@ static void mdss_fb_input_event_handler(struct input_handle *handle, struct msm_fb_data_type *mfd = handle->handler->private; int rc; if (type != EV_ABS) if ((type != EV_ABS) || !mdss_fb_is_power_on(mfd)) return; if (mfd->mdp.input_event_handler) { Loading drivers/video/msm/mdss/mdss_mdp.c +24 −13 Original line number Diff line number Diff line Loading @@ -631,15 +631,20 @@ static int mdss_mdp_clk_update(u32 clk_idx, u32 enable) return ret; } int mdss_mdp_vsync_clk_enable(int enable) int mdss_mdp_vsync_clk_enable(int enable, bool locked) { int ret = 0; pr_debug("clk enable=%d\n", enable); if (!locked) mutex_lock(&mdp_clk_lock); if (mdss_res->vsync_ena != enable) { mdss_res->vsync_ena = enable; ret = mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, enable); } if (!locked) mutex_unlock(&mdp_clk_lock); return ret; } Loading Loading @@ -673,14 +678,20 @@ void mdss_mdp_set_clk_rate(unsigned long rate) } } unsigned long mdss_mdp_get_clk_rate(u32 clk_idx) unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked) { unsigned long clk_rate = 0; struct clk *clk = mdss_mdp_get_clk(clk_idx); if (clk) { if (!locked) mutex_lock(&mdp_clk_lock); if (clk) clk_rate = clk_get_rate(clk); if (!locked) mutex_unlock(&mdp_clk_lock); } return clk_rate; } Loading Loading @@ -827,7 +838,7 @@ static int mdss_mdp_idle_pc_restore(void) } mdss_hw_init(mdata); mdss_iommu_ctrl(0); mdss_mdp_ctl_restore(); mdss_mdp_ctl_restore(true); mdata->idle_pc = false; end: Loading Loading @@ -956,10 +967,10 @@ void mdss_mdp_clk_ctrl(int enable) } } mutex_unlock(&mdp_clk_lock); if (enable && changed) mdss_mdp_idle_pc_restore(); mutex_unlock(&mdp_clk_lock); } static inline int mdss_mdp_irq_clk_register(struct mdss_data_type *mdata, Loading Loading @@ -1093,7 +1104,7 @@ static int mdss_mdp_irq_clk_setup(struct mdss_data_type *mdata) /* Setting the default clock rate to the max supported.*/ mdss_mdp_set_clk_rate(mdata->max_mdp_clk_rate); pr_debug("mdp clk rate=%ld\n", mdss_mdp_get_clk_rate(MDSS_CLK_MDP_CORE)); mdss_mdp_get_clk_rate(MDSS_CLK_MDP_CORE, false)); return 0; } Loading Loading @@ -1226,10 +1237,8 @@ static void mdss_hw_rev_init(struct mdss_data_type *mdata) if (mdata->mdp_rev) return; mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdata->mdp_rev = MDSS_REG_READ(mdata, MDSS_REG_HW_VERSION); mdss_mdp_hw_rev_caps_init(mdata); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); } /** Loading Loading @@ -1502,7 +1511,9 @@ static ssize_t mdss_mdp_show_capabilities(struct device *dev, #define SPRINT(fmt, ...) \ (cnt += scnprintf(buf + cnt, len - cnt, fmt, ##__VA_ARGS__)) mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_hw_rev_init(mdata); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); SPRINT("mdp_version=5\n"); SPRINT("hw_rev=%d\n", mdata->mdp_rev); Loading drivers/video/msm/mdss/mdss_mdp.h +4 −4 Original line number Diff line number Diff line Loading @@ -235,7 +235,7 @@ struct mdss_mdp_ctl_intfs_ops { struct mdss_mdp_vsync_handler *); 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 (*restore_fnc)(struct mdss_mdp_ctl *ctl, bool locked); int (*early_wake_up_fnc)(struct mdss_mdp_ctl *ctl); /* Loading Loading @@ -990,8 +990,8 @@ int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num, void mdss_mdp_footswitch_ctrl_splash(int on); void mdss_mdp_batfet_ctrl(struct mdss_data_type *mdata, int enable); void mdss_mdp_set_clk_rate(unsigned long min_clk_rate); unsigned long mdss_mdp_get_clk_rate(u32 clk_idx); int mdss_mdp_vsync_clk_enable(int enable); unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked); int mdss_mdp_vsync_clk_enable(int enable, bool locked); void mdss_mdp_clk_ctrl(int enable); struct mdss_data_type *mdss_mdp_get_mdata(void); int mdss_mdp_secure_display_ctrl(unsigned int enable); Loading Loading @@ -1265,7 +1265,7 @@ int mdss_mdp_wb_get_format(struct msm_fb_data_type *mfd, void mdss_mdp_pipe_calc_pixel_extn(struct mdss_mdp_pipe *pipe); int mdss_mdp_wb_set_secure(struct msm_fb_data_type *mfd, int enable); int mdss_mdp_wb_get_secure(struct msm_fb_data_type *mfd, uint8_t *enable); void mdss_mdp_ctl_restore(void); void mdss_mdp_ctl_restore(bool locked); int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl); int mdss_mdp_wait_for_xin_halt(u32 xin_id, bool is_vbif_nrt); void mdss_mdp_set_ot_limit(struct mdss_mdp_set_ot_params *params); Loading drivers/video/msm/mdss/mdss_mdp_ctl.c +9 −4 Original line number Diff line number Diff line Loading @@ -3144,19 +3144,25 @@ static void mdss_mdp_ctl_restore_sub(struct mdss_mdp_ctl *ctl) /* * mdss_mdp_ctl_restore() - restore mdp ctl path * @locked - boolean to signal that clock lock is already acquired * * This function is called whenever MDP comes out of a power collapse as * a result of a screen update. It restores the MDP controller's software * state to the hardware registers. * Function does not enable the clocks, so caller must make sure * clocks are enabled before calling. * The locked boolean in the parametrs signals that synchronization * with mdp clocks access is not required downstream. * Only call this function setting this value to true if the clocks access * synchronization is guaranteed by the caller. */ void mdss_mdp_ctl_restore(void) void mdss_mdp_ctl_restore(bool locked) { struct mdss_mdp_ctl *ctl = NULL; struct mdss_mdp_ctl *sctl; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); u32 cnum; mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); for (cnum = MDSS_MDP_CTL0; cnum < mdata->nctl; cnum++) { ctl = mdata->ctl_off + cnum; if (!mdss_mdp_ctl_is_power_on(ctl)) Loading @@ -3172,9 +3178,8 @@ void mdss_mdp_ctl_restore(void) mdss_mdp_ctl_split_display_enable(1, ctl, sctl); } if (ctl->ops.restore_fnc) ctl->ops.restore_fnc(ctl); ctl->ops.restore_fnc(ctl, locked); } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); } static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff) Loading drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +58 −48 Original line number Diff line number Diff line Loading @@ -179,7 +179,7 @@ static int mdss_mdp_tearcheck_enable(struct mdss_mdp_ctl *ctl, bool enable) } static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, struct mdss_mdp_cmd_ctx *ctx) struct mdss_mdp_cmd_ctx *ctx, bool locked) { struct mdss_mdp_pp_tear_check *te = NULL; struct mdss_panel_info *pinfo; Loading @@ -196,10 +196,10 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, pinfo = &ctl->panel_data->panel_info; te = &ctl->panel_data->panel_info.te; mdss_mdp_vsync_clk_enable(1); mdss_mdp_vsync_clk_enable(1, locked); vsync_clk_speed_hz = mdss_mdp_get_clk_rate(MDSS_CLK_MDP_VSYNC); mdss_mdp_get_clk_rate(MDSS_CLK_MDP_VSYNC, locked); total_lines = mdss_panel_get_vtotal(pinfo); Loading Loading @@ -258,7 +258,8 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, return 0; } static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx) static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx, bool locked) { int rc = 0; struct mdss_mdp_mixer *mixer; Loading @@ -267,7 +268,7 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx) mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_LEFT); if (mixer) { rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx); rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx, locked); if (rc) goto err; } Loading @@ -276,7 +277,7 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx) !is_dsc_compression(pinfo)) { mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_RIGHT); if (mixer) rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx); rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx, locked); } err: return rc; Loading Loading @@ -683,24 +684,32 @@ int mdss_mdp_resource_control(struct mdss_mdp_ctl *ctl, u32 sw_event) 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. * Cancel any work item pending and: * 1. If the current state is ON, stay in ON. * 2. If the current state is GATED, stay at GATED. * 3. If the current state is POWER-OFF, POWER-ON and * schedule a work item to POWER-OFF if no * kickoffs get scheduled. */ mutex_lock(&ctl->rsrc_lock); if (mdp5_data->resources_state != MDP_RSRC_CTL_STATE_OFF) { /* if panels are off, do not process early wake up */ if ((ctx && __mdss_mdp_cmd_is_panel_power_off(ctx)) || (sctx && __mdss_mdp_cmd_is_panel_power_off(sctx))) break; /* Cancel GATE Work Item */ if (cancel_work_sync(&ctx->gate_clk_work)) pr_debug("%s: %s - gate_work cancelled\n", __func__, get_sw_event_name(sw_event)); /* Cancel OFF Work Item */ 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 { mutex_lock(&ctl->rsrc_lock); if (mdp5_data->resources_state == MDP_RSRC_CTL_STATE_OFF) { mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_mdp_ctl_intf_event(ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, Loading Loading @@ -741,9 +750,6 @@ static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); if (__mdss_mdp_cmd_is_panel_power_off(ctx)) return; mutex_lock(&ctx->clk_mtx); MDSS_XLOG(ctx->pp_num, atomic_read(&ctx->koff_cnt)); Loading Loading @@ -960,11 +966,15 @@ static void clk_ctrl_delayed_off_work(struct work_struct *work) get_clk_pwr_state_name (mdp5_data->resources_state)); mutex_lock(&ctl->rsrc_lock); if (ctl->mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY) { mutex_lock(&cmd_clk_mtx); if (mdss_mdp_get_split_display_ctls(&ctl, &sctl)) { /* error when getting both controllers, just returnr */ pr_err("cannot get both controllers for the split display\n"); return; goto exit; } /* re-assign to have the correct order in the context */ Loading @@ -973,13 +983,10 @@ static void clk_ctrl_delayed_off_work(struct work_struct *work) if (!ctx || !sctx) { pr_err("invalid %s %s\n", ctx?"":"ctx", sctx?"":"sctx"); return; goto exit; } mutex_lock(&cmd_clk_mtx); } mutex_lock(&ctl->rsrc_lock); if (ctx->autorefresh_init) { /* * Driver shouldn't have scheduled this work item if Loading Loading @@ -1014,12 +1021,12 @@ static void clk_ctrl_delayed_off_work(struct work_struct *work) mdp5_data->resources_state = MDP_RSRC_CTL_STATE_OFF; exit: mutex_unlock(&ctl->rsrc_lock); /* do this at the end, so we can also protect the global power state*/ if (ctl->mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY) mutex_unlock(&cmd_clk_mtx); mutex_unlock(&ctl->rsrc_lock); ATRACE_END(__func__); } Loading Loading @@ -1053,12 +1060,16 @@ static void clk_ctrl_gate_work(struct work_struct *work) ctl->num, get_clk_pwr_state_name (mdp5_data->resources_state)); mutex_lock(&ctl->rsrc_lock); if (ctl->mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY) { mutex_lock(&cmd_clk_mtx); if (mdss_mdp_get_split_display_ctls(&ctl, &sctl)) { /* error when getting both controllers, just return */ pr_err("%s cannot get both cts for the split display\n", __func__); return; goto exit; } /* re-assign to have the correct order in the context */ Loading @@ -1067,13 +1078,10 @@ static void clk_ctrl_gate_work(struct work_struct *work) if (!ctx || !sctx) { pr_err("%s ERROR invalid %s %s\n", __func__, ctx?"":"ctx", sctx?"":"sctx"); return; goto exit; } mutex_lock(&cmd_clk_mtx); } mutex_lock(&ctl->rsrc_lock); if (ctx->autorefresh_init) { /* * Driver shouldn't have scheduled this work item if Loading Loading @@ -1104,12 +1112,12 @@ static void clk_ctrl_gate_work(struct work_struct *work) mdp5_data->resources_state = MDP_RSRC_CTL_STATE_GATE; exit: mutex_unlock(&ctl->rsrc_lock); /* unlock mutex needed for split display */ if (ctl->mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY) mutex_unlock(&cmd_clk_mtx); mutex_unlock(&ctl->rsrc_lock); ATRACE_END(__func__); } Loading Loading @@ -1685,17 +1693,14 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) return 0; } int mdss_mdp_cmd_restore(struct mdss_mdp_ctl *ctl) int mdss_mdp_cmd_restore(struct mdss_mdp_ctl *ctl, bool locked) { pr_debug("%s: called for ctl%d\n", __func__, ctl->num); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); if (mdss_mdp_cmd_tearcheck_setup(ctl->intf_ctx[MASTER_CTX])) if (mdss_mdp_cmd_tearcheck_setup(ctl->intf_ctx[MASTER_CTX], locked)) pr_warn("%s: tearcheck setup failed\n", __func__); else mdss_mdp_tearcheck_enable(ctl, true); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); return 0; } Loading Loading @@ -2005,6 +2010,7 @@ static int mdss_mdp_cmd_early_wake_up(struct mdss_mdp_ctl *ctl) * involves cancelling queued work items. So this will be * scheduled in a work item. */ if (ctx) schedule_work(&ctx->early_wakeup_clk_work); return 0; } Loading Loading @@ -2052,7 +2058,7 @@ static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num, mdss_mdp_cmd_pingpong_done, ctl); ret = mdss_mdp_cmd_tearcheck_setup(ctx); ret = mdss_mdp_cmd_tearcheck_setup(ctx, false); if (ret) pr_err("tearcheck setup failed\n"); Loading Loading @@ -2084,7 +2090,9 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, * explictly call the restore function to enable * tearcheck logic. */ mdss_mdp_cmd_restore(ctl); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_mdp_cmd_restore(ctl, false); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); /* Turn on panel so that it can exit low power mode */ return mdss_mdp_cmd_panel_on(ctl, sctl); Loading Loading @@ -2124,7 +2132,9 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, if (mdss_panel_is_power_on(ctx->panel_power_state)) { pr_debug("%s: cmd_start with panel always on\n", __func__); mdss_mdp_cmd_restore(ctl); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_mdp_cmd_restore(ctl, false); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); return mdss_mdp_cmd_panel_on(ctl, sctl); } else { pr_err("Intf %d already in use\n", session); Loading Loading
drivers/video/msm/mdss/mdss_fb.c +1 −1 Original line number Diff line number Diff line Loading @@ -807,7 +807,7 @@ static void mdss_fb_input_event_handler(struct input_handle *handle, struct msm_fb_data_type *mfd = handle->handler->private; int rc; if (type != EV_ABS) if ((type != EV_ABS) || !mdss_fb_is_power_on(mfd)) return; if (mfd->mdp.input_event_handler) { Loading
drivers/video/msm/mdss/mdss_mdp.c +24 −13 Original line number Diff line number Diff line Loading @@ -631,15 +631,20 @@ static int mdss_mdp_clk_update(u32 clk_idx, u32 enable) return ret; } int mdss_mdp_vsync_clk_enable(int enable) int mdss_mdp_vsync_clk_enable(int enable, bool locked) { int ret = 0; pr_debug("clk enable=%d\n", enable); if (!locked) mutex_lock(&mdp_clk_lock); if (mdss_res->vsync_ena != enable) { mdss_res->vsync_ena = enable; ret = mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, enable); } if (!locked) mutex_unlock(&mdp_clk_lock); return ret; } Loading Loading @@ -673,14 +678,20 @@ void mdss_mdp_set_clk_rate(unsigned long rate) } } unsigned long mdss_mdp_get_clk_rate(u32 clk_idx) unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked) { unsigned long clk_rate = 0; struct clk *clk = mdss_mdp_get_clk(clk_idx); if (clk) { if (!locked) mutex_lock(&mdp_clk_lock); if (clk) clk_rate = clk_get_rate(clk); if (!locked) mutex_unlock(&mdp_clk_lock); } return clk_rate; } Loading Loading @@ -827,7 +838,7 @@ static int mdss_mdp_idle_pc_restore(void) } mdss_hw_init(mdata); mdss_iommu_ctrl(0); mdss_mdp_ctl_restore(); mdss_mdp_ctl_restore(true); mdata->idle_pc = false; end: Loading Loading @@ -956,10 +967,10 @@ void mdss_mdp_clk_ctrl(int enable) } } mutex_unlock(&mdp_clk_lock); if (enable && changed) mdss_mdp_idle_pc_restore(); mutex_unlock(&mdp_clk_lock); } static inline int mdss_mdp_irq_clk_register(struct mdss_data_type *mdata, Loading Loading @@ -1093,7 +1104,7 @@ static int mdss_mdp_irq_clk_setup(struct mdss_data_type *mdata) /* Setting the default clock rate to the max supported.*/ mdss_mdp_set_clk_rate(mdata->max_mdp_clk_rate); pr_debug("mdp clk rate=%ld\n", mdss_mdp_get_clk_rate(MDSS_CLK_MDP_CORE)); mdss_mdp_get_clk_rate(MDSS_CLK_MDP_CORE, false)); return 0; } Loading Loading @@ -1226,10 +1237,8 @@ static void mdss_hw_rev_init(struct mdss_data_type *mdata) if (mdata->mdp_rev) return; mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdata->mdp_rev = MDSS_REG_READ(mdata, MDSS_REG_HW_VERSION); mdss_mdp_hw_rev_caps_init(mdata); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); } /** Loading Loading @@ -1502,7 +1511,9 @@ static ssize_t mdss_mdp_show_capabilities(struct device *dev, #define SPRINT(fmt, ...) \ (cnt += scnprintf(buf + cnt, len - cnt, fmt, ##__VA_ARGS__)) mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_hw_rev_init(mdata); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); SPRINT("mdp_version=5\n"); SPRINT("hw_rev=%d\n", mdata->mdp_rev); Loading
drivers/video/msm/mdss/mdss_mdp.h +4 −4 Original line number Diff line number Diff line Loading @@ -235,7 +235,7 @@ struct mdss_mdp_ctl_intfs_ops { struct mdss_mdp_vsync_handler *); 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 (*restore_fnc)(struct mdss_mdp_ctl *ctl, bool locked); int (*early_wake_up_fnc)(struct mdss_mdp_ctl *ctl); /* Loading Loading @@ -990,8 +990,8 @@ int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num, void mdss_mdp_footswitch_ctrl_splash(int on); void mdss_mdp_batfet_ctrl(struct mdss_data_type *mdata, int enable); void mdss_mdp_set_clk_rate(unsigned long min_clk_rate); unsigned long mdss_mdp_get_clk_rate(u32 clk_idx); int mdss_mdp_vsync_clk_enable(int enable); unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked); int mdss_mdp_vsync_clk_enable(int enable, bool locked); void mdss_mdp_clk_ctrl(int enable); struct mdss_data_type *mdss_mdp_get_mdata(void); int mdss_mdp_secure_display_ctrl(unsigned int enable); Loading Loading @@ -1265,7 +1265,7 @@ int mdss_mdp_wb_get_format(struct msm_fb_data_type *mfd, void mdss_mdp_pipe_calc_pixel_extn(struct mdss_mdp_pipe *pipe); int mdss_mdp_wb_set_secure(struct msm_fb_data_type *mfd, int enable); int mdss_mdp_wb_get_secure(struct msm_fb_data_type *mfd, uint8_t *enable); void mdss_mdp_ctl_restore(void); void mdss_mdp_ctl_restore(bool locked); int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl); int mdss_mdp_wait_for_xin_halt(u32 xin_id, bool is_vbif_nrt); void mdss_mdp_set_ot_limit(struct mdss_mdp_set_ot_params *params); Loading
drivers/video/msm/mdss/mdss_mdp_ctl.c +9 −4 Original line number Diff line number Diff line Loading @@ -3144,19 +3144,25 @@ static void mdss_mdp_ctl_restore_sub(struct mdss_mdp_ctl *ctl) /* * mdss_mdp_ctl_restore() - restore mdp ctl path * @locked - boolean to signal that clock lock is already acquired * * This function is called whenever MDP comes out of a power collapse as * a result of a screen update. It restores the MDP controller's software * state to the hardware registers. * Function does not enable the clocks, so caller must make sure * clocks are enabled before calling. * The locked boolean in the parametrs signals that synchronization * with mdp clocks access is not required downstream. * Only call this function setting this value to true if the clocks access * synchronization is guaranteed by the caller. */ void mdss_mdp_ctl_restore(void) void mdss_mdp_ctl_restore(bool locked) { struct mdss_mdp_ctl *ctl = NULL; struct mdss_mdp_ctl *sctl; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); u32 cnum; mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); for (cnum = MDSS_MDP_CTL0; cnum < mdata->nctl; cnum++) { ctl = mdata->ctl_off + cnum; if (!mdss_mdp_ctl_is_power_on(ctl)) Loading @@ -3172,9 +3178,8 @@ void mdss_mdp_ctl_restore(void) mdss_mdp_ctl_split_display_enable(1, ctl, sctl); } if (ctl->ops.restore_fnc) ctl->ops.restore_fnc(ctl); ctl->ops.restore_fnc(ctl, locked); } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); } static int mdss_mdp_ctl_start_sub(struct mdss_mdp_ctl *ctl, bool handoff) Loading
drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +58 −48 Original line number Diff line number Diff line Loading @@ -179,7 +179,7 @@ static int mdss_mdp_tearcheck_enable(struct mdss_mdp_ctl *ctl, bool enable) } static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, struct mdss_mdp_cmd_ctx *ctx) struct mdss_mdp_cmd_ctx *ctx, bool locked) { struct mdss_mdp_pp_tear_check *te = NULL; struct mdss_panel_info *pinfo; Loading @@ -196,10 +196,10 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, pinfo = &ctl->panel_data->panel_info; te = &ctl->panel_data->panel_info.te; mdss_mdp_vsync_clk_enable(1); mdss_mdp_vsync_clk_enable(1, locked); vsync_clk_speed_hz = mdss_mdp_get_clk_rate(MDSS_CLK_MDP_VSYNC); mdss_mdp_get_clk_rate(MDSS_CLK_MDP_VSYNC, locked); total_lines = mdss_panel_get_vtotal(pinfo); Loading Loading @@ -258,7 +258,8 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, return 0; } static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx) static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx, bool locked) { int rc = 0; struct mdss_mdp_mixer *mixer; Loading @@ -267,7 +268,7 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx) mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_LEFT); if (mixer) { rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx); rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx, locked); if (rc) goto err; } Loading @@ -276,7 +277,7 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx) !is_dsc_compression(pinfo)) { mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_RIGHT); if (mixer) rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx); rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx, locked); } err: return rc; Loading Loading @@ -683,24 +684,32 @@ int mdss_mdp_resource_control(struct mdss_mdp_ctl *ctl, u32 sw_event) 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. * Cancel any work item pending and: * 1. If the current state is ON, stay in ON. * 2. If the current state is GATED, stay at GATED. * 3. If the current state is POWER-OFF, POWER-ON and * schedule a work item to POWER-OFF if no * kickoffs get scheduled. */ mutex_lock(&ctl->rsrc_lock); if (mdp5_data->resources_state != MDP_RSRC_CTL_STATE_OFF) { /* if panels are off, do not process early wake up */ if ((ctx && __mdss_mdp_cmd_is_panel_power_off(ctx)) || (sctx && __mdss_mdp_cmd_is_panel_power_off(sctx))) break; /* Cancel GATE Work Item */ if (cancel_work_sync(&ctx->gate_clk_work)) pr_debug("%s: %s - gate_work cancelled\n", __func__, get_sw_event_name(sw_event)); /* Cancel OFF Work Item */ 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 { mutex_lock(&ctl->rsrc_lock); if (mdp5_data->resources_state == MDP_RSRC_CTL_STATE_OFF) { mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_mdp_ctl_intf_event(ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, Loading Loading @@ -741,9 +750,6 @@ static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); if (__mdss_mdp_cmd_is_panel_power_off(ctx)) return; mutex_lock(&ctx->clk_mtx); MDSS_XLOG(ctx->pp_num, atomic_read(&ctx->koff_cnt)); Loading Loading @@ -960,11 +966,15 @@ static void clk_ctrl_delayed_off_work(struct work_struct *work) get_clk_pwr_state_name (mdp5_data->resources_state)); mutex_lock(&ctl->rsrc_lock); if (ctl->mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY) { mutex_lock(&cmd_clk_mtx); if (mdss_mdp_get_split_display_ctls(&ctl, &sctl)) { /* error when getting both controllers, just returnr */ pr_err("cannot get both controllers for the split display\n"); return; goto exit; } /* re-assign to have the correct order in the context */ Loading @@ -973,13 +983,10 @@ static void clk_ctrl_delayed_off_work(struct work_struct *work) if (!ctx || !sctx) { pr_err("invalid %s %s\n", ctx?"":"ctx", sctx?"":"sctx"); return; goto exit; } mutex_lock(&cmd_clk_mtx); } mutex_lock(&ctl->rsrc_lock); if (ctx->autorefresh_init) { /* * Driver shouldn't have scheduled this work item if Loading Loading @@ -1014,12 +1021,12 @@ static void clk_ctrl_delayed_off_work(struct work_struct *work) mdp5_data->resources_state = MDP_RSRC_CTL_STATE_OFF; exit: mutex_unlock(&ctl->rsrc_lock); /* do this at the end, so we can also protect the global power state*/ if (ctl->mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY) mutex_unlock(&cmd_clk_mtx); mutex_unlock(&ctl->rsrc_lock); ATRACE_END(__func__); } Loading Loading @@ -1053,12 +1060,16 @@ static void clk_ctrl_gate_work(struct work_struct *work) ctl->num, get_clk_pwr_state_name (mdp5_data->resources_state)); mutex_lock(&ctl->rsrc_lock); if (ctl->mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY) { mutex_lock(&cmd_clk_mtx); if (mdss_mdp_get_split_display_ctls(&ctl, &sctl)) { /* error when getting both controllers, just return */ pr_err("%s cannot get both cts for the split display\n", __func__); return; goto exit; } /* re-assign to have the correct order in the context */ Loading @@ -1067,13 +1078,10 @@ static void clk_ctrl_gate_work(struct work_struct *work) if (!ctx || !sctx) { pr_err("%s ERROR invalid %s %s\n", __func__, ctx?"":"ctx", sctx?"":"sctx"); return; goto exit; } mutex_lock(&cmd_clk_mtx); } mutex_lock(&ctl->rsrc_lock); if (ctx->autorefresh_init) { /* * Driver shouldn't have scheduled this work item if Loading Loading @@ -1104,12 +1112,12 @@ static void clk_ctrl_gate_work(struct work_struct *work) mdp5_data->resources_state = MDP_RSRC_CTL_STATE_GATE; exit: mutex_unlock(&ctl->rsrc_lock); /* unlock mutex needed for split display */ if (ctl->mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY) mutex_unlock(&cmd_clk_mtx); mutex_unlock(&ctl->rsrc_lock); ATRACE_END(__func__); } Loading Loading @@ -1685,17 +1693,14 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) return 0; } int mdss_mdp_cmd_restore(struct mdss_mdp_ctl *ctl) int mdss_mdp_cmd_restore(struct mdss_mdp_ctl *ctl, bool locked) { pr_debug("%s: called for ctl%d\n", __func__, ctl->num); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); if (mdss_mdp_cmd_tearcheck_setup(ctl->intf_ctx[MASTER_CTX])) if (mdss_mdp_cmd_tearcheck_setup(ctl->intf_ctx[MASTER_CTX], locked)) pr_warn("%s: tearcheck setup failed\n", __func__); else mdss_mdp_tearcheck_enable(ctl, true); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); return 0; } Loading Loading @@ -2005,6 +2010,7 @@ static int mdss_mdp_cmd_early_wake_up(struct mdss_mdp_ctl *ctl) * involves cancelling queued work items. So this will be * scheduled in a work item. */ if (ctx) schedule_work(&ctx->early_wakeup_clk_work); return 0; } Loading Loading @@ -2052,7 +2058,7 @@ static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num, mdss_mdp_cmd_pingpong_done, ctl); ret = mdss_mdp_cmd_tearcheck_setup(ctx); ret = mdss_mdp_cmd_tearcheck_setup(ctx, false); if (ret) pr_err("tearcheck setup failed\n"); Loading Loading @@ -2084,7 +2090,9 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, * explictly call the restore function to enable * tearcheck logic. */ mdss_mdp_cmd_restore(ctl); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_mdp_cmd_restore(ctl, false); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); /* Turn on panel so that it can exit low power mode */ return mdss_mdp_cmd_panel_on(ctl, sctl); Loading Loading @@ -2124,7 +2132,9 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl, if (mdss_panel_is_power_on(ctx->panel_power_state)) { pr_debug("%s: cmd_start with panel always on\n", __func__); mdss_mdp_cmd_restore(ctl); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mdss_mdp_cmd_restore(ctl, false); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); return mdss_mdp_cmd_panel_on(ctl, sctl); } else { pr_err("Intf %d already in use\n", session); Loading