diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index f14e8a2a022d..985d531aaf9e 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -139,6 +139,21 @@ static const struct ddi_buf_trans skl_ddi_translations_dp[] = { | |||
139 | { 0x00004014, 0x00000087 }, | 139 | { 0x00004014, 0x00000087 }, |
140 | }; | 140 | }; |
141 | 141 | ||
142 | /* eDP 1.4 low vswing translation parameters */ | ||
143 | static const struct ddi_buf_trans skl_ddi_translations_edp[] = { | ||
144 | { 0x00000018, 0x000000a8 }, | ||
145 | { 0x00002016, 0x000000ab }, | ||
146 | { 0x00006012, 0x000000a2 }, | ||
147 | { 0x00008010, 0x00000088 }, | ||
148 | { 0x00000018, 0x000000ab }, | ||
149 | { 0x00004014, 0x000000a2 }, | ||
150 | { 0x00006012, 0x000000a6 }, | ||
151 | { 0x00000018, 0x000000a2 }, | ||
152 | { 0x00005013, 0x0000009c }, | ||
153 | { 0x00000018, 0x00000088 }, | ||
154 | }; | ||
155 | |||
156 | |||
142 | static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = { | 157 | static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = { |
143 | /* Idx NT mV T mV db */ | 158 | /* Idx NT mV T mV db */ |
144 | { 0x00000018, 0x000000a0 }, /* 0: 400 400 0 */ | 159 | { 0x00000018, 0x000000a0 }, /* 0: 400 400 0 */ |
@@ -187,7 +202,8 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) | |||
187 | { | 202 | { |
188 | struct drm_i915_private *dev_priv = dev->dev_private; | 203 | struct drm_i915_private *dev_priv = dev->dev_private; |
189 | u32 reg; | 204 | u32 reg; |
190 | int i, n_hdmi_entries, hdmi_800mV_0dB; | 205 | int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_800mV_0dB, |
206 | size; | ||
191 | int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; | 207 | int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; |
192 | const struct ddi_buf_trans *ddi_translations_fdi; | 208 | const struct ddi_buf_trans *ddi_translations_fdi; |
193 | const struct ddi_buf_trans *ddi_translations_dp; | 209 | const struct ddi_buf_trans *ddi_translations_dp; |
@@ -198,7 +214,15 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) | |||
198 | if (IS_SKYLAKE(dev)) { | 214 | if (IS_SKYLAKE(dev)) { |
199 | ddi_translations_fdi = NULL; | 215 | ddi_translations_fdi = NULL; |
200 | ddi_translations_dp = skl_ddi_translations_dp; | 216 | ddi_translations_dp = skl_ddi_translations_dp; |
201 | ddi_translations_edp = skl_ddi_translations_dp; | 217 | n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp); |
218 | if (dev_priv->vbt.edp_low_vswing) { | ||
219 | ddi_translations_edp = skl_ddi_translations_edp; | ||
220 | n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp); | ||
221 | } else { | ||
222 | ddi_translations_edp = skl_ddi_translations_dp; | ||
223 | n_edp_entries = ARRAY_SIZE(skl_ddi_translations_dp); | ||
224 | } | ||
225 | |||
202 | ddi_translations_hdmi = skl_ddi_translations_hdmi; | 226 | ddi_translations_hdmi = skl_ddi_translations_hdmi; |
203 | n_hdmi_entries = ARRAY_SIZE(skl_ddi_translations_hdmi); | 227 | n_hdmi_entries = ARRAY_SIZE(skl_ddi_translations_hdmi); |
204 | hdmi_800mV_0dB = 7; | 228 | hdmi_800mV_0dB = 7; |
@@ -207,6 +231,8 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) | |||
207 | ddi_translations_dp = bdw_ddi_translations_dp; | 231 | ddi_translations_dp = bdw_ddi_translations_dp; |
208 | ddi_translations_edp = bdw_ddi_translations_edp; | 232 | ddi_translations_edp = bdw_ddi_translations_edp; |
209 | ddi_translations_hdmi = bdw_ddi_translations_hdmi; | 233 | ddi_translations_hdmi = bdw_ddi_translations_hdmi; |
234 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); | ||
235 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); | ||
210 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | 236 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); |
211 | hdmi_800mV_0dB = 7; | 237 | hdmi_800mV_0dB = 7; |
212 | } else if (IS_HASWELL(dev)) { | 238 | } else if (IS_HASWELL(dev)) { |
@@ -214,6 +240,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) | |||
214 | ddi_translations_dp = hsw_ddi_translations_dp; | 240 | ddi_translations_dp = hsw_ddi_translations_dp; |
215 | ddi_translations_edp = hsw_ddi_translations_dp; | 241 | ddi_translations_edp = hsw_ddi_translations_dp; |
216 | ddi_translations_hdmi = hsw_ddi_translations_hdmi; | 242 | ddi_translations_hdmi = hsw_ddi_translations_hdmi; |
243 | n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp); | ||
217 | n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); | 244 | n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); |
218 | hdmi_800mV_0dB = 6; | 245 | hdmi_800mV_0dB = 6; |
219 | } else { | 246 | } else { |
@@ -222,6 +249,8 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) | |||
222 | ddi_translations_fdi = bdw_ddi_translations_fdi; | 249 | ddi_translations_fdi = bdw_ddi_translations_fdi; |
223 | ddi_translations_dp = bdw_ddi_translations_dp; | 250 | ddi_translations_dp = bdw_ddi_translations_dp; |
224 | ddi_translations_hdmi = bdw_ddi_translations_hdmi; | 251 | ddi_translations_hdmi = bdw_ddi_translations_hdmi; |
252 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); | ||
253 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); | ||
225 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | 254 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); |
226 | hdmi_800mV_0dB = 7; | 255 | hdmi_800mV_0dB = 7; |
227 | } | 256 | } |
@@ -229,29 +258,34 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) | |||
229 | switch (port) { | 258 | switch (port) { |
230 | case PORT_A: | 259 | case PORT_A: |
231 | ddi_translations = ddi_translations_edp; | 260 | ddi_translations = ddi_translations_edp; |
261 | size = n_edp_entries; | ||
232 | break; | 262 | break; |
233 | case PORT_B: | 263 | case PORT_B: |
234 | case PORT_C: | 264 | case PORT_C: |
235 | ddi_translations = ddi_translations_dp; | 265 | ddi_translations = ddi_translations_dp; |
266 | size = n_dp_entries; | ||
236 | break; | 267 | break; |
237 | case PORT_D: | 268 | case PORT_D: |
238 | if (intel_dp_is_edp(dev, PORT_D)) | 269 | if (intel_dp_is_edp(dev, PORT_D)) { |
239 | ddi_translations = ddi_translations_edp; | 270 | ddi_translations = ddi_translations_edp; |
240 | else | 271 | size = n_edp_entries; |
272 | } else { | ||
241 | ddi_translations = ddi_translations_dp; | 273 | ddi_translations = ddi_translations_dp; |
274 | size = n_dp_entries; | ||
275 | } | ||
242 | break; | 276 | break; |
243 | case PORT_E: | 277 | case PORT_E: |
244 | if (ddi_translations_fdi) | 278 | if (ddi_translations_fdi) |
245 | ddi_translations = ddi_translations_fdi; | 279 | ddi_translations = ddi_translations_fdi; |
246 | else | 280 | else |
247 | ddi_translations = ddi_translations_dp; | 281 | ddi_translations = ddi_translations_dp; |
282 | size = n_dp_entries; | ||
248 | break; | 283 | break; |
249 | default: | 284 | default: |
250 | BUG(); | 285 | BUG(); |
251 | } | 286 | } |
252 | 287 | ||
253 | for (i = 0, reg = DDI_BUF_TRANS(port); | 288 | for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) { |
254 | i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { | ||
255 | I915_WRITE(reg, ddi_translations[i].trans1); | 289 | I915_WRITE(reg, ddi_translations[i].trans1); |
256 | reg += 4; | 290 | reg += 4; |
257 | I915_WRITE(reg, ddi_translations[i].trans2); | 291 | I915_WRITE(reg, ddi_translations[i].trans2); |