diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2016-08-16 16:34:52 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-08-16 16:34:51 -0700 |
commit | fdcee0ef0c304574b4707f704c646cdf2901cd86 (patch) | |
tree | 43237c858751c7ba8ef6dbafa8d3e28f0521bec4 | |
parent | adc801c2ca9a3ff0cbd4ceba755b1d91204049e5 (diff) | |
parent | b62bc857c7e2a3a58e604111200e95db571eaa66 (diff) |
Merge "mdss: display-port: add support for edid read"
-rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.c | 69 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.h | 4 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_aux.c | 79 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_util.h | 1 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/msm_ext_display.c | 24 |
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; } |