diff options
author | Zhao Yakui <yakui.zhao@intel.com> | 2009-11-23 20:48:44 -0500 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-11-30 19:36:53 -0500 |
commit | 6363ee6f496eb7e3b3f78dc105e522c7b496089b (patch) | |
tree | 238a22cf4e317645bc77a62ff828e15b27d5ce7b /drivers/gpu/drm/i915/intel_bios.c | |
parent | c1b5dea097258b3d3d570d5ccc8f4bf5accb3f29 (diff) |
drm/i915: parse child device from VBT
On some laptops there is no HDMI/DP. But the xrandr still reports
several disconnected HDMI/display ports. In such case the user will be
confused.
>DVI1 disconnected (normal left inverted right x axis y axis)
>DP1 disconnected (normal left inverted right x axis y axis)
>DVI2 disconnected (normal left inverted right x axis y axis)
>DP2 disconnected (normal left inverted right x axis y axis)
>DP3 disconnected (normal left inverted right x axis y axis)
This patch set is to use the child device parsed in VBT to decide whether
the HDMI/DP/LVDS/TV should be initialized.
Parse the child device from VBT.
The device class type is also added for LFP, TV, HDMI, DP output.
https://bugs.freedesktop.org/show_bug.cgi?id=22785
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_bios.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 800d13bd9e6a..73ceb36c790e 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -404,6 +404,70 @@ parse_driver_features(struct drm_i915_private *dev_priv, | |||
404 | dev_priv->render_reclock_avail = true; | 404 | dev_priv->render_reclock_avail = true; |
405 | } | 405 | } |
406 | 406 | ||
407 | static void | ||
408 | parse_device_mapping(struct drm_i915_private *dev_priv, | ||
409 | struct bdb_header *bdb) | ||
410 | { | ||
411 | struct bdb_general_definitions *p_defs; | ||
412 | struct child_device_config *p_child, *child_dev_ptr; | ||
413 | int i, child_device_num, count; | ||
414 | u16 block_size; | ||
415 | |||
416 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | ||
417 | if (!p_defs) { | ||
418 | DRM_DEBUG_KMS("No general definition block is found\n"); | ||
419 | return; | ||
420 | } | ||
421 | /* judge whether the size of child device meets the requirements. | ||
422 | * If the child device size obtained from general definition block | ||
423 | * is different with sizeof(struct child_device_config), skip the | ||
424 | * parsing of sdvo device info | ||
425 | */ | ||
426 | if (p_defs->child_dev_size != sizeof(*p_child)) { | ||
427 | /* different child dev size . Ignore it */ | ||
428 | DRM_DEBUG_KMS("different child size is found. Invalid.\n"); | ||
429 | return; | ||
430 | } | ||
431 | /* get the block size of general definitions */ | ||
432 | block_size = get_blocksize(p_defs); | ||
433 | /* get the number of child device */ | ||
434 | child_device_num = (block_size - sizeof(*p_defs)) / | ||
435 | sizeof(*p_child); | ||
436 | count = 0; | ||
437 | /* get the number of child device that is present */ | ||
438 | for (i = 0; i < child_device_num; i++) { | ||
439 | p_child = &(p_defs->devices[i]); | ||
440 | if (!p_child->device_type) { | ||
441 | /* skip the device block if device type is invalid */ | ||
442 | continue; | ||
443 | } | ||
444 | count++; | ||
445 | } | ||
446 | if (!count) { | ||
447 | DRM_DEBUG_KMS("no child dev is parsed from VBT \n"); | ||
448 | return; | ||
449 | } | ||
450 | dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL); | ||
451 | if (!dev_priv->child_dev) { | ||
452 | DRM_DEBUG_KMS("No memory space for child device\n"); | ||
453 | return; | ||
454 | } | ||
455 | |||
456 | dev_priv->child_dev_num = count; | ||
457 | count = 0; | ||
458 | for (i = 0; i < child_device_num; i++) { | ||
459 | p_child = &(p_defs->devices[i]); | ||
460 | if (!p_child->device_type) { | ||
461 | /* skip the device block if device type is invalid */ | ||
462 | continue; | ||
463 | } | ||
464 | child_dev_ptr = dev_priv->child_dev + count; | ||
465 | count++; | ||
466 | memcpy((void *)child_dev_ptr, (void *)p_child, | ||
467 | sizeof(*p_child)); | ||
468 | } | ||
469 | return; | ||
470 | } | ||
407 | /** | 471 | /** |
408 | * intel_init_bios - initialize VBIOS settings & find VBT | 472 | * intel_init_bios - initialize VBIOS settings & find VBT |
409 | * @dev: DRM device | 473 | * @dev: DRM device |
@@ -455,6 +519,7 @@ intel_init_bios(struct drm_device *dev) | |||
455 | parse_lfp_panel_data(dev_priv, bdb); | 519 | parse_lfp_panel_data(dev_priv, bdb); |
456 | parse_sdvo_panel_data(dev_priv, bdb); | 520 | parse_sdvo_panel_data(dev_priv, bdb); |
457 | parse_sdvo_device_mapping(dev_priv, bdb); | 521 | parse_sdvo_device_mapping(dev_priv, bdb); |
522 | parse_device_mapping(dev_priv, bdb); | ||
458 | parse_driver_features(dev_priv, bdb); | 523 | parse_driver_features(dev_priv, bdb); |
459 | 524 | ||
460 | pci_unmap_rom(pdev, bios); | 525 | pci_unmap_rom(pdev, bios); |