aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorPaulo Zanoni <paulo.r.zanoni@intel.com>2013-09-11 17:02:47 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-10-01 01:45:04 -0400
commit768f69c9fe601af39dfeb377f45909896f201444 (patch)
treece10f4bd9733cd6620360918d215decc404cc9b3 /drivers/gpu/drm/i915
parentf740334775efd30631c556f7654b92dae66df494 (diff)
drm/i915: VBT's child_device_config changes over time
We currently treat the child_device_config as a simple struct, but this is not correct: new BDB versions change the meaning of some offsets, so the struct needs to be adjusted for each version. Since there are too many changes (today we're in version 170!), making a big versioned union would be too complicated, so child_device_config is now a union of 3 things: (i) a "raw" byte array that's safe to use anywhere; (ii) an "old" structure that's the one we've been using and should be safe to keep in the SDVO and TV code; and (iii) a "common" structure that should contain only fields that are common for all the known VBT versions. Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c36
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h33
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c6
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c3
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c8
6 files changed, 59 insertions, 29 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8c52cbdb76f3..9868a66ef59c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1090,7 +1090,7 @@ struct intel_vbt_data {
1090 int crt_ddc_pin; 1090 int crt_ddc_pin;
1091 1091
1092 int child_dev_num; 1092 int child_dev_num;
1093 struct child_device_config *child_dev; 1093 union child_device_config *child_dev;
1094}; 1094};
1095 1095
1096enum intel_ddb_partitioning { 1096enum intel_ddb_partitioning {
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 6668873fb3a8..33003b97f1f0 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -389,7 +389,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
389{ 389{
390 struct sdvo_device_mapping *p_mapping; 390 struct sdvo_device_mapping *p_mapping;
391 struct bdb_general_definitions *p_defs; 391 struct bdb_general_definitions *p_defs;
392 struct child_device_config *p_child; 392 union child_device_config *p_child;
393 int i, child_device_num, count; 393 int i, child_device_num, count;
394 u16 block_size; 394 u16 block_size;
395 395
@@ -416,36 +416,36 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
416 count = 0; 416 count = 0;
417 for (i = 0; i < child_device_num; i++) { 417 for (i = 0; i < child_device_num; i++) {
418 p_child = &(p_defs->devices[i]); 418 p_child = &(p_defs->devices[i]);
419 if (!p_child->device_type) { 419 if (!p_child->old.device_type) {
420 /* skip the device block if device type is invalid */ 420 /* skip the device block if device type is invalid */
421 continue; 421 continue;
422 } 422 }
423 if (p_child->slave_addr != SLAVE_ADDR1 && 423 if (p_child->old.slave_addr != SLAVE_ADDR1 &&
424 p_child->slave_addr != SLAVE_ADDR2) { 424 p_child->old.slave_addr != SLAVE_ADDR2) {
425 /* 425 /*
426 * If the slave address is neither 0x70 nor 0x72, 426 * If the slave address is neither 0x70 nor 0x72,
427 * it is not a SDVO device. Skip it. 427 * it is not a SDVO device. Skip it.
428 */ 428 */
429 continue; 429 continue;
430 } 430 }
431 if (p_child->dvo_port != DEVICE_PORT_DVOB && 431 if (p_child->old.dvo_port != DEVICE_PORT_DVOB &&
432 p_child->dvo_port != DEVICE_PORT_DVOC) { 432 p_child->old.dvo_port != DEVICE_PORT_DVOC) {
433 /* skip the incorrect SDVO port */ 433 /* skip the incorrect SDVO port */
434 DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n"); 434 DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
435 continue; 435 continue;
436 } 436 }
437 DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on" 437 DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
438 " %s port\n", 438 " %s port\n",
439 p_child->slave_addr, 439 p_child->old.slave_addr,
440 (p_child->dvo_port == DEVICE_PORT_DVOB) ? 440 (p_child->old.dvo_port == DEVICE_PORT_DVOB) ?
441 "SDVOB" : "SDVOC"); 441 "SDVOB" : "SDVOC");
442 p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]); 442 p_mapping = &(dev_priv->sdvo_mappings[p_child->old.dvo_port - 1]);
443 if (!p_mapping->initialized) { 443 if (!p_mapping->initialized) {
444 p_mapping->dvo_port = p_child->dvo_port; 444 p_mapping->dvo_port = p_child->old.dvo_port;
445 p_mapping->slave_addr = p_child->slave_addr; 445 p_mapping->slave_addr = p_child->old.slave_addr;
446 p_mapping->dvo_wiring = p_child->dvo_wiring; 446 p_mapping->dvo_wiring = p_child->old.dvo_wiring;
447 p_mapping->ddc_pin = p_child->ddc_pin; 447 p_mapping->ddc_pin = p_child->old.ddc_pin;
448 p_mapping->i2c_pin = p_child->i2c_pin; 448 p_mapping->i2c_pin = p_child->old.i2c_pin;
449 p_mapping->initialized = 1; 449 p_mapping->initialized = 1;
450 DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n", 450 DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",
451 p_mapping->dvo_port, 451 p_mapping->dvo_port,
@@ -457,7 +457,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
457 DRM_DEBUG_KMS("Maybe one SDVO port is shared by " 457 DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
458 "two SDVO device.\n"); 458 "two SDVO device.\n");
459 } 459 }
460 if (p_child->slave2_addr) { 460 if (p_child->old.slave2_addr) {
461 /* Maybe this is a SDVO device with multiple inputs */ 461 /* Maybe this is a SDVO device with multiple inputs */
462 /* And the mapping info is not added */ 462 /* And the mapping info is not added */
463 DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this" 463 DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this"
@@ -588,7 +588,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
588 struct bdb_header *bdb) 588 struct bdb_header *bdb)
589{ 589{
590 struct bdb_general_definitions *p_defs; 590 struct bdb_general_definitions *p_defs;
591 struct child_device_config *p_child, *child_dev_ptr; 591 union child_device_config *p_child, *child_dev_ptr;
592 int i, child_device_num, count; 592 int i, child_device_num, count;
593 u16 block_size; 593 u16 block_size;
594 594
@@ -616,7 +616,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
616 /* get the number of child device that is present */ 616 /* get the number of child device that is present */
617 for (i = 0; i < child_device_num; i++) { 617 for (i = 0; i < child_device_num; i++) {
618 p_child = &(p_defs->devices[i]); 618 p_child = &(p_defs->devices[i]);
619 if (!p_child->device_type) { 619 if (!p_child->common.device_type) {
620 /* skip the device block if device type is invalid */ 620 /* skip the device block if device type is invalid */
621 continue; 621 continue;
622 } 622 }
@@ -636,7 +636,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
636 count = 0; 636 count = 0;
637 for (i = 0; i < child_device_num; i++) { 637 for (i = 0; i < child_device_num; i++) {
638 p_child = &(p_defs->devices[i]); 638 p_child = &(p_defs->devices[i]);
639 if (!p_child->device_type) { 639 if (!p_child->common.device_type) {
640 /* skip the device block if device type is invalid */ 640 /* skip the device block if device type is invalid */
641 continue; 641 continue;
642 } 642 }
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 6e9250eb9c2c..1da2bf208299 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -202,7 +202,10 @@ struct bdb_general_features {
202#define DEVICE_PORT_DVOB 0x01 202#define DEVICE_PORT_DVOB 0x01
203#define DEVICE_PORT_DVOC 0x02 203#define DEVICE_PORT_DVOC 0x02
204 204
205struct child_device_config { 205/* We used to keep this struct but without any version control. We should avoid
206 * using it in the future, but it should be safe to keep using it in the old
207 * code. */
208struct old_child_dev_config {
206 u16 handle; 209 u16 handle;
207 u16 device_type; 210 u16 device_type;
208 u8 device_id[10]; /* ascii string */ 211 u8 device_id[10]; /* ascii string */
@@ -224,6 +227,32 @@ struct child_device_config {
224 u8 dvo_function; 227 u8 dvo_function;
225} __attribute__((packed)); 228} __attribute__((packed));
226 229
230/* This one contains field offsets that are known to be common for all BDB
231 * versions. Notice that the meaning of the contents contents may still change,
232 * but at least the offsets are consistent. */
233struct common_child_dev_config {
234 u16 handle;
235 u16 device_type;
236 u8 not_common1[12];
237 u8 dvo_port;
238 u8 not_common2[2];
239 u8 ddc_pin;
240 u16 edid_ptr;
241} __attribute__((packed));
242
243/* This field changes depending on the BDB version, so the most reliable way to
244 * read it is by checking the BDB version and reading the raw pointer. */
245union child_device_config {
246 /* This one is safe to be used anywhere, but the code should still check
247 * the BDB version. */
248 u8 raw[33];
249 /* This one should only be kept for legacy code. */
250 struct old_child_dev_config old;
251 /* This one should also be safe to use anywhere, even without version
252 * checks. */
253 struct common_child_dev_config common;
254};
255
227struct bdb_general_definitions { 256struct bdb_general_definitions {
228 /* DDC GPIO */ 257 /* DDC GPIO */
229 u8 crt_ddc_gmbus_pin; 258 u8 crt_ddc_gmbus_pin;
@@ -249,7 +278,7 @@ struct bdb_general_definitions {
249 * number = (block_size - sizeof(bdb_general_definitions))/ 278 * number = (block_size - sizeof(bdb_general_definitions))/
250 * sizeof(child_device_config); 279 * sizeof(child_device_config);
251 */ 280 */
252 struct child_device_config devices[0]; 281 union child_device_config devices[0];
253} __attribute__((packed)); 282} __attribute__((packed));
254 283
255struct bdb_lvds_options { 284struct bdb_lvds_options {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 7e4052ea99c5..7823a1b5c7a6 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3203,7 +3203,7 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc)
3203bool intel_dpd_is_edp(struct drm_device *dev) 3203bool intel_dpd_is_edp(struct drm_device *dev)
3204{ 3204{
3205 struct drm_i915_private *dev_priv = dev->dev_private; 3205 struct drm_i915_private *dev_priv = dev->dev_private;
3206 struct child_device_config *p_child; 3206 union child_device_config *p_child;
3207 int i; 3207 int i;
3208 3208
3209 if (!dev_priv->vbt.child_dev_num) 3209 if (!dev_priv->vbt.child_dev_num)
@@ -3212,8 +3212,8 @@ bool intel_dpd_is_edp(struct drm_device *dev)
3212 for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { 3212 for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
3213 p_child = dev_priv->vbt.child_dev + i; 3213 p_child = dev_priv->vbt.child_dev + i;
3214 3214
3215 if (p_child->dvo_port == PORT_IDPD && 3215 if (p_child->common.dvo_port == PORT_IDPD &&
3216 p_child->device_type == DEVICE_TYPE_eDP) 3216 p_child->common.device_type == DEVICE_TYPE_eDP)
3217 return true; 3217 return true;
3218 } 3218 }
3219 return false; 3219 return false;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 639650c66e59..67a4a8fd5f89 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -794,7 +794,8 @@ static bool lvds_is_present_in_vbt(struct drm_device *dev,
794 return true; 794 return true;
795 795
796 for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { 796 for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
797 struct child_device_config *child = dev_priv->vbt.child_dev + i; 797 union child_device_config *uchild = dev_priv->vbt.child_dev + i;
798 struct old_child_dev_config *child = &uchild->old;
798 799
799 /* If the device type is not LFP, continue. 800 /* If the device type is not LFP, continue.
800 * We have to check both the new identifiers as well as the 801 * We have to check both the new identifiers as well as the
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index e6e93ce34f7b..11c15fbf9e55 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1518,7 +1518,7 @@ static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1518static int tv_is_present_in_vbt(struct drm_device *dev) 1518static int tv_is_present_in_vbt(struct drm_device *dev)
1519{ 1519{
1520 struct drm_i915_private *dev_priv = dev->dev_private; 1520 struct drm_i915_private *dev_priv = dev->dev_private;
1521 struct child_device_config *p_child; 1521 union child_device_config *p_child;
1522 int i, ret; 1522 int i, ret;
1523 1523
1524 if (!dev_priv->vbt.child_dev_num) 1524 if (!dev_priv->vbt.child_dev_num)
@@ -1530,13 +1530,13 @@ static int tv_is_present_in_vbt(struct drm_device *dev)
1530 /* 1530 /*
1531 * If the device type is not TV, continue. 1531 * If the device type is not TV, continue.
1532 */ 1532 */
1533 if (p_child->device_type != DEVICE_TYPE_INT_TV && 1533 if (p_child->old.device_type != DEVICE_TYPE_INT_TV &&
1534 p_child->device_type != DEVICE_TYPE_TV) 1534 p_child->old.device_type != DEVICE_TYPE_TV)
1535 continue; 1535 continue;
1536 /* Only when the addin_offset is non-zero, it is regarded 1536 /* Only when the addin_offset is non-zero, it is regarded
1537 * as present. 1537 * as present.
1538 */ 1538 */
1539 if (p_child->addin_offset) { 1539 if (p_child->old.addin_offset) {
1540 ret = 1; 1540 ret = 1;
1541 break; 1541 break;
1542 } 1542 }