drm/i915: Remove "i2c_speed" nonsense from child device table
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_bios.c
index 927442a11925f990fcb45b5cba763a3cb7d521bc..63880e2e5cfd4c2028f9933081606b57e2d5380f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2006 Intel Corporation
+ * Copyright Â© 2006 Intel Corporation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -74,7 +74,7 @@ get_blocksize(void *p)
 
 static void
 fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
-                       struct lvds_dvo_timing *dvo_timing)
+                       const struct lvds_dvo_timing *dvo_timing)
 {
        panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
                dvo_timing->hactive_lo;
@@ -115,20 +115,75 @@ fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
        drm_mode_set_name(panel_fixed_mode);
 }
 
+static bool
+lvds_dvo_timing_equal_size(const struct lvds_dvo_timing *a,
+                          const struct lvds_dvo_timing *b)
+{
+       if (a->hactive_hi != b->hactive_hi ||
+           a->hactive_lo != b->hactive_lo)
+               return false;
+
+       if (a->hsync_off_hi != b->hsync_off_hi ||
+           a->hsync_off_lo != b->hsync_off_lo)
+               return false;
+
+       if (a->hsync_pulse_width != b->hsync_pulse_width)
+               return false;
+
+       if (a->hblank_hi != b->hblank_hi ||
+           a->hblank_lo != b->hblank_lo)
+               return false;
+
+       if (a->vactive_hi != b->vactive_hi ||
+           a->vactive_lo != b->vactive_lo)
+               return false;
+
+       if (a->vsync_off != b->vsync_off)
+               return false;
+
+       if (a->vsync_pulse_width != b->vsync_pulse_width)
+               return false;
+
+       if (a->vblank_hi != b->vblank_hi ||
+           a->vblank_lo != b->vblank_lo)
+               return false;
+
+       return true;
+}
+
+static const struct lvds_dvo_timing *
+get_lvds_dvo_timing(const struct bdb_lvds_lfp_data *lvds_lfp_data,
+                   const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs,
+                   int index)
+{
+       /*
+        * the size of fp_timing varies on the different platform.
+        * So calculate the DVO timing relative offset in LVDS data
+        * entry to get the DVO timing entry
+        */
+
+       int lfp_data_size =
+               lvds_lfp_data_ptrs->ptr[1].dvo_timing_offset -
+               lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset;
+       int dvo_timing_offset =
+               lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset -
+               lvds_lfp_data_ptrs->ptr[0].fp_timing_offset;
+       char *entry = (char *)lvds_lfp_data->data + lfp_data_size * index;
+
+       return (struct lvds_dvo_timing *)(entry + dvo_timing_offset);
+}
+
 /* Try to find integrated panel data */
 static void
 parse_lfp_panel_data(struct drm_i915_private *dev_priv,
                            struct bdb_header *bdb)
 {
-       struct bdb_lvds_options *lvds_options;
-       struct bdb_lvds_lfp_data *lvds_lfp_data;
-       struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
-       struct bdb_lvds_lfp_data_entry *entry;
-       struct lvds_dvo_timing *dvo_timing;
+       const struct bdb_lvds_options *lvds_options;
+       const struct bdb_lvds_lfp_data *lvds_lfp_data;
+       const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
+       const struct lvds_dvo_timing *panel_dvo_timing;
        struct drm_display_mode *panel_fixed_mode;
-       int lfp_data_size, dvo_timing_offset;
-       int i, temp_downclock;
-       struct drm_display_mode *temp_mode;
+       int i, downclock;
 
        lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
        if (!lvds_options)
@@ -150,75 +205,44 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
 
        dev_priv->lvds_vbt = 1;
 
-       lfp_data_size = lvds_lfp_data_ptrs->ptr[1].dvo_timing_offset -
-               lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset;
-       entry = (struct bdb_lvds_lfp_data_entry *)
-               ((uint8_t *)lvds_lfp_data->data + (lfp_data_size *
-                                                  lvds_options->panel_type));
-       dvo_timing_offset = lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset -
-               lvds_lfp_data_ptrs->ptr[0].fp_timing_offset;
-
-       /*
-        * the size of fp_timing varies on the different platform.
-        * So calculate the DVO timing relative offset in LVDS data
-        * entry to get the DVO timing entry
-        */
-       dvo_timing = (struct lvds_dvo_timing *)
-                       ((unsigned char *)entry + dvo_timing_offset);
+       panel_dvo_timing = get_lvds_dvo_timing(lvds_lfp_data,
+                                              lvds_lfp_data_ptrs,
+                                              lvds_options->panel_type);
 
        panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
        if (!panel_fixed_mode)
                return;
 
-       fill_detail_timing_data(panel_fixed_mode, dvo_timing);
+       fill_detail_timing_data(panel_fixed_mode, panel_dvo_timing);
 
        dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
 
        DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n");
        drm_mode_debug_printmodeline(panel_fixed_mode);
 
-       temp_mode = kzalloc(sizeof(*temp_mode), GFP_KERNEL);
-       temp_downclock = panel_fixed_mode->clock;
        /*
-        * enumerate the LVDS panel timing info entry in VBT to check whether
-        * the LVDS downclock is found.
+        * Iterate over the LVDS panel timing info to find the lowest clock
+        * for the native resolution.
         */
+       downclock = panel_dvo_timing->clock;
        for (i = 0; i < 16; i++) {
-               entry = (struct bdb_lvds_lfp_data_entry *)
-                       ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * i));
-               dvo_timing = (struct lvds_dvo_timing *)
-                       ((unsigned char *)entry + dvo_timing_offset);
-
-               fill_detail_timing_data(temp_mode, dvo_timing);
-
-               if (temp_mode->hdisplay == panel_fixed_mode->hdisplay &&
-               temp_mode->hsync_start == panel_fixed_mode->hsync_start &&
-               temp_mode->hsync_end == panel_fixed_mode->hsync_end &&
-               temp_mode->htotal == panel_fixed_mode->htotal &&
-               temp_mode->vdisplay == panel_fixed_mode->vdisplay &&
-               temp_mode->vsync_start == panel_fixed_mode->vsync_start &&
-               temp_mode->vsync_end == panel_fixed_mode->vsync_end &&
-               temp_mode->vtotal == panel_fixed_mode->vtotal &&
-               temp_mode->clock < temp_downclock) {
-                       /*
-                        * downclock is already found. But we expect
-                        * to find the lower downclock.
-                        */
-                       temp_downclock = temp_mode->clock;
-               }
-               /* clear it to zero */
-               memset(temp_mode, 0, sizeof(*temp_mode));
+               const struct lvds_dvo_timing *dvo_timing;
+
+               dvo_timing = get_lvds_dvo_timing(lvds_lfp_data,
+                                                lvds_lfp_data_ptrs,
+                                                i);
+               if (lvds_dvo_timing_equal_size(dvo_timing, panel_dvo_timing) &&
+                   dvo_timing->clock < downclock)
+                       downclock = dvo_timing->clock;
        }
