Message ID | 1265970453-4375-1-git-send-email-surbhi.palande@canonical.com |
---|---|
State | Accepted |
Delegated to: | Andy Whitcroft |
Headers | show |
Hi, Apologies for sending this patch 3 times. There was some problem with my smtp settings :( Sorry ! Warm Regards, Surbhi. Surbhi Palande wrote: > From 2f8055156e9160f3d83e56122c90c3ece2e09819 Mon Sep 17 00:00:00 2001 > From: Adam Jackson <ajax@redhat.com> > Date: Thu, 3 Dec 2009 17:44:36 -0500 > Subject: [PATCH] [PATCH] UBUNTU [Lucid]: [Upstream] drm/edid: Unify detailed block parsing between base and extension blocks > > BugLink: http://bugs.launchpad.net/bugs/500999 > > Also fix an embarassing bug in standard timing subblock parsing that > would result in an infinite loop. > > Signed-off-by: Adam Jackson <ajax@redhat.com> > Signed-off-by: Dave Airlie <airlied@redhat.com> > (cherry picked from commit 9cf00977da092096c7a983276dad8b3002d23a99) > > Signed-off-by: Surbhi Palande <Surbhi.Palande@canonical.com> > --- > drivers/gpu/drm/drm_edid.c | 163 ++++++++++++++++--------------------------- > 1 files changed, 61 insertions(+), 102 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index b54ba63..d5671c3 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -834,8 +834,57 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid > return modes; > } > > +static int add_detailed_modes(struct drm_connector *connector, > + struct detailed_timing *timing, > + struct edid *edid, u32 quirks, int preferred) > +{ > + int i, modes = 0; > + struct detailed_non_pixel *data = &timing->data.other_data; > + int timing_level = standard_timing_level(edid); > + struct drm_display_mode *newmode; > + struct drm_device *dev = connector->dev; > + > + if (timing->pixel_clock) { > + newmode = drm_mode_detailed(dev, edid, timing, quirks); > + if (!newmode) > + return 0; > + > + if (preferred) > + newmode->type |= DRM_MODE_TYPE_PREFERRED; > + > + drm_mode_probed_add(connector, newmode); > + return 1; > + } > + > + /* other timing types */ > + switch (data->type) { > + case EDID_DETAIL_MONITOR_RANGE: > + /* Get monitor range data */ > + break; > + case EDID_DETAIL_STD_MODES: > + /* Six modes per detailed section */ > + for (i = 0; i < 6; i++) { > + struct std_timing *std; > + struct drm_display_mode *newmode; > + > + std = &data->data.timings[i]; > + newmode = drm_mode_std(dev, std, edid->revision, > + timing_level); > + if (newmode) { > + drm_mode_probed_add(connector, newmode); > + modes++; > + } > + } > + break; > + default: > + break; > + } > + > + return modes; > +} > + > /** > - * add_detailed_modes - get detailed mode info from EDID data > + * add_detailed_info - get detailed mode info from EDID data > * @connector: attached connector > * @edid: EDID block to scan > * @quirks: quirks to apply > @@ -846,67 +895,24 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid > static int add_detailed_info(struct drm_connector *connector, > struct edid *edid, u32 quirks) > { > - struct drm_device *dev = connector->dev; > - int i, j, modes = 0; > - int timing_level; > - > - timing_level = standard_timing_level(edid); > + int i, modes = 0; > > for (i = 0; i < EDID_DETAILED_TIMINGS; i++) { > struct detailed_timing *timing = &edid->detailed_timings[i]; > - struct detailed_non_pixel *data = &timing->data.other_data; > - struct drm_display_mode *newmode; > - > - /* X server check is version 1.1 or higher */ > - if (edid->version == 1 && edid->revision >= 1 && > - !timing->pixel_clock) { > - /* Other timing or info */ > - switch (data->type) { > - case EDID_DETAIL_MONITOR_SERIAL: > - break; > - case EDID_DETAIL_MONITOR_STRING: > - break; > - case EDID_DETAIL_MONITOR_RANGE: > - /* Get monitor range data */ > - break; > - case EDID_DETAIL_MONITOR_NAME: > - break; > - case EDID_DETAIL_MONITOR_CPDATA: > - break; > - case EDID_DETAIL_STD_MODES: > - for (j = 0; j < 6; i++) { > - struct std_timing *std; > - struct drm_display_mode *newmode; > - > - std = &data->data.timings[j]; > - newmode = drm_mode_std(dev, std, > - edid->revision, > - timing_level); > - if (newmode) { > - drm_mode_probed_add(connector, newmode); > - modes++; > - } > - } > - break; > - default: > - break; > - } > - } else { > - newmode = drm_mode_detailed(dev, edid, timing, quirks); > - if (!newmode) > - continue; > + int preferred = (i == 0) && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING); > > - /* First detailed mode is preferred */ > - if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) > - newmode->type |= DRM_MODE_TYPE_PREFERRED; > - drm_mode_probed_add(connector, newmode); > + /* In 1.0, only timings are allowed */ > + if (!timing->pixel_clock && edid->version == 1 && > + edid->revision == 0) > + continue; > > - modes++; > - } > + modes += add_detailed_modes(connector, timing, edid, quirks, > + preferred); > } > > return modes; > } > + > /** > * add_detailed_mode_eedid - get detailed mode info from addtional timing > * EDID block > @@ -920,12 +926,9 @@ static int add_detailed_info(struct drm_connector *connector, > static int add_detailed_info_eedid(struct drm_connector *connector, > struct edid *edid, u32 quirks) > { > - struct drm_device *dev = connector->dev; > - int i, j, modes = 0; > + int i, modes = 0; > char *edid_ext = NULL; > struct detailed_timing *timing; > - struct detailed_non_pixel *data; > - struct drm_display_mode *newmode; > int edid_ext_num; > int start_offset, end_offset; > int timing_level; > @@ -976,51 +979,7 @@ static int add_detailed_info_eedid(struct drm_connector *connector, > for (i = start_offset; i < end_offset; > i += sizeof(struct detailed_timing)) { > timing = (struct detailed_timing *)(edid_ext + i); > - data = &timing->data.other_data; > - /* Detailed mode timing */ > - if (timing->pixel_clock) { > - newmode = drm_mode_detailed(dev, edid, timing, quirks); > - if (!newmode) > - continue; > - > - drm_mode_probed_add(connector, newmode); > - > - modes++; > - continue; > - } > - > - /* Other timing or info */ > - switch (data->type) { > - case EDID_DETAIL_MONITOR_SERIAL: > - break; > - case EDID_DETAIL_MONITOR_STRING: > - break; > - case EDID_DETAIL_MONITOR_RANGE: > - /* Get monitor range data */ > - break; > - case EDID_DETAIL_MONITOR_NAME: > - break; > - case EDID_DETAIL_MONITOR_CPDATA: > - break; > - case EDID_DETAIL_STD_MODES: > - /* Five modes per detailed section */ > - for (j = 0; j < 5; i++) { > - struct std_timing *std; > - struct drm_display_mode *newmode; > - > - std = &data->data.timings[j]; > - newmode = drm_mode_std(dev, std, > - edid->revision, > - timing_level); > - if (newmode) { > - drm_mode_probed_add(connector, newmode); > - modes++; > - } > - } > - break; > - default: > - break; > - } > + modes += add_detailed_modes(connector, timing, edid, quirks, 0); > } > > return modes;
Surbhi Palande wrote: > From 2f8055156e9160f3d83e56122c90c3ece2e09819 Mon Sep 17 00:00:00 2001 > From: Adam Jackson <ajax@redhat.com> > Date: Thu, 3 Dec 2009 17:44:36 -0500 > Subject: [PATCH] [PATCH] UBUNTU [Lucid]: [Upstream] drm/edid: Unify detailed block parsing between base and extension blocks > > BugLink: http://bugs.launchpad.net/bugs/500999 > > Also fix an embarassing bug in standard timing subblock parsing that > would result in an infinite loop. > > Signed-off-by: Adam Jackson <ajax@redhat.com> > Signed-off-by: Dave Airlie <airlied@redhat.com> > (cherry picked from commit 9cf00977da092096c7a983276dad8b3002d23a99) > > Signed-off-by: Surbhi Palande <Surbhi.Palande@canonical.com> > --- > drivers/gpu/drm/drm_edid.c | 163 ++++++++++++++++--------------------------- > 1 files changed, 61 insertions(+), 102 deletions(-) > ACK
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index b54ba63..d5671c3 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -834,8 +834,57 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid return modes; } +static int add_detailed_modes(struct drm_connector *connector, + struct detailed_timing *timing, + struct edid *edid, u32 quirks, int preferred) +{ + int i, modes = 0; + struct detailed_non_pixel *data = &timing->data.other_data; + int timing_level = standard_timing_level(edid); + struct drm_display_mode *newmode; + struct drm_device *dev = connector->dev; + + if (timing->pixel_clock) { + newmode = drm_mode_detailed(dev, edid, timing, quirks); + if (!newmode) + return 0; + + if (preferred) + newmode->type |= DRM_MODE_TYPE_PREFERRED; + + drm_mode_probed_add(connector, newmode); + return 1; + } + + /* other timing types */ + switch (data->type) { + case EDID_DETAIL_MONITOR_RANGE: + /* Get monitor range data */ + break; + case EDID_DETAIL_STD_MODES: + /* Six modes per detailed section */ + for (i = 0; i < 6; i++) { + struct std_timing *std; + struct drm_display_mode *newmode; + + std = &data->data.timings[i]; + newmode = drm_mode_std(dev, std, edid->revision, + timing_level); + if (newmode) { + drm_mode_probed_add(connector, newmode); + modes++; + } + } + break; + default: + break; + } + + return modes; +} + /** - * add_detailed_modes - get detailed mode info from EDID data + * add_detailed_info - get detailed mode info from EDID data * @connector: attached connector * @edid: EDID block to scan * @quirks: quirks to apply @@ -846,67 +895,24 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid static int add_detailed_info(struct drm_connector *connector, struct edid *edid, u32 quirks) { - struct drm_device *dev = connector->dev; - int i, j, modes = 0; - int timing_level; - - timing_level = standard_timing_level(edid); + int i, modes = 0; for (i = 0; i < EDID_DETAILED_TIMINGS; i++) { struct detailed_timing *timing = &edid->detailed_timings[i]; - struct detailed_non_pixel *data = &timing->data.other_data; - struct drm_display_mode *newmode; - - /* X server check is version 1.1 or higher */ - if (edid->version == 1 && edid->revision >= 1 && - !timing->pixel_clock) { - /* Other timing or info */ - switch (data->type) { - case EDID_DETAIL_MONITOR_SERIAL: - break; - case EDID_DETAIL_MONITOR_STRING: - break; - case EDID_DETAIL_MONITOR_RANGE: - /* Get monitor range data */ - break; - case EDID_DETAIL_MONITOR_NAME: - break; - case EDID_DETAIL_MONITOR_CPDATA: - break; - case EDID_DETAIL_STD_MODES: - for (j = 0; j < 6; i++) { - struct std_timing *std; - struct drm_display_mode *newmode; - - std = &data->data.timings[j]; - newmode = drm_mode_std(dev, std, - edid->revision, - timing_level); - if (newmode) { - drm_mode_probed_add(connector, newmode); - modes++; - } - } - break; - default: - break; - } - } else { - newmode = drm_mode_detailed(dev, edid, timing, quirks); - if (!newmode) - continue; + int preferred = (i == 0) && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING); - /* First detailed mode is preferred */ - if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) - newmode->type |= DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, newmode); + /* In 1.0, only timings are allowed */ + if (!timing->pixel_clock && edid->version == 1 && + edid->revision == 0) + continue; - modes++; - } + modes += add_detailed_modes(connector, timing, edid, quirks, + preferred); } return modes; } + /** * add_detailed_mode_eedid - get detailed mode info from addtional timing * EDID block @@ -920,12 +926,9 @@ static int add_detailed_info(struct drm_connector *connector, static int add_detailed_info_eedid(struct drm_connector *connector, struct edid *edid, u32 quirks) { - struct drm_device *dev = connector->dev; - int i, j, modes = 0; + int i, modes = 0; char *edid_ext = NULL; struct detailed_timing *timing; - struct detailed_non_pixel *data; - struct drm_display_mode *newmode; int edid_ext_num; int start_offset, end_offset; int timing_level; @@ -976,51 +979,7 @@ static int add_detailed_info_eedid(struct drm_connector *connector, for (i = start_offset; i < end_offset; i += sizeof(struct detailed_timing)) { timing = (struct detailed_timing *)(edid_ext + i); - data = &timing->data.other_data; - /* Detailed mode timing */ - if (timing->pixel_clock) { - newmode = drm_mode_detailed(dev, edid, timing, quirks); - if (!newmode) - continue; - - drm_mode_probed_add(connector, newmode); - - modes++; - continue; - } - - /* Other timing or info */ - switch (data->type) { - case EDID_DETAIL_MONITOR_SERIAL: - break; - case EDID_DETAIL_MONITOR_STRING: - break; - case EDID_DETAIL_MONITOR_RANGE: - /* Get monitor range data */ - break; - case EDID_DETAIL_MONITOR_NAME: - break; - case EDID_DETAIL_MONITOR_CPDATA: - break; - case EDID_DETAIL_STD_MODES: - /* Five modes per detailed section */ - for (j = 0; j < 5; i++) { - struct std_timing *std; - struct drm_display_mode *newmode; - - std = &data->data.timings[j]; - newmode = drm_mode_std(dev, std, - edid->revision, - timing_level); - if (newmode) { - drm_mode_probed_add(connector, newmode); - modes++; - } - } - break; - default: - break; - } + modes += add_detailed_modes(connector, timing, edid, quirks, 0); } return modes;