diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-11-26 11:22:10 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-11-29 06:36:57 -0500 |
commit | 13c7d8703127334890c894ddab13b3a92a26580a (patch) | |
tree | 5dcc1c9e98c52ec22be9b5c08c63f9a586777bca /drivers/gpu | |
parent | 1974cad0ee4ce84e5cb792e49c4f0d9421e0312c (diff) |
drm/i915: track is_dual_link in intel_lvds
Yeah, all users (both the clock selection special cases and the lvds
pin pair stuff) are still in common code, but this will change.
v2: Rebase on top of Jani Nikula's panel rework.
v3: Incorporate review from Paulo Zanoni:
- s/__is_dual_link_lvds/compute_is_dual_link_lvds
- kill dev_priv->lvds_val
- drop spurious whitespace change
v4: Add a debug printk to display the dual-link status, as suggested
by Paulo Zanoni in review.
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v3)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 44 |
2 files changed, 31 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 79589bbff3db..9be7efd43c6a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -705,7 +705,6 @@ typedef struct drm_i915_private { | |||
705 | unsigned int display_clock_mode:1; | 705 | unsigned int display_clock_mode:1; |
706 | int lvds_ssc_freq; | 706 | int lvds_ssc_freq; |
707 | unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ | 707 | unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ |
708 | unsigned int lvds_val; /* used for checking LVDS channel mode */ | ||
709 | struct { | 708 | struct { |
710 | int rate; | 709 | int rate; |
711 | int lanes; | 710 | int lanes; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 4158a8839433..31fdbfd48e44 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -52,6 +52,7 @@ struct intel_lvds_encoder { | |||
52 | u32 pfit_control; | 52 | u32 pfit_control; |
53 | u32 pfit_pgm_ratios; | 53 | u32 pfit_pgm_ratios; |
54 | bool pfit_dirty; | 54 | bool pfit_dirty; |
55 | bool is_dual_link; | ||
55 | 56 | ||
56 | struct intel_lvds_connector *attached_connector; | 57 | struct intel_lvds_connector *attached_connector; |
57 | }; | 58 | }; |
@@ -923,6 +924,23 @@ static const struct dmi_system_id intel_dual_link_lvds[] = { | |||
923 | 924 | ||
924 | bool intel_is_dual_link_lvds(struct drm_device *dev) | 925 | bool intel_is_dual_link_lvds(struct drm_device *dev) |
925 | { | 926 | { |
927 | struct intel_encoder *encoder; | ||
928 | struct intel_lvds_encoder *lvds_encoder; | ||
929 | |||
930 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
931 | base.head) { | ||
932 | if (encoder->type == INTEL_OUTPUT_LVDS) { | ||
933 | lvds_encoder = to_lvds_encoder(&encoder->base); | ||
934 | |||
935 | return lvds_encoder->is_dual_link; | ||
936 | } | ||
937 | } | ||
938 | |||
939 | return false; | ||
940 | } | ||
941 | |||
942 | static bool compute_is_dual_link_lvds(struct drm_device *dev) | ||
943 | { | ||
926 | unsigned int val; | 944 | unsigned int val; |
927 | struct drm_i915_private *dev_priv = dev->dev_private; | 945 | struct drm_i915_private *dev_priv = dev->dev_private; |
928 | u32 lvds_reg; | 946 | u32 lvds_reg; |
@@ -940,19 +958,15 @@ bool intel_is_dual_link_lvds(struct drm_device *dev) | |||
940 | if (dmi_check_system(intel_dual_link_lvds)) | 958 | if (dmi_check_system(intel_dual_link_lvds)) |
941 | return true; | 959 | return true; |
942 | 960 | ||
943 | if (dev_priv->lvds_val) | 961 | /* BIOS should set the proper LVDS register value at boot, but |
944 | val = dev_priv->lvds_val; | 962 | * in reality, it doesn't set the value when the lid is closed; |
945 | else { | 963 | * we need to check "the value to be set" in VBT when LVDS |
946 | /* BIOS should set the proper LVDS register value at boot, but | 964 | * register is uninitialized. |
947 | * in reality, it doesn't set the value when the lid is closed; | 965 | */ |
948 | * we need to check "the value to be set" in VBT when LVDS | 966 | val = I915_READ(lvds_reg); |
949 | * register is uninitialized. | 967 | if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED))) |
950 | */ | 968 | val = dev_priv->bios_lvds_val; |
951 | val = I915_READ(lvds_reg); | 969 | |
952 | if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED))) | ||
953 | val = dev_priv->bios_lvds_val; | ||
954 | dev_priv->lvds_val = val; | ||
955 | } | ||
956 | return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP; | 970 | return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP; |
957 | } | 971 | } |
958 | 972 | ||
@@ -1162,6 +1176,10 @@ bool intel_lvds_init(struct drm_device *dev) | |||
1162 | goto failed; | 1176 | goto failed; |
1163 | 1177 | ||
1164 | out: | 1178 | out: |
1179 | lvds_encoder->is_dual_link = compute_is_dual_link_lvds(dev); | ||
1180 | DRM_DEBUG_KMS("detected %s-link lvds configuration\n", | ||
1181 | lvds_encoder->is_dual_link ? "dual" : "single"); | ||
1182 | |||
1165 | /* | 1183 | /* |
1166 | * Unlock registers and just | 1184 | * Unlock registers and just |
1167 | * leave them unlocked | 1185 | * leave them unlocked |