diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-08-04 23:42:49 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 02:11:14 -0400 |
commit | 721b0821ad8fea80ea1b6b84cb9646881959e662 (patch) | |
tree | b9d84161531fcf2aae0493233662126d0b2b317e /drivers/gpu/drm | |
parent | 5b3eb95fd83861a8520a50aee517209b8c8b0505 (diff) |
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: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.c | 90 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 1 |
2 files changed, 40 insertions, 51 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index bea5df7cf93c..73b590a71949 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -4426,55 +4426,32 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b | |||
4426 | return 0; | 4426 | return 0; |
4427 | } | 4427 | } |
4428 | 4428 | ||
4429 | static uint8_t * | 4429 | /* BIT 'U'/'d' table encoder subtables have hashes matching them to |
4430 | bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent, | 4430 | * a particular set of encoders. |
4431 | uint16_t record, int record_len, int record_nr, | 4431 | * |
4432 | bool match_link) | 4432 | * This function returns true if a particular DCB entry matches. |
4433 | */ | ||
4434 | bool | ||
4435 | bios_encoder_match(struct dcb_entry *dcb, u32 hash) | ||
4433 | { | 4436 | { |
4434 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 4437 | if ((hash & 0x000000f0) != (dcb->location << 4)) |
4435 | struct nvbios *bios = &dev_priv->vbios; | 4438 | return false; |
4436 | uint32_t entry; | 4439 | if ((hash & 0x0000000f) != dcb->type) |
4437 | uint16_t table; | 4440 | return false; |
4438 | int i, v; | 4441 | if (!(hash & (dcb->or << 16))) |
4442 | return false; | ||
4439 | 4443 | ||
4440 | switch (dcbent->type) { | 4444 | switch (dcb->type) { |
4441 | case OUTPUT_TMDS: | 4445 | case OUTPUT_TMDS: |
4442 | case OUTPUT_LVDS: | 4446 | case OUTPUT_LVDS: |
4443 | case OUTPUT_DP: | 4447 | case OUTPUT_DP: |
4444 | break; | 4448 | if (hash & 0x00c00000) { |
4445 | default: | 4449 | if (!(hash & (dcb->sorconf.link << 22))) |
4446 | match_link = false; | 4450 | return false; |
4447 | break; | ||
4448 | } | ||
4449 | |||
4450 | for (i = 0; i < record_nr; i++, record += record_len) { | ||
4451 | table = ROM16(bios->data[record]); | ||
4452 | if (!table) | ||
4453 | continue; | ||
4454 | entry = ROM32(bios->data[table]); | ||
4455 | |||
4456 | if (match_link) { | ||
4457 | v = (entry & 0x00c00000) >> 22; | ||
4458 | if (!(v & dcbent->sorconf.link)) | ||
4459 | continue; | ||
4460 | } | 4451 | } |
4461 | 4452 | default: | |
4462 | v = (entry & 0x000f0000) >> 16; | 4453 | return true; |
4463 | if (!(v & dcbent->or)) | ||
4464 | continue; | ||
4465 | |||
4466 | v = (entry & 0x000000f0) >> 4; | ||
4467 | if (v != dcbent->location) | ||
4468 | continue; | ||
4469 | |||
4470 | v = (entry & 0x0000000f); | ||
4471 | if (v != dcbent->type) | ||
4472 | continue; | ||
4473 | |||
4474 | return &bios->data[table]; | ||
4475 | } | 4454 | } |
4476 | |||
4477 | return NULL; | ||
4478 | } | 4455 | } |
4479 | 4456 | ||
4480 | void * | 4457 | void * |
@@ -4483,7 +4460,8 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4483 | { | 4460 | { |
4484 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 4461 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
4485 | struct nvbios *bios = &dev_priv->vbios; | 4462 | struct nvbios *bios = &dev_priv->vbios; |
4486 | uint8_t *table; | 4463 | uint8_t *table, *entry; |
4464 | int i; | ||
4487 | 4465 | ||
4488 | if (!bios->display.dp_table_ptr) { | 4466 | if (!bios->display.dp_table_ptr) { |
4489 | NV_ERROR(dev, "No pointer to DisplayPort table\n"); | 4467 | 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 | return NULL; | 4475 | return NULL; |
4498 | } | 4476 | } |
4499 | 4477 | ||
4500 | *headerlen = table[4]; | 4478 | entry = table + table[1]; |
4501 | return bios_output_config_match(dev, dcbent, | 4479 | for (i = 0; i < table[3]; i++, entry += table[2]) { |
4502 | bios->display.dp_table_ptr + table[1], | 4480 | u8 *etable = ROMPTR(bios, entry[0]); |
4503 | table[2], table[3], table[0] >= 0x21); | 4481 | if (etable && bios_encoder_match(dcbent, ROM32(etable[0]))) { |
4482 | *headerlen = table[4]; | ||
4483 | return etable; | ||
4484 | } | ||
4485 | } | ||
4486 | |||
4487 | NV_ERROR(dev, "DisplayPort encoder table not found\n"); | ||
4488 | return NULL; | ||
4504 | } | 4489 | } |
4505 | 4490 | ||
4506 | int | 4491 | int |
@@ -4535,7 +4520,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk, | |||
4535 | uint8_t *table = &bios->data[bios->display.script_table_ptr]; | 4520 | uint8_t *table = &bios->data[bios->display.script_table_ptr]; |
4536 | uint8_t *otable = NULL; | 4521 | uint8_t *otable = NULL; |
4537 | uint16_t script; | 4522 | uint16_t script; |
4538 | int i = 0; | 4523 | int i; |
4539 | 4524 | ||
4540 | if (!bios->display.script_table_ptr) { | 4525 | if (!bios->display.script_table_ptr) { |
4541 | NV_ERROR(dev, "No pointer to output script table\n"); | 4526 | 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 | 4572 | ||
4588 | NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n", | 4573 | NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n", |
4589 | dcbent->type, dcbent->location, dcbent->or); | 4574 | dcbent->type, dcbent->location, dcbent->or); |
4590 | otable = bios_output_config_match(dev, dcbent, table[1] + | 4575 | for (i = 0; i < table[3]; i++) { |
4591 | bios->display.script_table_ptr, | 4576 | otable = ROMPTR(bios, table[table[1] + (i * table[2])]); |
4592 | table[2], table[3], table[0] >= 0x21); | 4577 | if (otable && bios_encoder_match(dcbent, ROM32(otable[0]))) |
4578 | break; | ||
4579 | } | ||
4580 | |||
4593 | if (!otable) { | 4581 | if (!otable) { |
4594 | NV_DEBUG_KMS(dev, "failed to match any output table\n"); | 4582 | NV_DEBUG_KMS(dev, "failed to match any output table\n"); |
4595 | return 1; | 4583 | return 1; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 3cf8e6a10e9d..d269b7ba45cc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -1090,6 +1090,7 @@ extern int run_tmds_table(struct drm_device *, struct dcb_entry *, | |||
1090 | int head, int pxclk); | 1090 | int head, int pxclk); |
1091 | extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head, | 1091 | extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head, |
1092 | enum LVDS_script, int pxclk); | 1092 | enum LVDS_script, int pxclk); |
1093 | bool bios_encoder_match(struct dcb_entry *, u32 hash); | ||
1093 | 1094 | ||
1094 | /* nouveau_ttm.c */ | 1095 | /* nouveau_ttm.c */ |
1095 | int nouveau_ttm_global_init(struct drm_nouveau_private *); | 1096 | int nouveau_ttm_global_init(struct drm_nouveau_private *); |