aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2010-03-29 17:43:23 -0400
committerDave Airlie <airlied@redhat.com>2010-04-05 20:40:20 -0400
commit7466f4cc508878a8328dff1c328a2b4108888d2e (patch)
treea46b13cd8b1baa22f241d1e8c90809a73c333561
parent2255be14cb82370a6af4054edb3b4cd170d80752 (diff)
drm/edid: Remove arbitrary EDID extension limit
Signed-off-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_crtc.c7
-rw-r--r--drivers/gpu/drm/drm_edid.c19
-rw-r--r--drivers/gpu/drm/drm_sysfs.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c8
-rw-r--r--include/drm/drm_edid.h3
5 files changed, 15 insertions, 24 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d91fb8c0b7b3..aa24f2f9dc0a 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -33,6 +33,7 @@
33#include "drm.h" 33#include "drm.h"
34#include "drmP.h" 34#include "drmP.h"
35#include "drm_crtc.h" 35#include "drm_crtc.h"
36#include "drm_edid.h"
36 37
37struct drm_prop_enum_list { 38struct drm_prop_enum_list {
38 int type; 39 int type;
@@ -2349,7 +2350,7 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
2349 struct edid *edid) 2350 struct edid *edid)
2350{ 2351{
2351 struct drm_device *dev = connector->dev; 2352 struct drm_device *dev = connector->dev;
2352 int ret = 0; 2353 int ret = 0, size;
2353 2354
2354 if (connector->edid_blob_ptr) 2355 if (connector->edid_blob_ptr)
2355 drm_property_destroy_blob(dev, connector->edid_blob_ptr); 2356 drm_property_destroy_blob(dev, connector->edid_blob_ptr);
@@ -2361,7 +2362,9 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
2361 return ret; 2362 return ret;
2362 } 2363 }
2363 2364
2364 connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 128, edid); 2365 size = EDID_LENGTH * (1 + edid->extensions);
2366 connector->edid_blob_ptr = drm_property_create_blob(connector->dev,
2367 size, edid);
2365 2368
2366 ret = drm_connector_property_set_value(connector, 2369 ret = drm_connector_property_set_value(connector,
2367 dev->mode_config.edid_property, 2370 dev->mode_config.edid_property,
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 58b67932f04a..cf24ecab6a4a 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1325,7 +1325,6 @@ static int add_detailed_info_eedid(struct drm_connector *connector,
1325 int i, modes = 0; 1325 int i, modes = 0;
1326 char *edid_ext = NULL; 1326 char *edid_ext = NULL;
1327 struct detailed_timing *timing; 1327 struct detailed_timing *timing;
1328 int edid_ext_num;
1329 int start_offset, end_offset; 1328 int start_offset, end_offset;
1330 int timing_level; 1329 int timing_level;
1331 1330
@@ -1342,19 +1341,15 @@ static int add_detailed_info_eedid(struct drm_connector *connector,
1342 return 0; 1341 return 0;
1343 } 1342 }
1344 1343
1345 /* Chose real EDID extension number */
1346 edid_ext_num = edid->extensions > DRM_MAX_EDID_EXT_NUM ?
1347 DRM_MAX_EDID_EXT_NUM : edid->extensions;
1348
1349 /* Find CEA extension */ 1344 /* Find CEA extension */
1350 for (i = 0; i < edid_ext_num; i++) { 1345 for (i = 0; i < edid->extensions; i++) {
1351 edid_ext = (char *)edid + EDID_LENGTH * (i + 1); 1346 edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
1352 /* This block is CEA extension */ 1347 /* This block is CEA extension */
1353 if (edid_ext[0] == 0x02) 1348 if (edid_ext[0] == 0x02)
1354 break; 1349 break;
1355 } 1350 }
1356 1351
1357 if (i == edid_ext_num) { 1352 if (i == edid->extensions) {
1358 /* if there is no additional timing EDID block, return */ 1353 /* if there is no additional timing EDID block, return */
1359 return 0; 1354 return 0;
1360 } 1355 }
@@ -1393,7 +1388,7 @@ static int add_detailed_info_eedid(struct drm_connector *connector,
1393bool drm_detect_hdmi_monitor(struct edid *edid) 1388bool drm_detect_hdmi_monitor(struct edid *edid)
1394{ 1389{
1395 char *edid_ext = NULL; 1390 char *edid_ext = NULL;
1396 int i, hdmi_id, edid_ext_num; 1391 int i, hdmi_id;
1397 int start_offset, end_offset; 1392 int start_offset, end_offset;
1398 bool is_hdmi = false; 1393 bool is_hdmi = false;
1399 1394
@@ -1401,19 +1396,15 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
1401 if (edid == NULL || edid->extensions == 0) 1396 if (edid == NULL || edid->extensions == 0)
1402 goto end; 1397 goto end;
1403 1398
1404 /* Chose real EDID extension number */
1405 edid_ext_num = edid->extensions > DRM_MAX_EDID_EXT_NUM ?
1406 DRM_MAX_EDID_EXT_NUM : edid->extensions;
1407
1408 /* Find CEA extension */ 1399 /* Find CEA extension */
1409 for (i = 0; i < edid_ext_num; i++) { 1400 for (i = 0; i < edid->extensions; i++) {
1410 edid_ext = (char *)edid + EDID_LENGTH * (i + 1); 1401 edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
1411 /* This block is CEA extension */ 1402 /* This block is CEA extension */
1412 if (edid_ext[0] == 0x02) 1403 if (edid_ext[0] == 0x02)
1413 break; 1404 break;
1414 } 1405 }
1415 1406
1416 if (i == edid_ext_num) 1407 if (i == edid->extensions)
1417 goto end; 1408 goto end;
1418 1409
1419 /* Data block offset in CEA extension block */ 1410 /* Data block offset in CEA extension block */
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 014ce24761b9..7b7c83f6041a 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -332,7 +332,7 @@ static struct device_attribute connector_attrs_opt1[] = {
332static struct bin_attribute edid_attr = { 332static struct bin_attribute edid_attr = {
333 .attr.name = "edid", 333 .attr.name = "edid",
334 .attr.mode = 0444, 334 .attr.mode = 0444,
335 .size = 128, 335 .size = 0,
336 .read = edid_show, 336 .read = edid_show,
337}; 337};
338 338
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 2becdeda68a3..20f38b85c70a 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -450,17 +450,17 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
450{ 450{
451 int edid_info; 451 int edid_info;
452 struct edid *edid; 452 struct edid *edid;
453 unsigned char *raw;
453 edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE); 454 edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
454 if (!edid_info) 455 if (!edid_info)
455 return false; 456 return false;
456 457
457 edid = kmalloc(EDID_LENGTH * (DRM_MAX_EDID_EXT_NUM + 1), 458 raw = rdev->bios + edid_info;
458 GFP_KERNEL); 459 edid = kmalloc(EDID_LENGTH * (raw[0x7e] + 1), GFP_KERNEL);
459 if (edid == NULL) 460 if (edid == NULL)
460 return false; 461 return false;
461 462
462 memcpy((unsigned char *)edid, 463 memcpy((unsigned char *)edid, raw, EDID_LENGTH * (raw[0x7e] + 1));
463 (unsigned char *)(rdev->bios + edid_info), EDID_LENGTH);
464 464
465 if (!drm_edid_is_valid(edid)) { 465 if (!drm_edid_is_valid(edid)) {
466 kfree(edid); 466 kfree(edid);
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index b4209898f115..d33c3e038606 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -201,7 +201,4 @@ struct edid {
201 201
202#define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) 202#define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
203 203
204/* define the number of Extension EDID block */
205#define DRM_MAX_EDID_EXT_NUM 4
206
207#endif /* __DRM_EDID_H__ */ 204#endif /* __DRM_EDID_H__ */