|
@@ -59,6 +59,16 @@ find_section(struct bdb_header *bdb, int section_id)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+static u16
|
|
|
+get_blocksize(void *p)
|
|
|
+{
|
|
|
+ u16 *block_ptr, block_size;
|
|
|
+
|
|
|
+ block_ptr = (u16 *)((char *)p - 2);
|
|
|
+ block_size = *block_ptr;
|
|
|
+ return block_size;
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
|
|
|
struct lvds_dvo_timing *dvo_timing)
|
|
@@ -214,6 +224,41 @@ parse_general_features(struct drm_i915_private *dev_priv,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+parse_general_definitions(struct drm_i915_private *dev_priv,
|
|
|
+ struct bdb_header *bdb)
|
|
|
+{
|
|
|
+ struct bdb_general_definitions *general;
|
|
|
+ const int crt_bus_map_table[] = {
|
|
|
+ GPIOB,
|
|
|
+ GPIOA,
|
|
|
+ GPIOC,
|
|
|
+ GPIOD,
|
|
|
+ GPIOE,
|
|
|
+ GPIOF,
|
|
|
+ };
|
|
|
+
|
|
|
+ /* Set sensible defaults in case we can't find the general block
|
|
|
+ or it is the wrong chipset */
|
|
|
+ dev_priv->crt_ddc_bus = -1;
|
|
|
+
|
|
|
+ general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
|
|
|
+ if (general) {
|
|
|
+ u16 block_size = get_blocksize(general);
|
|
|
+ if (block_size >= sizeof(*general)) {
|
|
|
+ int bus_pin = general->crt_ddc_gmbus_pin;
|
|
|
+ DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin);
|
|
|
+ if ((bus_pin >= 1) && (bus_pin <= 6)) {
|
|
|
+ dev_priv->crt_ddc_bus =
|
|
|
+ crt_bus_map_table[bus_pin-1];
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ DRM_DEBUG("BDB_GD too small (%d). Invalid.\n",
|
|
|
+ block_size);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
|
|
|
struct bdb_header *bdb)
|
|
@@ -222,7 +267,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
|
|
|
struct bdb_general_definitions *p_defs;
|
|
|
struct child_device_config *p_child;
|
|
|
int i, child_device_num, count;
|
|
|
- u16 block_size, *block_ptr;
|
|
|
+ u16 block_size;
|
|
|
|
|
|
p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
|
|
|
if (!p_defs) {
|
|
@@ -240,8 +285,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
|
|
|
return;
|
|
|
}
|
|
|
/* get the block size of general definitions */
|
|
|
- block_ptr = (u16 *)((char *)p_defs - 2);
|
|
|
- block_size = *block_ptr;
|
|
|
+ block_size = get_blocksize(p_defs);
|
|
|
/* get the number of child device */
|
|
|
child_device_num = (block_size - sizeof(*p_defs)) /
|
|
|
sizeof(*p_child);
|
|
@@ -362,6 +406,7 @@ intel_init_bios(struct drm_device *dev)
|
|
|
|
|
|
/* Grab useful general definitions */
|
|
|
parse_general_features(dev_priv, bdb);
|
|
|
+ parse_general_definitions(dev_priv, bdb);
|
|
|
parse_lfp_panel_data(dev_priv, bdb);
|
|
|
parse_sdvo_panel_data(dev_priv, bdb);
|
|
|
parse_sdvo_device_mapping(dev_priv, bdb);
|