aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_bios.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-08-19 11:09:23 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-08 05:13:32 -0400
commit44834a67c0082e2cf74b16be91e49108b1432d65 (patch)
treeebe2c53b1a08b99a95b579942ae2d7603935709d /drivers/gpu/drm/i915/intel_bios.c
parent3b61796785e7b0ca8846b7a709216dceb6e2f68d (diff)
drm/i915: Use the VBT from OpRegion when available (v3)
It is recommended that we use the Video BIOS tables that were copied into the OpRegion during POST when initialising the driver. This saves us from having to furtle around inside the ROM ourselves and possibly allows the vBIOS to adjust the tables prior to initialisation. On some systems, such as the Samsung N210, there is no accessible VBIOS and the only means of finding the VBT is through the OpRegion. v2: Rearrange the code so that ASLE is enabled along with ACPI v3: Enable OpRegion parsing even without ACPI Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_bios.c')
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c73
1 files changed, 42 insertions, 31 deletions
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 96f75d7f663..8d7deca6983 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -317,7 +317,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
317 317
318static void 318static void
319parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, 319parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
320 struct bdb_header *bdb) 320 struct bdb_header *bdb)
321{ 321{
322 struct sdvo_device_mapping *p_mapping; 322 struct sdvo_device_mapping *p_mapping;
323 struct bdb_general_definitions *p_defs; 323 struct bdb_general_definitions *p_defs;
@@ -327,7 +327,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
327 327
328 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); 328 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
329 if (!p_defs) { 329 if (!p_defs) {
330 DRM_DEBUG_KMS("No general definition block is found\n"); 330 DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
331 return; 331 return;
332 } 332 }
333 /* judge whether the size of child device meets the requirements. 333 /* judge whether the size of child device meets the requirements.
@@ -460,7 +460,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
460 460
461 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); 461 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
462 if (!p_defs) { 462 if (!p_defs) {
463 DRM_DEBUG_KMS("No general definition block is found\n"); 463 DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
464 return; 464 return;
465 } 465 }
466 /* judge whether the size of child device meets the requirements. 466 /* judge whether the size of child device meets the requirements.
@@ -513,6 +513,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
513 } 513 }
514 return; 514 return;
515} 515}
516
516/** 517/**
517 * intel_init_bios - initialize VBIOS settings & find VBT 518 * intel_init_bios - initialize VBIOS settings & find VBT
518 * @dev: DRM device 519 * @dev: DRM device
@@ -520,11 +521,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
520 * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers 521 * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers
521 * to appropriate values. 522 * to appropriate values.
522 * 523 *
523 * VBT existence is a sanity check that is relied on by other i830_bios.c code.
524 * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may
525 * feed an updated VBT back through that, compared to what we'll fetch using
526 * this method of groping around in the BIOS data.
527 *
528 * Returns 0 on success, nonzero on failure. 524 * Returns 0 on success, nonzero on failure.
529 */ 525 */
530bool 526bool
@@ -532,31 +528,45 @@ intel_init_bios(struct drm_device *dev)
532{ 528{
533 struct drm_i915_private *dev_priv = dev->dev_private; 529 struct drm_i915_private *dev_priv = dev->dev_private;
534 struct pci_dev *pdev = dev->pdev; 530 struct pci_dev *pdev = dev->pdev;
535 struct vbt_header *vbt = NULL; 531 struct bdb_header *bdb = NULL;
536 struct bdb_header *bdb; 532 u8 __iomem *bios = NULL;
537 u8 __iomem *bios; 533
538 size_t size; 534 /* XXX Should this validation be moved to intel_opregion.c? */
539 int i; 535 if (dev_priv->opregion.vbt) {
540 536 struct vbt_header *vbt = dev_priv->opregion.vbt;
541 bios = pci_map_rom(pdev, &size); 537 if (memcmp(vbt->signature, "$VBT", 4) == 0) {
542 if (!bios) 538 DRM_DEBUG_DRIVER("Using VBT from OpRegion: %20s\n",
543 return -1; 539 vbt->signature);
544 540 bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset);
545 /* Scour memory looking for the VBT signature */ 541 } else
546 for (i = 0; i + 4 < size; i++) { 542 dev_priv->opregion.vbt = NULL;
547 if (!memcmp(bios + i, "$VBT", 4)) {
548 vbt = (struct vbt_header *)(bios + i);
549 break;
550 }
551 } 543 }
552 544
553 if (!vbt) { 545 if (bdb == NULL) {
554 DRM_ERROR("VBT signature missing\n"); 546 struct vbt_header *vbt = NULL;
555 pci_unmap_rom(pdev, bios); 547 size_t size;
556 return -1; 548 int i;
557 }
558 549
559 bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); 550 bios = pci_map_rom(pdev, &size);
551 if (!bios)
552 return -1;
553
554 /* Scour memory looking for the VBT signature */
555 for (i = 0; i + 4 < size; i++) {
556 if (!memcmp(bios + i, "$VBT", 4)) {
557 vbt = (struct vbt_header *)(bios + i);
558 break;
559 }
560 }
561
562 if (!vbt) {
563 DRM_ERROR("VBT signature missing\n");
564 pci_unmap_rom(pdev, bios);
565 return -1;
566 }
567
568 bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);
569 }
560 570
561 /* Grab useful general definitions */ 571 /* Grab useful general definitions */
562 parse_general_features(dev_priv, bdb); 572 parse_general_features(dev_priv, bdb);
@@ -568,7 +578,8 @@ intel_init_bios(struct drm_device *dev)
568 parse_driver_features(dev_priv, bdb); 578 parse_driver_features(dev_priv, bdb);
569 parse_edp(dev_priv, bdb); 579 parse_edp(dev_priv, bdb);
570 580
571 pci_unmap_rom(pdev, bios); 581 if (bios)
582 pci_unmap_rom(pdev, bios);
572 583
573 return 0; 584 return 0;
574} 585}