Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c9c2625f authored by Dave Airlie's avatar Dave Airlie
Browse files

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.
parents c2b41276 522032da
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -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,
+543 −246

File changed.

Preview size limit exceeded, changes collapsed.

+69 −36
Original line number Diff line number Diff line
@@ -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;
}
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,16 +310,8 @@ 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_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;
@@ -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);

+1 −1
Original line number Diff line number Diff line
@@ -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,
};

+4 −4
Original line number Diff line number Diff line
@@ -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);
Loading