aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ddi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c46
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 */
143static 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
142static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = { 157static 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);