summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-08-16 16:34:52 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-08-16 16:34:51 -0700
commitfdcee0ef0c304574b4707f704c646cdf2901cd86 (patch)
tree43237c858751c7ba8ef6dbafa8d3e28f0521bec4
parentadc801c2ca9a3ff0cbd4ceba755b1d91204049e5 (diff)
parentb62bc857c7e2a3a58e604111200e95db571eaa66 (diff)
Merge "mdss: display-port: add support for edid read"
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c69
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h4
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c79
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.h1
-rw-r--r--drivers/video/fbdev/msm/msm_ext_display.c24
5 files changed, 96 insertions, 81 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index 0ac5ef4f750c..e0dd3f5d5635 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -42,43 +42,6 @@
#define VDDA_UA_ON_LOAD 100000 /* uA units */
#define VDDA_UA_OFF_LOAD 100 /* uA units */
-static char edid_buf1[] = {
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x22, 0xf0, 0x52, 0x29, 0x01, 0x01, 0x01, 0x01,
- 0x16, 0x16, 0x01, 0x03, 0x80, 0x30, 0x1b, 0x78,
- 0x2e, 0xee, 0x95, 0xa3, 0x54, 0x4c, 0x99, 0x26,
- 0x0f, 0x50, 0x54, 0xa1, 0x08, 0x00, 0xd1, 0xc0,
- 0x81, 0xc0, 0xa9, 0xc0, 0xb3, 0x00, 0x95, 0x00,
- 0x81, 0x40, 0x81, 0x80, 0x01, 0x01, 0x02, 0x3a,
- 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
- 0x45, 0x00, 0xdb, 0x0b, 0x11, 0x00, 0x00, 0x1e,
- 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, 0x4c, 0x18,
- 0x5e, 0x11, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x48,
- 0x50, 0x20, 0x5a, 0x52, 0x32, 0x32, 0x34, 0x30,
- 0x77, 0x0a, 0x20, 0x20, 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x43, 0x4e, 0x34, 0x32, 0x32, 0x32, 0x30,
- 0x30, 0x33, 0x46, 0x0a, 0x20, 0x20, 0x01, 0xb1,
-
- 0x02, 0x03, 0x17, 0xb1, 0x4c, 0x90, 0x1f, 0x05,
- 0x14, 0x04, 0x13, 0x03, 0x02, 0x07, 0x06, 0x12,
- 0x01, 0x65, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x02,
- 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58,
- 0x2c, 0x45, 0x00, 0xdb, 0x0b, 0x11, 0x00, 0x00,
- 0x1e, 0x02, 0x3a, 0x80, 0xd0, 0x72, 0x38, 0x2d,
- 0x40, 0x10, 0x2c, 0x45, 0x80, 0xdb, 0x0b, 0x11,
- 0x00, 0x00, 0x1e, 0x01, 0x1d, 0x00, 0x72, 0x51,
- 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00, 0xdb,
- 0x0b, 0x11, 0x00, 0x00, 0x1e, 0x01, 0x1d, 0x00,
- 0xbc, 0x52, 0xd0, 0x1e, 0x20, 0xb8, 0x28, 0x55,
- 0x40, 0xdb, 0x0b, 0x11, 0x00, 0x00, 0x1e, 0x8c,
- 0x0a, 0xd0, 0x8a, 0x20, 0xe0, 0x2d, 0x10, 0x10,
- 0x3e, 0x96, 0x00, 0xdb, 0x0b, 0x11, 0x00, 0x00,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b
-};
-
-
static void mdss_dp_put_dt_clk_data(struct device *dev,
struct dss_module_power *module_power)
{
@@ -945,9 +908,6 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
pr_err("Unabled to start core clocks\n");
return ret;
}
- mdss_dp_phy_reset(&dp_drv->ctrl_io);
- mdss_dp_aux_reset(&dp_drv->ctrl_io);
- mdss_dp_aux_ctrl(&dp_drv->ctrl_io, true);
mdss_dp_hpd_configure(&dp_drv->ctrl_io, true);
orientation = usbpd_get_plug_orientation(dp_drv->pd);
@@ -971,11 +931,6 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
if (dp_drv->new_vic && (dp_drv->new_vic != dp_drv->vic))
dp_init_panel_info(dp_drv, dp_drv->new_vic);
- mdss_dp_phy_aux_setup(&dp_drv->phy_io);
-
- mdss_dp_irq_enable(dp_drv);
- pr_debug("irq enabled\n");
- mdss_dp_dpcd_cap_read(dp_drv);
dp_drv->link_rate =
mdss_dp_gen_link_clk(&dp_drv->panel_data.panel_info,
dp_drv->dpcd.max_lane_count);
@@ -1143,9 +1098,10 @@ static int mdss_dp_edid_init(struct mdss_panel_data *pdata)
return -ENODEV;
}
- /* Use the existing EDID buffer for 1080p */
- memcpy(edid_init_data.buf, edid_buf1, sizeof(edid_buf1));
dp_drv->panel_data.panel_info.edid_data = edid_data;
+ /* initialize EDID buffer pointers */
+ dp_drv->edid_buf = edid_init_data.buf;
+ dp_drv->edid_buf_size = edid_init_data.buf_size;
return 0;
}
@@ -1189,17 +1145,30 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
mdss_dp_get_ctrl_hw_version(&dp_drv->ctrl_io),
mdss_dp_get_phy_hw_version(&dp_drv->phy_io));
+ mdss_dp_phy_aux_setup(&dp_drv->phy_io);
+
+ mdss_dp_irq_enable(dp_drv);
+ pr_debug("irq enabled\n");
+ mdss_dp_dpcd_cap_read(dp_drv);
+
+ ret = mdss_dp_edid_read(dp_drv);
+ if (ret)
+ goto edid_error;
+
+ pr_debug("edid_read success. buf_size=%d\n",
+ dp_drv->edid_buf_size);
+
ret = hdmi_edid_parser(dp_drv->panel_data.panel_info.edid_data);
if (ret) {
DEV_ERR("%s: edid parse failed\n", __func__);
- goto edid_parser_error;
+ goto edid_error;
}
mdss_dp_send_cable_notification(dp_drv, true);
return ret;
-edid_parser_error:
+edid_error:
mdss_dp_clk_ctrl(dp_drv, DP_CORE_PM, false);
clk_error:
mdss_dp_regulator_ctrl(dp_drv, false);
@@ -1422,7 +1391,7 @@ static void mdss_dp_event_work(struct work_struct *work)
switch (todo) {
case EV_EDID_READ:
- mdss_dp_edid_read(dp, 0);
+ mdss_dp_edid_read(dp);
break;
case EV_DPCD_CAP_READ:
mdss_dp_dpcd_cap_read(dp);
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index 03646cd7cc65..a8bb2ab5d343 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -378,6 +378,8 @@ struct mdss_dp_drv_pdata {
char train_link_rate; /* X 27000000 for real rate */
char train_lane_cnt;
+ u8 *edid_buf;
+ u32 edid_buf_size;
struct edp_edid edid;
struct dpcd_cap dpcd;
@@ -464,7 +466,7 @@ void mdss_dp_phy_initialize(struct mdss_dp_drv_pdata *dp);
void mdss_dp_dpcd_cap_read(struct mdss_dp_drv_pdata *dp);
int mdss_dp_dpcd_status_read(struct mdss_dp_drv_pdata *dp);
-void mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp, int block);
+int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp);
int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp);
void dp_aux_i2c_handler(struct mdss_dp_drv_pdata *dp, u32 isr);
void dp_aux_native_handler(struct mdss_dp_drv_pdata *dp, u32 isr);
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index 7b14a7efb9dc..dfba02871649 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -665,7 +665,7 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep)
char data = 0;
for (cnt = 5; cnt; cnt--) {
- ret = dp_aux_write_buf(ep, 0x50, &data, 1, 1);
+ ret = dp_aux_write_buf(ep, EDID_START_ADDRESS, &data, 1, 1);
pr_debug("ret=%d\n", ret);
if (ret >= 0)
break;
@@ -680,43 +680,85 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep)
return 0;
}
-static int dp_sink_edid_read(struct mdss_dp_drv_pdata *ep, int block)
+int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp)
{
struct edp_buf *rp;
int cnt, rlen;
int ret = 0;
+ int blk_num = 0;
- ret = dp_aux_chan_ready(ep);
+ ret = dp_aux_chan_ready(dp);
if (ret) {
pr_err("aux chan NOT ready\n");
return ret;
}
for (cnt = 5; cnt; cnt--) {
- rlen = dp_aux_read_buf(ep, 0x50, 128, 1);
+ rlen = dp_aux_read_buf
+ (dp, EDID_START_ADDRESS, EDID_BLOCK_SIZE, 1);
if (rlen > 0) {
- pr_debug("rlen=%d\n", rlen);
+ pr_debug("cnt=%d, block=%d, rlen=%d\n",
+ cnt, blk_num, rlen);
- rp = &ep->rxp;
+ rp = &dp->rxp;
if (!dp_edid_buf_error(rp->data, rp->len))
break;
}
}
- if (cnt <= 0) {
- pr_err("Failed\n");
+ if ((cnt <= 0) && (rlen != EDID_BLOCK_SIZE)) {
+ pr_err("Read failed. rlen=%d\n", rlen);
return -EINVAL;
}
- dp_extract_edid_manufacturer(&ep->edid, rp->data);
- dp_extract_edid_product(&ep->edid, rp->data);
- dp_extract_edid_version(&ep->edid, rp->data);
- dp_extract_edid_ext_block_cnt(&ep->edid, rp->data);
- dp_extract_edid_video_support(&ep->edid, rp->data);
- dp_extract_edid_feature(&ep->edid, rp->data);
- dp_extract_edid_detailed_timing_description(&ep->edid, rp->data);
+ rp = &dp->rxp;
+
+ dp_extract_edid_manufacturer(&dp->edid, rp->data);
+ dp_extract_edid_product(&dp->edid, rp->data);
+ dp_extract_edid_version(&dp->edid, rp->data);
+ dp_extract_edid_ext_block_cnt(&dp->edid, rp->data);
+ dp_extract_edid_video_support(&dp->edid, rp->data);
+ dp_extract_edid_feature(&dp->edid, rp->data);
+ dp_extract_edid_detailed_timing_description(&dp->edid, rp->data);
+ /* for the first block initialize the edid buffer size */
+ dp->edid_buf_size = 0;
+
+ pr_debug("edid extension = %d\n",
+ dp->edid.ext_block_cnt);
+
+ memcpy(dp->edid_buf, rp->data, EDID_BLOCK_SIZE);
+ dp->edid_buf_size += EDID_BLOCK_SIZE;
+
+ if (!dp->edid.ext_block_cnt)
+ return 0;
- return 128;
+ for (blk_num = 1; blk_num <= dp->edid.ext_block_cnt;
+ blk_num++) {
+ for (cnt = 5; cnt; cnt--) {
+ rlen = dp_aux_read_buf
+ (dp, EDID_START_ADDRESS +
+ (blk_num * EDID_BLOCK_SIZE),
+ EDID_BLOCK_SIZE, 1);
+ if (rlen > 0) {
+ pr_debug("cnt=%d, blk_num=%d, rlen=%d\n",
+ cnt, blk_num, rlen);
+ rp = &dp->rxp;
+ if (!dp_edid_buf_error(rp->data, rp->len))
+ break;
+ }
+ }
+
+ if ((cnt <= 0) && (rlen != EDID_BLOCK_SIZE)) {
+ pr_err("Read failed. rlen=%d\n", rlen);
+ return -EINVAL;
+ }
+
+ memcpy(dp->edid_buf + (blk_num * EDID_BLOCK_SIZE),
+ rp->data, EDID_BLOCK_SIZE);
+ dp->edid_buf_size += EDID_BLOCK_SIZE;
+ }
+
+ return 0;
}
static void dp_sink_capability_read(struct mdss_dp_drv_pdata *ep,
@@ -1357,11 +1399,6 @@ void mdss_dp_fill_link_cfg(struct mdss_dp_drv_pdata *ep)
}
-void mdss_dp_edid_read(struct mdss_dp_drv_pdata *ep, int block)
-{
- dp_sink_edid_read(ep, block);
-}
-
int mdss_dp_link_train(struct mdss_dp_drv_pdata *ep)
{
int ret;
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h
index 8ef00dd7248e..2079dba2a357 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.h
+++ b/drivers/video/fbdev/msm/mdss_dp_util.h
@@ -86,6 +86,7 @@
#define TXn_TX_DRV_LVL 0x001C
#define TCSR_USB3_DP_PHYMODE 0x48
+#define EDID_START_ADDRESS 0x50
struct lane_mapping {
char lane0;
diff --git a/drivers/video/fbdev/msm/msm_ext_display.c b/drivers/video/fbdev/msm/msm_ext_display.c
index 5474df66eefb..a21242870a35 100644
--- a/drivers/video/fbdev/msm/msm_ext_display.c
+++ b/drivers/video/fbdev/msm/msm_ext_display.c
@@ -360,10 +360,13 @@ static int msm_ext_disp_hpd(struct platform_device *pdev,
ext_disp->current_disp = data->type;
} else if ((state == EXT_DISPLAY_CABLE_DISCONNECT) &&
!ext_disp->ack_enabled) {
- ext_disp->ops->audio_info_setup = NULL;
- ext_disp->ops->get_audio_edid_blk = NULL;
- ext_disp->ops->cable_status = NULL;
- ext_disp->ops->get_intf_id = NULL;
+ if (ext_disp->ops) {
+ ext_disp->ops->audio_info_setup = NULL;
+ ext_disp->ops->get_audio_edid_blk = NULL;
+ ext_disp->ops->cable_status = NULL;
+ ext_disp->ops->get_intf_id = NULL;
+ }
+
ext_disp->current_disp = EXT_DISPLAY_TYPE_MAX;
}
@@ -451,7 +454,7 @@ static int msm_ext_disp_notify(struct platform_device *pdev,
if (ret)
goto end;
- if (new_state == EXT_DISPLAY_CABLE_CONNECT) {
+ if (new_state == EXT_DISPLAY_CABLE_CONNECT && ext_disp->ops) {
ext_disp->ops->audio_info_setup =
data->codec_ops.audio_info_setup;
ext_disp->ops->get_audio_edid_blk =
@@ -524,10 +527,13 @@ static int msm_ext_disp_audio_ack(struct platform_device *pdev, u32 ack)
* empty.
*/
if (!ack_hpd) {
- ext_disp->ops->audio_info_setup = NULL;
- ext_disp->ops->get_audio_edid_blk = NULL;
- ext_disp->ops->cable_status = NULL;
- ext_disp->ops->get_intf_id = NULL;
+ if (ext_disp->ops) {
+ ext_disp->ops->audio_info_setup = NULL;
+ ext_disp->ops->get_audio_edid_blk = NULL;
+ ext_disp->ops->cable_status = NULL;
+ ext_disp->ops->get_intf_id = NULL;
+ }
+
ext_disp->current_disp = EXT_DISPLAY_TYPE_MAX;
}