summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlhad Purnapatre <alhadp@codeaurora.org>2015-02-04 12:23:19 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:37:44 -0700
commit7bc39c66b21a09a06ec6253cd4a4ffc7522900b2 (patch)
tree5725ed479393cd7108321795d9cdc223a6f8165a
parentb8469cfdba8cde3629c6dcf9542769576f664ab0 (diff)
msm: mdss: hdmi: Initialize HDCP2.2 feature irrespective of QFPROM support
The HDCP 2.2 feature was being initialized only if QFPROM keys are present. This is not required for HDCP 2.2, only for 1.4. Instead, added gating for initialization of HDCP 2.2 feature by the version of HDMI Tx controller. HDMI Tx controller version 4.0.0 and above supports HDCP 2.2 auth. Change-Id: I7f2fae06ed09f3fde638faa416c926a038edbd76 Signed-off-by: Alhad Purnapatre <alhadp@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_hdcp.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c11
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c85
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.h2
4 files changed, 61 insertions, 38 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_hdcp.h b/drivers/video/fbdev/msm/mdss_hdmi_hdcp.h
index be162ae0a5ad..4d981df2a8f6 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_hdcp.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_hdcp.h
@@ -33,6 +33,7 @@ struct hdmi_hdcp_init_data {
void (*notify_status)(void *cb_data, enum hdmi_hdcp_state status);
struct hdmi_tx_ddc_ctrl *ddc_ctrl;
u32 phy_addr;
+ u32 hdmi_tx_ver;
};
struct hdmi_hdcp_ops {
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c b/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c
index 6c9d81f067d5..9835b3f5ac16 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c
@@ -32,6 +32,12 @@ static int hdcp2p2_authenticate(void *input);
#define HDCP_SINK_DDC_HDCP2_RXSTATUS 0x70 /* RxStatus, 2 bytes */
#define HDCP_SINK_DDC_HDCP2_READ_MESSAGE 0x80 /* HDCP Tx reads here */
+/*
+ * HDCP 2.2 encryption requires the data encryption block that is present in
+ * HDMI controller version 4.0.0 and above
+ */
+#define MIN_HDMI_TX_MAJOR_VERSION 4
+
struct hdcp2p2_message_map {
int msg_id;
const char *msg_name;
@@ -636,6 +642,11 @@ void *hdmi_hdcp2p2_init(struct hdmi_hdcp_init_data *init_data)
return ERR_PTR(-EINVAL);
}
+ if (init_data->hdmi_tx_ver < MIN_HDMI_TX_MAJOR_VERSION) {
+ DEV_DBG("%s: HDMI Tx does not support HDCP 2.2\n", __func__);
+ return ERR_PTR(-ENODEV);
+ }
+
hdcp2p2_ctrl = kzalloc(sizeof(*hdcp2p2_ctrl), GFP_KERNEL);
if (!hdcp2p2_ctrl) {
DEV_ERR("%s: Out of memory\n", __func__);
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index ff4276131478..0ee27c482307 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -374,7 +374,7 @@ static bool hdmi_tx_is_cea_format(int mode)
static inline bool hdmi_tx_is_hdcp_enabled(struct hdmi_tx_ctrl *hdmi_ctrl)
{
- if (hdmi_ctrl->hdcp_feature_on && hdmi_ctrl->present_hdcp)
+ if (hdmi_ctrl->hdcp_feature_on && hdmi_ctrl->hdcp14_present)
return true;
return false;
@@ -1152,6 +1152,7 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl)
struct hdmi_edid_init_data edid_init_data;
struct hdmi_hdcp_init_data hdcp_init_data;
struct hdmi_cec_init_data cec_init_data;
+ struct resource *res = NULL;
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
@@ -1175,31 +1176,33 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl)
hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID],
hdmi_ctrl->vid_cfg.vic);
- /* Initialize HDCP feature */
- if (hdmi_ctrl->present_hdcp) {
- struct resource *res = NULL;
- res = platform_get_resource_byname(hdmi_ctrl->pdev,
- IORESOURCE_MEM, hdmi_tx_io_name(HDMI_TX_CORE_IO));
- if (!res) {
- DEV_ERR("%s: Error getting HDMI tx core resource\n",
- __func__);
- return -ENODEV;
- }
- hdcp_init_data.phy_addr = res->start;
- hdcp_init_data.core_io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
- hdcp_init_data.qfprom_io =
- &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO];
- hdcp_init_data.mutex = &hdmi_ctrl->mutex;
- hdcp_init_data.sysfs_kobj = hdmi_ctrl->kobj;
- hdcp_init_data.ddc_ctrl = &hdmi_ctrl->ddc_ctrl;
- hdcp_init_data.workq = hdmi_ctrl->workq;
- hdcp_init_data.notify_status = hdmi_tx_hdcp_cb;
- hdcp_init_data.cb_data = (void *)hdmi_ctrl;
+ /* Initialize HDCP features */
+ res = platform_get_resource_byname(hdmi_ctrl->pdev,
+ IORESOURCE_MEM, hdmi_tx_io_name(HDMI_TX_CORE_IO));
+ if (!res) {
+ DEV_ERR("%s: Error getting HDMI tx core resource\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ hdcp_init_data.phy_addr = res->start;
+ hdcp_init_data.core_io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ hdcp_init_data.qfprom_io =
+ &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO];
+ hdcp_init_data.mutex = &hdmi_ctrl->mutex;
+ hdcp_init_data.sysfs_kobj = hdmi_ctrl->kobj;
+ hdcp_init_data.ddc_ctrl = &hdmi_ctrl->ddc_ctrl;
+ hdcp_init_data.workq = hdmi_ctrl->workq;
+ hdcp_init_data.notify_status = hdmi_tx_hdcp_cb;
+ hdcp_init_data.cb_data = (void *)hdmi_ctrl;
+ hdcp_init_data.hdmi_tx_ver = hdmi_ctrl->hdmi_tx_ver;
+
+ /*
+ * Try to initialize both HDCP 1.4 and 2.2 features, decide which one
+ * to use at HPD time
+ */
+ if (hdmi_ctrl->hdcp14_present) {
- /*
- * Initialize both HDCP 1.4 and 2.2 features, decide which one
- * to use at HPD time
- */
hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP] =
hdmi_hdcp_init(&hdcp_init_data);
@@ -1211,17 +1214,21 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl)
hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = NULL;
return -EPERM;
}
+ DEV_DBG("%s: HDCP 1.4 feature initialized\n", __func__);
+ }
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] =
- hdmi_hdcp2p2_init(&hdcp_init_data);
+ hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] =
+ hdmi_hdcp2p2_init(&hdcp_init_data);
- if (IS_ERR_OR_NULL(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2]))
- DEV_WARN("%s: hdmi_hdcp2p2_init failed\n", __func__);
-
- DEV_DBG("%s: HDCP feature initialized\n", __func__);
+ if (IS_ERR_OR_NULL(
+ hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2])) {
+ DEV_WARN("%s: hdmi_hdcp2p2_init failed\n", __func__);
+ hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] = NULL;
+ } else {
+ DEV_DBG("%s: HDCP 2.2 feature initialized\n", __func__);
}
+
/* Initialize CEC feature */
cec_init_data.io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
cec_init_data.sysfs_kobj = hdmi_ctrl->kobj;
@@ -1344,11 +1351,15 @@ static void hdmi_tx_hpd_int_work(struct work_struct *work)
DEV_ERR("%s: Failed to disable ddc power\n", __func__);
/* Figure out HDCP capabilities of sink */
+ hdmi_ctrl->hdcp_ops = NULL;
hdmi_ctrl->hdcp_feature_data =
hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2];
- hdmi_ctrl->hdcp_ops =
- hdmi_hdcp2p2_start(hdmi_ctrl->hdcp_feature_data);
- if (!hdmi_ctrl->hdcp_ops) {
+ if (hdmi_ctrl->hdcp_feature_data)
+ hdmi_ctrl->hdcp_ops =
+ hdmi_hdcp2p2_start(
+ hdmi_ctrl->hdcp_feature_data);
+
+ if (!hdmi_ctrl->hdcp_ops && hdmi_ctrl->hdcp14_present) {
hdmi_ctrl->hdcp_feature_data =
hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP];
hdmi_ctrl->hdcp_ops =
@@ -1398,10 +1409,10 @@ static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl)
}
if (hdcp_disabled) {
- hdmi_ctrl->present_hdcp = 0;
+ hdmi_ctrl->hdcp14_present = 0;
DEV_WARN("%s: HDCP disabled\n", __func__);
} else {
- hdmi_ctrl->present_hdcp = 1;
+ hdmi_ctrl->hdcp14_present = 1;
DEV_DBG("%s: Device is HDCP enabled\n", __func__);
}
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.h b/drivers/video/fbdev/msm/mdss_hdmi_tx.h
index b73580a56d12..6c10da4aaff3 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.h
@@ -168,7 +168,7 @@ struct hdmi_tx_ctrl {
bool hdcp_feature_on;
bool hpd_disabled;
bool ds_registered;
- u32 present_hdcp;
+ u32 hdcp14_present;
u8 spd_vendor_name[9];
u8 spd_product_description[17];