diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-10-11 11:35:22 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-10-11 11:35:22 -0700 |
| commit | c30ea8b0c1b1fca497ffacc41e5b3ecfc8a6933e (patch) | |
| tree | da6137fd568c5a252297746b39a10882fd505e1c /drivers/video/fbdev | |
| parent | ae7908ba2269cc465298a001385f0d37949b1ad3 (diff) | |
| parent | a03fd4699aa9bc709551f20055ea3240044cef0d (diff) | |
Merge "msm: mdss: edid: parse dtd and proper fps and pclk check"
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_edid.c | 170 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_util.c | 17 |
2 files changed, 88 insertions, 99 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.c b/drivers/video/fbdev/msm/mdss_hdmi_edid.c index 4f1435d006b2..2047a047b537 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.c @@ -698,7 +698,6 @@ static ssize_t hdmi_edid_sysfs_rda_3d_modes(struct device *dev, } } - DEV_DBG("%s: '%s'\n", __func__, buf); ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n"); return ret; @@ -1567,7 +1566,9 @@ static void hdmi_edid_detail_desc(struct hdmi_edid_ctrl *edid_ctrl, frame_data = (active_h + blank_h) * (active_v + blank_v); if (frame_data) { - int refresh_rate_khz = (pixel_clk * khz_to_hz) / frame_data; + u64 refresh_rate = (u64)pixel_clk * khz_to_hz * khz_to_hz; + + do_div(refresh_rate, frame_data); timing.active_h = active_h; timing.front_porch_h = front_porch_h; @@ -1582,19 +1583,24 @@ static void hdmi_edid_detail_desc(struct hdmi_edid_ctrl *edid_ctrl, (front_porch_v + pulse_width_v); timing.active_low_v = active_low_v; timing.pixel_freq = pixel_clk; - timing.refresh_rate = refresh_rate_khz * khz_to_hz; + timing.refresh_rate = refresh_rate; timing.interlaced = interlaced; timing.supported = true; timing.ar = aspect_ratio_4_3 ? HDMI_RES_AR_4_3 : (aspect_ratio_5_4 ? HDMI_RES_AR_5_4 : HDMI_RES_AR_16_9); - DEV_DBG("%s: new res: %dx%d%s@%dHz\n", __func__, + DEV_DBG("%s: new res: %dx%d%s@%d.%d%d%dHz\n", __func__, timing.active_h, timing.active_v, interlaced ? "i" : "p", - timing.refresh_rate / khz_to_hz); - - rc = hdmi_set_resv_timing_info(&timing); + timing.refresh_rate / khz_to_hz, + (timing.refresh_rate % khz_to_hz) / 100, + (timing.refresh_rate % 100) / 10, + timing.refresh_rate % 10); + + rc = hdmi_get_video_id_code(&timing, NULL); + if (rc < 0) + rc = hdmi_set_resv_timing_info(&timing); } else { DEV_ERR("%s: Invalid frame data\n", __func__); rc = -EINVAL; @@ -1642,6 +1648,7 @@ static void hdmi_edid_add_sink_video_format(struct hdmi_edid_ctrl *edid_ctrl, u32 supported = hdmi_edid_is_mode_supported(edid_ctrl, &timing); struct hdmi_edid_sink_data *sink_data = &edid_ctrl->sink_data; struct disp_mode_info *disp_mode_list = sink_data->disp_mode_list; + u32 i = 0; if (video_format >= HDMI_VFRMT_MAX) { DEV_ERR("%s: video format: %s is not supported\n", __func__, @@ -1653,6 +1660,15 @@ static void hdmi_edid_add_sink_video_format(struct hdmi_edid_ctrl *edid_ctrl, video_format, msm_hdmi_mode_2string(video_format), supported ? "Supported" : "Not-Supported"); + for (i = 0; i < sink_data->num_of_elements; i++) { + u32 vic = disp_mode_list[i].video_format; + + if (vic == video_format) { + DEV_DBG("%s: vic %d already added\n", __func__, vic); + return; + } + } + if (!ret && supported) { /* todo: MHL */ disp_mode_list[sink_data->num_of_elements].video_format = @@ -1970,6 +1986,7 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl) const u8 *svd = NULL; u32 has60hz_mode = false; u32 has50hz_mode = false; + u32 desc_offset = 0; bool read_block0_res = false; struct hdmi_edid_sink_data *sink_data = NULL; @@ -2033,103 +2050,66 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl) if (video_format == HDMI_VFRMT_640x480p60_4_3) has480p = true; } - } else if (!num_of_cea_blocks || read_block0_res) { - /* Detailed timing descriptors */ - u32 desc_offset = 0; - /* - * * Maximum 4 timing descriptor in block 0 - No CEA - * extension in this case - * * EDID_FIRST_TIMING_DESC[0x36] - 1st detailed timing - * descriptor - * * EDID_DETAIL_TIMING_DESC_BLCK_SZ[0x12] - Each detailed - * timing descriptor has block size of 18 - */ - while (4 > i && 0 != edid_blk0[0x36+desc_offset]) { - hdmi_edid_detail_desc(edid_ctrl, - edid_blk0+0x36+desc_offset, - &video_format); - - DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n", - __func__, __LINE__, - msm_hdmi_mode_2string(video_format)); - - hdmi_edid_add_sink_video_format(edid_ctrl, - video_format); - - if (video_format == HDMI_VFRMT_640x480p60_4_3) - has480p = true; - - /* Make a note of the preferred video format */ - if (i == 0) { - sink_data->preferred_video_format = - video_format; - } - desc_offset += 0x12; - ++i; - } - } else if (1 == num_of_cea_blocks) { - u32 desc_offset = 0; - - /* - * Read from both block 0 and block 1 - * Read EDID block[0] as above - */ - while (4 > i && 0 != edid_blk0[0x36+desc_offset]) { - hdmi_edid_detail_desc(edid_ctrl, - edid_blk0+0x36+desc_offset, - &video_format); + } - DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n", - __func__, __LINE__, - msm_hdmi_mode_2string(video_format)); + i = 0; + /* Read DTD resolutions from block0 */ + while (4 > i && 0 != edid_blk0[0x36+desc_offset]) { + hdmi_edid_detail_desc(edid_ctrl, + edid_blk0+0x36+desc_offset, + &video_format); + + DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n", + __func__, __LINE__, + msm_hdmi_mode_2string(video_format)); - hdmi_edid_add_sink_video_format(edid_ctrl, - video_format); + hdmi_edid_add_sink_video_format(edid_ctrl, + video_format); - if (video_format == HDMI_VFRMT_640x480p60_4_3) - has480p = true; + if (video_format == HDMI_VFRMT_640x480p60_4_3) + has480p = true; - /* Make a note of the preferred video format */ - if (i == 0) { - sink_data->preferred_video_format = - video_format; - } - desc_offset += 0x12; - ++i; + /* Make a note of the preferred video format */ + if (i == 0) { + sink_data->preferred_video_format = + video_format; } + desc_offset += 0x12; + ++i; + } - /* - * * Parse block 1 - CEA extension byte offset of first - * detailed timing generation - offset is relevant to - * the offset of block 1 - * * EDID_CEA_EXTENSION_FIRST_DESC[0x82]: Offset to CEA - * extension first timing desc - indicate the offset of - * the first detailed timing descriptor - * * EDID_BLOCK_SIZE = 0x80 Each page size in the EDID ROM - */ - desc_offset = edid_blk1[0x02]; - while (0 != edid_blk1[desc_offset]) { - hdmi_edid_detail_desc(edid_ctrl, - edid_blk1+desc_offset, - &video_format); - - DEV_DBG("[%s:%d] Block-1 Adding vid fmt = [%s]\n", - __func__, __LINE__, - msm_hdmi_mode_2string(video_format)); + /* + * * Parse block 1 - CEA extension byte offset of first + * detailed timing generation - offset is relevant to + * the offset of block 1 + * * EDID_CEA_EXTENSION_FIRST_DESC[0x82]: Offset to CEA + * extension first timing desc - indicate the offset of + * the first detailed timing descriptor + * * EDID_BLOCK_SIZE = 0x80 Each page size in the EDID ROM + */ + desc_offset = edid_blk1[0x02]; + i = 0; + while (!edid_blk1[desc_offset]) { + hdmi_edid_detail_desc(edid_ctrl, + edid_blk1+desc_offset, + &video_format); - hdmi_edid_add_sink_video_format(edid_ctrl, - video_format); - if (video_format == HDMI_VFRMT_640x480p60_4_3) - has480p = true; + DEV_DBG("[%s:%d] Block-1 Adding vid fmt = [%s]\n", + __func__, __LINE__, + msm_hdmi_mode_2string(video_format)); - /* Make a note of the preferred video format */ - if (i == 0) { - sink_data->preferred_video_format = - video_format; - } - desc_offset += 0x12; - ++i; + hdmi_edid_add_sink_video_format(edid_ctrl, + video_format); + if (video_format == HDMI_VFRMT_640x480p60_4_3) + has480p = true; + + /* Make a note of the preferred video format */ + if (i == 0) { + sink_data->preferred_video_format = + video_format; } + desc_offset += 0x12; + ++i; } std_blk = 0; diff --git a/drivers/video/fbdev/msm/mdss_hdmi_util.c b/drivers/video/fbdev/msm/mdss_hdmi_util.c index b3d929b15b44..c9fc8ba8bfdb 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_util.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_util.c @@ -639,7 +639,7 @@ int hdmi_get_video_id_code(struct msm_hdmi_mode_timing_info *timing_in, { int i, vic = -1; struct msm_hdmi_mode_timing_info supported_timing = {0}; - u32 ret; + u32 ret, pclk_delta, pclk, fps_delta, fps; if (!timing_in) { pr_err("invalid input\n"); @@ -647,9 +647,16 @@ int hdmi_get_video_id_code(struct msm_hdmi_mode_timing_info *timing_in, } /* active_low_h, active_low_v and interlaced are not checked against */ - for (i = 0; i < HDMI_VFRMT_MAX; i++) { + for (i = 1; i < HDMI_VFRMT_MAX; i++) { ret = hdmi_get_supported_mode(&supported_timing, ds_data, i); + pclk = supported_timing.pixel_freq; + fps = supported_timing.refresh_rate; + + /* as per standard, 0.5% of deviation is allowed */ + pclk_delta = (pclk / HDMI_KHZ_TO_HZ) * 5; + fps_delta = (fps / HDMI_KHZ_TO_HZ) * 5; + if (ret || !supported_timing.supported) continue; if (timing_in->active_h != supported_timing.active_h) @@ -668,9 +675,11 @@ int hdmi_get_video_id_code(struct msm_hdmi_mode_timing_info *timing_in, continue; if (timing_in->back_porch_v != supported_timing.back_porch_v) continue; - if (timing_in->pixel_freq != supported_timing.pixel_freq) + if (timing_in->pixel_freq < (pclk - pclk_delta) || + timing_in->pixel_freq > (pclk + pclk_delta)) continue; - if (timing_in->refresh_rate != supported_timing.refresh_rate) + if (timing_in->refresh_rate < (fps - fps_delta) || + timing_in->refresh_rate > (fps + fps_delta)) continue; vic = (int)supported_timing.video_format; |
