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

Commit 1eb38100 authored by Ben Skeggs's avatar Ben Skeggs Committed by Dave Airlie
Browse files

drm/nouveau: match U/DP script against SOR link



It appears version 0x21 'U' and 'd' tables require us to take the SOR link
into account when selecting the appropriate table for a particular output.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent f712d0c7
Loading
Loading
Loading
Loading
+20 −3
Original line number Original line Diff line number Diff line
@@ -3920,7 +3920,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b


static uint8_t *
static uint8_t *
bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent,
bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent,
			 uint16_t record, int record_len, int record_nr)
			 uint16_t record, int record_len, int record_nr,
			 bool match_link)
{
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nvbios *bios = &dev_priv->vbios;
	struct nvbios *bios = &dev_priv->vbios;
@@ -3928,12 +3929,28 @@ bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent,
	uint16_t table;
	uint16_t table;
	int i, v;
	int i, v;


	switch (dcbent->type) {
	case OUTPUT_TMDS:
	case OUTPUT_LVDS:
	case OUTPUT_DP:
		break;
	default:
		match_link = false;
		break;
	}

	for (i = 0; i < record_nr; i++, record += record_len) {
	for (i = 0; i < record_nr; i++, record += record_len) {
		table = ROM16(bios->data[record]);
		table = ROM16(bios->data[record]);
		if (!table)
		if (!table)
			continue;
			continue;
		entry = ROM32(bios->data[table]);
		entry = ROM32(bios->data[table]);


		if (match_link) {
			v = (entry & 0x00c00000) >> 22;
			if (!(v & dcbent->sorconf.link))
				continue;
		}

		v = (entry & 0x000f0000) >> 16;
		v = (entry & 0x000f0000) >> 16;
		if (!(v & dcbent->or))
		if (!(v & dcbent->or))
			continue;
			continue;
@@ -3975,7 +3992,7 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent,
	*length = table[4];
	*length = table[4];
	return bios_output_config_match(dev, dcbent,
	return bios_output_config_match(dev, dcbent,
					bios->display.dp_table_ptr + table[1],
					bios->display.dp_table_ptr + table[1],
					table[2], table[3]);
					table[2], table[3], table[0] >= 0x21);
}
}


int
int
@@ -4064,7 +4081,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
			dcbent->type, dcbent->location, dcbent->or);
			dcbent->type, dcbent->location, dcbent->or);
	otable = bios_output_config_match(dev, dcbent, table[1] +
	otable = bios_output_config_match(dev, dcbent, table[1] +
					  bios->display.script_table_ptr,
					  bios->display.script_table_ptr,
					  table[2], table[3]);
					  table[2], table[3], table[0] >= 0x21);
	if (!otable) {
	if (!otable) {
		NV_ERROR(dev, "Couldn't find matching output script table\n");
		NV_ERROR(dev, "Couldn't find matching output script table\n");
		return 1;
		return 1;