diff options
| author | zhaoyuan <yzhao@codeaurora.org> | 2017-04-18 15:09:16 +0800 |
|---|---|---|
| committer | zhaoyuan <yzhao@codeaurora.org> | 2017-05-05 15:29:53 +0800 |
| commit | 1db7368215726ef98d483ffdf8f542efe4d35493 (patch) | |
| tree | 6e13516e772af523c7619e3deaf36ba86b3a869c /drivers/video/fbdev/msm | |
| parent | baf0fa8f1ed33c6961353e951ed5b6e03e3ed6fd (diff) | |
msm: mdss: set HDMI max TMDS clock rate
Need consider both SINK and SOURCE max supported TMDS
clock. For the devices, if we set TMDS clock larger than
device caps, it could not display well. SINK max TMDS
clock could read from HDMI VSDB and HF-VSDB in EDID.
CRs-Fixed: 2035529
Change-Id: I1f31f2a05d0502367b877c4d324cbc131b2366d5
Signed-off-by: zhaoyuan <yzhao@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev/msm')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_edid.c | 42 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_edid.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.c | 8 |
3 files changed, 48 insertions, 3 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.c b/drivers/video/fbdev/msm/mdss_hdmi_edid.c index 599f6cb44c63..102c22cba7dd 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.c @@ -1283,6 +1283,7 @@ static void hdmi_edid_extract_speaker_allocation_data( static void hdmi_edid_extract_sink_caps(struct hdmi_edid_ctrl *edid_ctrl, const u8 *in_buf) { + u8 len; const u8 *vsd = NULL; if (!edid_ctrl) { @@ -1297,13 +1298,29 @@ static void hdmi_edid_extract_sink_caps(struct hdmi_edid_ctrl *edid_ctrl, edid_ctrl->basic_audio_supp = false; pr_debug("%s: basic audio supported: %s\n", __func__, edid_ctrl->basic_audio_supp ? "true" : "false"); + vsd = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, + VENDOR_SPECIFIC_DATA_BLOCK, &len); + + if (vsd == NULL || len == 0 || len > MAX_DATA_BLOCK_SIZE) + return; + + /* Max TMDS clock is in multiples of 5Mhz. */ + edid_ctrl->sink_caps.max_pclk_in_hz = vsd[7] * 5000000; vsd = hdmi_edid_find_hfvsdb(in_buf); if (vsd) { - /* Max pixel clock is in multiples of 5Mhz. */ - edid_ctrl->sink_caps.max_pclk_in_hz = - vsd[5]*5000000; + /* + * HF-VSDB define larger TMDS clock than VSDB. If sink + * supports TMDS Character Rates > 340M, the sink shall + * set Max_TMDS_Character_Rates appropriately and non-zero. + * Or, if sink dose not support TMDS Character Rates > 340M, + * the sink shall set this filed to 0. The max TMDS support + * clock Rate = Max_TMDS_Character_Rates * 5Mhz. + */ + if (vsd[5] != 0) + edid_ctrl->sink_caps.max_pclk_in_hz = + vsd[5] * 5000000; edid_ctrl->sink_caps.scdc_present = (vsd[6] & 0x80) ? true : false; edid_ctrl->sink_caps.scramble_support = @@ -2425,6 +2442,25 @@ bool hdmi_edid_is_dvi_mode(void *input) } /** + * hdmi_edid_get_sink_caps_max_tmds_clk() - get max tmds clock supported. + * Sink side's limitation should be concerned as well. + * @input: edid parser data + * + * Return: max tmds clock + */ +u32 hdmi_edid_get_sink_caps_max_tmds_clk(void *input) +{ + struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input; + + if (!edid_ctrl) { + DEV_ERR("%s: invalid input\n", __func__); + return 0; + } + + return edid_ctrl->sink_caps.max_pclk_in_hz; +} + +/** * hdmi_edid_get_deep_color() - get deep color info supported by sink * @input: edid parser data * diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.h b/drivers/video/fbdev/msm/mdss_hdmi_edid.h index 557e9326a81d..af802bb45f89 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.h @@ -81,5 +81,6 @@ void hdmi_edid_config_override(void *input, bool enable, struct hdmi_edid_override_data *data); void hdmi_edid_set_max_pclk_rate(void *input, u32 max_pclk_khz); bool hdmi_edid_is_audio_supported(void *input); +u32 hdmi_edid_get_sink_caps_max_tmds_clk(void *input); #endif /* __HDMI_EDID_H__ */ diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index 42845f9ff192..8fa229aaa174 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -2224,6 +2224,14 @@ static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl) status = hdmi_edid_parser(data); if (status) DEV_ERR("%s: edid parse failed\n", __func__); + else + /* + * Updata HDMI max supported TMDS clock, consider + * both sink and source capicity. + */ + hdmi_edid_set_max_pclk_rate(data, + min(hdmi_edid_get_sink_caps_max_tmds_clk(data) / 1000, + hdmi_ctrl->max_pclk_khz)); } bail: if (hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_DDC_PM, false)) |
