aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRob Clark <rob@ti.com>2011-03-26 16:00:12 -0500
committerRicardo Salveti de Araujo <ricardo.salveti@canonical.com>2011-05-16 22:51:33 -0300
commit3470803999902d75785fb634f4cf8036ab6c2127 (patch)
tree13de90257f5b08f38d27a4b1639c2ccf1fcdb6c5 /drivers
parent5686410a6094b68aa665a33097aa0f381e2b7125 (diff)
downloadlinux-linaro-android-3470803999902d75785fb634f4cf8036ab6c2127.tar.gz
OMAP: DSS: HDMI: tame hdmi driver
Main change is to avoid automatically picking timings. Now the driver defaults to a safe 640x480, and leaves it to the upper layer (drm driver) to pick the desired resolution based on what the user selects and the drm infrastucture's parsing of the EDID. Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/omap2/dss/hdmi.c130
1 files changed, 13 insertions, 117 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index fd0d57807c6..13fcb99ff58 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -50,7 +50,10 @@ static struct {
u8 edid_set;
bool custom_set;
struct hdmi_config cfg;
-} hdmi;
+} hdmi = {
+ .code = 4, /*setting default value of 640 480 VGA*/
+ .mode = 0,
+};
/*
* Logic for the below structure :
@@ -547,129 +550,22 @@ static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
return cm;
}
-static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
- struct omap_video_timings *timings)
-{
- /* X and Y resolution */
- timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
- edid[current_descriptor_addrs + 2]);
- timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
- edid[current_descriptor_addrs + 5]);
-
- timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
- edid[current_descriptor_addrs]);
-
- timings->pixel_clock = 10 * timings->pixel_clock;
-
- /* HORIZONTAL FRONT PORCH */
- timings->hfp = edid[current_descriptor_addrs + 8] |
- ((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
- /* HORIZONTAL SYNC WIDTH */
- timings->hsw = edid[current_descriptor_addrs + 9] |
- ((edid[current_descriptor_addrs + 11] & 0x30) << 4);
- /* HORIZONTAL BACK PORCH */
- timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
- edid[current_descriptor_addrs + 3]) -
- (timings->hfp + timings->hsw);
- /* VERTICAL FRONT PORCH */
- timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
- ((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
- /* VERTICAL SYNC WIDTH */
- timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
- ((edid[current_descriptor_addrs + 11] & 0x03) << 4);
- /* VERTICAL BACK PORCH */
- timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
- edid[current_descriptor_addrs + 6]) -
- (timings->vfp + timings->vsw);
-
-}
-
-/* Description : This function gets the resolution information from EDID */
-static void get_edid_timing_data(u8 *edid)
-{
- u8 count;
- u16 current_descriptor_addrs;
- struct hdmi_cm cm;
- struct omap_video_timings edid_timings;
-
- /* seach block 0, there are 4 DTDs arranged in priority order */
- for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
- current_descriptor_addrs =
- EDID_DESCRIPTOR_BLOCK0_ADDRESS +
- count * EDID_TIMING_DESCRIPTOR_SIZE;
- get_horz_vert_timing_info(current_descriptor_addrs,
- edid, &edid_timings);
- cm = hdmi_get_code(&edid_timings);
- DSSDBG("Block0[%d] value matches code = %d , mode = %d\n",
- count, cm.code, cm.mode);
- if (cm.code == -1) {
- continue;
- } else {
- hdmi.code = cm.code;
- hdmi.mode = cm.mode;
- DSSDBG("code = %d , mode = %d\n",
- hdmi.code, hdmi.mode);
- return;
- }
- }
- if (edid[0x7e] != 0x00) {
- for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
- count++) {
- current_descriptor_addrs =
- EDID_DESCRIPTOR_BLOCK1_ADDRESS +
- count * EDID_TIMING_DESCRIPTOR_SIZE;
- get_horz_vert_timing_info(current_descriptor_addrs,
- edid, &edid_timings);
- cm = hdmi_get_code(&edid_timings);
- DSSDBG("Block1[%d] value matches code = %d, mode = %d",
- count, cm.code, cm.mode);
- if (cm.code == -1) {
- continue;
- } else {
- hdmi.code = cm.code;
- hdmi.mode = cm.mode;
- DSSDBG("code = %d , mode = %d\n",
- hdmi.code, hdmi.mode);
- return;
- }
- }
- }
-
- DSSINFO("no valid timing found , falling back to VGA\n");
- hdmi.code = 4; /* setting default value of 640 480 VGA */
- hdmi.mode = HDMI_DVI;
-}
-
-static void hdmi_read_edid(struct omap_video_timings *dp)
+static void hdmi_read_edid()
{
- int ret = 0, code;
+ int ret = 0;
- memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
-
- if (!hdmi.edid_set)
+ if (!hdmi.edid_set) {
+ memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH);
+ }
if (!ret) {
if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
- /* search for timings of default resolution */
- get_edid_timing_data(hdmi.edid);
hdmi.edid_set = true;
}
} else {
DSSWARN("failed to read E-EDID\n");
}
-
- if (!hdmi.edid_set) {
- DSSINFO("fallback to VGA\n");
- hdmi.code = 4; /* setting default value of 640 480 VGA */
- hdmi.mode = HDMI_DVI;
- }
-
- code = get_timings_index();
-
- if (dp) {
- *dp = cea_vesa_timings[code].timings;
- }
}
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
@@ -1126,11 +1022,11 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
dssdev->panel.timings.x_res,
dssdev->panel.timings.y_res);
- if (!hdmi.custom_set) {
+ if (!hdmi.edid_set) {
DSSDBG("Read EDID as no EDID is not set on poweron\n");
- hdmi_read_edid(p);
- dirty = get_timings_index() != code;
+ hdmi_read_edid();
}
+
code = get_timings_index();
dssdev->panel.timings = cea_vesa_timings[code].timings;
update_hdmi_timings(&hdmi.cfg, p, code);
@@ -1216,7 +1112,7 @@ bool omapdss_hdmi_is_detected(struct omap_dss_device *dssdev)
int omapdss_hdmi_get_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
{
if (!hdmi.edid_set)
- hdmi_read_edid(NULL);
+ hdmi_read_edid();
if (!hdmi.edid_set)
return -EINVAL;
memcpy(buf, hdmi.edid, min(len, HDMI_EDID_MAX_LENGTH));