aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-08-04 23:42:49 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 02:11:14 -0400
commit721b0821ad8fea80ea1b6b84cb9646881959e662 (patch)
treeb9d84161531fcf2aae0493233662126d0b2b317e /drivers/gpu/drm
parent5b3eb95fd83861a8520a50aee517209b8c8b0505 (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.c90
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
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
4429static uint8_t * 4429/* BIT 'U'/'d' table encoder subtables have hashes matching them to
4430bios_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 */
4434bool
4435bios_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
4480void * 4457void *
@@ -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
4506int 4491int
@@ -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);
1091extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head, 1091extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head,
1092 enum LVDS_script, int pxclk); 1092 enum LVDS_script, int pxclk);
1093bool bios_encoder_match(struct dcb_entry *, u32 hash);
1093 1094
1094/* nouveau_ttm.c */ 1095/* nouveau_ttm.c */
1095int nouveau_ttm_global_init(struct drm_nouveau_private *); 1096int nouveau_ttm_global_init(struct drm_nouveau_private *);