]>
Commit | Line | Data |
---|---|---|
5a5e98ca GKH |
1 | From 7ff9a55614712adf13ce7990565be0263e620f5e Mon Sep 17 00:00:00 2001 |
2 | From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> | |
3 | Date: Tue, 12 Jul 2016 15:59:30 +0300 | |
4 | Subject: drm/i915: Program iboost settings for HDMI/DVI on SKL | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | From: Ville Syrjälä <ville.syrjala@linux.intel.com> | |
10 | ||
11 | commit 7ff9a55614712adf13ce7990565be0263e620f5e upstream. | |
12 | ||
13 | Currently we fail to program the iboost stuff for HDMI/DVI. Let's remedy | |
14 | that. | |
15 | ||
16 | Fixes: f8896f5d58e6 ("drm/i915/skl: Buffer translation improvements") | |
17 | Cc: David Weinehall <david.weinehall@linux.intel.com> | |
18 | Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> | |
19 | Link: http://patchwork.freedesktop.org/patch/msgid/1468328376-6380-4-git-send-email-ville.syrjala@linux.intel.com | |
20 | Reviewed-by: David Weinehall <david.weinehall@linux.intel.com> | |
21 | (cherry picked from commit 8d8bb85eb7d859aa9bbe36e588690a1d22af7608) | |
22 | Signed-off-by: Jani Nikula <jani.nikula@intel.com> | |
23 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
24 | ||
25 | --- | |
26 | drivers/gpu/drm/i915/intel_ddi.c | 51 ++++++++++++++++++++++++++++++--------- | |
27 | 1 file changed, 40 insertions(+), 11 deletions(-) | |
28 | ||
29 | --- a/drivers/gpu/drm/i915/intel_ddi.c | |
30 | +++ b/drivers/gpu/drm/i915/intel_ddi.c | |
31 | @@ -388,6 +388,40 @@ skl_get_buf_trans_hdmi(struct drm_i915_p | |
32 | } | |
33 | } | |
34 | ||
35 | +static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port) | |
36 | +{ | |
37 | + int n_hdmi_entries; | |
38 | + int hdmi_level; | |
39 | + int hdmi_default_entry; | |
40 | + | |
41 | + hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; | |
42 | + | |
43 | + if (IS_BROXTON(dev_priv)) | |
44 | + return hdmi_level; | |
45 | + | |
46 | + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { | |
47 | + skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); | |
48 | + hdmi_default_entry = 8; | |
49 | + } else if (IS_BROADWELL(dev_priv)) { | |
50 | + n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | |
51 | + hdmi_default_entry = 7; | |
52 | + } else if (IS_HASWELL(dev_priv)) { | |
53 | + n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); | |
54 | + hdmi_default_entry = 6; | |
55 | + } else { | |
56 | + WARN(1, "ddi translation table missing\n"); | |
57 | + n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | |
58 | + hdmi_default_entry = 7; | |
59 | + } | |
60 | + | |
61 | + /* Choose a good default if VBT is badly populated */ | |
62 | + if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN || | |
63 | + hdmi_level >= n_hdmi_entries) | |
64 | + hdmi_level = hdmi_default_entry; | |
65 | + | |
66 | + return hdmi_level; | |
67 | +} | |
68 | + | |
69 | /* | |
70 | * Starting with Haswell, DDI port buffers must be programmed with correct | |
71 | * values in advance. The buffer values are different for FDI and DP modes, | |
72 | @@ -399,7 +433,7 @@ void intel_prepare_ddi_buffer(struct int | |
73 | { | |
74 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | |
75 | u32 iboost_bit = 0; | |
76 | - int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry, | |
77 | + int i, n_hdmi_entries, n_dp_entries, n_edp_entries, | |
78 | size; | |
79 | int hdmi_level; | |
80 | enum port port; | |
81 | @@ -410,7 +444,7 @@ void intel_prepare_ddi_buffer(struct int | |
82 | const struct ddi_buf_trans *ddi_translations; | |
83 | ||
84 | port = intel_ddi_get_encoder_port(encoder); | |
85 | - hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; | |
86 | + hdmi_level = intel_ddi_hdmi_level(dev_priv, port); | |
87 | ||
88 | if (IS_BROXTON(dev_priv)) { | |
89 | if (encoder->type != INTEL_OUTPUT_HDMI) | |
90 | @@ -430,7 +464,6 @@ void intel_prepare_ddi_buffer(struct int | |
91 | skl_get_buf_trans_edp(dev_priv, &n_edp_entries); | |
92 | ddi_translations_hdmi = | |
93 | skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); | |
94 | - hdmi_default_entry = 8; | |
95 | /* If we're boosting the current, set bit 31 of trans1 */ | |
96 | if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level || | |
97 | dev_priv->vbt.ddi_port_info[port].dp_boost_level) | |
98 | @@ -456,7 +489,6 @@ void intel_prepare_ddi_buffer(struct int | |
99 | ||
100 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); | |
101 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | |
102 | - hdmi_default_entry = 7; | |
103 | } else if (IS_HASWELL(dev_priv)) { | |
104 | ddi_translations_fdi = hsw_ddi_translations_fdi; | |
105 | ddi_translations_dp = hsw_ddi_translations_dp; | |
106 | @@ -464,7 +496,6 @@ void intel_prepare_ddi_buffer(struct int | |
107 | ddi_translations_hdmi = hsw_ddi_translations_hdmi; | |
108 | n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp); | |
109 | n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); | |
110 | - hdmi_default_entry = 6; | |
111 | } else { | |
112 | WARN(1, "ddi translation table missing\n"); | |
113 | ddi_translations_edp = bdw_ddi_translations_dp; | |
114 | @@ -474,7 +505,6 @@ void intel_prepare_ddi_buffer(struct int | |
115 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); | |
116 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); | |
117 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | |
118 | - hdmi_default_entry = 7; | |
119 | } | |
120 | ||
121 | switch (encoder->type) { | |
122 | @@ -505,11 +535,6 @@ void intel_prepare_ddi_buffer(struct int | |
123 | if (encoder->type != INTEL_OUTPUT_HDMI) | |
124 | return; | |
125 | ||
126 | - /* Choose a good default if VBT is badly populated */ | |
127 | - if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN || | |
128 | - hdmi_level >= n_hdmi_entries) | |
129 | - hdmi_level = hdmi_default_entry; | |
130 | - | |
131 | /* Entry 9 is for HDMI: */ | |
132 | I915_WRITE(DDI_BUF_TRANS_LO(port, i), | |
133 | ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit); | |
134 | @@ -1639,6 +1664,10 @@ static void intel_ddi_pre_enable(struct | |
135 | intel_dp_stop_link_train(intel_dp); | |
136 | } else if (type == INTEL_OUTPUT_HDMI) { | |
137 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | |
138 | + int level = intel_ddi_hdmi_level(dev_priv, port); | |
139 | + | |
140 | + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) | |
141 | + skl_ddi_set_iboost(intel_encoder, level); | |
142 | ||
143 | intel_hdmi->set_infoframes(encoder, | |
144 | crtc->config->has_hdmi_sink, |