diff options
| -rw-r--r-- | drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c | 13 | ||||
| -rw-r--r-- | drivers/misc/hdcp.c | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.c | 27 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 126 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_video.c | 16 |
8 files changed, 136 insertions, 57 deletions
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c index 0ca4d910ad72..58cb160f118e 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c @@ -551,11 +551,18 @@ static int sde_smmu_fault_handler(struct iommu_domain *domain, sde_smmu = (struct sde_smmu_client *)token; - /* trigger rotator panic and dump */ - SDEROT_ERR("trigger rotator panic and dump, iova=0x%08lx\n", iova); + /* trigger rotator dump */ + SDEROT_ERR("trigger rotator dump, iova=0x%08lx, flags=0x%x\n", + iova, flags); + SDEROT_ERR("SMMU device:%s", sde_smmu->dev->kobj.name); - sde_rot_dump_panic(); + /* generate dump, but no panic */ + sde_rot_evtlog_tout_handler(false, __func__, "rot", "vbif_dbg_bus"); + /* + * return -ENOSYS to allow smmu driver to dump out useful + * debug info. + */ return rc; } diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c index bd21f8cca2aa..460ffc79f566 100644 --- a/drivers/misc/hdcp.c +++ b/drivers/misc/hdcp.c @@ -2103,7 +2103,8 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle) (rc == 0) && (rsp_buf->status == 0)) { pr_debug("Got Auth_Stream_Ready, nothing sent to rx\n"); - if (!hdcp_lib_enable_encryption(handle)) { + if (!handle->authenticated && + !hdcp_lib_enable_encryption(handle)) { handle->authenticated = true; cdata.cmd = HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS; diff --git a/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c b/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c index 3bcacf945761..5a677dfe7484 100644 --- a/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c +++ b/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c @@ -449,7 +449,7 @@ static struct attribute *dp_hdcp2p2_fs_attrs[] = { }; static struct attribute_group dp_hdcp2p2_fs_attr_group = { - .name = "dp_hdcp2p2", + .name = "hdcp2p2", .attrs = dp_hdcp2p2_fs_attrs, }; diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index f4c4c509410a..db27842eaccc 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -892,6 +892,12 @@ static ssize_t mdss_fb_get_persist_mode(struct device *dev, return ret; } +static ssize_t mdss_fb_idle_pc_notify(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "idle power collapsed\n"); +} + static DEVICE_ATTR(msm_fb_type, S_IRUGO, mdss_fb_get_type, NULL); static DEVICE_ATTR(msm_fb_split, S_IRUGO | S_IWUSR, mdss_fb_show_split, mdss_fb_store_split); @@ -912,6 +918,8 @@ static DEVICE_ATTR(measured_fps, S_IRUGO | S_IWUSR | S_IWGRP, mdss_fb_get_fps_info, NULL); static DEVICE_ATTR(msm_fb_persist_mode, S_IRUGO | S_IWUSR, mdss_fb_get_persist_mode, mdss_fb_change_persist_mode); +static DEVICE_ATTR(idle_power_collapse, S_IRUGO, mdss_fb_idle_pc_notify, NULL); + static struct attribute *mdss_fb_attrs[] = { &dev_attr_msm_fb_type.attr, &dev_attr_msm_fb_split.attr, @@ -925,6 +933,7 @@ static struct attribute *mdss_fb_attrs[] = { &dev_attr_msm_fb_dfps_mode.attr, &dev_attr_measured_fps.attr, &dev_attr_msm_fb_persist_mode.attr, + &dev_attr_idle_power_collapse.attr, NULL, }; @@ -4470,7 +4479,7 @@ err: static int __mdss_fb_copy_destscaler_data(struct fb_info *info, struct mdp_layer_commit *commit) { - int i; + int i = 0; int ret = 0; u32 data_size; struct mdp_destination_scaler_data __user *ds_data_user; @@ -4543,6 +4552,7 @@ static int __mdss_fb_copy_destscaler_data(struct fb_info *info, data_size); if (ret) { pr_err("scale data copy from user failed\n"); + kfree(scale_data); goto err; } } @@ -4552,7 +4562,7 @@ static int __mdss_fb_copy_destscaler_data(struct fb_info *info, err: if (ds_data) { - for (i = 0; i < commit->commit_v1.dest_scaler_cnt; i++) { + for (i--; i >= 0; i--) { scale_data = to_user_ptr(ds_data[i].scale); kfree(scale_data); } @@ -5176,3 +5186,16 @@ void mdss_fb_calc_fps(struct msm_fb_data_type *mfd) mfd->fps_info.frame_count = 0; } } + +void mdss_fb_idle_pc(struct msm_fb_data_type *mfd) +{ + struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); + + if (mdss_fb_is_power_off(mfd)) + return; + + if ((mfd->panel_info->type == MIPI_CMD_PANEL) && mdp5_data) { + pr_debug("Notify fb%d idle power collapsed\n", mfd->index); + sysfs_notify(&mfd->fbi->dev->kobj, NULL, "idle_power_collapse"); + } +} diff --git a/drivers/video/fbdev/msm/mdss_fb.h b/drivers/video/fbdev/msm/mdss_fb.h index 111d7cfc7c9a..d64580a35775 100644 --- a/drivers/video/fbdev/msm/mdss_fb.h +++ b/drivers/video/fbdev/msm/mdss_fb.h @@ -468,4 +468,5 @@ void mdss_fb_report_panel_dead(struct msm_fb_data_type *mfd); void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo, struct fb_var_screeninfo *var); void mdss_fb_calc_fps(struct msm_fb_data_type *mfd); +void mdss_fb_idle_pc(struct msm_fb_data_type *mfd); #endif /* MDSS_FB_H */ diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index d8d11f21f3b2..21728c5dee45 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -1355,6 +1355,68 @@ static inline void __mdss_mdp_reg_access_clk_enable( } } +/* + * __mdss_mdp_clk_control - Overall MDSS clock control for power on/off + */ +static void __mdss_mdp_clk_control(struct mdss_data_type *mdata, bool enable) +{ + int rc = 0; + unsigned long flags; + + if (enable) { + pm_runtime_get_sync(&mdata->pdev->dev); + + mdss_update_reg_bus_vote(mdata->reg_bus_clt, + VOTE_INDEX_LOW); + + rc = mdss_iommu_ctrl(1); + if (IS_ERR_VALUE(rc)) + pr_err("IOMMU attach failed\n"); + + /* Active+Sleep */ + msm_bus_scale_client_update_context(mdata->bus_hdl, + false, mdata->curr_bw_uc_idx); + + spin_lock_irqsave(&mdp_lock, flags); + mdata->clk_ena = enable; + spin_unlock_irqrestore(&mdp_lock, flags); + + mdss_mdp_clk_update(MDSS_CLK_MNOC_AHB, 1); + mdss_mdp_clk_update(MDSS_CLK_AHB, 1); + mdss_mdp_clk_update(MDSS_CLK_AXI, 1); + mdss_mdp_clk_update(MDSS_CLK_MDP_CORE, 1); + mdss_mdp_clk_update(MDSS_CLK_MDP_LUT, 1); + if (mdata->vsync_ena) + mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, 1); + } else { + spin_lock_irqsave(&mdp_lock, flags); + mdata->clk_ena = enable; + spin_unlock_irqrestore(&mdp_lock, flags); + + if (mdata->vsync_ena) + mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, 0); + + mdss_mdp_clk_update(MDSS_CLK_MDP_LUT, 0); + mdss_mdp_clk_update(MDSS_CLK_MDP_CORE, 0); + mdss_mdp_clk_update(MDSS_CLK_AXI, 0); + mdss_mdp_clk_update(MDSS_CLK_AHB, 0); + mdss_mdp_clk_update(MDSS_CLK_MNOC_AHB, 0); + + /* release iommu control */ + mdss_iommu_ctrl(0); + + /* Active-Only */ + msm_bus_scale_client_update_context(mdata->bus_hdl, + true, mdata->ao_bw_uc_idx); + + mdss_update_reg_bus_vote(mdata->reg_bus_clt, + VOTE_INDEX_DISABLE); + + pm_runtime_mark_last_busy(&mdata->pdev->dev); + pm_runtime_put_autosuspend(&mdata->pdev->dev); + } +} + int __mdss_mdp_vbif_halt(struct mdss_data_type *mdata, bool is_nrt) { int rc = 0; @@ -1646,9 +1708,7 @@ void mdss_mdp_clk_ctrl(int enable) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); static int mdp_clk_cnt; - unsigned long flags; int changed = 0; - int rc = 0; mutex_lock(&mdp_clk_lock); if (enable) { @@ -1672,49 +1732,8 @@ void mdss_mdp_clk_ctrl(int enable) __builtin_return_address(0), current->group_leader->comm, mdata->bus_ref_cnt, changed, enable); - if (changed) { - if (enable) { - pm_runtime_get_sync(&mdata->pdev->dev); - - mdss_update_reg_bus_vote(mdata->reg_bus_clt, - VOTE_INDEX_LOW); - - rc = mdss_iommu_ctrl(1); - if (IS_ERR_VALUE(rc)) - pr_err("IOMMU attach failed\n"); - - /* Active+Sleep */ - msm_bus_scale_client_update_context(mdata->bus_hdl, - false, mdata->curr_bw_uc_idx); - } - - spin_lock_irqsave(&mdp_lock, flags); - mdata->clk_ena = enable; - spin_unlock_irqrestore(&mdp_lock, flags); - - mdss_mdp_clk_update(MDSS_CLK_MNOC_AHB, enable); - mdss_mdp_clk_update(MDSS_CLK_AHB, enable); - mdss_mdp_clk_update(MDSS_CLK_AXI, enable); - mdss_mdp_clk_update(MDSS_CLK_MDP_CORE, enable); - mdss_mdp_clk_update(MDSS_CLK_MDP_LUT, enable); - if (mdata->vsync_ena) - mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, enable); - - if (!enable) { - /* release iommu control */ - mdss_iommu_ctrl(0); - - /* Active-Only */ - msm_bus_scale_client_update_context(mdata->bus_hdl, - true, mdata->ao_bw_uc_idx); - - mdss_update_reg_bus_vote(mdata->reg_bus_clt, - VOTE_INDEX_DISABLE); - - pm_runtime_mark_last_busy(&mdata->pdev->dev); - pm_runtime_put_autosuspend(&mdata->pdev->dev); - } - } + if (changed) + __mdss_mdp_clk_control(mdata, enable); if (enable && changed) mdss_mdp_idle_pc_restore(); @@ -5092,6 +5111,22 @@ vreg_set_voltage_fail: } /** + * mdss_mdp_notify_idle_pc() - Notify fb driver of idle power collapse + * @mdata: MDP private data + * + * This function is called if there are active overlays. + */ +static void mdss_mdp_notify_idle_pc(struct mdss_data_type *mdata) +{ + int i; + + for (i = 0; i < mdata->nctl; i++) + if ((mdata->ctl_off[i].ref_cnt) && + !mdss_mdp_ctl_is_power_off(&mdata->ctl_off[i])) + mdss_fb_idle_pc(mdata->ctl_off[i].mfd); +} + +/** * mdss_mdp_footswitch_ctrl() - Disable/enable MDSS GDSC and CX/Batfet rails * @mdata: MDP private data * @on: 1 to turn on footswitch, 0 to turn off footswitch @@ -5155,6 +5190,7 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on) mdss_mdp_memory_retention_ctrl(MEM_RETAIN_ON, PERIPH_RETAIN_OFF); mdata->idle_pc = true; + mdss_mdp_notify_idle_pc(mdata); pr_debug("idle pc. active overlays=%d\n", active_cnt); } else { diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index e258f258aeca..7b0207de101a 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -892,7 +892,7 @@ static u32 __calc_prefill_line_time_us(struct mdss_mdp_ctl *ctl) static u32 __get_min_prefill_line_time_us(struct mdss_mdp_ctl *ctl) { - u32 vbp_min = 0; + u32 vbp_min = UINT_MAX; int i; struct mdss_data_type *mdata; @@ -914,6 +914,9 @@ static u32 __get_min_prefill_line_time_us(struct mdss_mdp_ctl *ctl) } } + if (vbp_min == UINT_MAX) + vbp_min = 0; + return vbp_min; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index 663d63092ebf..5173567a3420 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -1896,7 +1896,6 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_format_params *fmt; struct mdss_data_type *mdata = ctl->mdata; struct dsc_desc *dsc = NULL; - u32 hdmi_dp_core; ctx->ctl = ctl; ctx->intf_type = ctl->intf_type; @@ -2033,10 +2032,19 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, mdp_video_write(ctx, MDSS_MDP_REG_INTF_PANEL_FORMAT, ctl->dst_format); - hdmi_dp_core = (ctx->intf_type == MDSS_INTF_EDP) ? 1 : 0; - - writel_relaxed(hdmi_dp_core, mdata->mdp_base + + /* select HDMI or DP core usage */ + switch (ctx->intf_type) { + case MDSS_INTF_EDP: + writel_relaxed(0x1, mdata->mdp_base + + MDSS_MDP_HDMI_DP_CORE_SELECT); + break; + case MDSS_INTF_HDMI: + writel_relaxed(0x0, mdata->mdp_base + MDSS_MDP_HDMI_DP_CORE_SELECT); + break; + default: + break; + } return 0; } |
