aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2009-11-23 20:48:44 -0500
committerEric Anholt <eric@anholt.net>2009-11-30 19:36:53 -0500
commit6363ee6f496eb7e3b3f78dc105e522c7b496089b (patch)
tree238a22cf4e317645bc77a62ff828e15b27d5ce7b /drivers/gpu/drm
parentc1b5dea097258b3d3d570d5ccc8f4bf5accb3f29 (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')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c9
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c65
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h17
4 files changed, 93 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 093146bacf84..a8efe78e5c57 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1526,6 +1526,15 @@ int i915_driver_unload(struct drm_device *dev)
1526 } 1526 }
1527 1527
1528 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 1528 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1529 /*
1530 * free the memory space allocated for the child device
1531 * config parsed from VBT
1532 */
1533 if (dev_priv->child_dev && dev_priv->child_dev_num) {
1534 kfree(dev_priv->child_dev);
1535 dev_priv->child_dev = NULL;
1536 dev_priv->child_dev_num = 0;
1537 }
1529 drm_irq_uninstall(dev); 1538 drm_irq_uninstall(dev);
1530 vga_client_register(dev->pdev, NULL, NULL, NULL); 1539 vga_client_register(dev->pdev, NULL, NULL, NULL);
1531 } 1540 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 13ede75ff6ce..cc91cff8871c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -545,6 +545,8 @@ typedef struct drm_i915_private {
545 struct timer_list idle_timer; 545 struct timer_list idle_timer;
546 bool busy; 546 bool busy;
547 u16 orig_clock; 547 u16 orig_clock;
548 int child_dev_num;
549 struct child_device_config *child_dev;
548} drm_i915_private_t; 550} drm_i915_private_t;
549 551
550/** driver private structure attached to each drm_gem_object */ 552/** driver private structure attached to each drm_gem_object */
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
407static void
408parse_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);
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 0f8e5f69ac7a..425ac9d7f724 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -549,4 +549,21 @@ bool intel_init_bios(struct drm_device *dev);
549#define SWF14_APM_STANDBY 0x1 549#define SWF14_APM_STANDBY 0x1
550#define SWF14_APM_RESTORE 0x0 550#define SWF14_APM_RESTORE 0x0
551 551
552/* Add the device class for LFP, TV, HDMI */
553#define DEVICE_TYPE_INT_LFP 0x1022
554#define DEVICE_TYPE_INT_TV 0x1009
555#define DEVICE_TYPE_HDMI 0x60D2
556#define DEVICE_TYPE_DP 0x68C6
557#define DEVICE_TYPE_eDP 0x78C6
558
559/* define the DVO port for HDMI output type */
560#define DVO_B 1
561#define DVO_C 2
562#define DVO_D 3
563
564/* define the PORT for DP output type */
565#define PORT_IDPB 7
566#define PORT_IDPC 8
567#define PORT_IDPD 9
568
552#endif /* _I830_BIOS_H_ */ 569#endif /* _I830_BIOS_H_ */