blob: 29b76286ed7232827a03fca27c61c0f32edbbde4 [file] [log] [blame]
Eugeni Dodonov45244b82012-05-09 15:37:20 -03001/*
2 * Copyright © 2012 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eugeni Dodonov <eugeni.dodonov@intel.com>
25 *
26 */
27
28#include "i915_drv.h"
29#include "intel_drv.h"
30
31/* HDMI/DVI modes ignore everything but the last 2 items. So we share
32 * them for both DP and FDI transports, allowing those ports to
33 * automatically adapt to HDMI connections as well
34 */
35static const u32 hsw_ddi_translations_dp[] = {
Damien Lespiauac921bd2014-08-01 11:07:57 +010036 0x00FFFFFF, 0x0006000E,
Eugeni Dodonov45244b82012-05-09 15:37:20 -030037 0x00D75FFF, 0x0005000A,
38 0x00C30FFF, 0x00040006,
39 0x80AAAFFF, 0x000B0000,
40 0x00FFFFFF, 0x0005000A,
41 0x00D75FFF, 0x000C0004,
42 0x80C30FFF, 0x000B0000,
43 0x00FFFFFF, 0x00040006,
44 0x80D75FFF, 0x000B0000,
Eugeni Dodonov45244b82012-05-09 15:37:20 -030045};
46
47static const u32 hsw_ddi_translations_fdi[] = {
Damien Lespiauac921bd2014-08-01 11:07:57 +010048 0x00FFFFFF, 0x0007000E,
Eugeni Dodonov45244b82012-05-09 15:37:20 -030049 0x00D75FFF, 0x000F000A,
50 0x00C30FFF, 0x00060006,
51 0x00AAAFFF, 0x001E0000,
52 0x00FFFFFF, 0x000F000A,
53 0x00D75FFF, 0x00160004,
54 0x00C30FFF, 0x001E0000,
55 0x00FFFFFF, 0x00060006,
56 0x00D75FFF, 0x001E0000,
Paulo Zanoni6acab152013-09-12 17:06:24 -030057};
58
59static const u32 hsw_ddi_translations_hdmi[] = {
60 /* Idx NT mV diff T mV diff db */
61 0x00FFFFFF, 0x0006000E, /* 0: 400 400 0 */
62 0x00E79FFF, 0x000E000C, /* 1: 400 500 2 */
63 0x00D75FFF, 0x0005000A, /* 2: 400 600 3.5 */
64 0x00FFFFFF, 0x0005000A, /* 3: 600 600 0 */
65 0x00E79FFF, 0x001D0007, /* 4: 600 750 2 */
66 0x00D75FFF, 0x000C0004, /* 5: 600 900 3.5 */
67 0x00FFFFFF, 0x00040006, /* 6: 800 800 0 */
68 0x80E79FFF, 0x00030002, /* 7: 800 1000 2 */
69 0x00FFFFFF, 0x00140005, /* 8: 850 850 0 */
70 0x00FFFFFF, 0x000C0004, /* 9: 900 900 0 */
71 0x00FFFFFF, 0x001C0003, /* 10: 950 950 0 */
72 0x80FFFFFF, 0x00030002, /* 11: 1000 1000 0 */
Eugeni Dodonov45244b82012-05-09 15:37:20 -030073};
74
Paulo Zanoni300644c2013-11-02 21:07:42 -070075static const u32 bdw_ddi_translations_edp[] = {
Damien Lespiauac921bd2014-08-01 11:07:57 +010076 0x00FFFFFF, 0x00000012,
Paulo Zanoni300644c2013-11-02 21:07:42 -070077 0x00EBAFFF, 0x00020011,
78 0x00C71FFF, 0x0006000F,
Paulo Zanoni9576c272014-06-13 18:45:40 -030079 0x00AAAFFF, 0x000E000A,
Paulo Zanoni300644c2013-11-02 21:07:42 -070080 0x00FFFFFF, 0x00020011,
81 0x00DB6FFF, 0x0005000F,
82 0x00BEEFFF, 0x000A000C,
83 0x00FFFFFF, 0x0005000F,
84 0x00DB6FFF, 0x000A000C,
Paulo Zanoni300644c2013-11-02 21:07:42 -070085};
86
Art Runyane58623c2013-11-02 21:07:41 -070087static const u32 bdw_ddi_translations_dp[] = {
Damien Lespiauac921bd2014-08-01 11:07:57 +010088 0x00FFFFFF, 0x0007000E,
Art Runyane58623c2013-11-02 21:07:41 -070089 0x00D75FFF, 0x000E000A,
90 0x00BEFFFF, 0x00140006,
Paulo Zanoni9576c272014-06-13 18:45:40 -030091 0x80B2CFFF, 0x001B0002,
Art Runyane58623c2013-11-02 21:07:41 -070092 0x00FFFFFF, 0x000E000A,
93 0x00D75FFF, 0x00180004,
94 0x80CB2FFF, 0x001B0002,
95 0x00F7DFFF, 0x00180004,
96 0x80D75FFF, 0x001B0002,
Art Runyane58623c2013-11-02 21:07:41 -070097};
98
99static const u32 bdw_ddi_translations_fdi[] = {
Damien Lespiauac921bd2014-08-01 11:07:57 +0100100 0x00FFFFFF, 0x0001000E,
Art Runyane58623c2013-11-02 21:07:41 -0700101 0x00D75FFF, 0x0004000A,
102 0x00C30FFF, 0x00070006,
103 0x00AAAFFF, 0x000C0000,
104 0x00FFFFFF, 0x0004000A,
105 0x00D75FFF, 0x00090004,
106 0x00C30FFF, 0x000C0000,
107 0x00FFFFFF, 0x00070006,
108 0x00D75FFF, 0x000C0000,
Art Runyane58623c2013-11-02 21:07:41 -0700109};
110
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100111static const u32 bdw_ddi_translations_hdmi[] = {
112 /* Idx NT mV diff T mV diff db */
113 0x00FFFFFF, 0x0007000E, /* 0: 400 400 0 */
114 0x00D75FFF, 0x000E000A, /* 1: 400 600 3.5 */
115 0x00BEFFFF, 0x00140006, /* 2: 400 800 6 */
116 0x00FFFFFF, 0x0009000D, /* 3: 450 450 0 */
117 0x00FFFFFF, 0x000E000A, /* 4: 600 600 0 */
118 0x00D7FFFF, 0x00140006, /* 5: 600 800 2.5 */
119 0x80CB2FFF, 0x001B0002, /* 6: 600 1000 4.5 */
120 0x00FFFFFF, 0x00140006, /* 7: 800 800 0 */
121 0x80E79FFF, 0x001B0002, /* 8: 800 1000 2 */
122 0x80FFFFFF, 0x001B0002, /* 9: 1000 1000 0 */
123};
124
Jani Nikula20f4dbe2013-08-30 19:40:28 +0300125enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
Paulo Zanonifc914632012-10-05 12:05:54 -0300126{
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300127 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonifc914632012-10-05 12:05:54 -0300128 int type = intel_encoder->type;
129
Dave Airlie0e32b392014-05-02 14:02:48 +1000130 if (type == INTEL_OUTPUT_DP_MST) {
131 struct intel_digital_port *intel_dig_port = enc_to_mst(encoder)->primary;
132 return intel_dig_port->port;
133 } else if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP ||
Paulo Zanoni00c09d72012-10-26 19:05:52 -0200134 type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_UNKNOWN) {
Paulo Zanoni174edf12012-10-26 19:05:50 -0200135 struct intel_digital_port *intel_dig_port =
136 enc_to_dig_port(encoder);
137 return intel_dig_port->port;
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300138
Paulo Zanonifc914632012-10-05 12:05:54 -0300139 } else if (type == INTEL_OUTPUT_ANALOG) {
140 return PORT_E;
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300141
Paulo Zanonifc914632012-10-05 12:05:54 -0300142 } else {
143 DRM_ERROR("Invalid DDI encoder type %d\n", type);
144 BUG();
145 }
146}
147
Art Runyane58623c2013-11-02 21:07:41 -0700148/*
149 * Starting with Haswell, DDI port buffers must be programmed with correct
150 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300151 * but the HDMI/DVI fields are shared among those. So we program the DDI
152 * in either FDI or DP modes only, as HDMI connections will work with both
153 * of those
154 */
Paulo Zanoniad8d2702013-08-05 17:25:56 -0300155static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300156{
157 struct drm_i915_private *dev_priv = dev->dev_private;
158 u32 reg;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100159 int i, n_hdmi_entries, hdmi_800mV_0dB;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300160 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Art Runyane58623c2013-11-02 21:07:41 -0700161 const u32 *ddi_translations_fdi;
162 const u32 *ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700163 const u32 *ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100164 const u32 *ddi_translations_hdmi;
Art Runyane58623c2013-11-02 21:07:41 -0700165 const u32 *ddi_translations;
166
167 if (IS_BROADWELL(dev)) {
168 ddi_translations_fdi = bdw_ddi_translations_fdi;
169 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700170 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100171 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Damien Lespiaud6699dd2014-08-09 16:29:31 +0100172 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi) / 2;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100173 hdmi_800mV_0dB = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700174 } else if (IS_HASWELL(dev)) {
175 ddi_translations_fdi = hsw_ddi_translations_fdi;
176 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700177 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100178 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Damien Lespiaud6699dd2014-08-09 16:29:31 +0100179 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi) / 2;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100180 hdmi_800mV_0dB = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700181 } else {
182 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700183 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700184 ddi_translations_fdi = bdw_ddi_translations_fdi;
185 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100186 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Damien Lespiaud6699dd2014-08-09 16:29:31 +0100187 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi) / 2;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100188 hdmi_800mV_0dB = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700189 }
190
Paulo Zanoni300644c2013-11-02 21:07:42 -0700191 switch (port) {
192 case PORT_A:
193 ddi_translations = ddi_translations_edp;
194 break;
195 case PORT_B:
196 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700197 ddi_translations = ddi_translations_dp;
198 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700199 case PORT_D:
Ville Syrjälä5d8a7752013-11-01 18:22:39 +0200200 if (intel_dp_is_edp(dev, PORT_D))
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700201 ddi_translations = ddi_translations_edp;
202 else
203 ddi_translations = ddi_translations_dp;
204 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700205 case PORT_E:
206 ddi_translations = ddi_translations_fdi;
207 break;
208 default:
209 BUG();
210 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300211
Paulo Zanonif72d19f2013-08-05 17:25:55 -0300212 for (i = 0, reg = DDI_BUF_TRANS(port);
213 i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) {
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300214 I915_WRITE(reg, ddi_translations[i]);
215 reg += 4;
216 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100217
218 /* Choose a good default if VBT is badly populated */
219 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
220 hdmi_level >= n_hdmi_entries)
221 hdmi_level = hdmi_800mV_0dB;
222
Paulo Zanoni6acab152013-09-12 17:06:24 -0300223 /* Entry 9 is for HDMI: */
224 for (i = 0; i < 2; i++) {
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100225 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level * 2 + i]);
Paulo Zanoni6acab152013-09-12 17:06:24 -0300226 reg += 4;
227 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300228}
229
230/* Program DDI buffers translations for DP. By default, program ports A-D in DP
231 * mode and port E for FDI.
232 */
233void intel_prepare_ddi(struct drm_device *dev)
234{
235 int port;
236
Paulo Zanoni0d536cb2012-11-23 16:46:41 -0200237 if (!HAS_DDI(dev))
238 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300239
Paulo Zanoniad8d2702013-08-05 17:25:56 -0300240 for (port = PORT_A; port <= PORT_E; port++)
241 intel_prepare_ddi_buffers(dev, port);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300242}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300243
Paulo Zanoni248138b2012-11-29 11:29:31 -0200244static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
245 enum port port)
246{
247 uint32_t reg = DDI_BUF_CTL(port);
248 int i;
249
250 for (i = 0; i < 8; i++) {
251 udelay(1);
252 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
253 return;
254 }
255 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
256}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300257
258/* Starting with Haswell, different DDI ports can work in FDI mode for
259 * connection to the PCH-located connectors. For this, it is necessary to train
260 * both the DDI port and PCH receiver for the desired DDI buffer settings.
261 *
262 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
263 * please note that when FDI mode is active on DDI E, it shares 2 lines with
264 * DDI A (which is used for eDP)
265 */
266
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530267#define NUM_FDI_TRANSLATION_ENTRIES (ARRAY_SIZE(hsw_ddi_translations_fdi) / 2)
268
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300269void hsw_fdi_link_train(struct drm_crtc *crtc)
270{
271 struct drm_device *dev = crtc->dev;
272 struct drm_i915_private *dev_priv = dev->dev_private;
273 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200274 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300275
Paulo Zanoni04945642012-11-01 21:00:59 -0200276 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
277 * mode set "sequence for CRT port" document:
278 * - TP1 to TP2 time with the default value
279 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100280 *
281 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200282 */
283 I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
284 FDI_RX_PWRDN_LANE0_VAL(2) |
285 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
286
287 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000288 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100289 FDI_RX_PLL_ENABLE |
Daniel Vetter627eb5a2013-04-29 19:33:42 +0200290 FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
Paulo Zanoni04945642012-11-01 21:00:59 -0200291 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
292 POSTING_READ(_FDI_RXA_CTL);
293 udelay(220);
294
295 /* Switch from Rawclk to PCDclk */
296 rx_ctl_val |= FDI_PCDCLK;
297 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
298
299 /* Configure Port Clock Select */
Daniel Vetterde7cfc62014-06-25 22:01:54 +0300300 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config.ddi_pll_sel);
301 WARN_ON(intel_crtc->config.ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200302
303 /* Start the training iterating through available voltages and emphasis,
304 * testing each value twice. */
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530305 for (i = 0; i < NUM_FDI_TRANSLATION_ENTRIES * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300306 /* Configure DP_TP_CTL with auto-training */
307 I915_WRITE(DP_TP_CTL(PORT_E),
308 DP_TP_CTL_FDI_AUTOTRAIN |
309 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
310 DP_TP_CTL_LINK_TRAIN_PAT1 |
311 DP_TP_CTL_ENABLE);
312
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000313 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
314 * DDI E does not support port reversal, the functionality is
315 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
316 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300317 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200318 DDI_BUF_CTL_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100319 ((intel_crtc->config.fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530320 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200321 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300322
323 udelay(600);
324
Paulo Zanoni04945642012-11-01 21:00:59 -0200325 /* Program PCH FDI Receiver TU */
326 I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300327
Paulo Zanoni04945642012-11-01 21:00:59 -0200328 /* Enable PCH FDI Receiver with auto-training */
329 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
330 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
331 POSTING_READ(_FDI_RXA_CTL);
332
333 /* Wait for FDI receiver lane calibration */
334 udelay(30);
335
336 /* Unset FDI_RX_MISC pwrdn lanes */
337 temp = I915_READ(_FDI_RXA_MISC);
338 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
339 I915_WRITE(_FDI_RXA_MISC, temp);
340 POSTING_READ(_FDI_RXA_MISC);
341
342 /* Wait for FDI auto training time */
343 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300344
345 temp = I915_READ(DP_TP_STATUS(PORT_E));
346 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200347 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300348
349 /* Enable normal pixel sending for FDI */
350 I915_WRITE(DP_TP_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200351 DP_TP_CTL_FDI_AUTOTRAIN |
352 DP_TP_CTL_LINK_TRAIN_NORMAL |
353 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
354 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300355
Paulo Zanoni04945642012-11-01 21:00:59 -0200356 return;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300357 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200358
Paulo Zanoni248138b2012-11-29 11:29:31 -0200359 temp = I915_READ(DDI_BUF_CTL(PORT_E));
360 temp &= ~DDI_BUF_CTL_ENABLE;
361 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
362 POSTING_READ(DDI_BUF_CTL(PORT_E));
363
Paulo Zanoni04945642012-11-01 21:00:59 -0200364 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200365 temp = I915_READ(DP_TP_CTL(PORT_E));
366 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
367 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
368 I915_WRITE(DP_TP_CTL(PORT_E), temp);
369 POSTING_READ(DP_TP_CTL(PORT_E));
370
371 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200372
373 rx_ctl_val &= ~FDI_RX_ENABLE;
374 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200375 POSTING_READ(_FDI_RXA_CTL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200376
377 /* Reset FDI_RX_MISC pwrdn lanes */
378 temp = I915_READ(_FDI_RXA_MISC);
379 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
380 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
381 I915_WRITE(_FDI_RXA_MISC, temp);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200382 POSTING_READ(_FDI_RXA_MISC);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300383 }
384
Paulo Zanoni04945642012-11-01 21:00:59 -0200385 DRM_ERROR("FDI link training failed!\n");
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300386}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300387
Dave Airlie44905a22014-05-02 13:36:43 +1000388void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
389{
390 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
391 struct intel_digital_port *intel_dig_port =
392 enc_to_dig_port(&encoder->base);
393
394 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530395 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Dave Airlie44905a22014-05-02 13:36:43 +1000396 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
397
398}
399
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300400static struct intel_encoder *
401intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
402{
403 struct drm_device *dev = crtc->dev;
404 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
405 struct intel_encoder *intel_encoder, *ret = NULL;
406 int num_encoders = 0;
407
408 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
409 ret = intel_encoder;
410 num_encoders++;
411 }
412
413 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300414 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
415 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300416
417 BUG_ON(ret == NULL);
418 return ret;
419}
420
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100421#define LC_FREQ 2700
422#define LC_FREQ_2K (LC_FREQ * 2000)
423
424#define P_MIN 2
425#define P_MAX 64
426#define P_INC 2
427
428/* Constraints for PLL good behavior */
429#define REF_MIN 48
430#define REF_MAX 400
431#define VCO_MIN 2400
432#define VCO_MAX 4800
433
434#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a))
435
436struct wrpll_rnp {
437 unsigned p, n2, r2;
438};
439
440static unsigned wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300441{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100442 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300443
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100444 switch (clock) {
445 case 25175000:
446 case 25200000:
447 case 27000000:
448 case 27027000:
449 case 37762500:
450 case 37800000:
451 case 40500000:
452 case 40541000:
453 case 54000000:
454 case 54054000:
455 case 59341000:
456 case 59400000:
457 case 72000000:
458 case 74176000:
459 case 74250000:
460 case 81000000:
461 case 81081000:
462 case 89012000:
463 case 89100000:
464 case 108000000:
465 case 108108000:
466 case 111264000:
467 case 111375000:
468 case 148352000:
469 case 148500000:
470 case 162000000:
471 case 162162000:
472 case 222525000:
473 case 222750000:
474 case 296703000:
475 case 297000000:
476 budget = 0;
477 break;
478 case 233500000:
479 case 245250000:
480 case 247750000:
481 case 253250000:
482 case 298000000:
483 budget = 1500;
484 break;
485 case 169128000:
486 case 169500000:
487 case 179500000:
488 case 202000000:
489 budget = 2000;
490 break;
491 case 256250000:
492 case 262500000:
493 case 270000000:
494 case 272500000:
495 case 273750000:
496 case 280750000:
497 case 281250000:
498 case 286000000:
499 case 291750000:
500 budget = 4000;
501 break;
502 case 267250000:
503 case 268500000:
504 budget = 5000;
505 break;
506 default:
507 budget = 1000;
508 break;
509 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300510
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100511 return budget;
512}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300513
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100514static void wrpll_update_rnp(uint64_t freq2k, unsigned budget,
515 unsigned r2, unsigned n2, unsigned p,
516 struct wrpll_rnp *best)
517{
518 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300519
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100520 /* No best (r,n,p) yet */
521 if (best->p == 0) {
522 best->p = p;
523 best->n2 = n2;
524 best->r2 = r2;
525 return;
526 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300527
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100528 /*
529 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
530 * freq2k.
531 *
532 * delta = 1e6 *
533 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
534 * freq2k;
535 *
536 * and we would like delta <= budget.
537 *
538 * If the discrepancy is above the PPM-based budget, always prefer to
539 * improve upon the previous solution. However, if you're within the
540 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
541 */
542 a = freq2k * budget * p * r2;
543 b = freq2k * budget * best->p * best->r2;
544 diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2));
545 diff_best = ABS_DIFF((freq2k * best->p * best->r2),
546 (LC_FREQ_2K * best->n2));
547 c = 1000000 * diff;
548 d = 1000000 * diff_best;
549
550 if (a < c && b < d) {
551 /* If both are above the budget, pick the closer */
552 if (best->p * best->r2 * diff < p * r2 * diff_best) {
553 best->p = p;
554 best->n2 = n2;
555 best->r2 = r2;
556 }
557 } else if (a >= c && b < d) {
558 /* If A is below the threshold but B is above it? Update. */
559 best->p = p;
560 best->n2 = n2;
561 best->r2 = r2;
562 } else if (a >= c && b >= d) {
563 /* Both are below the limit, so pick the higher n2/(r2*r2) */
564 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
565 best->p = p;
566 best->n2 = n2;
567 best->r2 = r2;
568 }
569 }
570 /* Otherwise a < c && b >= d, do nothing */
571}
572
Jesse Barnes11578552014-01-21 12:42:10 -0800573static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
574 int reg)
575{
576 int refclk = LC_FREQ;
577 int n, p, r;
578 u32 wrpll;
579
580 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300581 switch (wrpll & WRPLL_PLL_REF_MASK) {
582 case WRPLL_PLL_SSC:
583 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800584 /*
585 * We could calculate spread here, but our checking
586 * code only cares about 5% accuracy, and spread is a max of
587 * 0.5% downspread.
588 */
589 refclk = 135;
590 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300591 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800592 refclk = LC_FREQ;
593 break;
594 default:
595 WARN(1, "bad wrpll refclk\n");
596 return 0;
597 }
598
599 r = wrpll & WRPLL_DIVIDER_REF_MASK;
600 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
601 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
602
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800603 /* Convert to KHz, p & r have a fixed point portion */
604 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800605}
606
Daniel Vetter3d51278a2014-07-29 20:57:08 +0200607static void hsw_ddi_clock_get(struct intel_encoder *encoder,
608 struct intel_crtc_config *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -0800609{
610 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -0800611 int link_clock = 0;
612 u32 val, pll;
613
Daniel Vetter26804af2014-06-25 22:01:55 +0300614 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -0800615 switch (val & PORT_CLK_SEL_MASK) {
616 case PORT_CLK_SEL_LCPLL_810:
617 link_clock = 81000;
618 break;
619 case PORT_CLK_SEL_LCPLL_1350:
620 link_clock = 135000;
621 break;
622 case PORT_CLK_SEL_LCPLL_2700:
623 link_clock = 270000;
624 break;
625 case PORT_CLK_SEL_WRPLL1:
626 link_clock = intel_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL1);
627 break;
628 case PORT_CLK_SEL_WRPLL2:
629 link_clock = intel_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL2);
630 break;
631 case PORT_CLK_SEL_SPLL:
632 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
633 if (pll == SPLL_PLL_FREQ_810MHz)
634 link_clock = 81000;
635 else if (pll == SPLL_PLL_FREQ_1350MHz)
636 link_clock = 135000;
637 else if (pll == SPLL_PLL_FREQ_2700MHz)
638 link_clock = 270000;
639 else {
640 WARN(1, "bad spll freq\n");
641 return;
642 }
643 break;
644 default:
645 WARN(1, "bad port clock sel\n");
646 return;
647 }
648
649 pipe_config->port_clock = link_clock * 2;
650
651 if (pipe_config->has_pch_encoder)
652 pipe_config->adjusted_mode.crtc_clock =
653 intel_dotclock_calculate(pipe_config->port_clock,
654 &pipe_config->fdi_m_n);
655 else if (pipe_config->has_dp_encoder)
656 pipe_config->adjusted_mode.crtc_clock =
657 intel_dotclock_calculate(pipe_config->port_clock,
658 &pipe_config->dp_m_n);
659 else
660 pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
661}
662
Daniel Vetter3d51278a2014-07-29 20:57:08 +0200663void intel_ddi_clock_get(struct intel_encoder *encoder,
664 struct intel_crtc_config *pipe_config)
665{
666 hsw_ddi_clock_get(encoder, pipe_config);
667}
668
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100669static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +0100670hsw_ddi_calculate_wrpll(int clock /* in Hz */,
671 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100672{
673 uint64_t freq2k;
674 unsigned p, n2, r2;
675 struct wrpll_rnp best = { 0, 0, 0 };
676 unsigned budget;
677
678 freq2k = clock / 100;
679
680 budget = wrpll_get_budget_for_freq(clock);
681
682 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
683 * and directly pass the LC PLL to it. */
684 if (freq2k == 5400000) {
685 *n2_out = 2;
686 *p_out = 1;
687 *r2_out = 2;
688 return;
689 }
690
691 /*
692 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
693 * the WR PLL.
694 *
695 * We want R so that REF_MIN <= Ref <= REF_MAX.
696 * Injecting R2 = 2 * R gives:
697 * REF_MAX * r2 > LC_FREQ * 2 and
698 * REF_MIN * r2 < LC_FREQ * 2
699 *
700 * Which means the desired boundaries for r2 are:
701 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
702 *
703 */
704 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
705 r2 <= LC_FREQ * 2 / REF_MIN;
706 r2++) {
707
708 /*
709 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
710 *
711 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
712 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
713 * VCO_MAX * r2 > n2 * LC_FREQ and
714 * VCO_MIN * r2 < n2 * LC_FREQ)
715 *
716 * Which means the desired boundaries for n2 are:
717 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
718 */
719 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
720 n2 <= VCO_MAX * r2 / LC_FREQ;
721 n2++) {
722
723 for (p = P_MIN; p <= P_MAX; p += P_INC)
724 wrpll_update_rnp(freq2k, budget,
725 r2, n2, p, &best);
726 }
727 }
728
729 *n2_out = best.n2;
730 *p_out = best.p;
731 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300732}
733
Damien Lespiau0220ab62014-07-29 18:06:22 +0100734static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +0100735hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
736 struct intel_encoder *intel_encoder,
737 int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300738{
Damien Lespiaud664c0c2014-07-29 18:06:23 +0100739 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +0300740 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +0300741 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100742 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300743
Damien Lespiaud664c0c2014-07-29 18:06:23 +0100744 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300745
Daniel Vetter114fe482014-06-25 22:01:48 +0300746 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300747 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
748 WRPLL_DIVIDER_POST(p);
749
Daniel Vetter716c2e52014-06-25 22:02:02 +0300750 intel_crtc->config.dpll_hw_state.wrpll = val;
751
752 pll = intel_get_shared_dpll(intel_crtc);
753 if (pll == NULL) {
754 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
755 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -0200756 return false;
757 }
758
Daniel Vetter716c2e52014-06-25 22:02:02 +0300759 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300760 }
761
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300762 return true;
763}
764
Damien Lespiau0220ab62014-07-29 18:06:22 +0100765
766/*
767 * Tries to find a *shared* PLL for the CRTC and store it in
768 * intel_crtc->ddi_pll_sel.
769 *
770 * For private DPLLs, compute_config() should do the selection for us. This
771 * function should be folded into compute_config() eventually.
772 */
773bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
774{
775 struct drm_crtc *crtc = &intel_crtc->base;
776 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Damien Lespiau0220ab62014-07-29 18:06:22 +0100777 int clock = intel_crtc->config.port_clock;
778
779 intel_put_shared_dpll(intel_crtc);
780
Damien Lespiaud664c0c2014-07-29 18:06:23 +0100781 return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
Damien Lespiau0220ab62014-07-29 18:06:22 +0100782}
783
Paulo Zanonidae84792012-10-15 15:51:30 -0300784void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
785{
786 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
787 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
788 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Daniel Vetter3b117c82013-04-17 20:15:07 +0200789 enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -0300790 int type = intel_encoder->type;
791 uint32_t temp;
792
Dave Airlie0e32b392014-05-02 14:02:48 +1000793 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -0200794 temp = TRANS_MSA_SYNC_CLK;
Daniel Vetter965e0c42013-03-27 00:44:57 +0100795 switch (intel_crtc->config.pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -0300796 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -0200797 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -0300798 break;
799 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -0200800 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -0300801 break;
802 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -0200803 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -0300804 break;
805 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -0200806 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -0300807 break;
808 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +0100809 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -0300810 }
Paulo Zanonic9809792012-10-23 18:30:00 -0200811 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -0300812 }
813}
814
Dave Airlie0e32b392014-05-02 14:02:48 +1000815void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
816{
817 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
818 struct drm_device *dev = crtc->dev;
819 struct drm_i915_private *dev_priv = dev->dev_private;
820 enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
821 uint32_t temp;
822 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
823 if (state == true)
824 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
825 else
826 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
827 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
828}
829
Damien Lespiau8228c252013-03-07 15:30:27 +0000830void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300831{
832 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
833 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -0300834 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -0700835 struct drm_device *dev = crtc->dev;
836 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300837 enum pipe pipe = intel_crtc->pipe;
Daniel Vetter3b117c82013-04-17 20:15:07 +0200838 enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -0200839 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -0300840 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300841 uint32_t temp;
842
Paulo Zanoniad80a812012-10-24 16:06:19 -0200843 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
844 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -0200845 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -0300846
Daniel Vetter965e0c42013-03-27 00:44:57 +0100847 switch (intel_crtc->config.pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -0300848 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -0200849 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -0300850 break;
851 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -0200852 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -0300853 break;
854 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -0200855 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -0300856 break;
857 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -0200858 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -0300859 break;
860 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +0100861 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -0300862 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300863
Ville Syrjäläa6662832013-09-10 17:03:41 +0300864 if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -0200865 temp |= TRANS_DDI_PVSYNC;
Ville Syrjäläa6662832013-09-10 17:03:41 +0300866 if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -0200867 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c2012-08-08 14:15:28 -0300868
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -0200869 if (cpu_transcoder == TRANSCODER_EDP) {
870 switch (pipe) {
871 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -0700872 /* On Haswell, can only use the always-on power well for
873 * eDP when not using the panel fitter, and when not
874 * using motion blur mitigation (which we don't
875 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +0200876 if (IS_HASWELL(dev) &&
877 (intel_crtc->config.pch_pfit.enabled ||
878 intel_crtc->config.pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -0200879 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
880 else
881 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -0200882 break;
883 case PIPE_B:
884 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
885 break;
886 case PIPE_C:
887 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
888 break;
889 default:
890 BUG();
891 break;
892 }
893 }
894
Paulo Zanoni7739c332012-10-15 15:51:29 -0300895 if (type == INTEL_OUTPUT_HDMI) {
Daniel Vetter6897b4b2014-04-24 23:54:47 +0200896 if (intel_crtc->config.has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -0200897 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300898 else
Paulo Zanoniad80a812012-10-24 16:06:19 -0200899 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300900
Paulo Zanoni7739c332012-10-15 15:51:29 -0300901 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -0200902 temp |= TRANS_DDI_MODE_SELECT_FDI;
Daniel Vetter33d29b12013-02-13 18:04:45 +0100903 temp |= (intel_crtc->config.fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -0300904
905 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
906 type == INTEL_OUTPUT_EDP) {
907 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
908
Dave Airlie0e32b392014-05-02 14:02:48 +1000909 if (intel_dp->is_mst) {
910 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
911 } else
912 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
913
914 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
915 } else if (type == INTEL_OUTPUT_DP_MST) {
916 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
917
918 if (intel_dp->is_mst) {
919 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
920 } else
921 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -0300922
Daniel Vetter17aa6be2013-04-30 14:01:40 +0200923 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300924 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300925 WARN(1, "Invalid encoder type %d for pipe %c\n",
926 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300927 }
928
Paulo Zanoniad80a812012-10-24 16:06:19 -0200929 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300930}
931
Paulo Zanoniad80a812012-10-24 16:06:19 -0200932void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
933 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300934{
Paulo Zanoniad80a812012-10-24 16:06:19 -0200935 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300936 uint32_t val = I915_READ(reg);
937
Dave Airlie0e32b392014-05-02 14:02:48 +1000938 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -0200939 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300940 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -0300941}
942
Paulo Zanonibcbc8892012-10-26 19:05:51 -0200943bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
944{
945 struct drm_device *dev = intel_connector->base.dev;
946 struct drm_i915_private *dev_priv = dev->dev_private;
947 struct intel_encoder *intel_encoder = intel_connector->encoder;
948 int type = intel_connector->base.connector_type;
949 enum port port = intel_ddi_get_encoder_port(intel_encoder);
950 enum pipe pipe = 0;
951 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -0300952 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -0200953 uint32_t tmp;
954
Paulo Zanoni882244a2014-04-01 14:55:12 -0300955 power_domain = intel_display_port_power_domain(intel_encoder);
956 if (!intel_display_power_enabled(dev_priv, power_domain))
957 return false;
958
Paulo Zanonibcbc8892012-10-26 19:05:51 -0200959 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
960 return false;
961
962 if (port == PORT_A)
963 cpu_transcoder = TRANSCODER_EDP;
964 else
Daniel Vetter1a240d42012-11-29 22:18:51 +0100965 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -0200966
967 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
968
969 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
970 case TRANS_DDI_MODE_SELECT_HDMI:
971 case TRANS_DDI_MODE_SELECT_DVI:
972 return (type == DRM_MODE_CONNECTOR_HDMIA);
973
974 case TRANS_DDI_MODE_SELECT_DP_SST:
975 if (type == DRM_MODE_CONNECTOR_eDP)
976 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -0200977 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +1000978 case TRANS_DDI_MODE_SELECT_DP_MST:
979 /* if the transcoder is in MST state then
980 * connector isn't connected */
981 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -0200982
983 case TRANS_DDI_MODE_SELECT_FDI:
984 return (type == DRM_MODE_CONNECTOR_VGA);
985
986 default:
987 return false;
988 }
989}
990
Daniel Vetter85234cd2012-07-02 13:27:29 +0200991bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
992 enum pipe *pipe)
993{
994 struct drm_device *dev = encoder->base.dev;
995 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -0300996 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +0200997 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +0200998 u32 tmp;
999 int i;
1000
Imre Deak6d129be2014-03-05 16:20:54 +02001001 power_domain = intel_display_port_power_domain(encoder);
1002 if (!intel_display_power_enabled(dev_priv, power_domain))
1003 return false;
1004
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001005 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001006
1007 if (!(tmp & DDI_BUF_CTL_ENABLE))
1008 return false;
1009
Paulo Zanoniad80a812012-10-24 16:06:19 -02001010 if (port == PORT_A) {
1011 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001012
Paulo Zanoniad80a812012-10-24 16:06:19 -02001013 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
1014 case TRANS_DDI_EDP_INPUT_A_ON:
1015 case TRANS_DDI_EDP_INPUT_A_ONOFF:
1016 *pipe = PIPE_A;
1017 break;
1018 case TRANS_DDI_EDP_INPUT_B_ONOFF:
1019 *pipe = PIPE_B;
1020 break;
1021 case TRANS_DDI_EDP_INPUT_C_ONOFF:
1022 *pipe = PIPE_C;
1023 break;
1024 }
1025
1026 return true;
1027 } else {
1028 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
1029 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
1030
1031 if ((tmp & TRANS_DDI_PORT_MASK)
1032 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10001033 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
1034 return false;
1035
Paulo Zanoniad80a812012-10-24 16:06:19 -02001036 *pipe = i;
1037 return true;
1038 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02001039 }
1040 }
1041
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001042 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001043
Jesse Barnes22f9fe52013-04-02 10:03:55 -07001044 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001045}
1046
Paulo Zanonifc914632012-10-05 12:05:54 -03001047void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
1048{
1049 struct drm_crtc *crtc = &intel_crtc->base;
1050 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1051 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
1052 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Daniel Vetter3b117c82013-04-17 20:15:07 +02001053 enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03001054
Paulo Zanonibb523fc2012-10-23 18:29:56 -02001055 if (cpu_transcoder != TRANSCODER_EDP)
1056 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
1057 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03001058}
1059
1060void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
1061{
1062 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Daniel Vetter3b117c82013-04-17 20:15:07 +02001063 enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03001064
Paulo Zanonibb523fc2012-10-23 18:29:56 -02001065 if (cpu_transcoder != TRANSCODER_EDP)
1066 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
1067 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03001068}
1069
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001070static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001071{
Paulo Zanonic19b0662012-10-15 15:51:41 -03001072 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic19b0662012-10-15 15:51:41 -03001073 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02001074 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001075 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001076 int type = intel_encoder->type;
1077
Daniel Vetter30cf6db2014-04-24 23:54:58 +02001078 if (crtc->config.has_audio) {
1079 DRM_DEBUG_DRIVER("Audio on pipe %c on DDI\n",
1080 pipe_name(crtc->pipe));
1081
1082 /* write eld */
1083 DRM_DEBUG_DRIVER("DDI audio: write eld information\n");
1084 intel_write_eld(encoder, &crtc->config.adjusted_mode);
1085 }
1086
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001087 if (type == INTEL_OUTPUT_EDP) {
1088 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01001089 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001090 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001091
Daniel Vetterde7cfc62014-06-25 22:01:54 +03001092 WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE);
1093 I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel);
Paulo Zanonic19b0662012-10-15 15:51:41 -03001094
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001095 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03001096 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02001097
Dave Airlie44905a22014-05-02 13:36:43 +10001098 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03001099
1100 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
1101 intel_dp_start_link_train(intel_dp);
1102 intel_dp_complete_link_train(intel_dp);
Imre Deak3ab9c632013-05-03 12:57:41 +03001103 if (port != PORT_A)
1104 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02001105 } else if (type == INTEL_OUTPUT_HDMI) {
1106 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
1107
1108 intel_hdmi->set_infoframes(encoder,
1109 crtc->config.has_hdmi_sink,
1110 &crtc->config.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03001111 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001112}
1113
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001114static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001115{
1116 struct drm_encoder *encoder = &intel_encoder->base;
1117 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
1118 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001119 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03001120 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03001121 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03001122
1123 val = I915_READ(DDI_BUF_CTL(port));
1124 if (val & DDI_BUF_CTL_ENABLE) {
1125 val &= ~DDI_BUF_CTL_ENABLE;
1126 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03001127 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03001128 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001129
Paulo Zanonia836bdf2012-10-15 15:51:32 -03001130 val = I915_READ(DP_TP_CTL(port));
1131 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
1132 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
1133 I915_WRITE(DP_TP_CTL(port), val);
1134
1135 if (wait)
1136 intel_wait_ddi_buf_idle(dev_priv, port);
1137
Jani Nikula76bb80e2013-11-15 15:29:57 +02001138 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001139 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02001140 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02001141 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01001142 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001143 }
1144
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001145 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
1146}
1147
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001148static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001149{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03001150 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08001151 struct drm_crtc *crtc = encoder->crtc;
1152 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1153 int pipe = intel_crtc->pipe;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03001154 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001155 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03001156 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1157 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08001158 uint32_t tmp;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001159
Paulo Zanoni6547fef2012-10-15 15:51:40 -03001160 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00001161 struct intel_digital_port *intel_dig_port =
1162 enc_to_dig_port(encoder);
1163
Paulo Zanoni6547fef2012-10-15 15:51:40 -03001164 /* In HDMI/DVI mode, the port width, and swing/emphasis values
1165 * are ignored so nothing special needs to be done besides
1166 * enabling the port.
1167 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00001168 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07001169 intel_dig_port->saved_port_bits |
1170 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02001171 } else if (type == INTEL_OUTPUT_EDP) {
1172 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1173
Imre Deak3ab9c632013-05-03 12:57:41 +03001174 if (port == PORT_A)
1175 intel_dp_stop_link_train(intel_dp);
1176
Daniel Vetter4be73782014-01-17 14:39:48 +01001177 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi49065572013-07-11 18:45:05 -03001178 intel_edp_psr_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03001179 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08001180
Daniel Vetter9ed109a2014-04-24 23:54:52 +02001181 if (intel_crtc->config.has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03001182 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08001183 tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
1184 tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4));
1185 I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
1186 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02001187}
1188
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001189static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02001190{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02001191 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08001192 struct drm_crtc *crtc = encoder->crtc;
1193 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1194 int pipe = intel_crtc->pipe;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02001195 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08001196 struct drm_device *dev = encoder->dev;
1197 struct drm_i915_private *dev_priv = dev->dev_private;
1198 uint32_t tmp;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02001199
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03001200 /* We can't touch HSW_AUD_PIN_ELD_CP_VLD uncionditionally because this
1201 * register is part of the power well on Haswell. */
1202 if (intel_crtc->config.has_audio) {
1203 tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
1204 tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) <<
1205 (pipe * 4));
1206 I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
1207 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
1208 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03001209
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02001210 if (type == INTEL_OUTPUT_EDP) {
1211 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1212
Rodrigo Vivi49065572013-07-11 18:45:05 -03001213 intel_edp_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01001214 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02001215 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001216}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03001217
Damien Lespiauad13d602014-07-29 18:06:24 +01001218static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv)
1219{
1220 uint32_t lcpll = I915_READ(LCPLL_CTL);
1221 uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
1222
1223 if (lcpll & LCPLL_CD_SOURCE_FCLK)
1224 return 800000;
1225 else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
1226 return 450000;
1227 else if (freq == LCPLL_CLK_FREQ_450)
1228 return 450000;
1229 else if (freq == LCPLL_CLK_FREQ_54O_BDW)
1230 return 540000;
1231 else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
1232 return 337500;
1233 else
1234 return 675000;
1235}
1236
1237static int hsw_get_cdclk_freq(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03001238{
Paulo Zanonie39bf982013-11-02 21:07:36 -07001239 struct drm_device *dev = dev_priv->dev;
Paulo Zanonia4006642013-08-06 18:57:11 -03001240 uint32_t lcpll = I915_READ(LCPLL_CTL);
Paulo Zanonie39bf982013-11-02 21:07:36 -07001241 uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
Paulo Zanonia4006642013-08-06 18:57:11 -03001242
Damien Lespiauad13d602014-07-29 18:06:24 +01001243 if (lcpll & LCPLL_CD_SOURCE_FCLK)
Paulo Zanonia4006642013-08-06 18:57:11 -03001244 return 800000;
Damien Lespiauad13d602014-07-29 18:06:24 +01001245 else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
Paulo Zanonib2b877f2013-05-03 17:23:42 -03001246 return 450000;
Damien Lespiauad13d602014-07-29 18:06:24 +01001247 else if (freq == LCPLL_CLK_FREQ_450)
Paulo Zanonib2b877f2013-05-03 17:23:42 -03001248 return 450000;
Damien Lespiauad13d602014-07-29 18:06:24 +01001249 else if (IS_ULT(dev))
1250 return 337500;
1251 else
1252 return 540000;
1253}
1254
1255int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
1256{
1257 struct drm_device *dev = dev_priv->dev;
1258
1259 if (IS_BROADWELL(dev))
1260 return bdw_get_cdclk_freq(dev_priv);
1261
1262 /* Haswell */
1263 return hsw_get_cdclk_freq(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03001264}
1265
Daniel Vettere0b01be2014-06-25 22:02:01 +03001266static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
1267 struct intel_shared_dpll *pll)
1268{
Daniel Vettere0b01be2014-06-25 22:02:01 +03001269 I915_WRITE(WRPLL_CTL(pll->id), pll->hw_state.wrpll);
1270 POSTING_READ(WRPLL_CTL(pll->id));
1271 udelay(20);
1272}
1273
Daniel Vetter12030432014-06-25 22:02:00 +03001274static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
1275 struct intel_shared_dpll *pll)
1276{
1277 uint32_t val;
1278
1279 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03001280 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
1281 POSTING_READ(WRPLL_CTL(pll->id));
1282}
1283
Daniel Vetterd452c5b2014-07-04 11:27:39 -03001284static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
1285 struct intel_shared_dpll *pll,
1286 struct intel_dpll_hw_state *hw_state)
1287{
1288 uint32_t val;
1289
1290 if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_PLLS))
1291 return false;
1292
1293 val = I915_READ(WRPLL_CTL(pll->id));
1294 hw_state->wrpll = val;
1295
1296 return val & WRPLL_PLL_ENABLE;
1297}
1298
Damien Lespiauca1381b2014-07-15 15:05:33 +01001299static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03001300 "WRPLL 1",
1301 "WRPLL 2",
1302};
1303
Damien Lespiau143b3072014-07-29 18:06:19 +01001304static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03001305{
Daniel Vetter9cd86932014-06-25 22:01:57 +03001306 int i;
1307
Daniel Vetter716c2e52014-06-25 22:02:02 +03001308 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03001309
Daniel Vetter716c2e52014-06-25 22:02:02 +03001310 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03001311 dev_priv->shared_dplls[i].id = i;
1312 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03001313 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03001314 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03001315 dev_priv->shared_dplls[i].get_hw_state =
1316 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03001317 }
Damien Lespiau143b3072014-07-29 18:06:19 +01001318}
1319
1320void intel_ddi_pll_init(struct drm_device *dev)
1321{
1322 struct drm_i915_private *dev_priv = dev->dev_private;
1323 uint32_t val = I915_READ(LCPLL_CTL);
1324
1325 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03001326
1327 /* The LCPLL register should be turned on by the BIOS. For now let's
1328 * just check its state and print errors in case something is wrong.
1329 * Don't even try to turn it on.
1330 */
1331
Paulo Zanonib2b877f2013-05-03 17:23:42 -03001332 DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
Paulo Zanoni79f689a2012-10-05 12:05:52 -03001333 intel_ddi_get_cdclk_freq(dev_priv));
1334
1335 if (val & LCPLL_CD_SOURCE_FCLK)
1336 DRM_ERROR("CDCLK source is not LCPLL\n");
1337
1338 if (val & LCPLL_PLL_DISABLE)
1339 DRM_ERROR("LCPLL is disabled\n");
1340}
Paulo Zanonic19b0662012-10-15 15:51:41 -03001341
1342void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
1343{
Paulo Zanoni174edf12012-10-26 19:05:50 -02001344 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
1345 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03001346 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001347 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03001348 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05301349 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03001350
1351 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
1352 val = I915_READ(DDI_BUF_CTL(port));
1353 if (val & DDI_BUF_CTL_ENABLE) {
1354 val &= ~DDI_BUF_CTL_ENABLE;
1355 I915_WRITE(DDI_BUF_CTL(port), val);
1356 wait = true;
1357 }
1358
1359 val = I915_READ(DP_TP_CTL(port));
1360 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
1361 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
1362 I915_WRITE(DP_TP_CTL(port), val);
1363 POSTING_READ(DP_TP_CTL(port));
1364
1365 if (wait)
1366 intel_wait_ddi_buf_idle(dev_priv, port);
1367 }
1368
Dave Airlie0e32b392014-05-02 14:02:48 +10001369 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03001370 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10001371 if (intel_dp->is_mst)
1372 val |= DP_TP_CTL_MODE_MST;
1373 else {
1374 val |= DP_TP_CTL_MODE_SST;
1375 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
1376 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
1377 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03001378 I915_WRITE(DP_TP_CTL(port), val);
1379 POSTING_READ(DP_TP_CTL(port));
1380
1381 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
1382 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
1383 POSTING_READ(DDI_BUF_CTL(port));
1384
1385 udelay(600);
1386}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001387
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02001388void intel_ddi_fdi_disable(struct drm_crtc *crtc)
1389{
1390 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1391 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
1392 uint32_t val;
1393
1394 intel_ddi_post_disable(intel_encoder);
1395
1396 val = I915_READ(_FDI_RXA_CTL);
1397 val &= ~FDI_RX_ENABLE;
1398 I915_WRITE(_FDI_RXA_CTL, val);
1399
1400 val = I915_READ(_FDI_RXA_MISC);
1401 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
1402 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
1403 I915_WRITE(_FDI_RXA_MISC, val);
1404
1405 val = I915_READ(_FDI_RXA_CTL);
1406 val &= ~FDI_PCDCLK;
1407 I915_WRITE(_FDI_RXA_CTL, val);
1408
1409 val = I915_READ(_FDI_RXA_CTL);
1410 val &= ~FDI_RX_PLL_ENABLE;
1411 I915_WRITE(_FDI_RXA_CTL, val);
1412}
1413
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001414static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
1415{
Dave Airlie0e32b392014-05-02 14:02:48 +10001416 struct intel_digital_port *intel_dig_port = enc_to_dig_port(&intel_encoder->base);
1417 int type = intel_dig_port->base.type;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001418
Dave Airlie0e32b392014-05-02 14:02:48 +10001419 if (type != INTEL_OUTPUT_DISPLAYPORT &&
1420 type != INTEL_OUTPUT_EDP &&
1421 type != INTEL_OUTPUT_UNKNOWN) {
1422 return;
1423 }
1424
1425 intel_dp_hot_plug(intel_encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001426}
1427
Ville Syrjälä6801c182013-09-24 14:24:05 +03001428void intel_ddi_get_config(struct intel_encoder *encoder,
1429 struct intel_crtc_config *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07001430{
1431 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1432 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
1433 enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
1434 u32 temp, flags = 0;
1435
1436 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1437 if (temp & TRANS_DDI_PHSYNC)
1438 flags |= DRM_MODE_FLAG_PHSYNC;
1439 else
1440 flags |= DRM_MODE_FLAG_NHSYNC;
1441 if (temp & TRANS_DDI_PVSYNC)
1442 flags |= DRM_MODE_FLAG_PVSYNC;
1443 else
1444 flags |= DRM_MODE_FLAG_NVSYNC;
1445
1446 pipe_config->adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03001447
1448 switch (temp & TRANS_DDI_BPC_MASK) {
1449 case TRANS_DDI_BPC_6:
1450 pipe_config->pipe_bpp = 18;
1451 break;
1452 case TRANS_DDI_BPC_8:
1453 pipe_config->pipe_bpp = 24;
1454 break;
1455 case TRANS_DDI_BPC_10:
1456 pipe_config->pipe_bpp = 30;
1457 break;
1458 case TRANS_DDI_BPC_12:
1459 pipe_config->pipe_bpp = 36;
1460 break;
1461 default:
1462 break;
1463 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03001464
1465 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
1466 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02001467 pipe_config->has_hdmi_sink = true;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03001468 case TRANS_DDI_MODE_SELECT_DVI:
1469 case TRANS_DDI_MODE_SELECT_FDI:
1470 break;
1471 case TRANS_DDI_MODE_SELECT_DP_SST:
1472 case TRANS_DDI_MODE_SELECT_DP_MST:
1473 pipe_config->has_dp_encoder = true;
1474 intel_dp_get_m_n(intel_crtc, pipe_config);
1475 break;
1476 default:
1477 break;
1478 }
Daniel Vetter10214422013-11-18 07:38:16 +01001479
Paulo Zanonia60551b2014-05-21 16:23:20 -03001480 if (intel_display_power_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
1481 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
1482 if (temp & (AUDIO_OUTPUT_ENABLE_A << (intel_crtc->pipe * 4)))
1483 pipe_config->has_audio = true;
1484 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02001485
Daniel Vetter10214422013-11-18 07:38:16 +01001486 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
1487 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
1488 /*
1489 * This is a big fat ugly hack.
1490 *
1491 * Some machines in UEFI boot mode provide us a VBT that has 18
1492 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
1493 * unknown we fail to light up. Yet the same BIOS boots up with
1494 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
1495 * max, not what it tells us to use.
1496 *
1497 * Note: This will still be broken if the eDP panel is not lit
1498 * up by the BIOS, and thus we can't get the mode at module
1499 * load.
1500 */
1501 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
1502 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
1503 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
1504 }
Jesse Barnes11578552014-01-21 12:42:10 -08001505
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001506 hsw_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07001507}
1508
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001509static void intel_ddi_destroy(struct drm_encoder *encoder)
1510{
1511 /* HDMI has nothing special to destroy, so we can go with this. */
1512 intel_dp_encoder_destroy(encoder);
1513}
1514
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01001515static bool intel_ddi_compute_config(struct intel_encoder *encoder,
1516 struct intel_crtc_config *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001517{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01001518 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02001519 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001520
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01001521 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001522
Daniel Vettereccb1402013-05-22 00:50:22 +02001523 if (port == PORT_A)
1524 pipe_config->cpu_transcoder = TRANSCODER_EDP;
1525
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001526 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01001527 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001528 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01001529 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001530}
1531
1532static const struct drm_encoder_funcs intel_ddi_funcs = {
1533 .destroy = intel_ddi_destroy,
1534};
1535
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03001536static struct intel_connector *
1537intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
1538{
1539 struct intel_connector *connector;
1540 enum port port = intel_dig_port->port;
1541
1542 connector = kzalloc(sizeof(*connector), GFP_KERNEL);
1543 if (!connector)
1544 return NULL;
1545
1546 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
1547 if (!intel_dp_init_connector(intel_dig_port, connector)) {
1548 kfree(connector);
1549 return NULL;
1550 }
1551
1552 return connector;
1553}
1554
1555static struct intel_connector *
1556intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
1557{
1558 struct intel_connector *connector;
1559 enum port port = intel_dig_port->port;
1560
1561 connector = kzalloc(sizeof(*connector), GFP_KERNEL);
1562 if (!connector)
1563 return NULL;
1564
1565 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
1566 intel_hdmi_init_connector(intel_dig_port, connector);
1567
1568 return connector;
1569}
1570
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001571void intel_ddi_init(struct drm_device *dev, enum port port)
1572{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00001573 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001574 struct intel_digital_port *intel_dig_port;
1575 struct intel_encoder *intel_encoder;
1576 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03001577 bool init_hdmi, init_dp;
1578
1579 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
1580 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
1581 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
1582 if (!init_dp && !init_hdmi) {
Chris Wilsonf68d6972014-08-04 07:15:09 +01001583 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03001584 port_name(port));
1585 init_hdmi = true;
1586 init_dp = true;
1587 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001588
Daniel Vetterb14c5672013-09-19 12:18:32 +02001589 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001590 if (!intel_dig_port)
1591 return;
1592
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001593 intel_encoder = &intel_dig_port->base;
1594 encoder = &intel_encoder->base;
1595
1596 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
1597 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001598
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01001599 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001600 intel_encoder->enable = intel_enable_ddi;
1601 intel_encoder->pre_enable = intel_ddi_pre_enable;
1602 intel_encoder->disable = intel_disable_ddi;
1603 intel_encoder->post_disable = intel_ddi_post_disable;
1604 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07001605 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001606
1607 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07001608 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
1609 (DDI_BUF_PORT_REVERSAL |
1610 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001611
1612 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01001613 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02001614 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001615 intel_encoder->hot_plug = intel_ddi_hot_plug;
1616
Chris Wilsonf68d6972014-08-04 07:15:09 +01001617 if (init_dp) {
1618 if (!intel_ddi_init_dp_connector(intel_dig_port))
1619 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10001620
Chris Wilsonf68d6972014-08-04 07:15:09 +01001621 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
1622 dev_priv->hpd_irq_port[port] = intel_dig_port;
1623 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02001624
Paulo Zanoni311a2092013-09-12 17:12:18 -03001625 /* In theory we don't need the encoder->type check, but leave it just in
1626 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01001627 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
1628 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
1629 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02001630 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01001631
1632 return;
1633
1634err:
1635 drm_encoder_cleanup(encoder);
1636 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001637}