summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c13
-rw-r--r--drivers/misc/hdcp.c3
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c27
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c126
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c5
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_video.c16
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;
}