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: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
f712d0c7e7
commit
1eb38100ab
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue