Commit 721b0821 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/bios: simplify U/d table hash matching func to just match

The caller is now responsible for parsing its own lists (or whatever) of
possible encoders.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 5b3eb95f
...@@ -4426,55 +4426,32 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b ...@@ -4426,55 +4426,32 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
return 0; return 0;
} }
static uint8_t * /* BIT 'U'/'d' table encoder subtables have hashes matching them to
bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent, * a particular set of encoders.
uint16_t record, int record_len, int record_nr, *
bool match_link) * This function returns true if a particular DCB entry matches.
*/
bool
bios_encoder_match(struct dcb_entry *dcb, u32 hash)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; if ((hash & 0x000000f0) != (dcb->location << 4))
struct nvbios *bios = &dev_priv->vbios; return false;
uint32_t entry; if ((hash & 0x0000000f) != dcb->type)
uint16_t table; return false;
int i, v; if (!(hash & (dcb->or << 16)))
return false;
switch (dcbent->type) { switch (dcb->type) {
case OUTPUT_TMDS: case OUTPUT_TMDS:
case OUTPUT_LVDS: case OUTPUT_LVDS:
case OUTPUT_DP: case OUTPUT_DP:
break; if (hash & 0x00c00000) {
default: if (!(hash & (dcb->sorconf.link << 22)))
match_link = false; return false;
break;
}
for (i = 0; i < record_nr; i++, record += record_len) {
table = ROM16(bios->data[record]);
if (!table)
continue;
entry = ROM32(bios->data[table]);
if (match_link) {
v = (entry & 0x00c00000) >> 22;
if (!(v & dcbent->sorconf.link))
continue;
} }
default:
v = (entry & 0x000f0000) >> 16; return true;
if (!(v & dcbent->or))
continue;
v = (entry & 0x000000f0) >> 4;
if (v != dcbent->location)
continue;
v = (entry & 0x0000000f);
if (v != dcbent->type)
continue;
return &bios->data[table];
} }
return NULL;
} }
void * void *
...@@ -4483,7 +4460,8 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent, ...@@ -4483,7 +4460,8 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent,
{ {
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;
uint8_t *table; uint8_t *table, *entry;
int i;
if (!bios->display.dp_table_ptr) { if (!bios->display.dp_table_ptr) {
NV_ERROR(dev, "No pointer to DisplayPort table\n"); NV_ERROR(dev, "No pointer to DisplayPort table\n");
...@@ -4497,10 +4475,17 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent, ...@@ -4497,10 +4475,17 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent,
return NULL; return NULL;
} }
*headerlen = table[4]; entry = table + table[1];
return bios_output_config_match(dev, dcbent, for (i = 0; i < table[3]; i++, entry += table[2]) {
bios->display.dp_table_ptr + table[1], u8 *etable = ROMPTR(bios, entry[0]);
table[2], table[3], table[0] >= 0x21); if (etable && bios_encoder_match(dcbent, ROM32(etable[0]))) {
*headerlen = table[4];
return etable;
}
}
NV_ERROR(dev, "DisplayPort encoder table not found\n");
return NULL;
} }
int int
...@@ -4535,7 +4520,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk, ...@@ -4535,7 +4520,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
uint8_t *table = &bios->data[bios->display.script_table_ptr]; uint8_t *table = &bios->data[bios->display.script_table_ptr];
uint8_t *otable = NULL; uint8_t *otable = NULL;
uint16_t script; uint16_t script;
int i = 0; int i;
if (!bios->display.script_table_ptr) { if (!bios->display.script_table_ptr) {
NV_ERROR(dev, "No pointer to output script table\n"); NV_ERROR(dev, "No pointer to output script table\n");
...@@ -4587,9 +4572,12 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk, ...@@ -4587,9 +4572,12 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n", NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n",
dcbent->type, dcbent->location, dcbent->or); dcbent->type, dcbent->location, dcbent->or);
otable = bios_output_config_match(dev, dcbent, table[1] + for (i = 0; i < table[3]; i++) {
bios->display.script_table_ptr, otable = ROMPTR(bios, table[table[1] + (i * table[2])]);
table[2], table[3], table[0] >= 0x21); if (otable && bios_encoder_match(dcbent, ROM32(otable[0])))
break;
}
if (!otable) { if (!otable) {
NV_DEBUG_KMS(dev, "failed to match any output table\n"); NV_DEBUG_KMS(dev, "failed to match any output table\n");
return 1; return 1;
......
...@@ -1090,6 +1090,7 @@ extern int run_tmds_table(struct drm_device *, struct dcb_entry *, ...@@ -1090,6 +1090,7 @@ extern int run_tmds_table(struct drm_device *, struct dcb_entry *,
int head, int pxclk); int head, int pxclk);
extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head, extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head,
enum LVDS_script, int pxclk); enum LVDS_script, int pxclk);
bool bios_encoder_match(struct dcb_entry *, u32 hash);
/* nouveau_ttm.c */ /* nouveau_ttm.c */
int nouveau_ttm_global_init(struct drm_nouveau_private *); int nouveau_ttm_global_init(struct drm_nouveau_private *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment