drm/edid: Remove arbitrary EDID extension limit
Signed-off-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
2255be14cb
commit
7466f4cc50
5 changed files with 15 additions and 24 deletions
|
@ -33,6 +33,7 @@
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "drm_crtc.h"
|
#include "drm_crtc.h"
|
||||||
|
#include "drm_edid.h"
|
||||||
|
|
||||||
struct drm_prop_enum_list {
|
struct drm_prop_enum_list {
|
||||||
int type;
|
int type;
|
||||||
|
@ -2349,7 +2350,7 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
|
||||||
struct edid *edid)
|
struct edid *edid)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = connector->dev;
|
struct drm_device *dev = connector->dev;
|
||||||
int ret = 0;
|
int ret = 0, size;
|
||||||
|
|
||||||
if (connector->edid_blob_ptr)
|
if (connector->edid_blob_ptr)
|
||||||
drm_property_destroy_blob(dev, connector->edid_blob_ptr);
|
drm_property_destroy_blob(dev, connector->edid_blob_ptr);
|
||||||
|
@ -2361,7 +2362,9 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 128, edid);
|
size = EDID_LENGTH * (1 + edid->extensions);
|
||||||
|
connector->edid_blob_ptr = drm_property_create_blob(connector->dev,
|
||||||
|
size, edid);
|
||||||
|
|
||||||
ret = drm_connector_property_set_value(connector,
|
ret = drm_connector_property_set_value(connector,
|
||||||
dev->mode_config.edid_property,
|
dev->mode_config.edid_property,
|
||||||
|
|
|
@ -1325,7 +1325,6 @@ static int add_detailed_info_eedid(struct drm_connector *connector,
|
||||||
int i, modes = 0;
|
int i, modes = 0;
|
||||||
char *edid_ext = NULL;
|
char *edid_ext = NULL;
|
||||||
struct detailed_timing *timing;
|
struct detailed_timing *timing;
|
||||||
int edid_ext_num;
|
|
||||||
int start_offset, end_offset;
|
int start_offset, end_offset;
|
||||||
int timing_level;
|
int timing_level;
|
||||||
|
|
||||||
|
@ -1342,19 +1341,15 @@ static int add_detailed_info_eedid(struct drm_connector *connector,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Chose real EDID extension number */
|
|
||||||
edid_ext_num = edid->extensions > DRM_MAX_EDID_EXT_NUM ?
|
|
||||||
DRM_MAX_EDID_EXT_NUM : edid->extensions;
|
|
||||||
|
|
||||||
/* Find CEA extension */
|
/* Find CEA extension */
|
||||||
for (i = 0; i < edid_ext_num; i++) {
|
for (i = 0; i < edid->extensions; i++) {
|
||||||
edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
|
edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
|
||||||
/* This block is CEA extension */
|
/* This block is CEA extension */
|
||||||
if (edid_ext[0] == 0x02)
|
if (edid_ext[0] == 0x02)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == edid_ext_num) {
|
if (i == edid->extensions) {
|
||||||
/* if there is no additional timing EDID block, return */
|
/* if there is no additional timing EDID block, return */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1393,7 +1388,7 @@ static int add_detailed_info_eedid(struct drm_connector *connector,
|
||||||
bool drm_detect_hdmi_monitor(struct edid *edid)
|
bool drm_detect_hdmi_monitor(struct edid *edid)
|
||||||
{
|
{
|
||||||
char *edid_ext = NULL;
|
char *edid_ext = NULL;
|
||||||
int i, hdmi_id, edid_ext_num;
|
int i, hdmi_id;
|
||||||
int start_offset, end_offset;
|
int start_offset, end_offset;
|
||||||
bool is_hdmi = false;
|
bool is_hdmi = false;
|
||||||
|
|
||||||
|
@ -1401,19 +1396,15 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
|
||||||
if (edid == NULL || edid->extensions == 0)
|
if (edid == NULL || edid->extensions == 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* Chose real EDID extension number */
|
|
||||||
edid_ext_num = edid->extensions > DRM_MAX_EDID_EXT_NUM ?
|
|
||||||
DRM_MAX_EDID_EXT_NUM : edid->extensions;
|
|
||||||
|
|
||||||
/* Find CEA extension */
|
/* Find CEA extension */
|
||||||
for (i = 0; i < edid_ext_num; i++) {
|
for (i = 0; i < edid->extensions; i++) {
|
||||||
edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
|
edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
|
||||||
/* This block is CEA extension */
|
/* This block is CEA extension */
|
||||||
if (edid_ext[0] == 0x02)
|
if (edid_ext[0] == 0x02)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == edid_ext_num)
|
if (i == edid->extensions)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* Data block offset in CEA extension block */
|
/* Data block offset in CEA extension block */
|
||||||
|
|
|
@ -332,7 +332,7 @@ static struct device_attribute connector_attrs_opt1[] = {
|
||||||
static struct bin_attribute edid_attr = {
|
static struct bin_attribute edid_attr = {
|
||||||
.attr.name = "edid",
|
.attr.name = "edid",
|
||||||
.attr.mode = 0444,
|
.attr.mode = 0444,
|
||||||
.size = 128,
|
.size = 0,
|
||||||
.read = edid_show,
|
.read = edid_show,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -450,17 +450,17 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
int edid_info;
|
int edid_info;
|
||||||
struct edid *edid;
|
struct edid *edid;
|
||||||
|
unsigned char *raw;
|
||||||
edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
|
edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
|
||||||
if (!edid_info)
|
if (!edid_info)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
edid = kmalloc(EDID_LENGTH * (DRM_MAX_EDID_EXT_NUM + 1),
|
raw = rdev->bios + edid_info;
|
||||||
GFP_KERNEL);
|
edid = kmalloc(EDID_LENGTH * (raw[0x7e] + 1), GFP_KERNEL);
|
||||||
if (edid == NULL)
|
if (edid == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
memcpy((unsigned char *)edid,
|
memcpy((unsigned char *)edid, raw, EDID_LENGTH * (raw[0x7e] + 1));
|
||||||
(unsigned char *)(rdev->bios + edid_info), EDID_LENGTH);
|
|
||||||
|
|
||||||
if (!drm_edid_is_valid(edid)) {
|
if (!drm_edid_is_valid(edid)) {
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
|
|
|
@ -201,7 +201,4 @@ struct edid {
|
||||||
|
|
||||||
#define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
|
#define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
|
||||||
|
|
||||||
/* define the number of Extension EDID block */
|
|
||||||
#define DRM_MAX_EDID_EXT_NUM 4
|
|
||||||
|
|
||||||
#endif /* __DRM_EDID_H__ */
|
#endif /* __DRM_EDID_H__ */
|
||||||
|
|
Loading…
Reference in a new issue