diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_bios.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 137 |
1 files changed, 120 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 96cd256e60e6..f27567747580 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -114,6 +114,8 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
114 | struct lvds_dvo_timing *dvo_timing; | 114 | struct lvds_dvo_timing *dvo_timing; |
115 | struct drm_display_mode *panel_fixed_mode; | 115 | struct drm_display_mode *panel_fixed_mode; |
116 | int lfp_data_size, dvo_timing_offset; | 116 | int lfp_data_size, dvo_timing_offset; |
117 | int i, temp_downclock; | ||
118 | struct drm_display_mode *temp_mode; | ||
117 | 119 | ||
118 | /* Defaults if we can't find VBT info */ | 120 | /* Defaults if we can't find VBT info */ |
119 | dev_priv->lvds_dither = 0; | 121 | dev_priv->lvds_dither = 0; |
@@ -159,9 +161,49 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
159 | 161 | ||
160 | dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode; | 162 | dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode; |
161 | 163 | ||
162 | DRM_DEBUG("Found panel mode in BIOS VBT tables:\n"); | 164 | DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n"); |
163 | drm_mode_debug_printmodeline(panel_fixed_mode); | 165 | drm_mode_debug_printmodeline(panel_fixed_mode); |
164 | 166 | ||
167 | temp_mode = kzalloc(sizeof(*temp_mode), GFP_KERNEL); | ||
168 | temp_downclock = panel_fixed_mode->clock; | ||
169 | /* | ||
170 | * enumerate the LVDS panel timing info entry in VBT to check whether | ||
171 | * the LVDS downclock is found. | ||
172 | */ | ||
173 | for (i = 0; i < 16; i++) { | ||
174 | entry = (struct bdb_lvds_lfp_data_entry *) | ||
175 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * i)); | ||
176 | dvo_timing = (struct lvds_dvo_timing *) | ||
177 | ((unsigned char *)entry + dvo_timing_offset); | ||
178 | |||
179 | fill_detail_timing_data(temp_mode, dvo_timing); | ||
180 | |||
181 | if (temp_mode->hdisplay == panel_fixed_mode->hdisplay && | ||
182 | temp_mode->hsync_start == panel_fixed_mode->hsync_start && | ||
183 | temp_mode->hsync_end == panel_fixed_mode->hsync_end && | ||
184 | temp_mode->htotal == panel_fixed_mode->htotal && | ||
185 | temp_mode->vdisplay == panel_fixed_mode->vdisplay && | ||
186 | temp_mode->vsync_start == panel_fixed_mode->vsync_start && | ||
187 | temp_mode->vsync_end == panel_fixed_mode->vsync_end && | ||
188 | temp_mode->vtotal == panel_fixed_mode->vtotal && | ||
189 | temp_mode->clock < temp_downclock) { | ||
190 | /* | ||
191 | * downclock is already found. But we expect | ||
192 | * to find the lower downclock. | ||
193 | */ | ||
194 | temp_downclock = temp_mode->clock; | ||
195 | } | ||
196 | /* clear it to zero */ | ||
197 | memset(temp_mode, 0, sizeof(*temp_mode)); | ||
198 | } | ||
199 | kfree(temp_mode); | ||
200 | if (temp_downclock < panel_fixed_mode->clock) { | ||
201 | dev_priv->lvds_downclock_avail = 1; | ||
202 | dev_priv->lvds_downclock = temp_downclock; | ||
203 | DRM_DEBUG_KMS("LVDS downclock is found in VBT. ", | ||
204 | "Normal Clock %dKHz, downclock %dKHz\n", | ||
205 | temp_downclock, panel_fixed_mode->clock); | ||
206 | } | ||
165 | return; | 207 | return; |
166 | } | 208 | } |
167 | 209 | ||
@@ -217,7 +259,7 @@ parse_general_features(struct drm_i915_private *dev_priv, | |||
217 | if (IS_I85X(dev_priv->dev)) | 259 | if (IS_I85X(dev_priv->dev)) |
218 | dev_priv->lvds_ssc_freq = | 260 | dev_priv->lvds_ssc_freq = |
219 | general->ssc_freq ? 66 : 48; | 261 | general->ssc_freq ? 66 : 48; |
220 | else if (IS_IGDNG(dev_priv->dev)) | 262 | else if (IS_IRONLAKE(dev_priv->dev)) |
221 | dev_priv->lvds_ssc_freq = | 263 | dev_priv->lvds_ssc_freq = |
222 | general->ssc_freq ? 100 : 120; | 264 | general->ssc_freq ? 100 : 120; |
223 | else | 265 | else |
@@ -241,22 +283,18 @@ parse_general_definitions(struct drm_i915_private *dev_priv, | |||
241 | GPIOF, | 283 | GPIOF, |
242 | }; | 284 | }; |
243 | 285 | ||
244 | /* Set sensible defaults in case we can't find the general block | ||
245 | or it is the wrong chipset */ | ||
246 | dev_priv->crt_ddc_bus = -1; | ||
247 | |||
248 | general = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 286 | general = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
249 | if (general) { | 287 | if (general) { |
250 | u16 block_size = get_blocksize(general); | 288 | u16 block_size = get_blocksize(general); |
251 | if (block_size >= sizeof(*general)) { | 289 | if (block_size >= sizeof(*general)) { |
252 | int bus_pin = general->crt_ddc_gmbus_pin; | 290 | int bus_pin = general->crt_ddc_gmbus_pin; |
253 | DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin); | 291 | DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin); |
254 | if ((bus_pin >= 1) && (bus_pin <= 6)) { | 292 | if ((bus_pin >= 1) && (bus_pin <= 6)) { |
255 | dev_priv->crt_ddc_bus = | 293 | dev_priv->crt_ddc_bus = |
256 | crt_bus_map_table[bus_pin-1]; | 294 | crt_bus_map_table[bus_pin-1]; |
257 | } | 295 | } |
258 | } else { | 296 | } else { |
259 | DRM_DEBUG("BDB_GD too small (%d). Invalid.\n", | 297 | DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n", |
260 | block_size); | 298 | block_size); |
261 | } | 299 | } |
262 | } | 300 | } |
@@ -274,7 +312,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
274 | 312 | ||
275 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 313 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
276 | if (!p_defs) { | 314 | if (!p_defs) { |
277 | DRM_DEBUG("No general definition block is found\n"); | 315 | DRM_DEBUG_KMS("No general definition block is found\n"); |
278 | return; | 316 | return; |
279 | } | 317 | } |
280 | /* judge whether the size of child device meets the requirements. | 318 | /* judge whether the size of child device meets the requirements. |
@@ -284,7 +322,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
284 | */ | 322 | */ |
285 | if (p_defs->child_dev_size != sizeof(*p_child)) { | 323 | if (p_defs->child_dev_size != sizeof(*p_child)) { |
286 | /* different child dev size . Ignore it */ | 324 | /* different child dev size . Ignore it */ |
287 | DRM_DEBUG("different child size is found. Invalid.\n"); | 325 | DRM_DEBUG_KMS("different child size is found. Invalid.\n"); |
288 | return; | 326 | return; |
289 | } | 327 | } |
290 | /* get the block size of general definitions */ | 328 | /* get the block size of general definitions */ |
@@ -310,11 +348,11 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
310 | if (p_child->dvo_port != DEVICE_PORT_DVOB && | 348 | if (p_child->dvo_port != DEVICE_PORT_DVOB && |
311 | p_child->dvo_port != DEVICE_PORT_DVOC) { | 349 | p_child->dvo_port != DEVICE_PORT_DVOC) { |
312 | /* skip the incorrect SDVO port */ | 350 | /* skip the incorrect SDVO port */ |
313 | DRM_DEBUG("Incorrect SDVO port. Skip it \n"); | 351 | DRM_DEBUG_KMS("Incorrect SDVO port. Skip it \n"); |
314 | continue; | 352 | continue; |
315 | } | 353 | } |
316 | DRM_DEBUG("the SDVO device with slave addr %2x is found on " | 354 | DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on" |
317 | "%s port\n", | 355 | " %s port\n", |
318 | p_child->slave_addr, | 356 | p_child->slave_addr, |
319 | (p_child->dvo_port == DEVICE_PORT_DVOB) ? | 357 | (p_child->dvo_port == DEVICE_PORT_DVOB) ? |
320 | "SDVOB" : "SDVOC"); | 358 | "SDVOB" : "SDVOC"); |
@@ -325,21 +363,21 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
325 | p_mapping->dvo_wiring = p_child->dvo_wiring; | 363 | p_mapping->dvo_wiring = p_child->dvo_wiring; |
326 | p_mapping->initialized = 1; | 364 | p_mapping->initialized = 1; |
327 | } else { | 365 | } else { |
328 | DRM_DEBUG("Maybe one SDVO port is shared by " | 366 | DRM_DEBUG_KMS("Maybe one SDVO port is shared by " |
329 | "two SDVO device.\n"); | 367 | "two SDVO device.\n"); |
330 | } | 368 | } |
331 | if (p_child->slave2_addr) { | 369 | if (p_child->slave2_addr) { |
332 | /* Maybe this is a SDVO device with multiple inputs */ | 370 | /* Maybe this is a SDVO device with multiple inputs */ |
333 | /* And the mapping info is not added */ | 371 | /* And the mapping info is not added */ |
334 | DRM_DEBUG("there exists the slave2_addr. Maybe this " | 372 | DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this" |
335 | "is a SDVO device with multiple inputs.\n"); | 373 | " is a SDVO device with multiple inputs.\n"); |
336 | } | 374 | } |
337 | count++; | 375 | count++; |
338 | } | 376 | } |
339 | 377 | ||
340 | if (!count) { | 378 | if (!count) { |
341 | /* No SDVO device info is found */ | 379 | /* No SDVO device info is found */ |
342 | DRM_DEBUG("No SDVO device info is found in VBT\n"); | 380 | DRM_DEBUG_KMS("No SDVO device info is found in VBT\n"); |
343 | } | 381 | } |
344 | return; | 382 | return; |
345 | } | 383 | } |
@@ -366,6 +404,70 @@ parse_driver_features(struct drm_i915_private *dev_priv, | |||
366 | dev_priv->render_reclock_avail = true; | 404 | dev_priv->render_reclock_avail = true; |
367 | } | 405 | } |
368 | 406 | ||
407 | static void | ||
408 | parse_device_mapping(struct drm_i915_private *dev_priv, | ||
409 | struct bdb_header *bdb) | ||
410 | { | ||
411 | struct bdb_general_definitions *p_defs; | ||
412 | struct child_device_config *p_child, *child_dev_ptr; | ||
413 | int i, child_device_num, count; | ||
414 | u16 block_size; | ||
415 | |||
416 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | ||
417 | if (!p_defs) { | ||
418 | DRM_DEBUG_KMS("No general definition block is found\n"); | ||
419 | return; | ||
420 | } | ||
421 | /* judge whether the size of child device meets the requirements. | ||
422 | * If the child device size obtained from general definition block | ||
423 | * is different with sizeof(struct child_device_config), skip the | ||
424 | * parsing of sdvo device info | ||
425 | */ | ||
426 | if (p_defs->child_dev_size != sizeof(*p_child)) { | ||
427 | /* different child dev size . Ignore it */ | ||
428 | DRM_DEBUG_KMS("different child size is found. Invalid.\n"); | ||
429 | return; | ||
430 | } | ||
431 | /* get the block size of general definitions */ | ||
432 | block_size = get_blocksize(p_defs); | ||
433 | /* get the number of child device */ | ||
434 | child_device_num = (block_size - sizeof(*p_defs)) / | ||
435 | sizeof(*p_child); | ||
436 | count = 0; | ||
437 | /* get the number of child device that is present */ | ||
438 | for (i = 0; i < child_device_num; i++) { | ||
439 | p_child = &(p_defs->devices[i]); | ||
440 | if (!p_child->device_type) { | ||
441 | /* skip the device block if device type is invalid */ | ||
442 | continue; | ||
443 | } | ||
444 | count++; | ||
445 | } | ||
446 | if (!count) { | ||
447 | DRM_DEBUG_KMS("no child dev is parsed from VBT \n"); | ||
448 | return; | ||
449 | } | ||
450 | dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL); | ||
451 | if (!dev_priv->child_dev) { | ||
452 | DRM_DEBUG_KMS("No memory space for child device\n"); | ||
453 | return; | ||
454 | } | ||
455 | |||
456 | dev_priv->child_dev_num = count; | ||
457 | count = 0; | ||
458 | for (i = 0; i < child_device_num; i++) { | ||
459 | p_child = &(p_defs->devices[i]); | ||
460 | if (!p_child->device_type) { | ||
461 | /* skip the device block if device type is invalid */ | ||
462 | continue; | ||
463 | } | ||
464 | child_dev_ptr = dev_priv->child_dev + count; | ||
465 | count++; | ||
466 | memcpy((void *)child_dev_ptr, (void *)p_child, | ||
467 | sizeof(*p_child)); | ||
468 | } | ||
469 | return; | ||
470 | } | ||
369 | /** | 471 | /** |
370 | * intel_init_bios - initialize VBIOS settings & find VBT | 472 | * intel_init_bios - initialize VBIOS settings & find VBT |
371 | * @dev: DRM device | 473 | * @dev: DRM device |
@@ -417,6 +519,7 @@ intel_init_bios(struct drm_device *dev) | |||
417 | parse_lfp_panel_data(dev_priv, bdb); | 519 | parse_lfp_panel_data(dev_priv, bdb); |
418 | parse_sdvo_panel_data(dev_priv, bdb); | 520 | parse_sdvo_panel_data(dev_priv, bdb); |
419 | parse_sdvo_device_mapping(dev_priv, bdb); | 521 | parse_sdvo_device_mapping(dev_priv, bdb); |
522 | parse_device_mapping(dev_priv, bdb); | ||
420 | parse_driver_features(dev_priv, bdb); | 523 | parse_driver_features(dev_priv, bdb); |
421 | 524 | ||
422 | pci_unmap_rom(pdev, bios); | 525 | pci_unmap_rom(pdev, bios); |