aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_bios.c
diff options
context:
space:
mode:
authorDavid Müller (ELSOFT AG) <d.mueller@elsoft.ch>2009-08-29 02:54:45 -0400
committerEric Anholt <eric@anholt.net>2009-08-29 21:23:40 -0400
commitdb54501900ad3665dd669f5708ecd04fc5aed495 (patch)
tree023eac651618698ab37f3e3112f957a07b6192eb /drivers/gpu/drm/i915/intel_bios.c
parenta09ba7faf75fa4b21980d81de8e5f3d5c0785ccf (diff)
drm/i915: Improve CRTDDC mapping by using VBT info
Use VBT information to determine which DDC bus to use for CRTDCC. Fall back to GPIOA if VBT info is not available. Signed-off-by: David Müller <d.mueller@elsoft.ch> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net> Tested on: 855 (David), and 945GM, 965GM, GM45, and G45 (anholt)
Diffstat (limited to 'drivers/gpu/drm/i915/intel_bios.c')
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 300aee3296c..f806fcc54e0 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -59,6 +59,16 @@ find_section(struct bdb_header *bdb, int section_id)
59 return NULL; 59 return NULL;
60} 60}
61 61
62static u16
63get_blocksize(void *p)
64{
65 u16 *block_ptr, block_size;
66
67 block_ptr = (u16 *)((char *)p - 2);
68 block_size = *block_ptr;
69 return block_size;
70}
71
62static void 72static void
63fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, 73fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
64 struct lvds_dvo_timing *dvo_timing) 74 struct lvds_dvo_timing *dvo_timing)
@@ -215,6 +225,41 @@ parse_general_features(struct drm_i915_private *dev_priv,
215} 225}
216 226
217static void 227static void
228parse_general_definitions(struct drm_i915_private *dev_priv,
229 struct bdb_header *bdb)
230{
231 struct bdb_general_definitions *general;
232 const int crt_bus_map_table[] = {
233 GPIOB,
234 GPIOA,
235 GPIOC,
236 GPIOD,
237 GPIOE,
238 GPIOF,
239 };
240
241 /* Set sensible defaults in case we can't find the general block
242 or it is the wrong chipset */
243 dev_priv->crt_ddc_bus = -1;
244
245 general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
246 if (general) {
247 u16 block_size = get_blocksize(general);
248 if (block_size >= sizeof(*general)) {
249 int bus_pin = general->crt_ddc_gmbus_pin;
250 DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin);
251 if ((bus_pin >= 1) && (bus_pin <= 6)) {
252 dev_priv->crt_ddc_bus =
253 crt_bus_map_table[bus_pin-1];
254 }
255 } else {
256 DRM_DEBUG("BDB_GD too small (%d). Invalid.\n",
257 block_size);
258 }
259 }
260}
261
262static void
218parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, 263parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
219 struct bdb_header *bdb) 264 struct bdb_header *bdb)
220{ 265{
@@ -222,7 +267,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
222 struct bdb_general_definitions *p_defs; 267 struct bdb_general_definitions *p_defs;
223 struct child_device_config *p_child; 268 struct child_device_config *p_child;
224 int i, child_device_num, count; 269 int i, child_device_num, count;
225 u16 block_size, *block_ptr; 270 u16 block_size;
226 271
227 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); 272 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
228 if (!p_defs) { 273 if (!p_defs) {
@@ -240,8 +285,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
240 return; 285 return;
241 } 286 }
242 /* get the block size of general definitions */ 287 /* get the block size of general definitions */
243 block_ptr = (u16 *)((char *)p_defs - 2); 288 block_size = get_blocksize(p_defs);
244 block_size = *block_ptr;
245 /* get the number of child device */ 289 /* get the number of child device */
246 child_device_num = (block_size - sizeof(*p_defs)) / 290 child_device_num = (block_size - sizeof(*p_defs)) /
247 sizeof(*p_child); 291 sizeof(*p_child);
@@ -362,6 +406,7 @@ intel_init_bios(struct drm_device *dev)
362 406
363 /* Grab useful general definitions */ 407 /* Grab useful general definitions */
364 parse_general_features(dev_priv, bdb); 408 parse_general_features(dev_priv, bdb);
409 parse_general_definitions(dev_priv, bdb);
365 parse_lfp_panel_data(dev_priv, bdb); 410 parse_lfp_panel_data(dev_priv, bdb);
366 parse_sdvo_panel_data(dev_priv, bdb); 411 parse_sdvo_panel_data(dev_priv, bdb);
367 parse_sdvo_device_mapping(dev_priv, bdb); 412 parse_sdvo_device_mapping(dev_priv, bdb);