summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-10-11 11:35:22 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-11 11:35:22 -0700
commitc30ea8b0c1b1fca497ffacc41e5b3ecfc8a6933e (patch)
treeda6137fd568c5a252297746b39a10882fd505e1c /drivers/video/fbdev
parentae7908ba2269cc465298a001385f0d37949b1ad3 (diff)
parenta03fd4699aa9bc709551f20055ea3240044cef0d (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.c170
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_util.c17
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;