blob: f6b3ccc4ab66909c8dcf1c728d2bd1fc72664c11 [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
Jani Nikula10122052014-08-27 16:27:30 +030031struct ddi_buf_trans {
32 u32 trans1; /* balance leg enable, de-emph level */
33 u32 trans2; /* vref sel, vswing */
34};
35
Eugeni Dodonov45244b82012-05-09 15:37:20 -030036/* HDMI/DVI modes ignore everything but the last 2 items. So we share
37 * them for both DP and FDI transports, allowing those ports to
38 * automatically adapt to HDMI connections as well
39 */
Jani Nikula10122052014-08-27 16:27:30 +030040static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
41 { 0x00FFFFFF, 0x0006000E },
42 { 0x00D75FFF, 0x0005000A },
43 { 0x00C30FFF, 0x00040006 },
44 { 0x80AAAFFF, 0x000B0000 },
45 { 0x00FFFFFF, 0x0005000A },
46 { 0x00D75FFF, 0x000C0004 },
47 { 0x80C30FFF, 0x000B0000 },
48 { 0x00FFFFFF, 0x00040006 },
49 { 0x80D75FFF, 0x000B0000 },
Eugeni Dodonov45244b82012-05-09 15:37:20 -030050};
51
Jani Nikula10122052014-08-27 16:27:30 +030052static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
53 { 0x00FFFFFF, 0x0007000E },
54 { 0x00D75FFF, 0x000F000A },
55 { 0x00C30FFF, 0x00060006 },
56 { 0x00AAAFFF, 0x001E0000 },
57 { 0x00FFFFFF, 0x000F000A },
58 { 0x00D75FFF, 0x00160004 },
59 { 0x00C30FFF, 0x001E0000 },
60 { 0x00FFFFFF, 0x00060006 },
61 { 0x00D75FFF, 0x001E0000 },
Paulo Zanoni6acab152013-09-12 17:06:24 -030062};
63
Jani Nikula10122052014-08-27 16:27:30 +030064static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
65 /* Idx NT mV d T mV d db */
66 { 0x00FFFFFF, 0x0006000E }, /* 0: 400 400 0 */
67 { 0x00E79FFF, 0x000E000C }, /* 1: 400 500 2 */
68 { 0x00D75FFF, 0x0005000A }, /* 2: 400 600 3.5 */
69 { 0x00FFFFFF, 0x0005000A }, /* 3: 600 600 0 */
70 { 0x00E79FFF, 0x001D0007 }, /* 4: 600 750 2 */
71 { 0x00D75FFF, 0x000C0004 }, /* 5: 600 900 3.5 */
72 { 0x00FFFFFF, 0x00040006 }, /* 6: 800 800 0 */
73 { 0x80E79FFF, 0x00030002 }, /* 7: 800 1000 2 */
74 { 0x00FFFFFF, 0x00140005 }, /* 8: 850 850 0 */
75 { 0x00FFFFFF, 0x000C0004 }, /* 9: 900 900 0 */
76 { 0x00FFFFFF, 0x001C0003 }, /* 10: 950 950 0 */
77 { 0x80FFFFFF, 0x00030002 }, /* 11: 1000 1000 0 */
Eugeni Dodonov45244b82012-05-09 15:37:20 -030078};
79
Jani Nikula10122052014-08-27 16:27:30 +030080static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
81 { 0x00FFFFFF, 0x00000012 },
82 { 0x00EBAFFF, 0x00020011 },
83 { 0x00C71FFF, 0x0006000F },
84 { 0x00AAAFFF, 0x000E000A },
85 { 0x00FFFFFF, 0x00020011 },
86 { 0x00DB6FFF, 0x0005000F },
87 { 0x00BEEFFF, 0x000A000C },
88 { 0x00FFFFFF, 0x0005000F },
89 { 0x00DB6FFF, 0x000A000C },
Paulo Zanoni300644c2013-11-02 21:07:42 -070090};
91
Jani Nikula10122052014-08-27 16:27:30 +030092static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
93 { 0x00FFFFFF, 0x0007000E },
94 { 0x00D75FFF, 0x000E000A },
95 { 0x00BEFFFF, 0x00140006 },
96 { 0x80B2CFFF, 0x001B0002 },
97 { 0x00FFFFFF, 0x000E000A },
Rodrigo Vivi17b523b2014-09-24 20:32:43 -040098 { 0x00DB6FFF, 0x00160005 },
Rodrigo Vivi6805b2a2014-09-25 12:28:32 -040099 { 0x80C71FFF, 0x001A0002 },
Jani Nikula10122052014-08-27 16:27:30 +0300100 { 0x00F7DFFF, 0x00180004 },
101 { 0x80D75FFF, 0x001B0002 },
Art Runyane58623c2013-11-02 21:07:41 -0700102};
103
Jani Nikula10122052014-08-27 16:27:30 +0300104static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
105 { 0x00FFFFFF, 0x0001000E },
106 { 0x00D75FFF, 0x0004000A },
107 { 0x00C30FFF, 0x00070006 },
108 { 0x00AAAFFF, 0x000C0000 },
109 { 0x00FFFFFF, 0x0004000A },
110 { 0x00D75FFF, 0x00090004 },
111 { 0x00C30FFF, 0x000C0000 },
112 { 0x00FFFFFF, 0x00070006 },
113 { 0x00D75FFF, 0x000C0000 },
Art Runyane58623c2013-11-02 21:07:41 -0700114};
115
Jani Nikula10122052014-08-27 16:27:30 +0300116static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
117 /* Idx NT mV d T mV df db */
118 { 0x00FFFFFF, 0x0007000E }, /* 0: 400 400 0 */
119 { 0x00D75FFF, 0x000E000A }, /* 1: 400 600 3.5 */
120 { 0x00BEFFFF, 0x00140006 }, /* 2: 400 800 6 */
121 { 0x00FFFFFF, 0x0009000D }, /* 3: 450 450 0 */
122 { 0x00FFFFFF, 0x000E000A }, /* 4: 600 600 0 */
123 { 0x00D7FFFF, 0x00140006 }, /* 5: 600 800 2.5 */
124 { 0x80CB2FFF, 0x001B0002 }, /* 6: 600 1000 4.5 */
125 { 0x00FFFFFF, 0x00140006 }, /* 7: 800 800 0 */
126 { 0x80E79FFF, 0x001B0002 }, /* 8: 800 1000 2 */
127 { 0x80FFFFFF, 0x001B0002 }, /* 9: 1000 1000 0 */
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100128};
129
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000130static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
Damien Lespiau6c930682014-11-26 13:37:26 +0000131 { 0x00000018, 0x000000a2 },
132 { 0x00004014, 0x0000009B },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000133 { 0x00006012, 0x00000088 },
Damien Lespiau6c930682014-11-26 13:37:26 +0000134 { 0x00008010, 0x00000087 },
135 { 0x00000018, 0x0000009B },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000136 { 0x00004014, 0x00000088 },
Damien Lespiau6c930682014-11-26 13:37:26 +0000137 { 0x00006012, 0x00000087 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000138 { 0x00000018, 0x00000088 },
Damien Lespiau6c930682014-11-26 13:37:26 +0000139 { 0x00004014, 0x00000087 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000140};
141
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530142/* 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
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000157static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
Sonika Jindalb7192a52015-04-15 11:02:33 +0530158 { 0x00000018, 0x000000ac },
159 { 0x00005012, 0x0000009d },
160 { 0x00007011, 0x00000088 },
161 { 0x00000018, 0x000000a1 },
162 { 0x00000018, 0x00000098 },
163 { 0x00004013, 0x00000088 },
164 { 0x00006012, 0x00000087 },
165 { 0x00000018, 0x000000df },
166 { 0x00003015, 0x00000087 },
167 { 0x00003015, 0x000000c7 },
168 { 0x00000018, 0x000000c7 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000169};
170
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530171struct bxt_ddi_buf_trans {
172 u32 margin; /* swing value */
173 u32 scale; /* scale value */
174 u32 enable; /* scale enable */
175 u32 deemphasis;
176 bool default_index; /* true if the entry represents default value */
177};
178
179/* BSpec does not define separate vswing/pre-emphasis values for eDP.
180 * Using DP values for eDP as well.
181 */
182static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
183 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300184 { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */
185 { 78, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
186 { 104, 0x9A, 0, 64, false }, /* 2: 400 6 */
187 { 154, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
188 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
189 { 116, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
190 { 154, 0x9A, 0, 64, false }, /* 6: 600 6 */
191 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
192 { 154, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530193 { 154, 0x9A, 1, 128, false }, /* 9: 1200 0 */
194};
195
196/* BSpec has 2 recommended values - entries 0 and 8.
197 * Using the entry with higher vswing.
198 */
199static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
200 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300201 { 52, 0x9A, 0, 128, false }, /* 0: 400 0 */
202 { 52, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
203 { 52, 0x9A, 0, 64, false }, /* 2: 400 6 */
204 { 42, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
205 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
206 { 77, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
207 { 77, 0x9A, 0, 64, false }, /* 6: 600 6 */
208 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
209 { 102, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530210 { 154, 0x9A, 1, 128, true }, /* 9: 1200 0 */
211};
212
Imre Deaka1e6ad62015-04-17 19:31:21 +0300213static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
214 struct intel_digital_port **dig_port,
215 enum port *port)
Paulo Zanonifc914632012-10-05 12:05:54 -0300216{
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300217 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonifc914632012-10-05 12:05:54 -0300218 int type = intel_encoder->type;
219
Dave Airlie0e32b392014-05-02 14:02:48 +1000220 if (type == INTEL_OUTPUT_DP_MST) {
Imre Deaka1e6ad62015-04-17 19:31:21 +0300221 *dig_port = enc_to_mst(encoder)->primary;
222 *port = (*dig_port)->port;
Dave Airlie0e32b392014-05-02 14:02:48 +1000223 } else if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP ||
Paulo Zanoni00c09d72012-10-26 19:05:52 -0200224 type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_UNKNOWN) {
Imre Deaka1e6ad62015-04-17 19:31:21 +0300225 *dig_port = enc_to_dig_port(encoder);
226 *port = (*dig_port)->port;
Paulo Zanonifc914632012-10-05 12:05:54 -0300227 } else if (type == INTEL_OUTPUT_ANALOG) {
Imre Deaka1e6ad62015-04-17 19:31:21 +0300228 *dig_port = NULL;
229 *port = PORT_E;
Paulo Zanonifc914632012-10-05 12:05:54 -0300230 } else {
231 DRM_ERROR("Invalid DDI encoder type %d\n", type);
232 BUG();
233 }
234}
235
Imre Deaka1e6ad62015-04-17 19:31:21 +0300236enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
237{
238 struct intel_digital_port *dig_port;
239 enum port port;
240
241 ddi_get_encoder_port(intel_encoder, &dig_port, &port);
242
243 return port;
244}
245
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100246static bool
247intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
248{
249 return intel_dig_port->hdmi.hdmi_reg;
250}
251
Art Runyane58623c2013-11-02 21:07:41 -0700252/*
253 * Starting with Haswell, DDI port buffers must be programmed with correct
254 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300255 * but the HDMI/DVI fields are shared among those. So we program the DDI
256 * in either FDI or DP modes only, as HDMI connections will work with both
257 * of those
258 */
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300259static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
260 bool supports_hdmi)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300261{
262 struct drm_i915_private *dev_priv = dev->dev_private;
263 u32 reg;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000264 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530265 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300266 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300267 const struct ddi_buf_trans *ddi_translations_fdi;
268 const struct ddi_buf_trans *ddi_translations_dp;
269 const struct ddi_buf_trans *ddi_translations_edp;
270 const struct ddi_buf_trans *ddi_translations_hdmi;
271 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700272
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530273 if (IS_BROXTON(dev)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300274 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530275 return;
276
277 /* Vswing programming for HDMI */
278 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
279 INTEL_OUTPUT_HDMI);
280 return;
281 } else if (IS_SKYLAKE(dev)) {
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000282 ddi_translations_fdi = NULL;
283 ddi_translations_dp = skl_ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530284 n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp);
Sonika Jindal9e458032015-05-06 17:35:48 +0530285 if (dev_priv->edp_low_vswing) {
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530286 ddi_translations_edp = skl_ddi_translations_edp;
287 n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp);
288 } else {
289 ddi_translations_edp = skl_ddi_translations_dp;
290 n_edp_entries = ARRAY_SIZE(skl_ddi_translations_dp);
291 }
292
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000293 ddi_translations_hdmi = skl_ddi_translations_hdmi;
294 n_hdmi_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
Sonika Jindalb7192a52015-04-15 11:02:33 +0530295 hdmi_default_entry = 7;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000296 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700297 ddi_translations_fdi = bdw_ddi_translations_fdi;
298 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700299 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100300 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530301 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
302 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300303 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000304 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700305 } else if (IS_HASWELL(dev)) {
306 ddi_translations_fdi = hsw_ddi_translations_fdi;
307 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700308 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100309 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530310 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300311 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000312 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700313 } else {
314 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700315 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700316 ddi_translations_fdi = bdw_ddi_translations_fdi;
317 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100318 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530319 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
320 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300321 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000322 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700323 }
324
Paulo Zanoni300644c2013-11-02 21:07:42 -0700325 switch (port) {
326 case PORT_A:
327 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530328 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700329 break;
330 case PORT_B:
331 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700332 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530333 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700334 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700335 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530336 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700337 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530338 size = n_edp_entries;
339 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700340 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530341 size = n_dp_entries;
342 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700343 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700344 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000345 if (ddi_translations_fdi)
346 ddi_translations = ddi_translations_fdi;
347 else
348 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530349 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700350 break;
351 default:
352 BUG();
353 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300354
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530355 for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) {
Jani Nikula10122052014-08-27 16:27:30 +0300356 I915_WRITE(reg, ddi_translations[i].trans1);
357 reg += 4;
358 I915_WRITE(reg, ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300359 reg += 4;
360 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100361
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300362 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100363 return;
364
Damien Lespiauce4dd492014-08-01 11:07:54 +0100365 /* Choose a good default if VBT is badly populated */
366 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
367 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000368 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100369
Paulo Zanoni6acab152013-09-12 17:06:24 -0300370 /* Entry 9 is for HDMI: */
Jani Nikula10122052014-08-27 16:27:30 +0300371 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1);
372 reg += 4;
373 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2);
374 reg += 4;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300375}
376
377/* Program DDI buffers translations for DP. By default, program ports A-D in DP
378 * mode and port E for FDI.
379 */
380void intel_prepare_ddi(struct drm_device *dev)
381{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300382 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100383 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300384
Paulo Zanoni0d536cb42012-11-23 16:46:41 -0200385 if (!HAS_DDI(dev))
386 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300387
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300388 for_each_intel_encoder(dev, intel_encoder) {
389 struct intel_digital_port *intel_dig_port;
390 enum port port;
391 bool supports_hdmi;
392
393 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
394
395 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100396 continue;
397
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300398 supports_hdmi = intel_dig_port &&
399 intel_dig_port_supports_hdmi(intel_dig_port);
400
401 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
402 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100403 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300404}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300405
Paulo Zanoni248138b2012-11-29 11:29:31 -0200406static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
407 enum port port)
408{
409 uint32_t reg = DDI_BUF_CTL(port);
410 int i;
411
Vandana Kannan3449ca82015-03-27 14:19:09 +0200412 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200413 udelay(1);
414 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
415 return;
416 }
417 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
418}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300419
420/* Starting with Haswell, different DDI ports can work in FDI mode for
421 * connection to the PCH-located connectors. For this, it is necessary to train
422 * both the DDI port and PCH receiver for the desired DDI buffer settings.
423 *
424 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
425 * please note that when FDI mode is active on DDI E, it shares 2 lines with
426 * DDI A (which is used for eDP)
427 */
428
429void hsw_fdi_link_train(struct drm_crtc *crtc)
430{
431 struct drm_device *dev = crtc->dev;
432 struct drm_i915_private *dev_priv = dev->dev_private;
433 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200434 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300435
Paulo Zanoni04945642012-11-01 21:00:59 -0200436 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
437 * mode set "sequence for CRT port" document:
438 * - TP1 to TP2 time with the default value
439 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100440 *
441 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200442 */
443 I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
444 FDI_RX_PWRDN_LANE0_VAL(2) |
445 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
446
447 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000448 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100449 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200450 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Paulo Zanoni04945642012-11-01 21:00:59 -0200451 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
452 POSTING_READ(_FDI_RXA_CTL);
453 udelay(220);
454
455 /* Switch from Rawclk to PCDclk */
456 rx_ctl_val |= FDI_PCDCLK;
457 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
458
459 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200460 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
461 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200462
463 /* Start the training iterating through available voltages and emphasis,
464 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300465 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300466 /* Configure DP_TP_CTL with auto-training */
467 I915_WRITE(DP_TP_CTL(PORT_E),
468 DP_TP_CTL_FDI_AUTOTRAIN |
469 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
470 DP_TP_CTL_LINK_TRAIN_PAT1 |
471 DP_TP_CTL_ENABLE);
472
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000473 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
474 * DDI E does not support port reversal, the functionality is
475 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
476 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300477 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200478 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200479 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530480 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200481 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300482
483 udelay(600);
484
Paulo Zanoni04945642012-11-01 21:00:59 -0200485 /* Program PCH FDI Receiver TU */
486 I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300487
Paulo Zanoni04945642012-11-01 21:00:59 -0200488 /* Enable PCH FDI Receiver with auto-training */
489 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
490 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
491 POSTING_READ(_FDI_RXA_CTL);
492
493 /* Wait for FDI receiver lane calibration */
494 udelay(30);
495
496 /* Unset FDI_RX_MISC pwrdn lanes */
497 temp = I915_READ(_FDI_RXA_MISC);
498 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
499 I915_WRITE(_FDI_RXA_MISC, temp);
500 POSTING_READ(_FDI_RXA_MISC);
501
502 /* Wait for FDI auto training time */
503 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300504
505 temp = I915_READ(DP_TP_STATUS(PORT_E));
506 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200507 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300508
509 /* Enable normal pixel sending for FDI */
510 I915_WRITE(DP_TP_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200511 DP_TP_CTL_FDI_AUTOTRAIN |
512 DP_TP_CTL_LINK_TRAIN_NORMAL |
513 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
514 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300515
Paulo Zanoni04945642012-11-01 21:00:59 -0200516 return;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300517 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200518
Paulo Zanoni248138b2012-11-29 11:29:31 -0200519 temp = I915_READ(DDI_BUF_CTL(PORT_E));
520 temp &= ~DDI_BUF_CTL_ENABLE;
521 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
522 POSTING_READ(DDI_BUF_CTL(PORT_E));
523
Paulo Zanoni04945642012-11-01 21:00:59 -0200524 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200525 temp = I915_READ(DP_TP_CTL(PORT_E));
526 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
527 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
528 I915_WRITE(DP_TP_CTL(PORT_E), temp);
529 POSTING_READ(DP_TP_CTL(PORT_E));
530
531 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200532
533 rx_ctl_val &= ~FDI_RX_ENABLE;
534 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200535 POSTING_READ(_FDI_RXA_CTL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200536
537 /* Reset FDI_RX_MISC pwrdn lanes */
538 temp = I915_READ(_FDI_RXA_MISC);
539 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
540 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
541 I915_WRITE(_FDI_RXA_MISC, temp);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200542 POSTING_READ(_FDI_RXA_MISC);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300543 }
544
Paulo Zanoni04945642012-11-01 21:00:59 -0200545 DRM_ERROR("FDI link training failed!\n");
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300546}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300547
Dave Airlie44905a272014-05-02 13:36:43 +1000548void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
549{
550 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
551 struct intel_digital_port *intel_dig_port =
552 enc_to_dig_port(&encoder->base);
553
554 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530555 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Dave Airlie44905a272014-05-02 13:36:43 +1000556 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
557
558}
559
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300560static struct intel_encoder *
561intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
562{
563 struct drm_device *dev = crtc->dev;
564 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
565 struct intel_encoder *intel_encoder, *ret = NULL;
566 int num_encoders = 0;
567
568 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
569 ret = intel_encoder;
570 num_encoders++;
571 }
572
573 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300574 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
575 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300576
577 BUG_ON(ret == NULL);
578 return ret;
579}
580
Satheeshakrishna Mbcddf6102014-08-22 09:49:10 +0530581struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200582intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200583{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200584 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
585 struct intel_encoder *ret = NULL;
586 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300587 struct drm_connector *connector;
588 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200589 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200590 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200591
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200592 state = crtc_state->base.state;
593
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300594 for_each_connector_in_state(state, connector, connector_state, i) {
595 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200596 continue;
597
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300598 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200599 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200600 }
601
602 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
603 pipe_name(crtc->pipe));
604
605 BUG_ON(ret == NULL);
606 return ret;
607}
608
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100609#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100610#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100611
612#define P_MIN 2
613#define P_MAX 64
614#define P_INC 2
615
616/* Constraints for PLL good behavior */
617#define REF_MIN 48
618#define REF_MAX 400
619#define VCO_MIN 2400
620#define VCO_MAX 4800
621
Damien Lespiau27893392014-09-04 12:27:23 +0100622#define abs_diff(a, b) ({ \
623 typeof(a) __a = (a); \
624 typeof(b) __b = (b); \
625 (void) (&__a == &__b); \
626 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100627
Damien Lespiau63582982015-05-07 18:38:46 +0100628struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100629 unsigned p, n2, r2;
630};
631
Damien Lespiau63582982015-05-07 18:38:46 +0100632static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300633{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100634 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300635
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100636 switch (clock) {
637 case 25175000:
638 case 25200000:
639 case 27000000:
640 case 27027000:
641 case 37762500:
642 case 37800000:
643 case 40500000:
644 case 40541000:
645 case 54000000:
646 case 54054000:
647 case 59341000:
648 case 59400000:
649 case 72000000:
650 case 74176000:
651 case 74250000:
652 case 81000000:
653 case 81081000:
654 case 89012000:
655 case 89100000:
656 case 108000000:
657 case 108108000:
658 case 111264000:
659 case 111375000:
660 case 148352000:
661 case 148500000:
662 case 162000000:
663 case 162162000:
664 case 222525000:
665 case 222750000:
666 case 296703000:
667 case 297000000:
668 budget = 0;
669 break;
670 case 233500000:
671 case 245250000:
672 case 247750000:
673 case 253250000:
674 case 298000000:
675 budget = 1500;
676 break;
677 case 169128000:
678 case 169500000:
679 case 179500000:
680 case 202000000:
681 budget = 2000;
682 break;
683 case 256250000:
684 case 262500000:
685 case 270000000:
686 case 272500000:
687 case 273750000:
688 case 280750000:
689 case 281250000:
690 case 286000000:
691 case 291750000:
692 budget = 4000;
693 break;
694 case 267250000:
695 case 268500000:
696 budget = 5000;
697 break;
698 default:
699 budget = 1000;
700 break;
701 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300702
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100703 return budget;
704}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300705
Damien Lespiau63582982015-05-07 18:38:46 +0100706static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
707 unsigned r2, unsigned n2, unsigned p,
708 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100709{
710 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300711
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100712 /* No best (r,n,p) yet */
713 if (best->p == 0) {
714 best->p = p;
715 best->n2 = n2;
716 best->r2 = r2;
717 return;
718 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300719
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100720 /*
721 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
722 * freq2k.
723 *
724 * delta = 1e6 *
725 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
726 * freq2k;
727 *
728 * and we would like delta <= budget.
729 *
730 * If the discrepancy is above the PPM-based budget, always prefer to
731 * improve upon the previous solution. However, if you're within the
732 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
733 */
734 a = freq2k * budget * p * r2;
735 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100736 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
737 diff_best = abs_diff(freq2k * best->p * best->r2,
738 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100739 c = 1000000 * diff;
740 d = 1000000 * diff_best;
741
742 if (a < c && b < d) {
743 /* If both are above the budget, pick the closer */
744 if (best->p * best->r2 * diff < p * r2 * diff_best) {
745 best->p = p;
746 best->n2 = n2;
747 best->r2 = r2;
748 }
749 } else if (a >= c && b < d) {
750 /* If A is below the threshold but B is above it? Update. */
751 best->p = p;
752 best->n2 = n2;
753 best->r2 = r2;
754 } else if (a >= c && b >= d) {
755 /* Both are below the limit, so pick the higher n2/(r2*r2) */
756 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
757 best->p = p;
758 best->n2 = n2;
759 best->r2 = r2;
760 }
761 }
762 /* Otherwise a < c && b >= d, do nothing */
763}
764
Damien Lespiau63582982015-05-07 18:38:46 +0100765static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, int reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800766{
767 int refclk = LC_FREQ;
768 int n, p, r;
769 u32 wrpll;
770
771 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300772 switch (wrpll & WRPLL_PLL_REF_MASK) {
773 case WRPLL_PLL_SSC:
774 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800775 /*
776 * We could calculate spread here, but our checking
777 * code only cares about 5% accuracy, and spread is a max of
778 * 0.5% downspread.
779 */
780 refclk = 135;
781 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300782 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800783 refclk = LC_FREQ;
784 break;
785 default:
786 WARN(1, "bad wrpll refclk\n");
787 return 0;
788 }
789
790 r = wrpll & WRPLL_DIVIDER_REF_MASK;
791 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
792 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
793
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800794 /* Convert to KHz, p & r have a fixed point portion */
795 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800796}
797
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000798static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
799 uint32_t dpll)
800{
801 uint32_t cfgcr1_reg, cfgcr2_reg;
802 uint32_t cfgcr1_val, cfgcr2_val;
803 uint32_t p0, p1, p2, dco_freq;
804
805 cfgcr1_reg = GET_CFG_CR1_REG(dpll);
806 cfgcr2_reg = GET_CFG_CR2_REG(dpll);
807
808 cfgcr1_val = I915_READ(cfgcr1_reg);
809 cfgcr2_val = I915_READ(cfgcr2_reg);
810
811 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
812 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
813
814 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
815 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
816 else
817 p1 = 1;
818
819
820 switch (p0) {
821 case DPLL_CFGCR2_PDIV_1:
822 p0 = 1;
823 break;
824 case DPLL_CFGCR2_PDIV_2:
825 p0 = 2;
826 break;
827 case DPLL_CFGCR2_PDIV_3:
828 p0 = 3;
829 break;
830 case DPLL_CFGCR2_PDIV_7:
831 p0 = 7;
832 break;
833 }
834
835 switch (p2) {
836 case DPLL_CFGCR2_KDIV_5:
837 p2 = 5;
838 break;
839 case DPLL_CFGCR2_KDIV_2:
840 p2 = 2;
841 break;
842 case DPLL_CFGCR2_KDIV_3:
843 p2 = 3;
844 break;
845 case DPLL_CFGCR2_KDIV_1:
846 p2 = 1;
847 break;
848 }
849
850 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
851
852 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
853 1000) / 0x8000;
854
855 return dco_freq / (p0 * p1 * p2 * 5);
856}
857
858
859static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +0200860 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000861{
862 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000863 int link_clock = 0;
864 uint32_t dpll_ctl1, dpll;
865
Damien Lespiau134ffa42014-11-14 17:24:34 +0000866 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000867
868 dpll_ctl1 = I915_READ(DPLL_CTRL1);
869
870 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
871 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
872 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +0100873 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
874 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000875
876 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +0100877 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000878 link_clock = 81000;
879 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +0100880 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +0530881 link_clock = 108000;
882 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +0100883 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000884 link_clock = 135000;
885 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +0100886 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +0530887 link_clock = 162000;
888 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +0100889 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +0530890 link_clock = 216000;
891 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +0100892 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000893 link_clock = 270000;
894 break;
895 default:
896 WARN(1, "Unsupported link rate\n");
897 break;
898 }
899 link_clock *= 2;
900 }
901
902 pipe_config->port_clock = link_clock;
903
904 if (pipe_config->has_dp_encoder)
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +0200905 pipe_config->base.adjusted_mode.crtc_clock =
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000906 intel_dotclock_calculate(pipe_config->port_clock,
907 &pipe_config->dp_m_n);
908 else
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +0200909 pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000910}
911
Daniel Vetter3d51278a2014-07-29 20:57:08 +0200912static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +0200913 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -0800914{
915 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -0800916 int link_clock = 0;
917 u32 val, pll;
918
Daniel Vetter26804af2014-06-25 22:01:55 +0300919 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -0800920 switch (val & PORT_CLK_SEL_MASK) {
921 case PORT_CLK_SEL_LCPLL_810:
922 link_clock = 81000;
923 break;
924 case PORT_CLK_SEL_LCPLL_1350:
925 link_clock = 135000;
926 break;
927 case PORT_CLK_SEL_LCPLL_2700:
928 link_clock = 270000;
929 break;
930 case PORT_CLK_SEL_WRPLL1:
Damien Lespiau63582982015-05-07 18:38:46 +0100931 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL1);
Jesse Barnes11578552014-01-21 12:42:10 -0800932 break;
933 case PORT_CLK_SEL_WRPLL2:
Damien Lespiau63582982015-05-07 18:38:46 +0100934 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL2);
Jesse Barnes11578552014-01-21 12:42:10 -0800935 break;
936 case PORT_CLK_SEL_SPLL:
937 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
938 if (pll == SPLL_PLL_FREQ_810MHz)
939 link_clock = 81000;
940 else if (pll == SPLL_PLL_FREQ_1350MHz)
941 link_clock = 135000;
942 else if (pll == SPLL_PLL_FREQ_2700MHz)
943 link_clock = 270000;
944 else {
945 WARN(1, "bad spll freq\n");
946 return;
947 }
948 break;
949 default:
950 WARN(1, "bad port clock sel\n");
951 return;
952 }
953
954 pipe_config->port_clock = link_clock * 2;
955
956 if (pipe_config->has_pch_encoder)
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +0200957 pipe_config->base.adjusted_mode.crtc_clock =
Jesse Barnes11578552014-01-21 12:42:10 -0800958 intel_dotclock_calculate(pipe_config->port_clock,
959 &pipe_config->fdi_m_n);
960 else if (pipe_config->has_dp_encoder)
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +0200961 pipe_config->base.adjusted_mode.crtc_clock =
Jesse Barnes11578552014-01-21 12:42:10 -0800962 intel_dotclock_calculate(pipe_config->port_clock,
963 &pipe_config->dp_m_n);
964 else
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +0200965 pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
Jesse Barnes11578552014-01-21 12:42:10 -0800966}
967
Satheeshakrishna M977bb382014-08-22 09:49:12 +0530968static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
969 enum intel_dpll_id dpll)
970{
971 /* FIXME formula not available in bspec */
972 return 0;
973}
974
975static void bxt_ddi_clock_get(struct intel_encoder *encoder,
976 struct intel_crtc_state *pipe_config)
977{
978 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
979 enum port port = intel_ddi_get_encoder_port(encoder);
980 uint32_t dpll = port;
981
982 pipe_config->port_clock =
983 bxt_calc_pll_link(dev_priv, dpll);
984
985 if (pipe_config->has_dp_encoder)
986 pipe_config->base.adjusted_mode.crtc_clock =
987 intel_dotclock_calculate(pipe_config->port_clock,
988 &pipe_config->dp_m_n);
989 else
990 pipe_config->base.adjusted_mode.crtc_clock =
991 pipe_config->port_clock;
992}
993
Daniel Vetter3d51278a2014-07-29 20:57:08 +0200994void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +0200995 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +0200996{
Damien Lespiau22606a12014-12-12 14:26:57 +0000997 struct drm_device *dev = encoder->base.dev;
998
999 if (INTEL_INFO(dev)->gen <= 8)
1000 hsw_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301001 else if (IS_SKYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001002 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301003 else if (IS_BROXTON(dev))
1004 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001005}
1006
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001007static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001008hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1009 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001010{
1011 uint64_t freq2k;
1012 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001013 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001014 unsigned budget;
1015
1016 freq2k = clock / 100;
1017
Damien Lespiau63582982015-05-07 18:38:46 +01001018 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001019
1020 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1021 * and directly pass the LC PLL to it. */
1022 if (freq2k == 5400000) {
1023 *n2_out = 2;
1024 *p_out = 1;
1025 *r2_out = 2;
1026 return;
1027 }
1028
1029 /*
1030 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1031 * the WR PLL.
1032 *
1033 * We want R so that REF_MIN <= Ref <= REF_MAX.
1034 * Injecting R2 = 2 * R gives:
1035 * REF_MAX * r2 > LC_FREQ * 2 and
1036 * REF_MIN * r2 < LC_FREQ * 2
1037 *
1038 * Which means the desired boundaries for r2 are:
1039 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1040 *
1041 */
1042 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1043 r2 <= LC_FREQ * 2 / REF_MIN;
1044 r2++) {
1045
1046 /*
1047 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1048 *
1049 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1050 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1051 * VCO_MAX * r2 > n2 * LC_FREQ and
1052 * VCO_MIN * r2 < n2 * LC_FREQ)
1053 *
1054 * Which means the desired boundaries for n2 are:
1055 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1056 */
1057 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1058 n2 <= VCO_MAX * r2 / LC_FREQ;
1059 n2++) {
1060
1061 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001062 hsw_wrpll_update_rnp(freq2k, budget,
1063 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001064 }
1065 }
1066
1067 *n2_out = best.n2;
1068 *p_out = best.p;
1069 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001070}
1071
Damien Lespiau0220ab62014-07-29 18:06:22 +01001072static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001073hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001074 struct intel_crtc_state *crtc_state,
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001075 struct intel_encoder *intel_encoder,
1076 int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001077{
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001078 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001079 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001080 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001081 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001082
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001083 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001084
Daniel Vetter114fe482014-06-25 22:01:48 +03001085 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001086 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1087 WRPLL_DIVIDER_POST(p);
1088
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001089 memset(&crtc_state->dpll_hw_state, 0,
1090 sizeof(crtc_state->dpll_hw_state));
1091
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001092 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001093
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001094 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001095 if (pll == NULL) {
1096 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1097 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001098 return false;
1099 }
1100
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001101 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001102 }
1103
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001104 return true;
1105}
1106
Damien Lespiaudc253812015-06-25 16:15:06 +01001107struct skl_wrpll_context {
1108 uint64_t min_deviation; /* current minimal deviation */
1109 uint64_t central_freq; /* chosen central freq */
1110 uint64_t dco_freq; /* chosen dco freq */
1111 unsigned int p; /* chosen divider */
1112};
1113
1114static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1115{
1116 memset(ctx, 0, sizeof(*ctx));
1117
1118 ctx->min_deviation = U64_MAX;
1119}
1120
1121/* DCO freq must be within +1%/-6% of the DCO central freq */
1122#define SKL_DCO_MAX_PDEVIATION 100
1123#define SKL_DCO_MAX_NDEVIATION 600
1124
1125static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1126 uint64_t central_freq,
1127 uint64_t dco_freq,
1128 unsigned int divider)
1129{
1130 uint64_t deviation;
1131
1132 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1133 central_freq);
1134
1135 /* positive deviation */
1136 if (dco_freq >= central_freq) {
1137 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1138 deviation < ctx->min_deviation) {
1139 ctx->min_deviation = deviation;
1140 ctx->central_freq = central_freq;
1141 ctx->dco_freq = dco_freq;
1142 ctx->p = divider;
1143 }
1144 /* negative deviation */
1145 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1146 deviation < ctx->min_deviation) {
1147 ctx->min_deviation = deviation;
1148 ctx->central_freq = central_freq;
1149 ctx->dco_freq = dco_freq;
1150 ctx->p = divider;
1151 }
1152
1153}
1154
1155static void skl_wrpll_get_multipliers(unsigned int p,
1156 unsigned int *p0 /* out */,
1157 unsigned int *p1 /* out */,
1158 unsigned int *p2 /* out */)
1159{
1160 /* even dividers */
1161 if (p % 2 == 0) {
1162 unsigned int half = p / 2;
1163
1164 if (half == 1 || half == 2 || half == 3 || half == 5) {
1165 *p0 = 2;
1166 *p1 = 1;
1167 *p2 = half;
1168 } else if (half % 2 == 0) {
1169 *p0 = 2;
1170 *p1 = half / 2;
1171 *p2 = 2;
1172 } else if (half % 3 == 0) {
1173 *p0 = 3;
1174 *p1 = half / 3;
1175 *p2 = 2;
1176 } else if (half % 7 == 0) {
1177 *p0 = 7;
1178 *p1 = half / 7;
1179 *p2 = 2;
1180 }
1181 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1182 *p0 = 3;
1183 *p1 = 1;
1184 *p2 = p / 3;
1185 } else if (p == 5 || p == 7) {
1186 *p0 = p;
1187 *p1 = 1;
1188 *p2 = 1;
1189 } else if (p == 15) {
1190 *p0 = 3;
1191 *p1 = 1;
1192 *p2 = 5;
1193 } else if (p == 21) {
1194 *p0 = 7;
1195 *p1 = 1;
1196 *p2 = 3;
1197 } else if (p == 35) {
1198 *p0 = 7;
1199 *p1 = 1;
1200 *p2 = 5;
1201 }
1202}
1203
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001204struct skl_wrpll_params {
1205 uint32_t dco_fraction;
1206 uint32_t dco_integer;
1207 uint32_t qdiv_ratio;
1208 uint32_t qdiv_mode;
1209 uint32_t kdiv;
1210 uint32_t pdiv;
1211 uint32_t central_freq;
1212};
1213
Damien Lespiau76516fb2015-05-07 18:38:42 +01001214static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1215 uint64_t afe_clock,
1216 uint64_t central_freq,
1217 uint32_t p0, uint32_t p1, uint32_t p2)
1218{
1219 uint64_t dco_freq;
1220
Damien Lespiau76516fb2015-05-07 18:38:42 +01001221 switch (central_freq) {
1222 case 9600000000ULL:
1223 params->central_freq = 0;
1224 break;
1225 case 9000000000ULL:
1226 params->central_freq = 1;
1227 break;
1228 case 8400000000ULL:
1229 params->central_freq = 3;
1230 }
1231
1232 switch (p0) {
1233 case 1:
1234 params->pdiv = 0;
1235 break;
1236 case 2:
1237 params->pdiv = 1;
1238 break;
1239 case 3:
1240 params->pdiv = 2;
1241 break;
1242 case 7:
1243 params->pdiv = 4;
1244 break;
1245 default:
1246 WARN(1, "Incorrect PDiv\n");
1247 }
1248
1249 switch (p2) {
1250 case 5:
1251 params->kdiv = 0;
1252 break;
1253 case 2:
1254 params->kdiv = 1;
1255 break;
1256 case 3:
1257 params->kdiv = 2;
1258 break;
1259 case 1:
1260 params->kdiv = 3;
1261 break;
1262 default:
1263 WARN(1, "Incorrect KDiv\n");
1264 }
1265
1266 params->qdiv_ratio = p1;
1267 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1268
1269 dco_freq = p0 * p1 * p2 * afe_clock;
1270
1271 /*
1272 * Intermediate values are in Hz.
1273 * Divide by MHz to match bsepc
1274 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001275 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001276 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001277 div_u64((div_u64(dco_freq, 24) -
1278 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001279}
1280
Damien Lespiau318bd822015-05-07 18:38:40 +01001281static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001282skl_ddi_calculate_wrpll(int clock /* in Hz */,
1283 struct skl_wrpll_params *wrpll_params)
1284{
1285 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001286 uint64_t dco_central_freq[3] = {8400000000ULL,
1287 9000000000ULL,
1288 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001289 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1290 24, 28, 30, 32, 36, 40, 42, 44,
1291 48, 52, 54, 56, 60, 64, 66, 68,
1292 70, 72, 76, 78, 80, 84, 88, 90,
1293 92, 96, 98 };
1294 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1295 static const struct {
1296 const int *list;
1297 int n_dividers;
1298 } dividers[] = {
1299 { even_dividers, ARRAY_SIZE(even_dividers) },
1300 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1301 };
1302 struct skl_wrpll_context ctx;
1303 unsigned int dco, d, i;
1304 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001305
Damien Lespiaudc253812015-06-25 16:15:06 +01001306 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001307
Damien Lespiaudc253812015-06-25 16:15:06 +01001308 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1309 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1310 for (i = 0; i < dividers[d].n_dividers; i++) {
1311 unsigned int p = dividers[d].list[i];
1312 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001313
Damien Lespiaudc253812015-06-25 16:15:06 +01001314 skl_wrpll_try_divider(&ctx,
1315 dco_central_freq[dco],
1316 dco_freq,
1317 p);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001318 }
1319 }
Damien Lespiau267db662015-06-25 16:19:24 +01001320
1321 /*
1322 * If a solution is found with an even divider, prefer
1323 * this one.
1324 */
1325 if (d == 0 && ctx.p)
1326 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001327 }
1328
Damien Lespiaudc253812015-06-25 16:15:06 +01001329 if (!ctx.p) {
1330 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001331 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001332 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001333
Damien Lespiaudc253812015-06-25 16:15:06 +01001334 /*
1335 * gcc incorrectly analyses that these can be used without being
1336 * initialized. To be fair, it's hard to guess.
1337 */
1338 p0 = p1 = p2 = 0;
1339 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1340 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1341 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001342
Damien Lespiau318bd822015-05-07 18:38:40 +01001343 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001344}
1345
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001346static bool
1347skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001348 struct intel_crtc_state *crtc_state,
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001349 struct intel_encoder *intel_encoder,
1350 int clock)
1351{
1352 struct intel_shared_dpll *pll;
1353 uint32_t ctrl1, cfgcr1, cfgcr2;
1354
1355 /*
1356 * See comment in intel_dpll_hw_state to understand why we always use 0
1357 * as the DPLL id in this function.
1358 */
1359
1360 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1361
1362 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1363 struct skl_wrpll_params wrpll_params = { 0, };
1364
1365 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1366
Damien Lespiau318bd822015-05-07 18:38:40 +01001367 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1368 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001369
1370 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1371 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1372 wrpll_params.dco_integer;
1373
1374 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1375 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1376 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1377 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1378 wrpll_params.central_freq;
1379 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
1380 struct drm_encoder *encoder = &intel_encoder->base;
1381 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1382
1383 switch (intel_dp->link_bw) {
1384 case DP_LINK_BW_1_62:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001385 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001386 break;
1387 case DP_LINK_BW_2_7:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001388 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001389 break;
1390 case DP_LINK_BW_5_4:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001391 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001392 break;
1393 }
1394
1395 cfgcr1 = cfgcr2 = 0;
1396 } else /* eDP */
1397 return true;
1398
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001399 memset(&crtc_state->dpll_hw_state, 0,
1400 sizeof(crtc_state->dpll_hw_state));
1401
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001402 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1403 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1404 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001405
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001406 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001407 if (pll == NULL) {
1408 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1409 pipe_name(intel_crtc->pipe));
1410 return false;
1411 }
1412
1413 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001414 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001415
1416 return true;
1417}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001418
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301419/* bxt clock parameters */
1420struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301421 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301422 uint32_t p1;
1423 uint32_t p2;
1424 uint32_t m2_int;
1425 uint32_t m2_frac;
1426 bool m2_frac_en;
1427 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301428};
1429
1430/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301431static const struct bxt_clk_div bxt_dp_clk_val[] = {
1432 {162000, 4, 2, 32, 1677722, 1, 1},
1433 {270000, 4, 1, 27, 0, 0, 1},
1434 {540000, 2, 1, 27, 0, 0, 1},
1435 {216000, 3, 2, 32, 1677722, 1, 1},
1436 {243000, 4, 1, 24, 1258291, 1, 1},
1437 {324000, 4, 1, 32, 1677722, 1, 1},
1438 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301439};
1440
1441static bool
1442bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1443 struct intel_crtc_state *crtc_state,
1444 struct intel_encoder *intel_encoder,
1445 int clock)
1446{
1447 struct intel_shared_dpll *pll;
1448 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301449 int vco = 0;
1450 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane0681e32015-05-13 12:20:35 +05301451 uint32_t dcoampovr_en_h, dco_amp, lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301452
1453 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1454 intel_clock_t best_clock;
1455
1456 /* Calculate HDMI div */
1457 /*
1458 * FIXME: tie the following calculation into
1459 * i9xx_crtc_compute_clock
1460 */
1461 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1462 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1463 clock, pipe_name(intel_crtc->pipe));
1464 return false;
1465 }
1466
1467 clk_div.p1 = best_clock.p1;
1468 clk_div.p2 = best_clock.p2;
1469 WARN_ON(best_clock.m1 != 2);
1470 clk_div.n = best_clock.n;
1471 clk_div.m2_int = best_clock.m2 >> 22;
1472 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1473 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1474
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301475 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301476 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1477 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301478 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301479
Sonika Jindal64987fc2015-05-26 17:50:13 +05301480 clk_div = bxt_dp_clk_val[0];
1481 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1482 if (bxt_dp_clk_val[i].clock == clock) {
1483 clk_div = bxt_dp_clk_val[i];
1484 break;
1485 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301486 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301487 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1488 }
1489
1490 dco_amp = 15;
1491 dcoampovr_en_h = 0;
1492 if (vco >= 6200000 && vco <= 6480000) {
1493 prop_coef = 4;
1494 int_coef = 9;
1495 gain_ctl = 3;
1496 targ_cnt = 8;
1497 } else if ((vco > 5400000 && vco < 6200000) ||
1498 (vco >= 4800000 && vco < 5400000)) {
1499 prop_coef = 5;
1500 int_coef = 11;
1501 gain_ctl = 3;
1502 targ_cnt = 9;
1503 if (vco >= 4800000 && vco < 5400000)
1504 dcoampovr_en_h = 1;
1505 } else if (vco == 5400000) {
1506 prop_coef = 3;
1507 int_coef = 8;
1508 gain_ctl = 1;
1509 targ_cnt = 9;
1510 } else {
1511 DRM_ERROR("Invalid VCO\n");
1512 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301513 }
1514
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001515 memset(&crtc_state->dpll_hw_state, 0,
1516 sizeof(crtc_state->dpll_hw_state));
1517
Vandana Kannane0681e32015-05-13 12:20:35 +05301518 if (clock > 270000)
1519 lanestagger = 0x18;
1520 else if (clock > 135000)
1521 lanestagger = 0x0d;
1522 else if (clock > 67000)
1523 lanestagger = 0x07;
1524 else if (clock > 33000)
1525 lanestagger = 0x04;
1526 else
1527 lanestagger = 0x02;
1528
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301529 crtc_state->dpll_hw_state.ebb0 =
1530 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1531 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1532 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1533 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1534
1535 if (clk_div.m2_frac_en)
1536 crtc_state->dpll_hw_state.pll3 =
1537 PORT_PLL_M2_FRAC_ENABLE;
1538
1539 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301540 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301541 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301542 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301543
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301544 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1545
1546 if (dcoampovr_en_h)
1547 crtc_state->dpll_hw_state.pll10 = PORT_PLL_DCO_AMP_OVR_EN_H;
1548
1549 crtc_state->dpll_hw_state.pll10 |= PORT_PLL_DCO_AMP(dco_amp);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301550
1551 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301552 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301553
1554 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1555 if (pll == NULL) {
1556 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1557 pipe_name(intel_crtc->pipe));
1558 return false;
1559 }
1560
1561 /* shared DPLL id 0 is DPLL A */
1562 crtc_state->ddi_pll_sel = pll->id;
1563
1564 return true;
1565}
1566
Damien Lespiau0220ab62014-07-29 18:06:22 +01001567/*
1568 * Tries to find a *shared* PLL for the CRTC and store it in
1569 * intel_crtc->ddi_pll_sel.
1570 *
1571 * For private DPLLs, compute_config() should do the selection for us. This
1572 * function should be folded into compute_config() eventually.
1573 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001574bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1575 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001576{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001577 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001578 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001579 intel_ddi_get_crtc_new_encoder(crtc_state);
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001580 int clock = crtc_state->port_clock;
Damien Lespiau0220ab62014-07-29 18:06:22 +01001581
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001582 if (IS_SKYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001583 return skl_ddi_pll_select(intel_crtc, crtc_state,
1584 intel_encoder, clock);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301585 else if (IS_BROXTON(dev))
1586 return bxt_ddi_pll_select(intel_crtc, crtc_state,
1587 intel_encoder, clock);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001588 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001589 return hsw_ddi_pll_select(intel_crtc, crtc_state,
1590 intel_encoder, clock);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001591}
1592
Paulo Zanonidae84792012-10-15 15:51:30 -03001593void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1594{
1595 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1596 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1597 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001598 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001599 int type = intel_encoder->type;
1600 uint32_t temp;
1601
Dave Airlie0e32b392014-05-02 14:02:48 +10001602 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001603 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001604 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001605 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001606 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001607 break;
1608 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001609 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001610 break;
1611 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001612 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001613 break;
1614 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001615 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001616 break;
1617 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001618 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001619 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001620 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001621 }
1622}
1623
Dave Airlie0e32b392014-05-02 14:02:48 +10001624void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1625{
1626 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1627 struct drm_device *dev = crtc->dev;
1628 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001629 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001630 uint32_t temp;
1631 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1632 if (state == true)
1633 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1634 else
1635 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1636 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1637}
1638
Damien Lespiau8228c252013-03-07 15:30:27 +00001639void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001640{
1641 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1642 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001643 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001644 struct drm_device *dev = crtc->dev;
1645 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001646 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001647 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001648 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001649 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001650 uint32_t temp;
1651
Paulo Zanoniad80a812012-10-24 16:06:19 -02001652 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1653 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001654 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001655
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001656 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001657 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001658 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001659 break;
1660 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001661 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001662 break;
1663 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001664 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001665 break;
1666 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001667 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001668 break;
1669 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001670 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001671 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001672
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001673 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001674 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001675 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001676 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001677
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001678 if (cpu_transcoder == TRANSCODER_EDP) {
1679 switch (pipe) {
1680 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001681 /* On Haswell, can only use the always-on power well for
1682 * eDP when not using the panel fitter, and when not
1683 * using motion blur mitigation (which we don't
1684 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001685 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001686 (intel_crtc->config->pch_pfit.enabled ||
1687 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001688 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1689 else
1690 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001691 break;
1692 case PIPE_B:
1693 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1694 break;
1695 case PIPE_C:
1696 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1697 break;
1698 default:
1699 BUG();
1700 break;
1701 }
1702 }
1703
Paulo Zanoni7739c332012-10-15 15:51:29 -03001704 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001705 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001706 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001707 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001708 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001709
Paulo Zanoni7739c332012-10-15 15:51:29 -03001710 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001711 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001712 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001713
1714 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1715 type == INTEL_OUTPUT_EDP) {
1716 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1717
Dave Airlie0e32b392014-05-02 14:02:48 +10001718 if (intel_dp->is_mst) {
1719 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1720 } else
1721 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1722
1723 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
1724 } else if (type == INTEL_OUTPUT_DP_MST) {
1725 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1726
1727 if (intel_dp->is_mst) {
1728 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1729 } else
1730 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001731
Daniel Vetter17aa6be2013-04-30 14:01:40 +02001732 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001733 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001734 WARN(1, "Invalid encoder type %d for pipe %c\n",
1735 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001736 }
1737
Paulo Zanoniad80a812012-10-24 16:06:19 -02001738 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001739}
1740
Paulo Zanoniad80a812012-10-24 16:06:19 -02001741void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1742 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001743{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001744 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001745 uint32_t val = I915_READ(reg);
1746
Dave Airlie0e32b392014-05-02 14:02:48 +10001747 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001748 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001749 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001750}
1751
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001752bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1753{
1754 struct drm_device *dev = intel_connector->base.dev;
1755 struct drm_i915_private *dev_priv = dev->dev_private;
1756 struct intel_encoder *intel_encoder = intel_connector->encoder;
1757 int type = intel_connector->base.connector_type;
1758 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1759 enum pipe pipe = 0;
1760 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001761 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001762 uint32_t tmp;
1763
Paulo Zanoni882244a2014-04-01 14:55:12 -03001764 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001765 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001766 return false;
1767
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001768 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1769 return false;
1770
1771 if (port == PORT_A)
1772 cpu_transcoder = TRANSCODER_EDP;
1773 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001774 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001775
1776 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1777
1778 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1779 case TRANS_DDI_MODE_SELECT_HDMI:
1780 case TRANS_DDI_MODE_SELECT_DVI:
1781 return (type == DRM_MODE_CONNECTOR_HDMIA);
1782
1783 case TRANS_DDI_MODE_SELECT_DP_SST:
1784 if (type == DRM_MODE_CONNECTOR_eDP)
1785 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001786 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001787 case TRANS_DDI_MODE_SELECT_DP_MST:
1788 /* if the transcoder is in MST state then
1789 * connector isn't connected */
1790 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001791
1792 case TRANS_DDI_MODE_SELECT_FDI:
1793 return (type == DRM_MODE_CONNECTOR_VGA);
1794
1795 default:
1796 return false;
1797 }
1798}
1799
Daniel Vetter85234cd2012-07-02 13:27:29 +02001800bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1801 enum pipe *pipe)
1802{
1803 struct drm_device *dev = encoder->base.dev;
1804 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001805 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001806 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001807 u32 tmp;
1808 int i;
1809
Imre Deak6d129be2014-03-05 16:20:54 +02001810 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001811 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02001812 return false;
1813
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001814 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001815
1816 if (!(tmp & DDI_BUF_CTL_ENABLE))
1817 return false;
1818
Paulo Zanoniad80a812012-10-24 16:06:19 -02001819 if (port == PORT_A) {
1820 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001821
Paulo Zanoniad80a812012-10-24 16:06:19 -02001822 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
1823 case TRANS_DDI_EDP_INPUT_A_ON:
1824 case TRANS_DDI_EDP_INPUT_A_ONOFF:
1825 *pipe = PIPE_A;
1826 break;
1827 case TRANS_DDI_EDP_INPUT_B_ONOFF:
1828 *pipe = PIPE_B;
1829 break;
1830 case TRANS_DDI_EDP_INPUT_C_ONOFF:
1831 *pipe = PIPE_C;
1832 break;
1833 }
1834
1835 return true;
1836 } else {
1837 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
1838 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
1839
1840 if ((tmp & TRANS_DDI_PORT_MASK)
1841 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10001842 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
1843 return false;
1844
Paulo Zanoniad80a812012-10-24 16:06:19 -02001845 *pipe = i;
1846 return true;
1847 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02001848 }
1849 }
1850
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001851 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001852
Jesse Barnes22f9fe52013-04-02 10:03:55 -07001853 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001854}
1855
Paulo Zanonifc914632012-10-05 12:05:54 -03001856void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
1857{
1858 struct drm_crtc *crtc = &intel_crtc->base;
1859 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1860 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
1861 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001862 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03001863
Paulo Zanonibb523fc2012-10-23 18:29:56 -02001864 if (cpu_transcoder != TRANSCODER_EDP)
1865 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
1866 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03001867}
1868
1869void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
1870{
1871 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001872 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03001873
Paulo Zanonibb523fc2012-10-23 18:29:56 -02001874 if (cpu_transcoder != TRANSCODER_EDP)
1875 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
1876 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03001877}
1878
Vandana Kannan96fb9f92014-11-18 15:45:27 +05301879void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
1880 enum port port, int type)
1881{
1882 struct drm_i915_private *dev_priv = dev->dev_private;
1883 const struct bxt_ddi_buf_trans *ddi_translations;
1884 u32 n_entries, i;
1885 uint32_t val;
1886
1887 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
1888 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
1889 ddi_translations = bxt_ddi_translations_dp;
1890 } else if (type == INTEL_OUTPUT_HDMI) {
1891 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
1892 ddi_translations = bxt_ddi_translations_hdmi;
1893 } else {
1894 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
1895 type);
1896 return;
1897 }
1898
1899 /* Check if default value has to be used */
1900 if (level >= n_entries ||
1901 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
1902 for (i = 0; i < n_entries; i++) {
1903 if (ddi_translations[i].default_index) {
1904 level = i;
1905 break;
1906 }
1907 }
1908 }
1909
1910 /*
1911 * While we write to the group register to program all lanes at once we
1912 * can read only lane registers and we pick lanes 0/1 for that.
1913 */
1914 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
1915 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
1916 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
1917
1918 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
1919 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
1920 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
1921 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
1922 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
1923
1924 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
1925 val &= ~UNIQE_TRANGE_EN_METHOD;
1926 if (ddi_translations[level].enable)
1927 val |= UNIQE_TRANGE_EN_METHOD;
1928 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
1929
1930 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
1931 val &= ~DE_EMPHASIS;
1932 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
1933 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
1934
1935 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
1936 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
1937 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
1938}
1939
Paulo Zanoni00c09d72012-10-26 19:05:52 -02001940static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001941{
Paulo Zanonic19b0662012-10-15 15:51:41 -03001942 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00001943 struct drm_device *dev = encoder->dev;
1944 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02001945 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001946 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001947 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05301948 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001949
1950 if (type == INTEL_OUTPUT_EDP) {
1951 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01001952 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001953 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001954
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00001955 if (IS_SKYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001956 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00001957 uint32_t val;
1958
Damien Lespiau5416d872014-11-14 17:24:33 +00001959 /*
1960 * DPLL0 is used for eDP and is the only "private" DPLL (as
1961 * opposed to shared) on SKL
1962 */
1963 if (type == INTEL_OUTPUT_EDP) {
1964 WARN_ON(dpll != SKL_DPLL0);
1965
1966 val = I915_READ(DPLL_CTRL1);
1967
1968 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
1969 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01001970 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001971 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00001972
1973 I915_WRITE(DPLL_CTRL1, val);
1974 POSTING_READ(DPLL_CTRL1);
1975 }
1976
1977 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00001978 val = I915_READ(DPLL_CTRL2);
1979
1980 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
1981 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
1982 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
1983 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
1984
1985 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00001986
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05301987 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001988 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
1989 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00001990 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03001991
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02001992 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03001993 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02001994
Dave Airlie44905a272014-05-02 13:36:43 +10001995 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03001996
1997 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
1998 intel_dp_start_link_train(intel_dp);
1999 intel_dp_complete_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002000 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002001 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002002 } else if (type == INTEL_OUTPUT_HDMI) {
2003 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2004
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302005 if (IS_BROXTON(dev)) {
2006 hdmi_level = dev_priv->vbt.
2007 ddi_port_info[port].hdmi_level_shift;
2008 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2009 INTEL_OUTPUT_HDMI);
2010 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002011 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002012 crtc->config->has_hdmi_sink,
2013 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002014 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002015}
2016
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002017static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002018{
2019 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002020 struct drm_device *dev = encoder->dev;
2021 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002022 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002023 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002024 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002025 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002026
2027 val = I915_READ(DDI_BUF_CTL(port));
2028 if (val & DDI_BUF_CTL_ENABLE) {
2029 val &= ~DDI_BUF_CTL_ENABLE;
2030 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002031 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002032 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002033
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002034 val = I915_READ(DP_TP_CTL(port));
2035 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2036 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2037 I915_WRITE(DP_TP_CTL(port), val);
2038
2039 if (wait)
2040 intel_wait_ddi_buf_idle(dev_priv, port);
2041
Jani Nikula76bb80e2013-11-15 15:29:57 +02002042 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002043 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002044 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002045 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002046 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002047 }
2048
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002049 if (IS_SKYLAKE(dev))
2050 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2051 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302052 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002053 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002054}
2055
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002056static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002057{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002058 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002059 struct drm_crtc *crtc = encoder->crtc;
2060 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002061 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002062 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002063 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2064 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002065
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002066 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002067 struct intel_digital_port *intel_dig_port =
2068 enc_to_dig_port(encoder);
2069
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002070 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2071 * are ignored so nothing special needs to be done besides
2072 * enabling the port.
2073 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002074 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002075 intel_dig_port->saved_port_bits |
2076 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002077 } else if (type == INTEL_OUTPUT_EDP) {
2078 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2079
Vandana Kannan23f08d82014-11-13 14:55:22 +00002080 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002081 intel_dp_stop_link_train(intel_dp);
2082
Daniel Vetter4be73782014-01-17 14:39:48 +01002083 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002084 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302085 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002086 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002087
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002088 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002089 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002090 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002091 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002092}
2093
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002094static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002095{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002096 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002097 struct drm_crtc *crtc = encoder->crtc;
2098 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002099 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002100 struct drm_device *dev = encoder->dev;
2101 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002102
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002103 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002104 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002105 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2106 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002107
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002108 if (type == INTEL_OUTPUT_EDP) {
2109 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2110
Vandana Kannanc3955782015-01-22 15:17:40 +05302111 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002112 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002113 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002114 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002115}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002116
Daniel Vettere0b01be2014-06-25 22:02:01 +03002117static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2118 struct intel_shared_dpll *pll)
2119{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002120 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002121 POSTING_READ(WRPLL_CTL(pll->id));
2122 udelay(20);
2123}
2124
Daniel Vetter12030432014-06-25 22:02:00 +03002125static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2126 struct intel_shared_dpll *pll)
2127{
2128 uint32_t val;
2129
2130 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002131 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2132 POSTING_READ(WRPLL_CTL(pll->id));
2133}
2134
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002135static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2136 struct intel_shared_dpll *pll,
2137 struct intel_dpll_hw_state *hw_state)
2138{
2139 uint32_t val;
2140
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002141 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002142 return false;
2143
2144 val = I915_READ(WRPLL_CTL(pll->id));
2145 hw_state->wrpll = val;
2146
2147 return val & WRPLL_PLL_ENABLE;
2148}
2149
Damien Lespiauca1381b2014-07-15 15:05:33 +01002150static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002151 "WRPLL 1",
2152 "WRPLL 2",
2153};
2154
Damien Lespiau143b3072014-07-29 18:06:19 +01002155static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002156{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002157 int i;
2158
Daniel Vetter716c2e52014-06-25 22:02:02 +03002159 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002160
Daniel Vetter716c2e52014-06-25 22:02:02 +03002161 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002162 dev_priv->shared_dplls[i].id = i;
2163 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002164 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002165 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002166 dev_priv->shared_dplls[i].get_hw_state =
2167 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002168 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002169}
2170
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002171static const char * const skl_ddi_pll_names[] = {
2172 "DPLL 1",
2173 "DPLL 2",
2174 "DPLL 3",
2175};
2176
2177struct skl_dpll_regs {
2178 u32 ctl, cfgcr1, cfgcr2;
2179};
2180
2181/* this array is indexed by the *shared* pll id */
2182static const struct skl_dpll_regs skl_dpll_regs[3] = {
2183 {
2184 /* DPLL 1 */
2185 .ctl = LCPLL2_CTL,
2186 .cfgcr1 = DPLL1_CFGCR1,
2187 .cfgcr2 = DPLL1_CFGCR2,
2188 },
2189 {
2190 /* DPLL 2 */
2191 .ctl = WRPLL_CTL1,
2192 .cfgcr1 = DPLL2_CFGCR1,
2193 .cfgcr2 = DPLL2_CFGCR2,
2194 },
2195 {
2196 /* DPLL 3 */
2197 .ctl = WRPLL_CTL2,
2198 .cfgcr1 = DPLL3_CFGCR1,
2199 .cfgcr2 = DPLL3_CFGCR2,
2200 },
2201};
2202
2203static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2204 struct intel_shared_dpll *pll)
2205{
2206 uint32_t val;
2207 unsigned int dpll;
2208 const struct skl_dpll_regs *regs = skl_dpll_regs;
2209
2210 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2211 dpll = pll->id + 1;
2212
2213 val = I915_READ(DPLL_CTRL1);
2214
2215 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002216 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002217 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2218
2219 I915_WRITE(DPLL_CTRL1, val);
2220 POSTING_READ(DPLL_CTRL1);
2221
2222 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2223 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2224 POSTING_READ(regs[pll->id].cfgcr1);
2225 POSTING_READ(regs[pll->id].cfgcr2);
2226
2227 /* the enable bit is always bit 31 */
2228 I915_WRITE(regs[pll->id].ctl,
2229 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2230
2231 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2232 DRM_ERROR("DPLL %d not locked\n", dpll);
2233}
2234
2235static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2236 struct intel_shared_dpll *pll)
2237{
2238 const struct skl_dpll_regs *regs = skl_dpll_regs;
2239
2240 /* the enable bit is always bit 31 */
2241 I915_WRITE(regs[pll->id].ctl,
2242 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2243 POSTING_READ(regs[pll->id].ctl);
2244}
2245
2246static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2247 struct intel_shared_dpll *pll,
2248 struct intel_dpll_hw_state *hw_state)
2249{
2250 uint32_t val;
2251 unsigned int dpll;
2252 const struct skl_dpll_regs *regs = skl_dpll_regs;
2253
2254 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2255 return false;
2256
2257 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2258 dpll = pll->id + 1;
2259
2260 val = I915_READ(regs[pll->id].ctl);
2261 if (!(val & LCPLL_PLL_ENABLE))
2262 return false;
2263
2264 val = I915_READ(DPLL_CTRL1);
2265 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2266
2267 /* avoid reading back stale values if HDMI mode is not enabled */
2268 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2269 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2270 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2271 }
2272
2273 return true;
2274}
2275
2276static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2277{
2278 int i;
2279
2280 dev_priv->num_shared_dpll = 3;
2281
2282 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2283 dev_priv->shared_dplls[i].id = i;
2284 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2285 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2286 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2287 dev_priv->shared_dplls[i].get_hw_state =
2288 skl_ddi_pll_get_hw_state;
2289 }
2290}
2291
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302292static void broxton_phy_init(struct drm_i915_private *dev_priv,
2293 enum dpio_phy phy)
2294{
2295 enum port port;
2296 uint32_t val;
2297
2298 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2299 val |= GT_DISPLAY_POWER_ON(phy);
2300 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2301
2302 /* Considering 10ms timeout until BSpec is updated */
2303 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2304 DRM_ERROR("timeout during PHY%d power on\n", phy);
2305
2306 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2307 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2308 int lane;
2309
2310 for (lane = 0; lane < 4; lane++) {
2311 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2312 /*
2313 * Note that on CHV this flag is called UPAR, but has
2314 * the same function.
2315 */
2316 val &= ~LATENCY_OPTIM;
2317 if (lane != 1)
2318 val |= LATENCY_OPTIM;
2319
2320 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2321 }
2322 }
2323
2324 /* Program PLL Rcomp code offset */
2325 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2326 val &= ~IREF0RC_OFFSET_MASK;
2327 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2328 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2329
2330 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2331 val &= ~IREF1RC_OFFSET_MASK;
2332 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2333 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2334
2335 /* Program power gating */
2336 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2337 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2338 SUS_CLK_CONFIG;
2339 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2340
2341 if (phy == DPIO_PHY0) {
2342 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2343 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2344 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2345 }
2346
2347 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2348 val &= ~OCL2_LDOFUSE_PWR_DIS;
2349 /*
2350 * On PHY1 disable power on the second channel, since no port is
2351 * connected there. On PHY0 both channels have a port, so leave it
2352 * enabled.
2353 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2354 * power down the second channel on PHY0 as well.
2355 */
2356 if (phy == DPIO_PHY1)
2357 val |= OCL2_LDOFUSE_PWR_DIS;
2358 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2359
2360 if (phy == DPIO_PHY0) {
2361 uint32_t grc_code;
2362 /*
2363 * PHY0 isn't connected to an RCOMP resistor so copy over
2364 * the corresponding calibrated value from PHY1, and disable
2365 * the automatic calibration on PHY0.
2366 */
2367 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2368 10))
2369 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2370
2371 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2372 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2373 grc_code = val << GRC_CODE_FAST_SHIFT |
2374 val << GRC_CODE_SLOW_SHIFT |
2375 val;
2376 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2377
2378 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2379 val |= GRC_DIS | GRC_RDY_OVRD;
2380 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2381 }
2382
2383 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2384 val |= COMMON_RESET_DIS;
2385 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2386}
2387
2388void broxton_ddi_phy_init(struct drm_device *dev)
2389{
2390 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2391 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2392 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2393}
2394
2395static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2396 enum dpio_phy phy)
2397{
2398 uint32_t val;
2399
2400 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2401 val &= ~COMMON_RESET_DIS;
2402 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2403}
2404
2405void broxton_ddi_phy_uninit(struct drm_device *dev)
2406{
2407 struct drm_i915_private *dev_priv = dev->dev_private;
2408
2409 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2410 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2411
2412 /* FIXME: do this in broxton_phy_uninit per phy */
2413 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2414}
2415
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302416static const char * const bxt_ddi_pll_names[] = {
2417 "PORT PLL A",
2418 "PORT PLL B",
2419 "PORT PLL C",
2420};
2421
2422static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2423 struct intel_shared_dpll *pll)
2424{
2425 uint32_t temp;
2426 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2427
2428 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2429 temp &= ~PORT_PLL_REF_SEL;
2430 /* Non-SSC reference */
2431 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2432
2433 /* Disable 10 bit clock */
2434 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2435 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2436 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2437
2438 /* Write P1 & P2 */
2439 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2440 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2441 temp |= pll->config.hw_state.ebb0;
2442 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2443
2444 /* Write M2 integer */
2445 temp = I915_READ(BXT_PORT_PLL(port, 0));
2446 temp &= ~PORT_PLL_M2_MASK;
2447 temp |= pll->config.hw_state.pll0;
2448 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2449
2450 /* Write N */
2451 temp = I915_READ(BXT_PORT_PLL(port, 1));
2452 temp &= ~PORT_PLL_N_MASK;
2453 temp |= pll->config.hw_state.pll1;
2454 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2455
2456 /* Write M2 fraction */
2457 temp = I915_READ(BXT_PORT_PLL(port, 2));
2458 temp &= ~PORT_PLL_M2_FRAC_MASK;
2459 temp |= pll->config.hw_state.pll2;
2460 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2461
2462 /* Write M2 fraction enable */
2463 temp = I915_READ(BXT_PORT_PLL(port, 3));
2464 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2465 temp |= pll->config.hw_state.pll3;
2466 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2467
2468 /* Write coeff */
2469 temp = I915_READ(BXT_PORT_PLL(port, 6));
2470 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2471 temp &= ~PORT_PLL_INT_COEFF_MASK;
2472 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2473 temp |= pll->config.hw_state.pll6;
2474 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2475
2476 /* Write calibration val */
2477 temp = I915_READ(BXT_PORT_PLL(port, 8));
2478 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2479 temp |= pll->config.hw_state.pll8;
2480 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2481
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302482 temp = I915_READ(BXT_PORT_PLL(port, 9));
2483 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
2484 temp |= (5 << 1);
2485 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2486
2487 temp = I915_READ(BXT_PORT_PLL(port, 10));
2488 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2489 temp &= ~PORT_PLL_DCO_AMP_MASK;
2490 temp |= pll->config.hw_state.pll10;
2491 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302492
2493 /* Recalibrate with new settings */
2494 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2495 temp |= PORT_PLL_RECALIBRATE;
2496 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2497 /* Enable 10 bit clock */
2498 temp |= PORT_PLL_10BIT_CLK_ENABLE;
2499 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2500
2501 /* Enable PLL */
2502 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2503 temp |= PORT_PLL_ENABLE;
2504 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2505 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2506
2507 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2508 PORT_PLL_LOCK), 200))
2509 DRM_ERROR("PLL %d not locked\n", port);
2510
2511 /*
2512 * While we write to the group register to program all lanes at once we
2513 * can read only lane registers and we pick lanes 0/1 for that.
2514 */
2515 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2516 temp &= ~LANE_STAGGER_MASK;
2517 temp &= ~LANESTAGGER_STRAP_OVRD;
2518 temp |= pll->config.hw_state.pcsdw12;
2519 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2520}
2521
2522static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2523 struct intel_shared_dpll *pll)
2524{
2525 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2526 uint32_t temp;
2527
2528 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2529 temp &= ~PORT_PLL_ENABLE;
2530 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2531 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2532}
2533
2534static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2535 struct intel_shared_dpll *pll,
2536 struct intel_dpll_hw_state *hw_state)
2537{
2538 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2539 uint32_t val;
2540
2541 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2542 return false;
2543
2544 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2545 if (!(val & PORT_PLL_ENABLE))
2546 return false;
2547
2548 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
2549 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
2550 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
2551 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
2552 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
2553 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
2554 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302555 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302556 /*
2557 * While we write to the group register to program all lanes at once we
2558 * can read only lane registers. We configure all lanes the same way, so
2559 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2560 */
2561 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2562 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port) != hw_state->pcsdw12))
2563 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2564 hw_state->pcsdw12,
2565 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
2566
2567 return true;
2568}
2569
2570static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2571{
2572 int i;
2573
2574 dev_priv->num_shared_dpll = 3;
2575
2576 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2577 dev_priv->shared_dplls[i].id = i;
2578 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2579 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2580 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2581 dev_priv->shared_dplls[i].get_hw_state =
2582 bxt_ddi_pll_get_hw_state;
2583 }
2584}
2585
Damien Lespiau143b3072014-07-29 18:06:19 +01002586void intel_ddi_pll_init(struct drm_device *dev)
2587{
2588 struct drm_i915_private *dev_priv = dev->dev_private;
2589 uint32_t val = I915_READ(LCPLL_CTL);
2590
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002591 if (IS_SKYLAKE(dev))
2592 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302593 else if (IS_BROXTON(dev))
2594 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002595 else
2596 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002597
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002598 if (IS_SKYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002599 int cdclk_freq;
2600
2601 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002602 dev_priv->skl_boot_cdclk = cdclk_freq;
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002603 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2604 DRM_ERROR("LCPLL1 is disabled\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002605 else
2606 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302607 } else if (IS_BROXTON(dev)) {
2608 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302609 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002610 } else {
2611 /*
2612 * The LCPLL register should be turned on by the BIOS. For now
2613 * let's just check its state and print errors in case
2614 * something is wrong. Don't even try to turn it on.
2615 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002616
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002617 if (val & LCPLL_CD_SOURCE_FCLK)
2618 DRM_ERROR("CDCLK source is not LCPLL\n");
2619
2620 if (val & LCPLL_PLL_DISABLE)
2621 DRM_ERROR("LCPLL is disabled\n");
2622 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002623}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002624
2625void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
2626{
Paulo Zanoni174edf12012-10-26 19:05:50 -02002627 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
2628 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002629 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02002630 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002631 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302632 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002633
2634 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2635 val = I915_READ(DDI_BUF_CTL(port));
2636 if (val & DDI_BUF_CTL_ENABLE) {
2637 val &= ~DDI_BUF_CTL_ENABLE;
2638 I915_WRITE(DDI_BUF_CTL(port), val);
2639 wait = true;
2640 }
2641
2642 val = I915_READ(DP_TP_CTL(port));
2643 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2644 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2645 I915_WRITE(DP_TP_CTL(port), val);
2646 POSTING_READ(DP_TP_CTL(port));
2647
2648 if (wait)
2649 intel_wait_ddi_buf_idle(dev_priv, port);
2650 }
2651
Dave Airlie0e32b392014-05-02 14:02:48 +10002652 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03002653 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10002654 if (intel_dp->is_mst)
2655 val |= DP_TP_CTL_MODE_MST;
2656 else {
2657 val |= DP_TP_CTL_MODE_SST;
2658 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
2659 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
2660 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002661 I915_WRITE(DP_TP_CTL(port), val);
2662 POSTING_READ(DP_TP_CTL(port));
2663
2664 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
2665 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
2666 POSTING_READ(DDI_BUF_CTL(port));
2667
2668 udelay(600);
2669}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002670
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02002671void intel_ddi_fdi_disable(struct drm_crtc *crtc)
2672{
2673 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2674 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2675 uint32_t val;
2676
2677 intel_ddi_post_disable(intel_encoder);
2678
2679 val = I915_READ(_FDI_RXA_CTL);
2680 val &= ~FDI_RX_ENABLE;
2681 I915_WRITE(_FDI_RXA_CTL, val);
2682
2683 val = I915_READ(_FDI_RXA_MISC);
2684 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
2685 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
2686 I915_WRITE(_FDI_RXA_MISC, val);
2687
2688 val = I915_READ(_FDI_RXA_CTL);
2689 val &= ~FDI_PCDCLK;
2690 I915_WRITE(_FDI_RXA_CTL, val);
2691
2692 val = I915_READ(_FDI_RXA_CTL);
2693 val &= ~FDI_RX_PLL_ENABLE;
2694 I915_WRITE(_FDI_RXA_CTL, val);
2695}
2696
Ville Syrjälä6801c182013-09-24 14:24:05 +03002697void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02002698 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07002699{
2700 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
2701 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02002702 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01002703 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07002704 u32 temp, flags = 0;
2705
2706 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
2707 if (temp & TRANS_DDI_PHSYNC)
2708 flags |= DRM_MODE_FLAG_PHSYNC;
2709 else
2710 flags |= DRM_MODE_FLAG_NHSYNC;
2711 if (temp & TRANS_DDI_PVSYNC)
2712 flags |= DRM_MODE_FLAG_PVSYNC;
2713 else
2714 flags |= DRM_MODE_FLAG_NVSYNC;
2715
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02002716 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03002717
2718 switch (temp & TRANS_DDI_BPC_MASK) {
2719 case TRANS_DDI_BPC_6:
2720 pipe_config->pipe_bpp = 18;
2721 break;
2722 case TRANS_DDI_BPC_8:
2723 pipe_config->pipe_bpp = 24;
2724 break;
2725 case TRANS_DDI_BPC_10:
2726 pipe_config->pipe_bpp = 30;
2727 break;
2728 case TRANS_DDI_BPC_12:
2729 pipe_config->pipe_bpp = 36;
2730 break;
2731 default:
2732 break;
2733 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03002734
2735 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
2736 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b52014-04-24 23:54:47 +02002737 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01002738 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
2739
2740 if (intel_hdmi->infoframe_enabled(&encoder->base))
2741 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08002742 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03002743 case TRANS_DDI_MODE_SELECT_DVI:
2744 case TRANS_DDI_MODE_SELECT_FDI:
2745 break;
2746 case TRANS_DDI_MODE_SELECT_DP_SST:
2747 case TRANS_DDI_MODE_SELECT_DP_MST:
2748 pipe_config->has_dp_encoder = true;
2749 intel_dp_get_m_n(intel_crtc, pipe_config);
2750 break;
2751 default:
2752 break;
2753 }
Daniel Vetter10214422013-11-18 07:38:16 +01002754
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002755 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03002756 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02002757 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03002758 pipe_config->has_audio = true;
2759 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02002760
Daniel Vetter10214422013-11-18 07:38:16 +01002761 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
2762 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
2763 /*
2764 * This is a big fat ugly hack.
2765 *
2766 * Some machines in UEFI boot mode provide us a VBT that has 18
2767 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
2768 * unknown we fail to light up. Yet the same BIOS boots up with
2769 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
2770 * max, not what it tells us to use.
2771 *
2772 * Note: This will still be broken if the eDP panel is not lit
2773 * up by the BIOS, and thus we can't get the mode at module
2774 * load.
2775 */
2776 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
2777 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
2778 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
2779 }
Jesse Barnes11578552014-01-21 12:42:10 -08002780
Damien Lespiau22606a12014-12-12 14:26:57 +00002781 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07002782}
2783
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002784static void intel_ddi_destroy(struct drm_encoder *encoder)
2785{
2786 /* HDMI has nothing special to destroy, so we can go with this. */
2787 intel_dp_encoder_destroy(encoder);
2788}
2789
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01002790static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02002791 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002792{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01002793 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02002794 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002795
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01002796 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002797
Daniel Vettereccb1402013-05-22 00:50:22 +02002798 if (port == PORT_A)
2799 pipe_config->cpu_transcoder = TRANSCODER_EDP;
2800
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002801 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01002802 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002803 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01002804 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002805}
2806
2807static const struct drm_encoder_funcs intel_ddi_funcs = {
2808 .destroy = intel_ddi_destroy,
2809};
2810
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03002811static struct intel_connector *
2812intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
2813{
2814 struct intel_connector *connector;
2815 enum port port = intel_dig_port->port;
2816
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03002817 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03002818 if (!connector)
2819 return NULL;
2820
2821 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
2822 if (!intel_dp_init_connector(intel_dig_port, connector)) {
2823 kfree(connector);
2824 return NULL;
2825 }
2826
2827 return connector;
2828}
2829
2830static struct intel_connector *
2831intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
2832{
2833 struct intel_connector *connector;
2834 enum port port = intel_dig_port->port;
2835
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03002836 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03002837 if (!connector)
2838 return NULL;
2839
2840 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
2841 intel_hdmi_init_connector(intel_dig_port, connector);
2842
2843 return connector;
2844}
2845
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002846void intel_ddi_init(struct drm_device *dev, enum port port)
2847{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002848 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002849 struct intel_digital_port *intel_dig_port;
2850 struct intel_encoder *intel_encoder;
2851 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03002852 bool init_hdmi, init_dp;
2853
2854 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
2855 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
2856 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
2857 if (!init_dp && !init_hdmi) {
Chris Wilsonf68d6972014-08-04 07:15:09 +01002858 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03002859 port_name(port));
2860 init_hdmi = true;
2861 init_dp = true;
2862 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002863
Daniel Vetterb14c5672013-09-19 12:18:32 +02002864 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002865 if (!intel_dig_port)
2866 return;
2867
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002868 intel_encoder = &intel_dig_port->base;
2869 encoder = &intel_encoder->base;
2870
2871 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
2872 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002873
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01002874 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002875 intel_encoder->enable = intel_enable_ddi;
2876 intel_encoder->pre_enable = intel_ddi_pre_enable;
2877 intel_encoder->disable = intel_disable_ddi;
2878 intel_encoder->post_disable = intel_ddi_post_disable;
2879 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07002880 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002881
2882 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002883 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
2884 (DDI_BUF_PORT_REVERSAL |
2885 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002886
2887 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01002888 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02002889 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002890
Chris Wilsonf68d6972014-08-04 07:15:09 +01002891 if (init_dp) {
2892 if (!intel_ddi_init_dp_connector(intel_dig_port))
2893 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10002894
Chris Wilsonf68d6972014-08-04 07:15:09 +01002895 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Jani Nikula5fcece82015-05-27 15:03:42 +03002896 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01002897 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02002898
Paulo Zanoni311a2092013-09-12 17:12:18 -03002899 /* In theory we don't need the encoder->type check, but leave it just in
2900 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01002901 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
2902 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
2903 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02002904 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01002905
2906 return;
2907
2908err:
2909 drm_encoder_cleanup(encoder);
2910 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002911}