-       kfree(temp_mode);
-       if (temp_downclock < panel_fixed_mode->clock &&
-           i915_lvds_downclock) {
+
+       if (downclock < panel_dvo_timing->clock && i915_lvds_downclock) {
                dev_priv->lvds_downclock_avail = 1;
-               dev_priv->lvds_downclock = temp_downclock;
+               dev_priv->lvds_downclock = downclock * 10;
                DRM_DEBUG_KMS("LVDS downclock is found in VBT. "
                              "Normal Clock %dKHz, downclock %dKHz\n",
-                             temp_downclock, panel_fixed_mode->clock);
+                             panel_fixed_mode->clock, 10*downclock);
        }
-       return;
 }
 
 /* Try to find sdvo panel data */
@@ -285,6 +309,13 @@ parse_general_features(struct drm_i915_private *dev_priv,
                dev_priv->lvds_use_ssc = general->enable_ssc;
                dev_priv->lvds_ssc_freq =
                        intel_bios_ssc_frequency(dev, general->ssc_freq);
+               dev_priv->display_clock_mode = general->display_clock_mode;
+               DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d\n",
+                             dev_priv->int_tv_support,
+                             dev_priv->int_crt_support,
+                             dev_priv->lvds_use_ssc,
+                             dev_priv->lvds_ssc_freq,
+                             dev_priv->display_clock_mode);
        }
 }
 
@@ -357,7 +388,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
                if (p_child->dvo_port != DEVICE_PORT_DVOB &&
                        p_child->dvo_port != DEVICE_PORT_DVOC) {
                        /* skip the incorrect SDVO port */
-                       DRM_DEBUG_KMS("Incorrect SDVO port. Skip it \n");
+                       DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
                        continue;
                }
                DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
@@ -372,15 +403,13 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
                        p_mapping->dvo_wiring = p_child->dvo_wiring;
                        p_mapping->ddc_pin = p_child->ddc_pin;
                        p_mapping->i2c_pin = p_child->i2c_pin;
-                       p_mapping->i2c_speed = p_child->i2c_speed;
                        p_mapping->initialized = 1;
-                       DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d, i2c_speed=%d\n",
+                       DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",
                                      p_mapping->dvo_port,
                                      p_mapping->slave_addr,
                                      p_mapping->dvo_wiring,
                                      p_mapping->ddc_pin,
-                                     p_mapping->i2c_pin,
-                                     p_mapping->i2c_speed);
+                                     p_mapping->i2c_pin);
                } else {
                        DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
                                         "two SDVO device.\n");
@@ -540,7 +569,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
                count++;
        }
        if (!count) {
-               DRM_DEBUG_KMS("no child dev is parsed from VBT \n");
+               DRM_DEBUG_KMS("no child dev is parsed from VBT\n");
                return;
        }
        dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL);
@@ -586,7 +615,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
        /* Default to using SSC */
        dev_priv->lvds_use_ssc = 1;
        dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1);
-       DRM_DEBUG("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq);
+       DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq);
 
        /* eDP data */
        dev_priv->edp.bpp = 18;
@@ -615,7 +644,7 @@ intel_parse_bios(struct drm_device *dev)
        if (dev_priv->opregion.vbt) {
                struct vbt_header *vbt = dev_priv->opregion.vbt;
                if (memcmp(vbt->signature, "$VBT", 4) == 0) {
-                       DRM_DEBUG_DRIVER("Using VBT from OpRegion: %20s\n",
+                       DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n",
                                         vbt->signature);
                        bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset);
                } else
This page took 0.031584 seconds and 5 git commands to generate.