Merge branch 'drm-edid-fixes' into drm-core-next
* drm-edid-fixes: drm/edid: When checking duplicate standard modes, walked the probed list drm/edid: Fix sync polarity for secondary GTF curve drm/modes: Fix interlaced mode names drm/edid: Add secondary GTF curve support drm/edid: Strengthen the algorithm for standard mode codes drm/edid: Fix the HDTV hack. drm/edid: Extend range-based mode addition for EDID 1.4 drm/edid: Add test for monitor reduced blanking support. drm/edid: Fix preferred mode parse for EDID 1.4 drm/edid: Remove some silly comments drm/edid: Remove arbitrary EDID extension limit drm/edid: Add modes for Established Timings III section drm/edid: Reshuffle mode list construction to closer match the spec drm/edid: Remove a redundant check drm/edid: Remove some misleading comments drm/edid: Fix secondary block fetch.
This commit is contained in:
commit
c9c2625ff4
|
@ -34,6 +34,7 @@
|
|||
#include "drm.h"
|
||||
#include "drmP.h"
|
||||
#include "drm_crtc.h"
|
||||
#include "drm_edid.h"
|
||||
|
||||
struct drm_prop_enum_list {
|
||||
int type;
|
||||
|
@ -2350,7 +2351,7 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
|
|||
struct edid *edid)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
int ret = 0;
|
||||
int ret = 0, size;
|
||||
|
||||
if (connector->edid_blob_ptr)
|
||||
drm_property_destroy_blob(dev, connector->edid_blob_ptr);
|
||||
|
@ -2362,7 +2363,9 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
|
|||
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,
|
||||
dev->mode_config.edid_property,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -258,8 +258,10 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
|
|||
drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP;
|
||||
/* 18/16. Find actual vertical frame frequency */
|
||||
/* ignore - just set the mode flag for interlaced */
|
||||
if (interlaced)
|
||||
if (interlaced) {
|
||||
drm_mode->vtotal *= 2;
|
||||
drm_mode->flags |= DRM_MODE_FLAG_INTERLACE;
|
||||
}
|
||||
/* Fill the mode line name */
|
||||
drm_mode_set_name(drm_mode);
|
||||
if (reduced)
|
||||
|
@ -268,43 +270,35 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
|
|||
else
|
||||
drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC |
|
||||
DRM_MODE_FLAG_NHSYNC);
|
||||
if (interlaced)
|
||||
drm_mode->flags |= DRM_MODE_FLAG_INTERLACE;
|
||||
|
||||
return drm_mode;
|
||||
return drm_mode;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_cvt_mode);
|
||||
|
||||
/**
|
||||
* drm_gtf_mode - create the modeline based on GTF algorithm
|
||||
* drm_gtf_mode_complex - create the modeline based on full GTF algorithm
|
||||
*
|
||||
* @dev :drm device
|
||||
* @hdisplay :hdisplay size
|
||||
* @vdisplay :vdisplay size
|
||||
* @vrefresh :vrefresh rate.
|
||||
* @interlaced :whether the interlace is supported
|
||||
* @margins :whether the margin is supported
|
||||
* @margins :desired margin size
|
||||
* @GTF_[MCKJ] :extended GTF formula parameters
|
||||
*
|
||||
* LOCKING.
|
||||
* none.
|
||||
*
|
||||
* return the modeline based on GTF algorithm
|
||||
* return the modeline based on full GTF algorithm.
|
||||
*
|
||||
* This function is to create the modeline based on the GTF algorithm.
|
||||
* Generalized Timing Formula is derived from:
|
||||
* GTF Spreadsheet by Andy Morrish (1/5/97)
|
||||
* available at http://www.vesa.org
|
||||
*
|
||||
* And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c.
|
||||
* What I have done is to translate it by using integer calculation.
|
||||
* I also refer to the function of fb_get_mode in the file of
|
||||
* drivers/video/fbmon.c
|
||||
* GTF feature blocks specify C and J in multiples of 0.5, so we pass them
|
||||
* in here multiplied by two. For a C of 40, pass in 80.
|
||||
*/
|
||||
struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay,
|
||||
int vdisplay, int vrefresh,
|
||||
bool interlaced, int margins)
|
||||
{
|
||||
/* 1) top/bottom margin size (% of height) - default: 1.8, */
|
||||
struct drm_display_mode *
|
||||
drm_gtf_mode_complex(struct drm_device *dev, int hdisplay, int vdisplay,
|
||||
int vrefresh, bool interlaced, int margins,
|
||||
int GTF_M, int GTF_2C, int GTF_K, int GTF_2J)
|
||||
{ /* 1) top/bottom margin size (% of height) - default: 1.8, */
|
||||
#define GTF_MARGIN_PERCENTAGE 18
|
||||
/* 2) character cell horizontal granularity (pixels) - default 8 */
|
||||
#define GTF_CELL_GRAN 8
|
||||
|
@ -316,17 +310,9 @@ struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay,
|
|||
#define H_SYNC_PERCENT 8
|
||||
/* min time of vsync + back porch (microsec) */
|
||||
#define MIN_VSYNC_PLUS_BP 550
|
||||
/* blanking formula gradient */
|
||||
#define GTF_M 600
|
||||
/* blanking formula offset */
|
||||
#define GTF_C 40
|
||||
/* blanking formula scaling factor */
|
||||
#define GTF_K 128
|
||||
/* blanking formula scaling factor */
|
||||
#define GTF_J 20
|
||||
/* C' and M' are part of the Blanking Duty Cycle computation */
|
||||
#define GTF_C_PRIME (((GTF_C - GTF_J) * GTF_K / 256) + GTF_J)
|
||||
#define GTF_M_PRIME (GTF_K * GTF_M / 256)
|
||||
#define GTF_C_PRIME ((((GTF_2C - GTF_2J) * GTF_K / 256) + GTF_2J) / 2)
|
||||
#define GTF_M_PRIME (GTF_K * GTF_M / 256)
|
||||
struct drm_display_mode *drm_mode;
|
||||
unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd;
|
||||
int top_margin, bottom_margin;
|
||||
|
@ -460,17 +446,61 @@ struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay,
|
|||
|
||||
drm_mode->clock = pixel_freq;
|
||||
|
||||
drm_mode_set_name(drm_mode);
|
||||
drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC;
|
||||
|
||||
if (interlaced) {
|
||||
drm_mode->vtotal *= 2;
|
||||
drm_mode->flags |= DRM_MODE_FLAG_INTERLACE;
|
||||
}
|
||||
|
||||
drm_mode_set_name(drm_mode);
|
||||
if (GTF_M == 600 && GTF_2C == 80 && GTF_K == 128 && GTF_2J == 40)
|
||||
drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC;
|
||||
else
|
||||
drm_mode->flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC;
|
||||
|
||||
return drm_mode;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gtf_mode_complex);
|
||||
|
||||
/**
|
||||
* drm_gtf_mode - create the modeline based on GTF algorithm
|
||||
*
|
||||
* @dev :drm device
|
||||
* @hdisplay :hdisplay size
|
||||
* @vdisplay :vdisplay size
|
||||
* @vrefresh :vrefresh rate.
|
||||
* @interlaced :whether the interlace is supported
|
||||
* @margins :whether the margin is supported
|
||||
*
|
||||
* LOCKING.
|
||||
* none.
|
||||
*
|
||||
* return the modeline based on GTF algorithm
|
||||
*
|
||||
* This function is to create the modeline based on the GTF algorithm.
|
||||
* Generalized Timing Formula is derived from:
|
||||
* GTF Spreadsheet by Andy Morrish (1/5/97)
|
||||
* available at http://www.vesa.org
|
||||
*
|
||||
* And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c.
|
||||
* What I have done is to translate it by using integer calculation.
|
||||
* I also refer to the function of fb_get_mode in the file of
|
||||
* drivers/video/fbmon.c
|
||||
*
|
||||
* Standard GTF parameters:
|
||||
* M = 600
|
||||
* C = 40
|
||||
* K = 128
|
||||
* J = 20
|
||||
*/
|
||||
struct drm_display_mode *
|
||||
drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh,
|
||||
bool lace, int margins)
|
||||
{
|
||||
return drm_gtf_mode_complex(dev, hdisplay, vdisplay, vrefresh, lace,
|
||||
margins, 600, 40 * 2, 128, 20 * 2);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gtf_mode);
|
||||
|
||||
/**
|
||||
* drm_mode_set_name - set the name on a mode
|
||||
* @mode: name will be set in this mode
|
||||
|
@ -482,8 +512,11 @@ EXPORT_SYMBOL(drm_gtf_mode);
|
|||
*/
|
||||
void drm_mode_set_name(struct drm_display_mode *mode)
|
||||
{
|
||||
snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d", mode->hdisplay,
|
||||
mode->vdisplay);
|
||||
bool interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
|
||||
|
||||
snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d%s",
|
||||
mode->hdisplay, mode->vdisplay,
|
||||
interlaced ? "i" : "");
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_set_name);
|
||||
|
||||
|
|
|
@ -333,7 +333,7 @@ static struct device_attribute connector_attrs_opt1[] = {
|
|||
static struct bin_attribute edid_attr = {
|
||||
.attr.name = "edid",
|
||||
.attr.mode = 0444,
|
||||
.size = 128,
|
||||
.size = 0,
|
||||
.read = edid_show,
|
||||
};
|
||||
|
||||
|
|
|
@ -450,17 +450,17 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
|
|||
{
|
||||
int edid_info;
|
||||
struct edid *edid;
|
||||
unsigned char *raw;
|
||||
edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
|
||||
if (!edid_info)
|
||||
return false;
|
||||
|
||||
edid = kmalloc(EDID_LENGTH * (DRM_MAX_EDID_EXT_NUM + 1),
|
||||
GFP_KERNEL);
|
||||
raw = rdev->bios + edid_info;
|
||||
edid = kmalloc(EDID_LENGTH * (raw[0x7e] + 1), GFP_KERNEL);
|
||||
if (edid == NULL)
|
||||
return false;
|
||||
|
||||
memcpy((unsigned char *)edid,
|
||||
(unsigned char *)(rdev->bios + edid_info), EDID_LENGTH);
|
||||
memcpy((unsigned char *)edid, raw, EDID_LENGTH * (raw[0x7e] + 1));
|
||||
|
||||
if (!drm_edid_is_valid(edid)) {
|
||||
kfree(edid);
|
||||
|
|
|
@ -666,8 +666,6 @@ extern void drm_fb_release(struct drm_file *file_priv);
|
|||
extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group);
|
||||
extern struct edid *drm_get_edid(struct drm_connector *connector,
|
||||
struct i2c_adapter *adapter);
|
||||
extern int drm_do_probe_ddc_edid(struct i2c_adapter *adapter,
|
||||
unsigned char *buf, int len);
|
||||
extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
|
||||
extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
|
||||
extern void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode);
|
||||
|
@ -799,6 +797,10 @@ extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
|
|||
extern struct drm_display_mode *drm_gtf_mode(struct drm_device *dev,
|
||||
int hdisplay, int vdisplay, int vrefresh,
|
||||
bool interlaced, int margins);
|
||||
extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev,
|
||||
int hdisplay, int vdisplay, int vrefresh,
|
||||
bool interlaced, int margins, int GTF_M,
|
||||
int GTF_2C, int GTF_K, int GTF_2J);
|
||||
extern int drm_add_modes_noedid(struct drm_connector *connector,
|
||||
int hdisplay, int vdisplay);
|
||||
|
||||
|
|
|
@ -201,7 +201,4 @@ struct edid {
|
|||
|
||||
#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__ */
|
||||
|
|
Loading…
Reference in a new issue