Commit 9340d8cf authored by Adam Jackson's avatar Adam Jackson Committed by Dave Airlie
Browse files

drm/edid: Decode 3-byte CVT codes from EDID 1.4



Signed-off-by: default avatarAdam Jackson <ajax@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 2dbdc52c
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -897,6 +897,51 @@ static int drm_gtf_modes_for_range(struct drm_connector *connector,
	return modes;
}

static int drm_cvt_modes(struct drm_connector *connector,
			 struct detailed_timing *timing)
{
	int i, j, modes = 0;
	struct drm_display_mode *newmode;
	struct drm_device *dev = connector->dev;
	struct cvt_timing *cvt;
	const int rates[] = { 60, 85, 75, 60, 50 };

	for (i = 0; i < 4; i++) {
		int width, height;
		cvt = &(timing->data.other_data.data.cvt[i]);

		height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2;
		switch (cvt->code[1] & 0xc0) {
		case 0x00:
			width = height * 4 / 3;
			break;
		case 0x40:
			width = height * 16 / 9;
			break;
		case 0x80:
			width = height * 16 / 10;
			break;
		case 0xc0:
			width = height * 15 / 9;
			break;
		}

		for (j = 1; j < 5; j++) {
			if (cvt->code[2] & (1 << j)) {
				newmode = drm_cvt_mode(dev, width, height,
						       rates[j], j == 0,
						       false, false);
				if (newmode) {
					drm_mode_probed_add(connector, newmode);
					modes++;
				}
			}
		}
	}

	return modes;
}

static int add_detailed_modes(struct drm_connector *connector,
			      struct detailed_timing *timing,
			      struct edid *edid, u32 quirks, int preferred)
@@ -941,6 +986,9 @@ static int add_detailed_modes(struct drm_connector *connector,
			}
		}
		break;
	case EDID_DETAIL_CVT_3BYTE:
		modes += drm_cvt_modes(connector, timing);
		break;
	default:
		break;
	}
+5 −0
Original line number Diff line number Diff line
@@ -106,6 +106,10 @@ struct detailed_data_color_point {
	u8 wpindex2[3];
} __attribute__((packed));

struct cvt_timing {
	u8 code[3];
} __attribute__((packed));

struct detailed_non_pixel {
	u8 pad1;
	u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name
@@ -117,6 +121,7 @@ struct detailed_non_pixel {
		struct detailed_data_monitor_range range;
		struct detailed_data_wpindex color;
		struct std_timing timings[5];
		struct cvt_timing cvt[4];
	} data;
} __attribute__((packed));