summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-09-20 10:20:40 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-09-20 10:20:40 -0700
commit329685a0d5003c58dc3ec3aec53a48e33bcd2aea (patch)
tree200e41f4ddb0402217885f96f68d1b4fbfe9462b
parente687086cb2bb24997c2cfdb3b81b39e38d68200d (diff)
parentf0b8cc92837076eb5ff43e70f7ae536bf45cea3b (diff)
Merge "msm: mdss: make hdcp 1.x data part of fb panel"
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c12
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c8
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_hdcp_1x.c91
-rw-r--r--drivers/video/fbdev/msm/mdss_hdcp_1x.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_panel.c69
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_panel.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c11
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_util.c68
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_util.h4
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h1
11 files changed, 152 insertions, 118 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index f8e34fed4730..57e18a7dc5e1 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -1398,6 +1398,8 @@ static int mdss_dp_hdcp_init(struct mdss_panel_data *pdata)
goto error;
}
+ dp_drv->panel_data.panel_info.hdcp_1x_data = dp_drv->hdcp_data;
+
pr_debug("HDCP 1.3 initialized\n");
dp_drv->hdcp_ops = hdcp_1x_start(dp_drv->hdcp_data);
@@ -1778,7 +1780,7 @@ irqreturn_t dp_isr(int irq, void *ptr)
{
struct mdss_dp_drv_pdata *dp = (struct mdss_dp_drv_pdata *)ptr;
unsigned char *base = dp->base;
- u32 isr1, isr2, mask1, mask2;
+ u32 isr1, isr2, mask1;
u32 ack;
spin_lock(&dp->lock);
@@ -1786,13 +1788,11 @@ irqreturn_t dp_isr(int irq, void *ptr)
isr2 = dp_read(base + DP_INTR_STATUS2);
mask1 = isr1 & dp->mask1;
- mask2 = isr2 & dp->mask2;
isr1 &= ~mask1; /* remove masks bit */
- isr2 &= ~mask2;
- pr_debug("isr=%x mask=%x isr2=%x mask2=%x\n",
- isr1, mask1, isr2, mask2);
+ pr_debug("isr=%x mask=%x isr2=%x\n",
+ isr1, mask1, isr2);
ack = isr1 & EDP_INTR_STATUS1;
ack <<= 1; /* ack bits */
@@ -1801,7 +1801,7 @@ irqreturn_t dp_isr(int irq, void *ptr)
ack = isr2 & EDP_INTR_STATUS2;
ack <<= 1; /* ack bits */
- ack |= mask2;
+ ack |= isr2;
dp_write(base + DP_INTR_STATUS2, ack);
spin_unlock(&dp->lock);
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index 0bbcd0c9041e..584d2edc364e 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -230,7 +230,9 @@ static int dp_aux_write_cmds(struct mdss_dp_drv_pdata *ep,
int dp_aux_write(void *ep, struct edp_cmd *cmd)
{
- return dp_aux_write_cmds(ep, cmd);
+ int rc = dp_aux_write_cmds(ep, cmd);
+
+ return rc < 0 ? -EINVAL : 0;
}
static int dp_aux_read_cmds(struct mdss_dp_drv_pdata *ep,
@@ -291,7 +293,9 @@ static int dp_aux_read_cmds(struct mdss_dp_drv_pdata *ep,
int dp_aux_read(void *ep, struct edp_cmd *cmds)
{
- return dp_aux_read_cmds(ep, cmds);
+ int rc = dp_aux_read_cmds(ep, cmds);
+
+ return rc < 0 ? -EINVAL : 0;
}
void dp_aux_native_handler(struct mdss_dp_drv_pdata *ep, u32 isr)
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h
index a9aff5373a2a..5eb9d092476f 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.h
+++ b/drivers/video/fbdev/msm/mdss_dp_util.h
@@ -183,8 +183,6 @@
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA11 (0x01C)
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA12 (0x020)
-#define DP_INTERRUPT_STATUS_2 (0x024)
-
struct lane_mapping {
char lane0;
char lane1;
diff --git a/drivers/video/fbdev/msm/mdss_hdcp_1x.c b/drivers/video/fbdev/msm/mdss_hdcp_1x.c
index 7f26007fab13..5b490ad67e65 100644
--- a/drivers/video/fbdev/msm/mdss_hdcp_1x.c
+++ b/drivers/video/fbdev/msm/mdss_hdcp_1x.c
@@ -19,6 +19,7 @@
#include <soc/qcom/scm.h>
#include <linux/hdcp_qseecom.h>
#include "mdss_hdcp_1x.h"
+#include "mdss_fb.h"
#include "mdss_dp_util.h"
#include "video/msm_hdmi_hdcp_mgr.h"
@@ -41,14 +42,14 @@
#define HDCP_INT_CLR (isr->auth_success_ack | isr->auth_fail_ack | \
isr->auth_fail_info_ack | isr->tx_req_ack | \
isr->encryption_ready_ack | \
- isr->encryption_not_ready | isr->tx_req_done_ack)
+ isr->encryption_not_ready_ack | isr->tx_req_done_ack)
#define HDCP_INT_EN (isr->auth_success_mask | isr->auth_fail_mask | \
isr->encryption_ready_mask | \
isr->encryption_not_ready_mask)
#define HDCP_POLL_SLEEP_US (20 * 1000)
-#define HDCP_POLL_TIMEOUT_US (HDCP_POLL_SLEEP_US * 1000)
+#define HDCP_POLL_TIMEOUT_US (HDCP_POLL_SLEEP_US * 100)
#define reg_set_data(x) \
(hdcp_ctrl->init_data.sec_access ? reg_set->sec_data##x : \
@@ -198,15 +199,15 @@ struct hdcp_reg_set {
{{"bcaps", 0x40, 1}, {"bksv", 0x00, 5}, {"r0'", 0x08, 2}, \
{"bstatus", 0x41, 2}, {"ksv-fifo", 0x43, 0}, {"v_h0", 0x20, 4}, \
{"v_h1", 0x24, 4}, {"v_h2", 0x28, 4}, {"v_h3", 0x2c, 4}, \
- {"v_h4", 0x30, 4}, {"an", 0x16, 8}, {"aksv", 0x10, 5}, \
- {"repater", 0x00, 0} }
+ {"v_h4", 0x30, 4}, {"an", 0x18, 8}, {"aksv", 0x10, 5}, \
+ {"repeater", 0x00, 0} }
#define HDCP_DP_SINK_ADDR_MAP \
{{"bcaps", 0x68028, 1}, {"bksv", 0x68000, 5}, {"r0'", 0x68005, 2}, \
{"bstatus", 0x6802A, 2}, {"ksv-fifo", 0x6802A, 0}, \
{"v_h0", 0x68014, 4}, {"v_h1", 0x68018, 4}, {"v_h2", 0x6801C, 4}, \
{"v_h3", 0x68020, 4}, {"v_h4", 0x68024, 4}, {"an", 0x6800C, 8}, \
- {"aksv", 0x68007, 5}, {"repater", 0x68028, 1} }
+ {"aksv", 0x68007, 5}, {"repeater", 0x68028, 1} }
#define HDCP_HDMI_INT_SET \
{HDMI_HDCP_INT_CTRL, \
@@ -215,7 +216,7 @@ struct hdcp_reg_set {
BIT(0), BIT(4), 0, 0, 0, 0}
#define HDCP_DP_INT_SET \
- {DP_INTERRUPT_STATUS_2, \
+ {DP_INTR_STATUS2, \
BIT(17), BIT(20), BIT(24), BIT(27), 0, 0, \
BIT(16), BIT(19), BIT(21), BIT(23), BIT(26), 0, 0, \
BIT(15), BIT(18), BIT(22), BIT(25), 0, 0}
@@ -554,7 +555,7 @@ static int hdcp_1x_read(struct hdcp_1x_ctrl *hdcp_ctrl,
cmd.out_buf = buf;
cmd.len = sink->len;
- rc = dp_aux_read(hdcp_ctrl->init_data.dp_data, &cmd);
+ rc = dp_aux_read(hdcp_ctrl->init_data.cb_data, &cmd);
if (rc)
DEV_ERR("%s: %s: %s read failed\n", __func__,
HDCP_STATE_NAME, sink->name);
@@ -564,7 +565,7 @@ static int hdcp_1x_read(struct hdcp_1x_ctrl *hdcp_ctrl,
}
static int hdcp_1x_write(struct hdcp_1x_ctrl *hdcp_ctrl,
- u32 offset, u32 len, u8 *buf, char *name)
+ struct hdcp_sink_addr *sink, u8 *buf)
{
int rc = 0;
struct hdmi_tx_ddc_data ddc_data;
@@ -573,28 +574,28 @@ static int hdcp_1x_write(struct hdcp_1x_ctrl *hdcp_ctrl,
memset(&ddc_data, 0, sizeof(ddc_data));
ddc_data.dev_addr = 0x74;
- ddc_data.offset = offset;
+ ddc_data.offset = sink->addr;
ddc_data.data_buf = buf;
- ddc_data.data_len = len;
- ddc_data.what = name;
+ ddc_data.data_len = sink->len;
+ ddc_data.what = sink->name;
hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;
rc = hdmi_ddc_write(hdcp_ctrl->init_data.ddc_ctrl);
if (rc)
DEV_ERR("%s: %s: %s write failed\n", __func__,
- HDCP_STATE_NAME, name);
+ HDCP_STATE_NAME, sink->name);
} else if (IS_ENABLED(CONFIG_FB_MSM_MDSS_DP_PANEL) &&
hdcp_ctrl->init_data.client_id == HDCP_CLIENT_DP) {
struct edp_cmd cmd = {0};
- cmd.addr = offset;
- cmd.len = len;
+ cmd.addr = sink->addr;
+ cmd.len = sink->len;
cmd.datap = buf;
- rc = dp_aux_write(hdcp_ctrl->init_data.dp_data, &cmd);
+ rc = dp_aux_write(hdcp_ctrl->init_data.cb_data, &cmd);
if (rc)
DEV_ERR("%s: %s: %s read failed\n", __func__,
- HDCP_STATE_NAME, name);
+ HDCP_STATE_NAME, sink->name);
}
return rc;
@@ -731,7 +732,7 @@ static int hdcp_1x_authentication_part1(struct hdcp_1x_ctrl *hdcp_ctrl)
link0_an_1 = DSS_REG_R(io, reg_set->data6);
if (hdcp_ctrl->init_data.client_id == HDCP_CLIENT_DP) {
udelay(1);
- link0_an_0 = DSS_REG_R(io, reg_set->data6);
+ link0_an_1 = DSS_REG_R(io, reg_set->data6);
}
/* Read AKSV */
@@ -754,13 +755,13 @@ static int hdcp_1x_authentication_part1(struct hdcp_1x_ctrl *hdcp_ctrl)
an[6] = (link0_an_1 >> 16) & 0xFF;
an[7] = (link0_an_1 >> 24) & 0xFF;
- rc = hdcp_1x_write(hdcp_ctrl, 0x18, 8, an, "an");
+ rc = hdcp_1x_write(hdcp_ctrl, &hdcp_ctrl->sink_addr.an, an);
if (IS_ERR_VALUE(rc)) {
DEV_ERR("%s: error writing an to sink\n", __func__);
goto error;
}
- rc = hdcp_1x_write(hdcp_ctrl, 0x10, 5, aksv, "aksv");
+ rc = hdcp_1x_write(hdcp_ctrl, &hdcp_ctrl->sink_addr.aksv, aksv);
if (IS_ERR_VALUE(rc)) {
DEV_ERR("%s: error writing aksv to sink\n", __func__);
goto error;
@@ -1325,10 +1326,12 @@ static void hdcp_1x_auth_work(struct work_struct *work)
}
io = hdcp_ctrl->init_data.core_io;
- /* Enabling Software DDC */
+ /* Enabling Software DDC for HDMI and REF timer for DP */
if (hdcp_ctrl->init_data.client_id == HDCP_CLIENT_HDMI)
DSS_REG_W_ND(io, HDMI_DDC_ARBITRATION, DSS_REG_R(io,
HDMI_DDC_ARBITRATION) & ~(BIT(4)));
+ else if (hdcp_ctrl->init_data.client_id == HDCP_CLIENT_DP)
+ DSS_REG_W(io, DP_DP_HPD_REFTIMER, 0x10013);
rc = hdcp_1x_authentication_part1(hdcp_ctrl);
if (rc) {
@@ -1628,12 +1631,45 @@ error:
return rc;
} /* hdcp_1x_isr */
+static struct hdcp_1x_ctrl *hdcp_1x_get_ctrl(struct device *dev)
+{
+ struct fb_info *fbi;
+ struct msm_fb_data_type *mfd;
+ struct mdss_panel_info *pinfo;
+
+ if (!dev) {
+ pr_err("invalid input\n");
+ goto error;
+ }
+
+ fbi = dev_get_drvdata(dev);
+ if (!fbi) {
+ pr_err("invalid fbi\n");
+ goto error;
+ }
+
+ mfd = fbi->par;
+ if (!mfd) {
+ pr_err("invalid mfd\n");
+ goto error;
+ }
+
+ pinfo = mfd->panel_info;
+ if (!pinfo) {
+ pr_err("invalid pinfo\n");
+ goto error;
+ }
+
+ return pinfo->hdcp_1x_data;
+
+error:
+ return NULL;
+}
static ssize_t hdcp_1x_sysfs_rda_status(struct device *dev,
struct device_attribute *attr, char *buf)
{
ssize_t ret;
- struct hdcp_1x_ctrl *hdcp_ctrl =
- hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP);
+ struct hdcp_1x_ctrl *hdcp_ctrl = hdcp_1x_get_ctrl(dev);
if (!hdcp_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
@@ -1652,8 +1688,7 @@ static ssize_t hdcp_1x_sysfs_rda_tp(struct device *dev,
struct device_attribute *attr, char *buf)
{
ssize_t ret = 0;
- struct hdcp_1x_ctrl *hdcp_ctrl =
- hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP);
+ struct hdcp_1x_ctrl *hdcp_ctrl = hdcp_1x_get_ctrl(dev);
if (!hdcp_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
@@ -1687,8 +1722,7 @@ static ssize_t hdcp_1x_sysfs_wta_tp(struct device *dev,
{
int msgid = 0;
ssize_t ret = count;
- struct hdcp_1x_ctrl *hdcp_ctrl =
- hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP);
+ struct hdcp_1x_ctrl *hdcp_ctrl = hdcp_1x_get_ctrl(dev);
if (!hdcp_ctrl || !buf) {
DEV_ERR("%s: invalid input\n", __func__);
@@ -1774,9 +1808,8 @@ void *hdcp_1x_init(struct hdcp_init_data *init_data)
};
if (!init_data || !init_data->core_io || !init_data->qfprom_io ||
- !init_data->mutex || !init_data->ddc_ctrl ||
- !init_data->notify_status || !init_data->workq ||
- !init_data->cb_data) {
+ !init_data->mutex || !init_data->notify_status ||
+ !init_data->workq || !init_data->cb_data) {
DEV_ERR("%s: invalid input\n", __func__);
goto error;
}
diff --git a/drivers/video/fbdev/msm/mdss_hdcp_1x.h b/drivers/video/fbdev/msm/mdss_hdcp_1x.h
index dbe91b459a9f..426b13a340f4 100644
--- a/drivers/video/fbdev/msm/mdss_hdcp_1x.h
+++ b/drivers/video/fbdev/msm/mdss_hdcp_1x.h
@@ -42,7 +42,6 @@ struct hdcp_init_data {
void *cb_data;
void (*notify_status)(void *cb_data, enum hdcp_states status);
struct hdmi_tx_ddc_ctrl *ddc_ctrl;
- void *dp_data;
u32 phy_addr;
u32 hdmi_tx_ver;
struct msm_hdmi_mode_timing_info *timing;
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_panel.c b/drivers/video/fbdev/msm/mdss_hdmi_panel.c
index 0335bf900866..522debfba8ce 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.c
@@ -150,74 +150,6 @@ enum hdmi_scaling_info {
HDMI_SCALING_HORZ_VERT,
};
-int hdmi_panel_get_vic(struct mdss_panel_info *pinfo,
- struct hdmi_util_ds_data *ds_data)
-{
- int new_vic = -1;
- u32 h_total, v_total;
- struct msm_hdmi_mode_timing_info timing;
-
- if (!pinfo) {
- pr_err("invalid panel data\n");
- return -EINVAL;
- }
-
- if (pinfo->vic) {
- struct msm_hdmi_mode_timing_info info = {0};
- u32 ret = hdmi_get_supported_mode(&info, ds_data, pinfo->vic);
- u32 supported = info.supported;
-
- if (!ret && supported) {
- new_vic = pinfo->vic;
- } else {
- pr_err("invalid or not supported vic %d\n",
- pinfo->vic);
- return -EPERM;
- }
- } else {
- timing.active_h = pinfo->xres;
- timing.back_porch_h = pinfo->lcdc.h_back_porch;
- timing.front_porch_h = pinfo->lcdc.h_front_porch;
- timing.pulse_width_h = pinfo->lcdc.h_pulse_width;
-
- h_total = timing.active_h + timing.back_porch_h +
- timing.front_porch_h + timing.pulse_width_h;
-
- pr_debug("ah=%d bph=%d fph=%d pwh=%d ht=%d\n",
- timing.active_h, timing.back_porch_h,
- timing.front_porch_h, timing.pulse_width_h,
- h_total);
-
- timing.active_v = pinfo->yres;
- timing.back_porch_v = pinfo->lcdc.v_back_porch;
- timing.front_porch_v = pinfo->lcdc.v_front_porch;
- timing.pulse_width_v = pinfo->lcdc.v_pulse_width;
-
- v_total = timing.active_v + timing.back_porch_v +
- timing.front_porch_v + timing.pulse_width_v;
-
- pr_debug("av=%d bpv=%d fpv=%d pwv=%d vt=%d\n",
- timing.active_v, timing.back_porch_v,
- timing.front_porch_v, timing.pulse_width_v, v_total);
-
- timing.pixel_freq = ((unsigned long int)pinfo->clk_rate / 1000);
- if (h_total && v_total) {
- timing.refresh_rate = ((timing.pixel_freq * 1000) /
- (h_total * v_total)) * 1000;
- } else {
- pr_err("cannot cal refresh rate\n");
- return -EPERM;
- }
-
- pr_debug("pixel_freq=%d refresh_rate=%d\n",
- timing.pixel_freq, timing.refresh_rate);
-
- new_vic = hdmi_get_video_id_code(&timing, ds_data);
- }
-
- return new_vic;
-}
-
static void hdmi_panel_update_dfps_data(struct hdmi_panel *panel)
{
struct mdss_panel_info *pinfo = panel->data->pinfo;
@@ -916,7 +848,6 @@ void *hdmi_panel_init(struct hdmi_panel_init_data *data)
if (data->ops) {
data->ops->on = hdmi_panel_power_on;
data->ops->off = hdmi_panel_power_off;
- data->ops->get_vic = hdmi_panel_get_vic;
data->ops->vendor = hdmi_panel_set_vendor_specific_infoframe;
data->ops->update_fps = hdmi_panel_update_fps;
}
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_panel.h b/drivers/video/fbdev/msm/mdss_hdmi_panel.h
index e5cc1486f222..6fa9af13d46e 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_panel.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.h
@@ -48,15 +48,12 @@ struct hdmi_panel_data {
* @off: pointer to a function which powers off the panel
* @vendor: pointer to a function which programs vendor specific infoframe
* @update_fps: pointer to a function which updates fps
- * @get_vic: pointer to a function which get the vic from panel information.
*/
struct hdmi_panel_ops {
int (*on)(void *input);
int (*off)(void *input);
void (*vendor)(void *input);
int (*update_fps)(void *input, u32 fps);
- int (*get_vic)(struct mdss_panel_info *pinfo,
- struct hdmi_util_ds_data *ds_data);
};
/**
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index 37081e5e4a0b..ace796163fa4 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -1814,6 +1814,8 @@ static int hdmi_tx_init_hdcp(struct hdmi_tx_ctrl *hdmi_ctrl)
goto end;
} else {
hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP, hdcp_data);
+ hdmi_ctrl->panel_data.panel_info.hdcp_1x_data =
+ hdcp_data;
DEV_DBG("%s: HDCP 1.4 initialized\n", __func__);
}
}
@@ -3115,9 +3117,8 @@ static int hdmi_tx_power_on(struct hdmi_tx_ctrl *hdmi_ctrl)
void *pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
void *edata = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID);
- if (hdmi_ctrl->panel_ops.get_vic)
- hdmi_ctrl->vic = hdmi_ctrl->panel_ops.get_vic(
- &panel_data->panel_info, &hdmi_ctrl->ds_data);
+ hdmi_panel_get_vic(&panel_data->panel_info,
+ &hdmi_ctrl->ds_data);
if (hdmi_ctrl->vic <= 0) {
DEV_ERR("%s: invalid vic\n", __func__);
@@ -3703,9 +3704,7 @@ static int hdmi_tx_evt_handle_check_param(struct hdmi_tx_ctrl *hdmi_ctrl)
int new_vic = -1;
int rc = 0;
- if (hdmi_ctrl->panel_ops.get_vic)
- new_vic = hdmi_ctrl->panel_ops.get_vic(
- hdmi_ctrl->evt_arg, &hdmi_ctrl->ds_data);
+ new_vic = hdmi_panel_get_vic(hdmi_ctrl->evt_arg, &hdmi_ctrl->ds_data);
if ((new_vic < 0) || (new_vic > HDMI_VFRMT_MAX)) {
DEV_ERR("%s: invalid or not supported vic\n", __func__);
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_util.c b/drivers/video/fbdev/msm/mdss_hdmi_util.c
index 555ba1ba5b1c..9ed909e9a387 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_util.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_util.c
@@ -33,6 +33,74 @@ enum trigger_mode {
TRIGGER_READ
};
+int hdmi_panel_get_vic(struct mdss_panel_info *pinfo,
+ struct hdmi_util_ds_data *ds_data)
+{
+ int new_vic = -1;
+ u32 h_total, v_total;
+ struct msm_hdmi_mode_timing_info timing;
+
+ if (!pinfo) {
+ pr_err("invalid panel data\n");
+ return -EINVAL;
+ }
+
+ if (pinfo->vic) {
+ struct msm_hdmi_mode_timing_info info = {0};
+ u32 ret = hdmi_get_supported_mode(&info, ds_data, pinfo->vic);
+ u32 supported = info.supported;
+
+ if (!ret && supported) {
+ new_vic = pinfo->vic;
+ } else {
+ pr_err("invalid or not supported vic %d\n",
+ pinfo->vic);
+ return -EPERM;
+ }
+ } else {
+ timing.active_h = pinfo->xres;
+ timing.back_porch_h = pinfo->lcdc.h_back_porch;
+ timing.front_porch_h = pinfo->lcdc.h_front_porch;
+ timing.pulse_width_h = pinfo->lcdc.h_pulse_width;
+
+ h_total = timing.active_h + timing.back_porch_h +
+ timing.front_porch_h + timing.pulse_width_h;
+
+ pr_debug("ah=%d bph=%d fph=%d pwh=%d ht=%d\n",
+ timing.active_h, timing.back_porch_h,
+ timing.front_porch_h, timing.pulse_width_h,
+ h_total);
+
+ timing.active_v = pinfo->yres;
+ timing.back_porch_v = pinfo->lcdc.v_back_porch;
+ timing.front_porch_v = pinfo->lcdc.v_front_porch;
+ timing.pulse_width_v = pinfo->lcdc.v_pulse_width;
+
+ v_total = timing.active_v + timing.back_porch_v +
+ timing.front_porch_v + timing.pulse_width_v;
+
+ pr_debug("av=%d bpv=%d fpv=%d pwv=%d vt=%d\n",
+ timing.active_v, timing.back_porch_v,
+ timing.front_porch_v, timing.pulse_width_v, v_total);
+
+ timing.pixel_freq = ((unsigned long int)pinfo->clk_rate / 1000);
+ if (h_total && v_total) {
+ timing.refresh_rate = ((timing.pixel_freq * 1000) /
+ (h_total * v_total)) * 1000;
+ } else {
+ pr_err("cannot cal refresh rate\n");
+ return -EPERM;
+ }
+
+ pr_debug("pixel_freq=%d refresh_rate=%d\n",
+ timing.pixel_freq, timing.refresh_rate);
+
+ new_vic = hdmi_get_video_id_code(&timing, ds_data);
+ }
+
+ return new_vic;
+}
+
int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing,
u32 timeout_ms)
{
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_util.h b/drivers/video/fbdev/msm/mdss_hdmi_util.h
index ceb171417822..e65cf915fe92 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_util.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_util.h
@@ -15,6 +15,8 @@
#include <linux/mdss_io_util.h>
#include "video/msm_hdmi_modes.h"
+#include "mdss_panel.h"
+
/* HDMI_TX Registers */
#define HDMI_CTRL (0x00000000)
#define HDMI_TEST_PATTERN (0x00000010)
@@ -489,6 +491,8 @@ const char *msm_hdmi_mode_2string(u32 mode);
int hdmi_set_resv_timing_info(struct msm_hdmi_mode_timing_info *mode);
bool hdmi_is_valid_resv_timing(int mode);
void hdmi_reset_resv_timing_info(void);
+int hdmi_panel_get_vic(struct mdss_panel_info *pinfo,
+ struct hdmi_util_ds_data *ds_data);
/* todo: Fix this. Right now this is defined in mdss_hdmi_tx.c */
void *hdmi_get_featuredata_from_sysfs_dev(struct device *device, u32 type);
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index 81b6fa7d35b3..b2b647dcc017 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -688,6 +688,7 @@ struct mdss_panel_info {
void *edid_data;
void *dba_data;
void *cec_data;
+ void *hdcp_1x_data;
char panel_name[MDSS_MAX_PANEL_LEN];
struct mdss_mdp_pp_tear_check te;