aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2009-07-27 22:54:13 -0400
committerEric Anholt <eric@anholt.net>2009-07-29 18:06:06 -0400
commitcdaa052b05e26d96a990af5d253fd2af5db2b1fc (patch)
tree47fc9b791bbf1aa4cb42eaf878c213299b61dd01
parent2ded9e2747d0a390d281bb5b16ff7f640ec85f78 (diff)
drm/I915: Fix offset to DVO timings in LVDS data
Now the DVO timing in LVDS data entry is obtained by using the following step: a. get the entry size for every LVDS panel data b. Get the LVDS fp entry for the preferred panel type c. get the DVO timing by using entry->dvo_timing In our driver the entry->dvo_timing is related with the size of lvds_fp_timing. For example: the size is 46. But it seems that the size of lvds_fp_timing varies on the differnt platform. In such case we will get the incorrect DVO timing entry because of the incorrect DVO offset in LVDS panel data entry. This also removes a hack on new IGDNG to get proper DVO timing. Calculate the DVO timing offset in LVDS data entry to get the DVO timing a. get the DVO timing offset in the LVDS fp data entry by using the pointer definition in LVDS data ptr b. get the LVDS data entry c. get the DVO timing by adding the DVO timing offset to data entry https://bugs.freedesktop.org/show_bug.cgi?id=22787 Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Tested-by: Zhenyu Wang <zhenyuw@linux.intel.com> Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 7cc447191028..5c7a62a96ae7 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -97,14 +97,13 @@ static void
97parse_lfp_panel_data(struct drm_i915_private *dev_priv, 97parse_lfp_panel_data(struct drm_i915_private *dev_priv,
98 struct bdb_header *bdb) 98 struct bdb_header *bdb)
99{ 99{
100 struct drm_device *dev = dev_priv->dev;
101 struct bdb_lvds_options *lvds_options; 100 struct bdb_lvds_options *lvds_options;
102 struct bdb_lvds_lfp_data *lvds_lfp_data; 101 struct bdb_lvds_lfp_data *lvds_lfp_data;
103 struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; 102 struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
104 struct bdb_lvds_lfp_data_entry *entry; 103 struct bdb_lvds_lfp_data_entry *entry;
105 struct lvds_dvo_timing *dvo_timing; 104 struct lvds_dvo_timing *dvo_timing;
106 struct drm_display_mode *panel_fixed_mode; 105 struct drm_display_mode *panel_fixed_mode;
107 int lfp_data_size; 106 int lfp_data_size, dvo_timing_offset;
108 107
109 /* Defaults if we can't find VBT info */ 108 /* Defaults if we can't find VBT info */
110 dev_priv->lvds_dither = 0; 109 dev_priv->lvds_dither = 0;
@@ -133,14 +132,16 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
133 entry = (struct bdb_lvds_lfp_data_entry *) 132 entry = (struct bdb_lvds_lfp_data_entry *)
134 ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * 133 ((uint8_t *)lvds_lfp_data->data + (lfp_data_size *
135 lvds_options->panel_type)); 134 lvds_options->panel_type));
135 dvo_timing_offset = lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset -
136 lvds_lfp_data_ptrs->ptr[0].fp_timing_offset;
136 137
137 /* On IGDNG mobile, LVDS data block removes panel fitting registers. 138 /*
138 So dec 2 dword from dvo_timing offset */ 139 * the size of fp_timing varies on the different platform.
139 if (IS_IGDNG(dev)) 140 * So calculate the DVO timing relative offset in LVDS data
140 dvo_timing = (struct lvds_dvo_timing *) 141 * entry to get the DVO timing entry
141 ((u8 *)&entry->dvo_timing - 8); 142 */
142 else 143 dvo_timing = (struct lvds_dvo_timing *)
143 dvo_timing = &entry->dvo_timing; 144 ((unsigned char *)entry + dvo_timing_offset);
144 145
145 panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); 146 panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
146 147