drm/i915/bios: parse SDVO device mapping from pre-parsed child devices
authorJani Nikula <jani.nikula@intel.com>
Thu, 28 Sep 2017 08:22:03 +0000 (11:22 +0300)
committerJani Nikula <jani.nikula@intel.com>
Tue, 10 Oct 2017 06:06:17 +0000 (09:06 +0300)
We parse and store the child devices in
parse_general_definitions(). There is no need to parse the VBT block
again for SDVO device mapping. Do the same as we do in
parse_ddi_ports().

We no longer have access to child device size at this stage, but we also
don't need to worry about reading past the child device anymore. Instead
of a child device size check, do a mild optimization by limiting the
parsing to gens 3 through 7.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/c918d4173dd38a165295f1270cb16c2c01bd8cd1.1506586821.git.jani.nikula@intel.com
drivers/gpu/drm/i915/intel_bios.c

index aaad984e35e228ded7cbff09c4235756c842e4d1..4d26fcc5cabb6f256a8b201525c8ece6d32ead0e 100644 (file)
@@ -442,37 +442,21 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
                          const struct bdb_header *bdb)
 {
        struct sdvo_device_mapping *mapping;
-       const struct bdb_general_definitions *defs;
        const struct child_device_config *child;
-       int i, child_device_num, count;
-       u16     block_size;
-
-       defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
-       if (!defs) {
-               DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
-               return;
-       }
+       int i, count = 0;
 
        /*
-        * Only parse SDVO mappings when the general definitions block child
-        * device size matches that of the *legacy* child device config
-        * struct. Thus, SDVO mapping will be skipped for newer VBT.
+        * Only parse SDVO mappings on gens that could have SDVO. This isn't
+        * accurate and doesn't have to be, as long as it's not too strict.
         */
-       if (defs->child_dev_size != LEGACY_CHILD_DEVICE_CONFIG_SIZE) {
-               DRM_DEBUG_KMS("Unsupported child device size for SDVO mapping.\n");
+       if (!IS_GEN(dev_priv, 3, 7)) {
+               DRM_DEBUG_KMS("Skipping SDVO device mapping\n");
                return;
        }
-       /* get the block size of general definitions */
-       block_size = get_blocksize(defs);
-       /* get the number of child device */
-       child_device_num = (block_size - sizeof(*defs)) / defs->child_dev_size;
-       count = 0;
-       for (i = 0; i < child_device_num; i++) {
-               child = child_device_ptr(defs, i);
-               if (!child->device_type) {
-                       /* skip the device block if device type is invalid */
-                       continue;
-               }
+
+       for (i = 0, count = 0; i < dev_priv->vbt.child_dev_num; i++) {
+               child = dev_priv->vbt.child_dev + i;
+
                if (child->slave_addr != SLAVE_ADDR1 &&
                    child->slave_addr != SLAVE_ADDR2) {
                        /*
@@ -523,7 +507,6 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
                /* No SDVO device info is found */
                DRM_DEBUG_KMS("No SDVO device info is found in VBT\n");
        }
-       return;
 }
 
 static void
@@ -1506,12 +1489,14 @@ void intel_bios_init(struct drm_i915_private *dev_priv)
        parse_lfp_panel_data(dev_priv, bdb);
        parse_lfp_backlight(dev_priv, bdb);
        parse_sdvo_panel_data(dev_priv, bdb);
-       parse_sdvo_device_mapping(dev_priv, bdb);
        parse_driver_features(dev_priv, bdb);
        parse_edp(dev_priv, bdb);
        parse_psr(dev_priv, bdb);
        parse_mipi_config(dev_priv, bdb);
        parse_mipi_sequence(dev_priv, bdb);
+
+       /* Further processing on pre-parsed data */
+       parse_sdvo_device_mapping(dev_priv, bdb);
        parse_ddi_ports(dev_priv, bdb);
 
 out: