summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAjay Singh Parmar <aparmar@codeaurora.org>2017-01-16 18:08:15 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-01-19 17:01:19 -0800
commit8647848087315ac492f3d43a37c6351972f5cd97 (patch)
treea197a3a99ee5be603500fbadf56f0f0ceffb8cdd
parent28ece3e2f1905b449bc6d5b8a48597af65582435 (diff)
msm: mdss: dp: add support to disable hdcp
For some use cases like running compliance test, it might be necessary to disable hdcp. Add a sysfs node to allow user to take action to enable/disable hdcp for such use cases. Change-Id: I8b9ae6d6d4e750be97fece172f635847ad2e05e4 Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c82
1 files changed, 73 insertions, 9 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index 095a9a6fb44b..f3c36c5c6b5a 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -1877,6 +1877,13 @@ end:
return rc;
}
+static inline bool dp_is_hdcp_enabled(struct mdss_dp_drv_pdata *dp_drv)
+{
+ return dp_drv->hdcp.feature_enabled &&
+ (dp_drv->hdcp.hdcp1_present || dp_drv->hdcp.hdcp2_present) &&
+ dp_drv->hdcp.ops;
+}
+
static void mdss_dp_hdcp_cb_work(struct work_struct *work)
{
struct mdss_dp_drv_pdata *dp;
@@ -1889,6 +1896,13 @@ static void mdss_dp_hdcp_cb_work(struct work_struct *work)
dp = container_of(dw, struct mdss_dp_drv_pdata, hdcp_cb_work);
base = dp->base;
+
+ if (dp->hdcp_status == HDCP_STATE_AUTHENTICATING &&
+ mdss_dp_is_audio_pattern_requested(dp)) {
+ pr_debug("no hdcp for audio tests\n");
+ return;
+ }
+
hdcp_auth_state = (dp_read(base + DP_HDCP_STATUS) >> 20) & 0x3;
pr_debug("hdcp auth state %d\n", hdcp_auth_state);
@@ -2428,6 +2442,50 @@ static ssize_t mdss_dp_rda_frame_crc(struct device *dev,
return ret;
}
+static ssize_t mdss_dp_wta_hdcp_feature(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ u32 hdcp;
+ int rc;
+ ssize_t ret = strnlen(buf, PAGE_SIZE);
+ struct mdss_dp_drv_pdata *dp = mdss_dp_get_drvdata(dev);
+
+ if (!dp) {
+ pr_err("invalid data\n");
+ ret = -EINVAL;
+ goto end;
+ }
+
+ rc = kstrtoint(buf, 10, &hdcp);
+ if (rc) {
+ pr_err("kstrtoint failed. ret=%d\n", rc);
+ ret = rc;
+ goto end;
+ }
+
+ dp->hdcp.feature_enabled = !!hdcp;
+ pr_debug("hdcp=%d\n", dp->hdcp.feature_enabled);
+end:
+ return ret;
+}
+
+static ssize_t mdss_dp_rda_hdcp_feature(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret;
+ struct mdss_dp_drv_pdata *dp = mdss_dp_get_drvdata(dev);
+
+ if (!dp) {
+ pr_err("invalid input\n");
+ return -EINVAL;
+ }
+
+ ret = snprintf(buf, PAGE_SIZE, "%d\n", dp->hdcp.feature_enabled);
+ pr_debug("hdcp: %d\n", dp->hdcp.feature_enabled);
+
+ return ret;
+}
+
static DEVICE_ATTR(connected, S_IRUGO, mdss_dp_rda_connected, NULL);
static DEVICE_ATTR(s3d_mode, S_IRUGO | S_IWUSR, mdss_dp_sysfs_rda_s3d_mode,
mdss_dp_sysfs_wta_s3d_mode);
@@ -2439,6 +2497,8 @@ static DEVICE_ATTR(config, S_IRUGO | S_IWUSR, mdss_dp_rda_config,
mdss_dp_wta_config);
static DEVICE_ATTR(frame_crc, S_IRUGO | S_IWUSR, mdss_dp_rda_frame_crc,
mdss_dp_wta_frame_crc);
+static DEVICE_ATTR(hdcp_feature, S_IRUGO | S_IWUSR, mdss_dp_rda_hdcp_feature,
+ mdss_dp_wta_hdcp_feature);
static struct attribute *mdss_dp_fs_attrs[] = {
&dev_attr_connected.attr,
@@ -2447,6 +2507,7 @@ static struct attribute *mdss_dp_fs_attrs[] = {
&dev_attr_psm.attr,
&dev_attr_config.attr,
&dev_attr_frame_crc.attr,
+ &dev_attr_hdcp_feature.attr,
NULL,
};
@@ -2514,6 +2575,11 @@ static void mdss_dp_update_hdcp_info(struct mdss_dp_drv_pdata *dp)
return;
}
+ if (!dp->hdcp.feature_enabled) {
+ pr_debug("feature not enabled\n");
+ return;
+ }
+
/* check first if hdcp2p2 is supported */
fd = dp->hdcp.hdcp2;
if (fd)
@@ -2543,13 +2609,6 @@ static void mdss_dp_update_hdcp_info(struct mdss_dp_drv_pdata *dp)
}
}
-static inline bool dp_is_hdcp_enabled(struct mdss_dp_drv_pdata *dp_drv)
-{
- return dp_drv->hdcp.feature_enabled &&
- (dp_drv->hdcp.hdcp1_present || dp_drv->hdcp.hdcp2_present) &&
- dp_drv->hdcp.ops;
-}
-
static int mdss_dp_event_handler(struct mdss_panel_data *pdata,
int event, void *arg)
{
@@ -2887,7 +2946,7 @@ irqreturn_t dp_isr(int irq, void *ptr)
dp_aux_native_handler(dp, isr1);
}
- if (dp->hdcp.ops && dp->hdcp.ops->isr) {
+ if (dp_is_hdcp_enabled(dp) && dp->hdcp.ops->isr) {
if (dp->hdcp.ops->isr(dp->hdcp.data))
pr_err("dp_hdcp_isr failed\n");
}
@@ -3188,6 +3247,11 @@ static int mdss_dp_process_audio_pattern_request(struct mdss_dp_drv_pdata *dp)
if (!mdss_dp_is_audio_pattern_requested(dp))
return -EINVAL;
+ if (dp_is_hdcp_enabled(dp) && dp->hdcp.ops->off) {
+ cancel_delayed_work(&dp->hdcp_cb_work);
+ dp->hdcp.ops->off(dp->hdcp.data);
+ }
+
pr_debug("sampling_rate=%s, channel_count=%d, pattern_type=%s\n",
mdss_dp_get_audio_sample_rate(
dp->test_data.test_audio_sampling_rate),
@@ -3438,7 +3502,7 @@ static void mdss_dp_process_attention(struct mdss_dp_drv_pdata *dp_drv)
if (dp_drv->alt_mode.dp_status.hpd_irq) {
pr_debug("Attention: hpd_irq high\n");
- if (dp_drv->hdcp.ops && dp_drv->hdcp.ops->cp_irq) {
+ if (dp_is_hdcp_enabled(dp_drv) && dp_drv->hdcp.ops->cp_irq) {
if (!dp_drv->hdcp.ops->cp_irq(dp_drv->hdcp.data))
return;
}