aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_bios.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_bios.c')
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c65
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
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);