blob: e7f0379453e83052e0a7a45db8e75bdd23c11e75 [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 */
David Weinehallf8896f52015-06-25 11:11:03 +030034 u8 i_boost; /* SKL: I_boost; valid: 0x0, 0x1, 0x3, 0x7 */
Jani Nikula10122052014-08-27 16:27:30 +030035};
36
Eugeni Dodonov45244b82012-05-09 15:37:20 -030037/* HDMI/DVI modes ignore everything but the last 2 items. So we share
38 * them for both DP and FDI transports, allowing those ports to
39 * automatically adapt to HDMI connections as well
40 */
Jani Nikula10122052014-08-27 16:27:30 +030041static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030042 { 0x00FFFFFF, 0x0006000E, 0x0 },
43 { 0x00D75FFF, 0x0005000A, 0x0 },
44 { 0x00C30FFF, 0x00040006, 0x0 },
45 { 0x80AAAFFF, 0x000B0000, 0x0 },
46 { 0x00FFFFFF, 0x0005000A, 0x0 },
47 { 0x00D75FFF, 0x000C0004, 0x0 },
48 { 0x80C30FFF, 0x000B0000, 0x0 },
49 { 0x00FFFFFF, 0x00040006, 0x0 },
50 { 0x80D75FFF, 0x000B0000, 0x0 },
Eugeni Dodonov45244b82012-05-09 15:37:20 -030051};
52
Jani Nikula10122052014-08-27 16:27:30 +030053static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030054 { 0x00FFFFFF, 0x0007000E, 0x0 },
55 { 0x00D75FFF, 0x000F000A, 0x0 },
56 { 0x00C30FFF, 0x00060006, 0x0 },
57 { 0x00AAAFFF, 0x001E0000, 0x0 },
58 { 0x00FFFFFF, 0x000F000A, 0x0 },
59 { 0x00D75FFF, 0x00160004, 0x0 },
60 { 0x00C30FFF, 0x001E0000, 0x0 },
61 { 0x00FFFFFF, 0x00060006, 0x0 },
62 { 0x00D75FFF, 0x001E0000, 0x0 },
Paulo Zanoni6acab152013-09-12 17:06:24 -030063};
64
Jani Nikula10122052014-08-27 16:27:30 +030065static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
66 /* Idx NT mV d T mV d db */
David Weinehallf8896f52015-06-25 11:11:03 +030067 { 0x00FFFFFF, 0x0006000E, 0x0 },/* 0: 400 400 0 */
68 { 0x00E79FFF, 0x000E000C, 0x0 },/* 1: 400 500 2 */
69 { 0x00D75FFF, 0x0005000A, 0x0 },/* 2: 400 600 3.5 */
70 { 0x00FFFFFF, 0x0005000A, 0x0 },/* 3: 600 600 0 */
71 { 0x00E79FFF, 0x001D0007, 0x0 },/* 4: 600 750 2 */
72 { 0x00D75FFF, 0x000C0004, 0x0 },/* 5: 600 900 3.5 */
73 { 0x00FFFFFF, 0x00040006, 0x0 },/* 6: 800 800 0 */
74 { 0x80E79FFF, 0x00030002, 0x0 },/* 7: 800 1000 2 */
75 { 0x00FFFFFF, 0x00140005, 0x0 },/* 8: 850 850 0 */
76 { 0x00FFFFFF, 0x000C0004, 0x0 },/* 9: 900 900 0 */
77 { 0x00FFFFFF, 0x001C0003, 0x0 },/* 10: 950 950 0 */
78 { 0x80FFFFFF, 0x00030002, 0x0 },/* 11: 1000 1000 0 */
Eugeni Dodonov45244b82012-05-09 15:37:20 -030079};
80
Jani Nikula10122052014-08-27 16:27:30 +030081static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030082 { 0x00FFFFFF, 0x00000012, 0x0 },
83 { 0x00EBAFFF, 0x00020011, 0x0 },
84 { 0x00C71FFF, 0x0006000F, 0x0 },
85 { 0x00AAAFFF, 0x000E000A, 0x0 },
86 { 0x00FFFFFF, 0x00020011, 0x0 },
87 { 0x00DB6FFF, 0x0005000F, 0x0 },
88 { 0x00BEEFFF, 0x000A000C, 0x0 },
89 { 0x00FFFFFF, 0x0005000F, 0x0 },
90 { 0x00DB6FFF, 0x000A000C, 0x0 },
Paulo Zanoni300644c2013-11-02 21:07:42 -070091};
92
Jani Nikula10122052014-08-27 16:27:30 +030093static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030094 { 0x00FFFFFF, 0x0007000E, 0x0 },
95 { 0x00D75FFF, 0x000E000A, 0x0 },
96 { 0x00BEFFFF, 0x00140006, 0x0 },
97 { 0x80B2CFFF, 0x001B0002, 0x0 },
98 { 0x00FFFFFF, 0x000E000A, 0x0 },
99 { 0x00DB6FFF, 0x00160005, 0x0 },
100 { 0x80C71FFF, 0x001A0002, 0x0 },
101 { 0x00F7DFFF, 0x00180004, 0x0 },
102 { 0x80D75FFF, 0x001B0002, 0x0 },
Art Runyane58623c2013-11-02 21:07:41 -0700103};
104
Jani Nikula10122052014-08-27 16:27:30 +0300105static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300106 { 0x00FFFFFF, 0x0001000E, 0x0 },
107 { 0x00D75FFF, 0x0004000A, 0x0 },
108 { 0x00C30FFF, 0x00070006, 0x0 },
109 { 0x00AAAFFF, 0x000C0000, 0x0 },
110 { 0x00FFFFFF, 0x0004000A, 0x0 },
111 { 0x00D75FFF, 0x00090004, 0x0 },
112 { 0x00C30FFF, 0x000C0000, 0x0 },
113 { 0x00FFFFFF, 0x00070006, 0x0 },
114 { 0x00D75FFF, 0x000C0000, 0x0 },
Art Runyane58623c2013-11-02 21:07:41 -0700115};
116
Jani Nikula10122052014-08-27 16:27:30 +0300117static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
118 /* Idx NT mV d T mV df db */
David Weinehallf8896f52015-06-25 11:11:03 +0300119 { 0x00FFFFFF, 0x0007000E, 0x0 },/* 0: 400 400 0 */
120 { 0x00D75FFF, 0x000E000A, 0x0 },/* 1: 400 600 3.5 */
121 { 0x00BEFFFF, 0x00140006, 0x0 },/* 2: 400 800 6 */
122 { 0x00FFFFFF, 0x0009000D, 0x0 },/* 3: 450 450 0 */
123 { 0x00FFFFFF, 0x000E000A, 0x0 },/* 4: 600 600 0 */
124 { 0x00D7FFFF, 0x00140006, 0x0 },/* 5: 600 800 2.5 */
125 { 0x80CB2FFF, 0x001B0002, 0x0 },/* 6: 600 1000 4.5 */
126 { 0x00FFFFFF, 0x00140006, 0x0 },/* 7: 800 800 0 */
127 { 0x80E79FFF, 0x001B0002, 0x0 },/* 8: 800 1000 2 */
128 { 0x80FFFFFF, 0x001B0002, 0x0 },/* 9: 1000 1000 0 */
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100129};
130
David Weinehallf8896f52015-06-25 11:11:03 +0300131/* Skylake H, S, and Skylake Y with 0.95V VccIO */
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000132static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300133 { 0x00002016, 0x000000A0, 0x0 },
134 { 0x00005012, 0x0000009B, 0x0 },
135 { 0x00007011, 0x00000088, 0x0 },
136 { 0x00009010, 0x000000C7, 0x0 },
137 { 0x00002016, 0x0000009B, 0x0 },
138 { 0x00005012, 0x00000088, 0x0 },
139 { 0x00007011, 0x000000C7, 0x0 },
140 { 0x00002016, 0x000000DF, 0x0 },
141 { 0x00005012, 0x000000C7, 0x0 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000142};
143
David Weinehallf8896f52015-06-25 11:11:03 +0300144/* Skylake U */
145static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
146 { 0x00002016, 0x000000A2, 0x0 },
147 { 0x00005012, 0x00000088, 0x0 },
148 { 0x00007011, 0x00000087, 0x0 },
149 { 0x80009010, 0x000000C7, 0x1 }, /* Uses I_boost */
150 { 0x00002016, 0x0000009D, 0x0 },
151 { 0x00005012, 0x000000C7, 0x0 },
152 { 0x00007011, 0x000000C7, 0x0 },
153 { 0x00002016, 0x00000088, 0x0 },
154 { 0x00005012, 0x000000C7, 0x0 },
155};
156
157/* Skylake Y with 0.85V VccIO */
158static const struct ddi_buf_trans skl_y_085v_ddi_translations_dp[] = {
159 { 0x00000018, 0x000000A2, 0x0 },
160 { 0x00005012, 0x00000088, 0x0 },
161 { 0x00007011, 0x00000087, 0x0 },
162 { 0x80009010, 0x000000C7, 0x1 }, /* Uses I_boost */
163 { 0x00000018, 0x0000009D, 0x0 },
164 { 0x00005012, 0x000000C7, 0x0 },
165 { 0x00007011, 0x000000C7, 0x0 },
166 { 0x00000018, 0x00000088, 0x0 },
167 { 0x00005012, 0x000000C7, 0x0 },
168};
169
170/*
171 * Skylake H and S, and Skylake Y with 0.95V VccIO
172 * eDP 1.4 low vswing translation parameters
173 */
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530174static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300175 { 0x00000018, 0x000000A8, 0x0 },
176 { 0x00004013, 0x000000A9, 0x0 },
177 { 0x00007011, 0x000000A2, 0x0 },
178 { 0x00009010, 0x0000009C, 0x0 },
179 { 0x00000018, 0x000000A9, 0x0 },
180 { 0x00006013, 0x000000A2, 0x0 },
181 { 0x00007011, 0x000000A6, 0x0 },
182 { 0x00000018, 0x000000AB, 0x0 },
183 { 0x00007013, 0x0000009F, 0x0 },
184 { 0x00000018, 0x000000DF, 0x0 },
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530185};
186
David Weinehallf8896f52015-06-25 11:11:03 +0300187/*
188 * Skylake U
189 * eDP 1.4 low vswing translation parameters
190 */
191static const struct ddi_buf_trans skl_u_ddi_translations_edp[] = {
192 { 0x00000018, 0x000000A8, 0x0 },
193 { 0x00004013, 0x000000A9, 0x0 },
194 { 0x00007011, 0x000000A2, 0x0 },
195 { 0x00009010, 0x0000009C, 0x0 },
196 { 0x00000018, 0x000000A9, 0x0 },
197 { 0x00006013, 0x000000A2, 0x0 },
198 { 0x00007011, 0x000000A6, 0x0 },
199 { 0x00002016, 0x000000AB, 0x0 },
200 { 0x00005013, 0x0000009F, 0x0 },
201 { 0x00000018, 0x000000DF, 0x0 },
202};
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530203
David Weinehallf8896f52015-06-25 11:11:03 +0300204/*
205 * Skylake Y with 0.95V VccIO
206 * eDP 1.4 low vswing translation parameters
207 */
208static const struct ddi_buf_trans skl_y_085v_ddi_translations_edp[] = {
209 { 0x00000018, 0x000000A8, 0x0 },
210 { 0x00004013, 0x000000AB, 0x0 },
211 { 0x00007011, 0x000000A4, 0x0 },
212 { 0x00009010, 0x000000DF, 0x0 },
213 { 0x00000018, 0x000000AA, 0x0 },
214 { 0x00006013, 0x000000A4, 0x0 },
215 { 0x00007011, 0x0000009D, 0x0 },
216 { 0x00000018, 0x000000A0, 0x0 },
217 { 0x00006012, 0x000000DF, 0x0 },
218 { 0x00000018, 0x0000008A, 0x0 },
219};
220
221/* Skylake H, S and U, and Skylake Y with 0.95V VccIO */
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000222static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300223 { 0x00000018, 0x000000AC, 0x0 },
224 { 0x00005012, 0x0000009D, 0x0 },
225 { 0x00007011, 0x00000088, 0x0 },
226 { 0x00000018, 0x000000A1, 0x0 },
227 { 0x00000018, 0x00000098, 0x0 },
228 { 0x00004013, 0x00000088, 0x0 },
229 { 0x00006012, 0x00000087, 0x0 },
230 { 0x00000018, 0x000000DF, 0x0 },
231 { 0x00003015, 0x00000087, 0x0 }, /* Default */
232 { 0x00003015, 0x000000C7, 0x0 },
233 { 0x00000018, 0x000000C7, 0x0 },
234};
235
236/* Skylake Y with 0.85V VccIO */
237static const struct ddi_buf_trans skl_y_085v_ddi_translations_hdmi[] = {
238 { 0x00000018, 0x000000A1, 0x0 },
239 { 0x00005012, 0x000000DF, 0x0 },
240 { 0x00007011, 0x00000084, 0x0 },
241 { 0x00000018, 0x000000A4, 0x0 },
242 { 0x00000018, 0x0000009D, 0x0 },
243 { 0x00004013, 0x00000080, 0x0 },
244 { 0x00006013, 0x000000C7, 0x0 },
245 { 0x00000018, 0x0000008A, 0x0 },
246 { 0x00003015, 0x000000C7, 0x0 }, /* Default */
247 { 0x80003015, 0x000000C7, 0x7 }, /* Uses I_boost */
248 { 0x00000018, 0x000000C7, 0x0 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000249};
250
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530251struct bxt_ddi_buf_trans {
252 u32 margin; /* swing value */
253 u32 scale; /* scale value */
254 u32 enable; /* scale enable */
255 u32 deemphasis;
256 bool default_index; /* true if the entry represents default value */
257};
258
259/* BSpec does not define separate vswing/pre-emphasis values for eDP.
260 * Using DP values for eDP as well.
261 */
262static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
263 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300264 { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */
265 { 78, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
266 { 104, 0x9A, 0, 64, false }, /* 2: 400 6 */
267 { 154, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
268 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
269 { 116, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
270 { 154, 0x9A, 0, 64, false }, /* 6: 600 6 */
271 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
272 { 154, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
David Weinehallf8896f52015-06-25 11:11:03 +0300273 { 154, 0x9A, 1, 128, false }, /* 9: 1200 0 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530274};
275
276/* BSpec has 2 recommended values - entries 0 and 8.
277 * Using the entry with higher vswing.
278 */
279static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
280 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300281 { 52, 0x9A, 0, 128, false }, /* 0: 400 0 */
282 { 52, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
283 { 52, 0x9A, 0, 64, false }, /* 2: 400 6 */
284 { 42, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
285 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
286 { 77, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
287 { 77, 0x9A, 0, 64, false }, /* 6: 600 6 */
288 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
289 { 102, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530290 { 154, 0x9A, 1, 128, true }, /* 9: 1200 0 */
291};
292
David Weinehallf8896f52015-06-25 11:11:03 +0300293static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
294 enum port port, int type);
295
Imre Deaka1e6ad62015-04-17 19:31:21 +0300296static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
297 struct intel_digital_port **dig_port,
298 enum port *port)
Paulo Zanonifc914632012-10-05 12:05:54 -0300299{
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300300 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonifc914632012-10-05 12:05:54 -0300301 int type = intel_encoder->type;
302
Dave Airlie0e32b392014-05-02 14:02:48 +1000303 if (type == INTEL_OUTPUT_DP_MST) {
Imre Deaka1e6ad62015-04-17 19:31:21 +0300304 *dig_port = enc_to_mst(encoder)->primary;
305 *port = (*dig_port)->port;
Dave Airlie0e32b392014-05-02 14:02:48 +1000306 } else if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP ||
Paulo Zanoni00c09d72012-10-26 19:05:52 -0200307 type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_UNKNOWN) {
Imre Deaka1e6ad62015-04-17 19:31:21 +0300308 *dig_port = enc_to_dig_port(encoder);
309 *port = (*dig_port)->port;
Paulo Zanonifc914632012-10-05 12:05:54 -0300310 } else if (type == INTEL_OUTPUT_ANALOG) {
Imre Deaka1e6ad62015-04-17 19:31:21 +0300311 *dig_port = NULL;
312 *port = PORT_E;
Paulo Zanonifc914632012-10-05 12:05:54 -0300313 } else {
314 DRM_ERROR("Invalid DDI encoder type %d\n", type);
315 BUG();
316 }
317}
318
Imre Deaka1e6ad62015-04-17 19:31:21 +0300319enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
320{
321 struct intel_digital_port *dig_port;
322 enum port port;
323
324 ddi_get_encoder_port(intel_encoder, &dig_port, &port);
325
326 return port;
327}
328
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100329static bool
330intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
331{
332 return intel_dig_port->hdmi.hdmi_reg;
333}
334
David Weinehallf8896f52015-06-25 11:11:03 +0300335static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,
336 int *n_entries)
337{
338 struct drm_i915_private *dev_priv = dev->dev_private;
339 const struct ddi_buf_trans *ddi_translations;
340 static int is_095v = -1;
341
342 if (is_095v == -1) {
343 u32 spr1 = I915_READ(UAIMI_SPR1);
344
345 is_095v = spr1 & SKL_VCCIO_MASK;
346 }
347
348 if (IS_SKL_ULX(dev) && !is_095v) {
349 ddi_translations = skl_y_085v_ddi_translations_dp;
350 *n_entries = ARRAY_SIZE(skl_y_085v_ddi_translations_dp);
351 } else if (IS_SKL_ULT(dev)) {
352 ddi_translations = skl_u_ddi_translations_dp;
353 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
354 } else {
355 ddi_translations = skl_ddi_translations_dp;
356 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
357 }
358
359 return ddi_translations;
360}
361
362static const struct ddi_buf_trans *skl_get_buf_trans_edp(struct drm_device *dev,
363 int *n_entries)
364{
365 struct drm_i915_private *dev_priv = dev->dev_private;
366 const struct ddi_buf_trans *ddi_translations;
367 static int is_095v = -1;
368
369 if (is_095v == -1) {
370 u32 spr1 = I915_READ(UAIMI_SPR1);
371
372 is_095v = spr1 & SKL_VCCIO_MASK;
373 }
374
375 if (IS_SKL_ULX(dev) && !is_095v) {
376 if (dev_priv->edp_low_vswing) {
377 ddi_translations = skl_y_085v_ddi_translations_edp;
378 *n_entries =
379 ARRAY_SIZE(skl_y_085v_ddi_translations_edp);
380 } else {
381 ddi_translations = skl_y_085v_ddi_translations_dp;
382 *n_entries =
383 ARRAY_SIZE(skl_y_085v_ddi_translations_dp);
384 }
385 } else if (IS_SKL_ULT(dev)) {
386 if (dev_priv->edp_low_vswing) {
387 ddi_translations = skl_u_ddi_translations_edp;
388 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
389 } else {
390 ddi_translations = skl_u_ddi_translations_dp;
391 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
392 }
393 } else {
394 if (dev_priv->edp_low_vswing) {
395 ddi_translations = skl_ddi_translations_edp;
396 *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
397 } else {
398 ddi_translations = skl_ddi_translations_dp;
399 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
400 }
401 }
402
403 return ddi_translations;
404}
405
406static const struct ddi_buf_trans *
407skl_get_buf_trans_hdmi(struct drm_device *dev,
408 int *n_entries)
409{
410 struct drm_i915_private *dev_priv = dev->dev_private;
411 const struct ddi_buf_trans *ddi_translations;
412 static int is_095v = -1;
413
414 if (is_095v == -1) {
415 u32 spr1 = I915_READ(UAIMI_SPR1);
416
417 is_095v = spr1 & SKL_VCCIO_MASK;
418 }
419
420 if (IS_SKL_ULX(dev) && !is_095v) {
421 ddi_translations = skl_y_085v_ddi_translations_hdmi;
422 *n_entries = ARRAY_SIZE(skl_y_085v_ddi_translations_hdmi);
423 } else {
424 ddi_translations = skl_ddi_translations_hdmi;
425 *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
426 }
427
428 return ddi_translations;
429}
430
Art Runyane58623c2013-11-02 21:07:41 -0700431/*
432 * Starting with Haswell, DDI port buffers must be programmed with correct
433 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300434 * but the HDMI/DVI fields are shared among those. So we program the DDI
435 * in either FDI or DP modes only, as HDMI connections will work with both
436 * of those
437 */
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300438static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
439 bool supports_hdmi)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300440{
441 struct drm_i915_private *dev_priv = dev->dev_private;
442 u32 reg;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000443 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530444 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300445 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300446 const struct ddi_buf_trans *ddi_translations_fdi;
447 const struct ddi_buf_trans *ddi_translations_dp;
448 const struct ddi_buf_trans *ddi_translations_edp;
449 const struct ddi_buf_trans *ddi_translations_hdmi;
450 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700451
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530452 if (IS_BROXTON(dev)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300453 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530454 return;
455
456 /* Vswing programming for HDMI */
457 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
458 INTEL_OUTPUT_HDMI);
459 return;
460 } else if (IS_SKYLAKE(dev)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300461 ddi_translations_dp =
462 skl_get_buf_trans_dp(dev, &n_dp_entries);
463 ddi_translations_edp =
464 skl_get_buf_trans_edp(dev, &n_edp_entries);
465 ddi_translations_hdmi =
466 skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
467 hdmi_default_entry = 8;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000468 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700469 ddi_translations_fdi = bdw_ddi_translations_fdi;
470 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700471 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100472 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530473 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
474 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300475 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000476 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700477 } else if (IS_HASWELL(dev)) {
478 ddi_translations_fdi = hsw_ddi_translations_fdi;
479 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700480 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100481 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530482 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300483 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000484 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700485 } else {
486 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700487 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700488 ddi_translations_fdi = bdw_ddi_translations_fdi;
489 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100490 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530491 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
492 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300493 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000494 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700495 }
496
Paulo Zanoni300644c2013-11-02 21:07:42 -0700497 switch (port) {
498 case PORT_A:
499 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530500 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700501 break;
502 case PORT_B:
503 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700504 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530505 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700506 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700507 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530508 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700509 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530510 size = n_edp_entries;
511 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700512 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530513 size = n_dp_entries;
514 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700515 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700516 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000517 if (ddi_translations_fdi)
518 ddi_translations = ddi_translations_fdi;
519 else
520 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530521 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700522 break;
523 default:
524 BUG();
525 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300526
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530527 for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) {
Jani Nikula10122052014-08-27 16:27:30 +0300528 I915_WRITE(reg, ddi_translations[i].trans1);
529 reg += 4;
530 I915_WRITE(reg, ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300531 reg += 4;
532 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100533
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300534 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100535 return;
536
Damien Lespiauce4dd492014-08-01 11:07:54 +0100537 /* Choose a good default if VBT is badly populated */
538 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
539 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000540 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100541
Paulo Zanoni6acab152013-09-12 17:06:24 -0300542 /* Entry 9 is for HDMI: */
Jani Nikula10122052014-08-27 16:27:30 +0300543 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1);
544 reg += 4;
545 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2);
546 reg += 4;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300547}
548
549/* Program DDI buffers translations for DP. By default, program ports A-D in DP
550 * mode and port E for FDI.
551 */
552void intel_prepare_ddi(struct drm_device *dev)
553{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300554 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100555 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300556
Paulo Zanoni0d536cb2012-11-23 16:46:41 -0200557 if (!HAS_DDI(dev))
558 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300559
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300560 for_each_intel_encoder(dev, intel_encoder) {
561 struct intel_digital_port *intel_dig_port;
562 enum port port;
563 bool supports_hdmi;
564
565 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
566
567 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100568 continue;
569
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300570 supports_hdmi = intel_dig_port &&
571 intel_dig_port_supports_hdmi(intel_dig_port);
572
573 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
574 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100575 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300576}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300577
Paulo Zanoni248138b2012-11-29 11:29:31 -0200578static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
579 enum port port)
580{
581 uint32_t reg = DDI_BUF_CTL(port);
582 int i;
583
Vandana Kannan3449ca82015-03-27 14:19:09 +0200584 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200585 udelay(1);
586 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
587 return;
588 }
589 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
590}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300591
592/* Starting with Haswell, different DDI ports can work in FDI mode for
593 * connection to the PCH-located connectors. For this, it is necessary to train
594 * both the DDI port and PCH receiver for the desired DDI buffer settings.
595 *
596 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
597 * please note that when FDI mode is active on DDI E, it shares 2 lines with
598 * DDI A (which is used for eDP)
599 */
600
601void hsw_fdi_link_train(struct drm_crtc *crtc)
602{
603 struct drm_device *dev = crtc->dev;
604 struct drm_i915_private *dev_priv = dev->dev_private;
605 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200606 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300607
Paulo Zanoni04945642012-11-01 21:00:59 -0200608 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
609 * mode set "sequence for CRT port" document:
610 * - TP1 to TP2 time with the default value
611 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100612 *
613 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200614 */
615 I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
616 FDI_RX_PWRDN_LANE0_VAL(2) |
617 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
618
619 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000620 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100621 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200622 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Paulo Zanoni04945642012-11-01 21:00:59 -0200623 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
624 POSTING_READ(_FDI_RXA_CTL);
625 udelay(220);
626
627 /* Switch from Rawclk to PCDclk */
628 rx_ctl_val |= FDI_PCDCLK;
629 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
630
631 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200632 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
633 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200634
635 /* Start the training iterating through available voltages and emphasis,
636 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300637 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300638 /* Configure DP_TP_CTL with auto-training */
639 I915_WRITE(DP_TP_CTL(PORT_E),
640 DP_TP_CTL_FDI_AUTOTRAIN |
641 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
642 DP_TP_CTL_LINK_TRAIN_PAT1 |
643 DP_TP_CTL_ENABLE);
644
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000645 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
646 * DDI E does not support port reversal, the functionality is
647 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
648 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300649 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200650 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200651 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530652 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200653 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300654
655 udelay(600);
656
Paulo Zanoni04945642012-11-01 21:00:59 -0200657 /* Program PCH FDI Receiver TU */
658 I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300659
Paulo Zanoni04945642012-11-01 21:00:59 -0200660 /* Enable PCH FDI Receiver with auto-training */
661 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
662 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
663 POSTING_READ(_FDI_RXA_CTL);
664
665 /* Wait for FDI receiver lane calibration */
666 udelay(30);
667
668 /* Unset FDI_RX_MISC pwrdn lanes */
669 temp = I915_READ(_FDI_RXA_MISC);
670 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
671 I915_WRITE(_FDI_RXA_MISC, temp);
672 POSTING_READ(_FDI_RXA_MISC);
673
674 /* Wait for FDI auto training time */
675 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300676
677 temp = I915_READ(DP_TP_STATUS(PORT_E));
678 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200679 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300680
681 /* Enable normal pixel sending for FDI */
682 I915_WRITE(DP_TP_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200683 DP_TP_CTL_FDI_AUTOTRAIN |
684 DP_TP_CTL_LINK_TRAIN_NORMAL |
685 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
686 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300687
Paulo Zanoni04945642012-11-01 21:00:59 -0200688 return;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300689 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200690
Paulo Zanoni248138b2012-11-29 11:29:31 -0200691 temp = I915_READ(DDI_BUF_CTL(PORT_E));
692 temp &= ~DDI_BUF_CTL_ENABLE;
693 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
694 POSTING_READ(DDI_BUF_CTL(PORT_E));
695
Paulo Zanoni04945642012-11-01 21:00:59 -0200696 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200697 temp = I915_READ(DP_TP_CTL(PORT_E));
698 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
699 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
700 I915_WRITE(DP_TP_CTL(PORT_E), temp);
701 POSTING_READ(DP_TP_CTL(PORT_E));
702
703 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200704
705 rx_ctl_val &= ~FDI_RX_ENABLE;
706 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200707 POSTING_READ(_FDI_RXA_CTL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200708
709 /* Reset FDI_RX_MISC pwrdn lanes */
710 temp = I915_READ(_FDI_RXA_MISC);
711 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
712 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
713 I915_WRITE(_FDI_RXA_MISC, temp);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200714 POSTING_READ(_FDI_RXA_MISC);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300715 }
716
Paulo Zanoni04945642012-11-01 21:00:59 -0200717 DRM_ERROR("FDI link training failed!\n");
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300718}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300719
Dave Airlie44905a272014-05-02 13:36:43 +1000720void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
721{
722 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
723 struct intel_digital_port *intel_dig_port =
724 enc_to_dig_port(&encoder->base);
725
726 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530727 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Dave Airlie44905a272014-05-02 13:36:43 +1000728 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
729
730}
731
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300732static struct intel_encoder *
733intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
734{
735 struct drm_device *dev = crtc->dev;
736 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
737 struct intel_encoder *intel_encoder, *ret = NULL;
738 int num_encoders = 0;
739
740 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
741 ret = intel_encoder;
742 num_encoders++;
743 }
744
745 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300746 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
747 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300748
749 BUG_ON(ret == NULL);
750 return ret;
751}
752
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530753struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200754intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200755{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200756 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
757 struct intel_encoder *ret = NULL;
758 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300759 struct drm_connector *connector;
760 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200761 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200762 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200763
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200764 state = crtc_state->base.state;
765
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300766 for_each_connector_in_state(state, connector, connector_state, i) {
767 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200768 continue;
769
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300770 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200771 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200772 }
773
774 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
775 pipe_name(crtc->pipe));
776
777 BUG_ON(ret == NULL);
778 return ret;
779}
780
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100781#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100782#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100783
784#define P_MIN 2
785#define P_MAX 64
786#define P_INC 2
787
788/* Constraints for PLL good behavior */
789#define REF_MIN 48
790#define REF_MAX 400
791#define VCO_MIN 2400
792#define VCO_MAX 4800
793
Damien Lespiau27893392014-09-04 12:27:23 +0100794#define abs_diff(a, b) ({ \
795 typeof(a) __a = (a); \
796 typeof(b) __b = (b); \
797 (void) (&__a == &__b); \
798 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100799
Damien Lespiau63582982015-05-07 18:38:46 +0100800struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100801 unsigned p, n2, r2;
802};
803
Damien Lespiau63582982015-05-07 18:38:46 +0100804static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300805{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100806 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300807
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100808 switch (clock) {
809 case 25175000:
810 case 25200000:
811 case 27000000:
812 case 27027000:
813 case 37762500:
814 case 37800000:
815 case 40500000:
816 case 40541000:
817 case 54000000:
818 case 54054000:
819 case 59341000:
820 case 59400000:
821 case 72000000:
822 case 74176000:
823 case 74250000:
824 case 81000000:
825 case 81081000:
826 case 89012000:
827 case 89100000:
828 case 108000000:
829 case 108108000:
830 case 111264000:
831 case 111375000:
832 case 148352000:
833 case 148500000:
834 case 162000000:
835 case 162162000:
836 case 222525000:
837 case 222750000:
838 case 296703000:
839 case 297000000:
840 budget = 0;
841 break;
842 case 233500000:
843 case 245250000:
844 case 247750000:
845 case 253250000:
846 case 298000000:
847 budget = 1500;
848 break;
849 case 169128000:
850 case 169500000:
851 case 179500000:
852 case 202000000:
853 budget = 2000;
854 break;
855 case 256250000:
856 case 262500000:
857 case 270000000:
858 case 272500000:
859 case 273750000:
860 case 280750000:
861 case 281250000:
862 case 286000000:
863 case 291750000:
864 budget = 4000;
865 break;
866 case 267250000:
867 case 268500000:
868 budget = 5000;
869 break;
870 default:
871 budget = 1000;
872 break;
873 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300874
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100875 return budget;
876}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300877
Damien Lespiau63582982015-05-07 18:38:46 +0100878static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
879 unsigned r2, unsigned n2, unsigned p,
880 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100881{
882 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300883
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100884 /* No best (r,n,p) yet */
885 if (best->p == 0) {
886 best->p = p;
887 best->n2 = n2;
888 best->r2 = r2;
889 return;
890 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300891
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100892 /*
893 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
894 * freq2k.
895 *
896 * delta = 1e6 *
897 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
898 * freq2k;
899 *
900 * and we would like delta <= budget.
901 *
902 * If the discrepancy is above the PPM-based budget, always prefer to
903 * improve upon the previous solution. However, if you're within the
904 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
905 */
906 a = freq2k * budget * p * r2;
907 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100908 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
909 diff_best = abs_diff(freq2k * best->p * best->r2,
910 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100911 c = 1000000 * diff;
912 d = 1000000 * diff_best;
913
914 if (a < c && b < d) {
915 /* If both are above the budget, pick the closer */
916 if (best->p * best->r2 * diff < p * r2 * diff_best) {
917 best->p = p;
918 best->n2 = n2;
919 best->r2 = r2;
920 }
921 } else if (a >= c && b < d) {
922 /* If A is below the threshold but B is above it? Update. */
923 best->p = p;
924 best->n2 = n2;
925 best->r2 = r2;
926 } else if (a >= c && b >= d) {
927 /* Both are below the limit, so pick the higher n2/(r2*r2) */
928 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
929 best->p = p;
930 best->n2 = n2;
931 best->r2 = r2;
932 }
933 }
934 /* Otherwise a < c && b >= d, do nothing */
935}
936
Damien Lespiau63582982015-05-07 18:38:46 +0100937static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, int reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800938{
939 int refclk = LC_FREQ;
940 int n, p, r;
941 u32 wrpll;
942
943 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300944 switch (wrpll & WRPLL_PLL_REF_MASK) {
945 case WRPLL_PLL_SSC:
946 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800947 /*
948 * We could calculate spread here, but our checking
949 * code only cares about 5% accuracy, and spread is a max of
950 * 0.5% downspread.
951 */
952 refclk = 135;
953 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300954 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800955 refclk = LC_FREQ;
956 break;
957 default:
958 WARN(1, "bad wrpll refclk\n");
959 return 0;
960 }
961
962 r = wrpll & WRPLL_DIVIDER_REF_MASK;
963 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
964 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
965
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800966 /* Convert to KHz, p & r have a fixed point portion */
967 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800968}
969
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000970static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
971 uint32_t dpll)
972{
973 uint32_t cfgcr1_reg, cfgcr2_reg;
974 uint32_t cfgcr1_val, cfgcr2_val;
975 uint32_t p0, p1, p2, dco_freq;
976
977 cfgcr1_reg = GET_CFG_CR1_REG(dpll);
978 cfgcr2_reg = GET_CFG_CR2_REG(dpll);
979
980 cfgcr1_val = I915_READ(cfgcr1_reg);
981 cfgcr2_val = I915_READ(cfgcr2_reg);
982
983 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
984 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
985
986 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
987 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
988 else
989 p1 = 1;
990
991
992 switch (p0) {
993 case DPLL_CFGCR2_PDIV_1:
994 p0 = 1;
995 break;
996 case DPLL_CFGCR2_PDIV_2:
997 p0 = 2;
998 break;
999 case DPLL_CFGCR2_PDIV_3:
1000 p0 = 3;
1001 break;
1002 case DPLL_CFGCR2_PDIV_7:
1003 p0 = 7;
1004 break;
1005 }
1006
1007 switch (p2) {
1008 case DPLL_CFGCR2_KDIV_5:
1009 p2 = 5;
1010 break;
1011 case DPLL_CFGCR2_KDIV_2:
1012 p2 = 2;
1013 break;
1014 case DPLL_CFGCR2_KDIV_3:
1015 p2 = 3;
1016 break;
1017 case DPLL_CFGCR2_KDIV_1:
1018 p2 = 1;
1019 break;
1020 }
1021
1022 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1023
1024 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1025 1000) / 0x8000;
1026
1027 return dco_freq / (p0 * p1 * p2 * 5);
1028}
1029
Ville Syrjälä398a0172015-06-30 15:33:51 +03001030static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1031{
1032 int dotclock;
1033
1034 if (pipe_config->has_pch_encoder)
1035 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1036 &pipe_config->fdi_m_n);
1037 else if (pipe_config->has_dp_encoder)
1038 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1039 &pipe_config->dp_m_n);
1040 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1041 dotclock = pipe_config->port_clock * 2 / 3;
1042 else
1043 dotclock = pipe_config->port_clock;
1044
1045 if (pipe_config->pixel_multiplier)
1046 dotclock /= pipe_config->pixel_multiplier;
1047
1048 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1049}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001050
1051static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001052 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001053{
1054 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001055 int link_clock = 0;
1056 uint32_t dpll_ctl1, dpll;
1057
Damien Lespiau134ffa42014-11-14 17:24:34 +00001058 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001059
1060 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1061
1062 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1063 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1064 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001065 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1066 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001067
1068 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001069 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001070 link_clock = 81000;
1071 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001072 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301073 link_clock = 108000;
1074 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001075 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001076 link_clock = 135000;
1077 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001078 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301079 link_clock = 162000;
1080 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001081 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301082 link_clock = 216000;
1083 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001084 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001085 link_clock = 270000;
1086 break;
1087 default:
1088 WARN(1, "Unsupported link rate\n");
1089 break;
1090 }
1091 link_clock *= 2;
1092 }
1093
1094 pipe_config->port_clock = link_clock;
1095
Ville Syrjälä398a0172015-06-30 15:33:51 +03001096 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001097}
1098
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001099static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001100 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001101{
1102 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001103 int link_clock = 0;
1104 u32 val, pll;
1105
Daniel Vetter26804af2014-06-25 22:01:55 +03001106 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001107 switch (val & PORT_CLK_SEL_MASK) {
1108 case PORT_CLK_SEL_LCPLL_810:
1109 link_clock = 81000;
1110 break;
1111 case PORT_CLK_SEL_LCPLL_1350:
1112 link_clock = 135000;
1113 break;
1114 case PORT_CLK_SEL_LCPLL_2700:
1115 link_clock = 270000;
1116 break;
1117 case PORT_CLK_SEL_WRPLL1:
Damien Lespiau63582982015-05-07 18:38:46 +01001118 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL1);
Jesse Barnes11578552014-01-21 12:42:10 -08001119 break;
1120 case PORT_CLK_SEL_WRPLL2:
Damien Lespiau63582982015-05-07 18:38:46 +01001121 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL2);
Jesse Barnes11578552014-01-21 12:42:10 -08001122 break;
1123 case PORT_CLK_SEL_SPLL:
1124 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1125 if (pll == SPLL_PLL_FREQ_810MHz)
1126 link_clock = 81000;
1127 else if (pll == SPLL_PLL_FREQ_1350MHz)
1128 link_clock = 135000;
1129 else if (pll == SPLL_PLL_FREQ_2700MHz)
1130 link_clock = 270000;
1131 else {
1132 WARN(1, "bad spll freq\n");
1133 return;
1134 }
1135 break;
1136 default:
1137 WARN(1, "bad port clock sel\n");
1138 return;
1139 }
1140
1141 pipe_config->port_clock = link_clock * 2;
1142
Ville Syrjälä398a0172015-06-30 15:33:51 +03001143 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001144}
1145
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301146static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1147 enum intel_dpll_id dpll)
1148{
Imre Deakaa610dc2015-06-22 23:35:52 +03001149 struct intel_shared_dpll *pll;
1150 struct intel_dpll_hw_state *state;
1151 intel_clock_t clock;
1152
1153 /* For DDI ports we always use a shared PLL. */
1154 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1155 return 0;
1156
1157 pll = &dev_priv->shared_dplls[dpll];
1158 state = &pll->config.hw_state;
1159
1160 clock.m1 = 2;
1161 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1162 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1163 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1164 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1165 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1166 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1167
1168 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301169}
1170
1171static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1172 struct intel_crtc_state *pipe_config)
1173{
1174 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1175 enum port port = intel_ddi_get_encoder_port(encoder);
1176 uint32_t dpll = port;
1177
Ville Syrjälä398a0172015-06-30 15:33:51 +03001178 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301179
Ville Syrjälä398a0172015-06-30 15:33:51 +03001180 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301181}
1182
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001183void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001184 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001185{
Damien Lespiau22606a12014-12-12 14:26:57 +00001186 struct drm_device *dev = encoder->base.dev;
1187
1188 if (INTEL_INFO(dev)->gen <= 8)
1189 hsw_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301190 else if (IS_SKYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001191 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301192 else if (IS_BROXTON(dev))
1193 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001194}
1195
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001196static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001197hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1198 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001199{
1200 uint64_t freq2k;
1201 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001202 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001203 unsigned budget;
1204
1205 freq2k = clock / 100;
1206
Damien Lespiau63582982015-05-07 18:38:46 +01001207 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001208
1209 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1210 * and directly pass the LC PLL to it. */
1211 if (freq2k == 5400000) {
1212 *n2_out = 2;
1213 *p_out = 1;
1214 *r2_out = 2;
1215 return;
1216 }
1217
1218 /*
1219 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1220 * the WR PLL.
1221 *
1222 * We want R so that REF_MIN <= Ref <= REF_MAX.
1223 * Injecting R2 = 2 * R gives:
1224 * REF_MAX * r2 > LC_FREQ * 2 and
1225 * REF_MIN * r2 < LC_FREQ * 2
1226 *
1227 * Which means the desired boundaries for r2 are:
1228 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1229 *
1230 */
1231 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1232 r2 <= LC_FREQ * 2 / REF_MIN;
1233 r2++) {
1234
1235 /*
1236 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1237 *
1238 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1239 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1240 * VCO_MAX * r2 > n2 * LC_FREQ and
1241 * VCO_MIN * r2 < n2 * LC_FREQ)
1242 *
1243 * Which means the desired boundaries for n2 are:
1244 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1245 */
1246 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1247 n2 <= VCO_MAX * r2 / LC_FREQ;
1248 n2++) {
1249
1250 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001251 hsw_wrpll_update_rnp(freq2k, budget,
1252 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001253 }
1254 }
1255
1256 *n2_out = best.n2;
1257 *p_out = best.p;
1258 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001259}
1260
Damien Lespiau0220ab62014-07-29 18:06:22 +01001261static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001262hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001263 struct intel_crtc_state *crtc_state,
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001264 struct intel_encoder *intel_encoder,
1265 int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001266{
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001267 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001268 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001269 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001270 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001271
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001272 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001273
Daniel Vetter114fe482014-06-25 22:01:48 +03001274 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001275 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1276 WRPLL_DIVIDER_POST(p);
1277
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001278 memset(&crtc_state->dpll_hw_state, 0,
1279 sizeof(crtc_state->dpll_hw_state));
1280
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001281 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001282
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001283 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001284 if (pll == NULL) {
1285 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1286 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001287 return false;
1288 }
1289
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001290 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001291 }
1292
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001293 return true;
1294}
1295
Damien Lespiaudc253812015-06-25 16:15:06 +01001296struct skl_wrpll_context {
1297 uint64_t min_deviation; /* current minimal deviation */
1298 uint64_t central_freq; /* chosen central freq */
1299 uint64_t dco_freq; /* chosen dco freq */
1300 unsigned int p; /* chosen divider */
1301};
1302
1303static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1304{
1305 memset(ctx, 0, sizeof(*ctx));
1306
1307 ctx->min_deviation = U64_MAX;
1308}
1309
1310/* DCO freq must be within +1%/-6% of the DCO central freq */
1311#define SKL_DCO_MAX_PDEVIATION 100
1312#define SKL_DCO_MAX_NDEVIATION 600
1313
1314static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1315 uint64_t central_freq,
1316 uint64_t dco_freq,
1317 unsigned int divider)
1318{
1319 uint64_t deviation;
1320
1321 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1322 central_freq);
1323
1324 /* positive deviation */
1325 if (dco_freq >= central_freq) {
1326 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1327 deviation < ctx->min_deviation) {
1328 ctx->min_deviation = deviation;
1329 ctx->central_freq = central_freq;
1330 ctx->dco_freq = dco_freq;
1331 ctx->p = divider;
1332 }
1333 /* negative deviation */
1334 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1335 deviation < ctx->min_deviation) {
1336 ctx->min_deviation = deviation;
1337 ctx->central_freq = central_freq;
1338 ctx->dco_freq = dco_freq;
1339 ctx->p = divider;
1340 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001341}
1342
1343static void skl_wrpll_get_multipliers(unsigned int p,
1344 unsigned int *p0 /* out */,
1345 unsigned int *p1 /* out */,
1346 unsigned int *p2 /* out */)
1347{
1348 /* even dividers */
1349 if (p % 2 == 0) {
1350 unsigned int half = p / 2;
1351
1352 if (half == 1 || half == 2 || half == 3 || half == 5) {
1353 *p0 = 2;
1354 *p1 = 1;
1355 *p2 = half;
1356 } else if (half % 2 == 0) {
1357 *p0 = 2;
1358 *p1 = half / 2;
1359 *p2 = 2;
1360 } else if (half % 3 == 0) {
1361 *p0 = 3;
1362 *p1 = half / 3;
1363 *p2 = 2;
1364 } else if (half % 7 == 0) {
1365 *p0 = 7;
1366 *p1 = half / 7;
1367 *p2 = 2;
1368 }
1369 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1370 *p0 = 3;
1371 *p1 = 1;
1372 *p2 = p / 3;
1373 } else if (p == 5 || p == 7) {
1374 *p0 = p;
1375 *p1 = 1;
1376 *p2 = 1;
1377 } else if (p == 15) {
1378 *p0 = 3;
1379 *p1 = 1;
1380 *p2 = 5;
1381 } else if (p == 21) {
1382 *p0 = 7;
1383 *p1 = 1;
1384 *p2 = 3;
1385 } else if (p == 35) {
1386 *p0 = 7;
1387 *p1 = 1;
1388 *p2 = 5;
1389 }
1390}
1391
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001392struct skl_wrpll_params {
1393 uint32_t dco_fraction;
1394 uint32_t dco_integer;
1395 uint32_t qdiv_ratio;
1396 uint32_t qdiv_mode;
1397 uint32_t kdiv;
1398 uint32_t pdiv;
1399 uint32_t central_freq;
1400};
1401
Damien Lespiau76516fb2015-05-07 18:38:42 +01001402static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1403 uint64_t afe_clock,
1404 uint64_t central_freq,
1405 uint32_t p0, uint32_t p1, uint32_t p2)
1406{
1407 uint64_t dco_freq;
1408
Damien Lespiau76516fb2015-05-07 18:38:42 +01001409 switch (central_freq) {
1410 case 9600000000ULL:
1411 params->central_freq = 0;
1412 break;
1413 case 9000000000ULL:
1414 params->central_freq = 1;
1415 break;
1416 case 8400000000ULL:
1417 params->central_freq = 3;
1418 }
1419
1420 switch (p0) {
1421 case 1:
1422 params->pdiv = 0;
1423 break;
1424 case 2:
1425 params->pdiv = 1;
1426 break;
1427 case 3:
1428 params->pdiv = 2;
1429 break;
1430 case 7:
1431 params->pdiv = 4;
1432 break;
1433 default:
1434 WARN(1, "Incorrect PDiv\n");
1435 }
1436
1437 switch (p2) {
1438 case 5:
1439 params->kdiv = 0;
1440 break;
1441 case 2:
1442 params->kdiv = 1;
1443 break;
1444 case 3:
1445 params->kdiv = 2;
1446 break;
1447 case 1:
1448 params->kdiv = 3;
1449 break;
1450 default:
1451 WARN(1, "Incorrect KDiv\n");
1452 }
1453
1454 params->qdiv_ratio = p1;
1455 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1456
1457 dco_freq = p0 * p1 * p2 * afe_clock;
1458
1459 /*
1460 * Intermediate values are in Hz.
1461 * Divide by MHz to match bsepc
1462 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001463 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001464 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001465 div_u64((div_u64(dco_freq, 24) -
1466 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001467}
1468
Damien Lespiau318bd822015-05-07 18:38:40 +01001469static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001470skl_ddi_calculate_wrpll(int clock /* in Hz */,
1471 struct skl_wrpll_params *wrpll_params)
1472{
1473 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001474 uint64_t dco_central_freq[3] = {8400000000ULL,
1475 9000000000ULL,
1476 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001477 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1478 24, 28, 30, 32, 36, 40, 42, 44,
1479 48, 52, 54, 56, 60, 64, 66, 68,
1480 70, 72, 76, 78, 80, 84, 88, 90,
1481 92, 96, 98 };
1482 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1483 static const struct {
1484 const int *list;
1485 int n_dividers;
1486 } dividers[] = {
1487 { even_dividers, ARRAY_SIZE(even_dividers) },
1488 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1489 };
1490 struct skl_wrpll_context ctx;
1491 unsigned int dco, d, i;
1492 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001493
Damien Lespiaudc253812015-06-25 16:15:06 +01001494 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001495
Damien Lespiaudc253812015-06-25 16:15:06 +01001496 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1497 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1498 for (i = 0; i < dividers[d].n_dividers; i++) {
1499 unsigned int p = dividers[d].list[i];
1500 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001501
Damien Lespiaudc253812015-06-25 16:15:06 +01001502 skl_wrpll_try_divider(&ctx,
1503 dco_central_freq[dco],
1504 dco_freq,
1505 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001506 /*
1507 * Skip the remaining dividers if we're sure to
1508 * have found the definitive divider, we can't
1509 * improve a 0 deviation.
1510 */
1511 if (ctx.min_deviation == 0)
1512 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001513 }
1514 }
Damien Lespiau267db662015-06-25 16:19:24 +01001515
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001516skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001517 /*
1518 * If a solution is found with an even divider, prefer
1519 * this one.
1520 */
1521 if (d == 0 && ctx.p)
1522 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001523 }
1524
Damien Lespiaudc253812015-06-25 16:15:06 +01001525 if (!ctx.p) {
1526 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001527 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001528 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001529
Damien Lespiaudc253812015-06-25 16:15:06 +01001530 /*
1531 * gcc incorrectly analyses that these can be used without being
1532 * initialized. To be fair, it's hard to guess.
1533 */
1534 p0 = p1 = p2 = 0;
1535 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1536 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1537 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001538
Damien Lespiau318bd822015-05-07 18:38:40 +01001539 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001540}
1541
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001542static bool
1543skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001544 struct intel_crtc_state *crtc_state,
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001545 struct intel_encoder *intel_encoder,
1546 int clock)
1547{
1548 struct intel_shared_dpll *pll;
1549 uint32_t ctrl1, cfgcr1, cfgcr2;
1550
1551 /*
1552 * See comment in intel_dpll_hw_state to understand why we always use 0
1553 * as the DPLL id in this function.
1554 */
1555
1556 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1557
1558 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1559 struct skl_wrpll_params wrpll_params = { 0, };
1560
1561 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1562
Damien Lespiau318bd822015-05-07 18:38:40 +01001563 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1564 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001565
1566 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1567 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1568 wrpll_params.dco_integer;
1569
1570 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1571 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1572 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1573 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1574 wrpll_params.central_freq;
1575 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
1576 struct drm_encoder *encoder = &intel_encoder->base;
1577 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1578
1579 switch (intel_dp->link_bw) {
1580 case DP_LINK_BW_1_62:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001581 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001582 break;
1583 case DP_LINK_BW_2_7:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001584 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001585 break;
1586 case DP_LINK_BW_5_4:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001587 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001588 break;
1589 }
1590
1591 cfgcr1 = cfgcr2 = 0;
1592 } else /* eDP */
1593 return true;
1594
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001595 memset(&crtc_state->dpll_hw_state, 0,
1596 sizeof(crtc_state->dpll_hw_state));
1597
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001598 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1599 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1600 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001601
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001602 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001603 if (pll == NULL) {
1604 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1605 pipe_name(intel_crtc->pipe));
1606 return false;
1607 }
1608
1609 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001610 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001611
1612 return true;
1613}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001614
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301615/* bxt clock parameters */
1616struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301617 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301618 uint32_t p1;
1619 uint32_t p2;
1620 uint32_t m2_int;
1621 uint32_t m2_frac;
1622 bool m2_frac_en;
1623 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301624};
1625
1626/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301627static const struct bxt_clk_div bxt_dp_clk_val[] = {
1628 {162000, 4, 2, 32, 1677722, 1, 1},
1629 {270000, 4, 1, 27, 0, 0, 1},
1630 {540000, 2, 1, 27, 0, 0, 1},
1631 {216000, 3, 2, 32, 1677722, 1, 1},
1632 {243000, 4, 1, 24, 1258291, 1, 1},
1633 {324000, 4, 1, 32, 1677722, 1, 1},
1634 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301635};
1636
1637static bool
1638bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1639 struct intel_crtc_state *crtc_state,
1640 struct intel_encoder *intel_encoder,
1641 int clock)
1642{
1643 struct intel_shared_dpll *pll;
1644 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301645 int vco = 0;
1646 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane0681e32015-05-13 12:20:35 +05301647 uint32_t dcoampovr_en_h, dco_amp, lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301648
1649 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1650 intel_clock_t best_clock;
1651
1652 /* Calculate HDMI div */
1653 /*
1654 * FIXME: tie the following calculation into
1655 * i9xx_crtc_compute_clock
1656 */
1657 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1658 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1659 clock, pipe_name(intel_crtc->pipe));
1660 return false;
1661 }
1662
1663 clk_div.p1 = best_clock.p1;
1664 clk_div.p2 = best_clock.p2;
1665 WARN_ON(best_clock.m1 != 2);
1666 clk_div.n = best_clock.n;
1667 clk_div.m2_int = best_clock.m2 >> 22;
1668 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1669 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1670
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301671 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301672 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1673 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301674 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301675
Sonika Jindal64987fc2015-05-26 17:50:13 +05301676 clk_div = bxt_dp_clk_val[0];
1677 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1678 if (bxt_dp_clk_val[i].clock == clock) {
1679 clk_div = bxt_dp_clk_val[i];
1680 break;
1681 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301682 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301683 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1684 }
1685
1686 dco_amp = 15;
1687 dcoampovr_en_h = 0;
1688 if (vco >= 6200000 && vco <= 6480000) {
1689 prop_coef = 4;
1690 int_coef = 9;
1691 gain_ctl = 3;
1692 targ_cnt = 8;
1693 } else if ((vco > 5400000 && vco < 6200000) ||
1694 (vco >= 4800000 && vco < 5400000)) {
1695 prop_coef = 5;
1696 int_coef = 11;
1697 gain_ctl = 3;
1698 targ_cnt = 9;
1699 if (vco >= 4800000 && vco < 5400000)
1700 dcoampovr_en_h = 1;
1701 } else if (vco == 5400000) {
1702 prop_coef = 3;
1703 int_coef = 8;
1704 gain_ctl = 1;
1705 targ_cnt = 9;
1706 } else {
1707 DRM_ERROR("Invalid VCO\n");
1708 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301709 }
1710
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001711 memset(&crtc_state->dpll_hw_state, 0,
1712 sizeof(crtc_state->dpll_hw_state));
1713
Vandana Kannane0681e32015-05-13 12:20:35 +05301714 if (clock > 270000)
1715 lanestagger = 0x18;
1716 else if (clock > 135000)
1717 lanestagger = 0x0d;
1718 else if (clock > 67000)
1719 lanestagger = 0x07;
1720 else if (clock > 33000)
1721 lanestagger = 0x04;
1722 else
1723 lanestagger = 0x02;
1724
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301725 crtc_state->dpll_hw_state.ebb0 =
1726 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1727 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1728 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1729 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1730
1731 if (clk_div.m2_frac_en)
1732 crtc_state->dpll_hw_state.pll3 =
1733 PORT_PLL_M2_FRAC_ENABLE;
1734
1735 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301736 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301737 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301738 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301739
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301740 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1741
Imre Deak05712c12015-06-18 17:25:54 +03001742 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1743
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301744 if (dcoampovr_en_h)
1745 crtc_state->dpll_hw_state.pll10 = PORT_PLL_DCO_AMP_OVR_EN_H;
1746
1747 crtc_state->dpll_hw_state.pll10 |= PORT_PLL_DCO_AMP(dco_amp);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301748
Imre Deak05712c12015-06-18 17:25:54 +03001749 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1750
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301751 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301752 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301753
1754 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1755 if (pll == NULL) {
1756 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1757 pipe_name(intel_crtc->pipe));
1758 return false;
1759 }
1760
1761 /* shared DPLL id 0 is DPLL A */
1762 crtc_state->ddi_pll_sel = pll->id;
1763
1764 return true;
1765}
1766
Damien Lespiau0220ab62014-07-29 18:06:22 +01001767/*
1768 * Tries to find a *shared* PLL for the CRTC and store it in
1769 * intel_crtc->ddi_pll_sel.
1770 *
1771 * For private DPLLs, compute_config() should do the selection for us. This
1772 * function should be folded into compute_config() eventually.
1773 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001774bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1775 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001776{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001777 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001778 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001779 intel_ddi_get_crtc_new_encoder(crtc_state);
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001780 int clock = crtc_state->port_clock;
Damien Lespiau0220ab62014-07-29 18:06:22 +01001781
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001782 if (IS_SKYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001783 return skl_ddi_pll_select(intel_crtc, crtc_state,
1784 intel_encoder, clock);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301785 else if (IS_BROXTON(dev))
1786 return bxt_ddi_pll_select(intel_crtc, crtc_state,
1787 intel_encoder, clock);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001788 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001789 return hsw_ddi_pll_select(intel_crtc, crtc_state,
1790 intel_encoder, clock);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001791}
1792
Paulo Zanonidae84792012-10-15 15:51:30 -03001793void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1794{
1795 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1796 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1797 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001798 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001799 int type = intel_encoder->type;
1800 uint32_t temp;
1801
Dave Airlie0e32b392014-05-02 14:02:48 +10001802 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001803 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001804 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001805 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001806 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001807 break;
1808 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001809 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001810 break;
1811 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001812 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001813 break;
1814 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001815 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001816 break;
1817 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001818 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001819 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001820 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001821 }
1822}
1823
Dave Airlie0e32b392014-05-02 14:02:48 +10001824void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1825{
1826 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1827 struct drm_device *dev = crtc->dev;
1828 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001829 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001830 uint32_t temp;
1831 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1832 if (state == true)
1833 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1834 else
1835 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1836 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1837}
1838
Damien Lespiau8228c252013-03-07 15:30:27 +00001839void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001840{
1841 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1842 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001843 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001844 struct drm_device *dev = crtc->dev;
1845 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001846 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001847 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001848 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001849 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001850 uint32_t temp;
1851
Paulo Zanoniad80a812012-10-24 16:06:19 -02001852 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1853 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001854 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001855
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001856 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001857 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001858 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001859 break;
1860 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001861 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001862 break;
1863 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001864 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001865 break;
1866 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001867 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001868 break;
1869 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001870 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001871 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001872
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001873 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001874 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001875 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001876 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001877
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001878 if (cpu_transcoder == TRANSCODER_EDP) {
1879 switch (pipe) {
1880 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001881 /* On Haswell, can only use the always-on power well for
1882 * eDP when not using the panel fitter, and when not
1883 * using motion blur mitigation (which we don't
1884 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001885 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001886 (intel_crtc->config->pch_pfit.enabled ||
1887 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001888 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1889 else
1890 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001891 break;
1892 case PIPE_B:
1893 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1894 break;
1895 case PIPE_C:
1896 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1897 break;
1898 default:
1899 BUG();
1900 break;
1901 }
1902 }
1903
Paulo Zanoni7739c332012-10-15 15:51:29 -03001904 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001905 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001906 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001907 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001908 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001909
Paulo Zanoni7739c332012-10-15 15:51:29 -03001910 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001911 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001912 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001913
1914 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1915 type == INTEL_OUTPUT_EDP) {
1916 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1917
Dave Airlie0e32b392014-05-02 14:02:48 +10001918 if (intel_dp->is_mst) {
1919 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1920 } else
1921 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1922
1923 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
1924 } else if (type == INTEL_OUTPUT_DP_MST) {
1925 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1926
1927 if (intel_dp->is_mst) {
1928 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1929 } else
1930 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001931
Daniel Vetter17aa6be2013-04-30 14:01:40 +02001932 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001933 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001934 WARN(1, "Invalid encoder type %d for pipe %c\n",
1935 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001936 }
1937
Paulo Zanoniad80a812012-10-24 16:06:19 -02001938 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001939}
1940
Paulo Zanoniad80a812012-10-24 16:06:19 -02001941void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1942 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001943{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001944 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001945 uint32_t val = I915_READ(reg);
1946
Dave Airlie0e32b392014-05-02 14:02:48 +10001947 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001948 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001949 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001950}
1951
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001952bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1953{
1954 struct drm_device *dev = intel_connector->base.dev;
1955 struct drm_i915_private *dev_priv = dev->dev_private;
1956 struct intel_encoder *intel_encoder = intel_connector->encoder;
1957 int type = intel_connector->base.connector_type;
1958 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1959 enum pipe pipe = 0;
1960 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001961 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001962 uint32_t tmp;
1963
Paulo Zanoni882244a2014-04-01 14:55:12 -03001964 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001965 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001966 return false;
1967
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001968 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1969 return false;
1970
1971 if (port == PORT_A)
1972 cpu_transcoder = TRANSCODER_EDP;
1973 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001974 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001975
1976 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1977
1978 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1979 case TRANS_DDI_MODE_SELECT_HDMI:
1980 case TRANS_DDI_MODE_SELECT_DVI:
1981 return (type == DRM_MODE_CONNECTOR_HDMIA);
1982
1983 case TRANS_DDI_MODE_SELECT_DP_SST:
1984 if (type == DRM_MODE_CONNECTOR_eDP)
1985 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001986 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001987 case TRANS_DDI_MODE_SELECT_DP_MST:
1988 /* if the transcoder is in MST state then
1989 * connector isn't connected */
1990 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001991
1992 case TRANS_DDI_MODE_SELECT_FDI:
1993 return (type == DRM_MODE_CONNECTOR_VGA);
1994
1995 default:
1996 return false;
1997 }
1998}
1999
Daniel Vetter85234cd2012-07-02 13:27:29 +02002000bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
2001 enum pipe *pipe)
2002{
2003 struct drm_device *dev = encoder->base.dev;
2004 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002005 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02002006 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002007 u32 tmp;
2008 int i;
2009
Imre Deak6d129be2014-03-05 16:20:54 +02002010 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002011 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02002012 return false;
2013
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002014 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002015
2016 if (!(tmp & DDI_BUF_CTL_ENABLE))
2017 return false;
2018
Paulo Zanoniad80a812012-10-24 16:06:19 -02002019 if (port == PORT_A) {
2020 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002021
Paulo Zanoniad80a812012-10-24 16:06:19 -02002022 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2023 case TRANS_DDI_EDP_INPUT_A_ON:
2024 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2025 *pipe = PIPE_A;
2026 break;
2027 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2028 *pipe = PIPE_B;
2029 break;
2030 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2031 *pipe = PIPE_C;
2032 break;
2033 }
2034
2035 return true;
2036 } else {
2037 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2038 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2039
2040 if ((tmp & TRANS_DDI_PORT_MASK)
2041 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002042 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2043 return false;
2044
Paulo Zanoniad80a812012-10-24 16:06:19 -02002045 *pipe = i;
2046 return true;
2047 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002048 }
2049 }
2050
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002051 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002052
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002053 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002054}
2055
Paulo Zanonifc914632012-10-05 12:05:54 -03002056void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2057{
2058 struct drm_crtc *crtc = &intel_crtc->base;
2059 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2060 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2061 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002062 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002063
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002064 if (cpu_transcoder != TRANSCODER_EDP)
2065 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2066 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002067}
2068
2069void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2070{
2071 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002072 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002073
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002074 if (cpu_transcoder != TRANSCODER_EDP)
2075 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2076 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002077}
2078
David Weinehallf8896f52015-06-25 11:11:03 +03002079static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2080 enum port port, int type)
2081{
2082 struct drm_i915_private *dev_priv = dev->dev_private;
2083 const struct ddi_buf_trans *ddi_translations;
2084 uint8_t iboost;
2085 int n_entries;
2086 u32 reg;
2087
2088 if (type == INTEL_OUTPUT_DISPLAYPORT) {
2089 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2090 iboost = ddi_translations[port].i_boost;
2091 } else if (type == INTEL_OUTPUT_EDP) {
2092 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2093 iboost = ddi_translations[port].i_boost;
2094 } else if (type == INTEL_OUTPUT_HDMI) {
2095 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2096 iboost = ddi_translations[port].i_boost;
2097 } else {
2098 return;
2099 }
2100
2101 /* Make sure that the requested I_boost is valid */
2102 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2103 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2104 return;
2105 }
2106
2107 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2108 reg &= ~BALANCE_LEG_MASK(port);
2109 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2110
2111 if (iboost)
2112 reg |= iboost << BALANCE_LEG_SHIFT(port);
2113 else
2114 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2115
2116 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2117}
2118
2119static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2120 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302121{
2122 struct drm_i915_private *dev_priv = dev->dev_private;
2123 const struct bxt_ddi_buf_trans *ddi_translations;
2124 u32 n_entries, i;
2125 uint32_t val;
2126
2127 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
2128 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2129 ddi_translations = bxt_ddi_translations_dp;
2130 } else if (type == INTEL_OUTPUT_HDMI) {
2131 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2132 ddi_translations = bxt_ddi_translations_hdmi;
2133 } else {
2134 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2135 type);
2136 return;
2137 }
2138
2139 /* Check if default value has to be used */
2140 if (level >= n_entries ||
2141 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2142 for (i = 0; i < n_entries; i++) {
2143 if (ddi_translations[i].default_index) {
2144 level = i;
2145 break;
2146 }
2147 }
2148 }
2149
2150 /*
2151 * While we write to the group register to program all lanes at once we
2152 * can read only lane registers and we pick lanes 0/1 for that.
2153 */
2154 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2155 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2156 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2157
2158 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2159 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2160 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2161 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2162 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2163
2164 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
2165 val &= ~UNIQE_TRANGE_EN_METHOD;
2166 if (ddi_translations[level].enable)
2167 val |= UNIQE_TRANGE_EN_METHOD;
2168 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2169
2170 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2171 val &= ~DE_EMPHASIS;
2172 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2173 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2174
2175 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2176 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2177 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2178}
2179
David Weinehallf8896f52015-06-25 11:11:03 +03002180static uint32_t translate_signal_level(int signal_levels)
2181{
2182 uint32_t level;
2183
2184 switch (signal_levels) {
2185 default:
2186 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2187 signal_levels);
2188 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2189 level = 0;
2190 break;
2191 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2192 level = 1;
2193 break;
2194 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2195 level = 2;
2196 break;
2197 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2198 level = 3;
2199 break;
2200
2201 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2202 level = 4;
2203 break;
2204 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2205 level = 5;
2206 break;
2207 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2208 level = 6;
2209 break;
2210
2211 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2212 level = 7;
2213 break;
2214 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2215 level = 8;
2216 break;
2217
2218 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2219 level = 9;
2220 break;
2221 }
2222
2223 return level;
2224}
2225
2226uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2227{
2228 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2229 struct drm_device *dev = dport->base.base.dev;
2230 struct intel_encoder *encoder = &dport->base;
2231 uint8_t train_set = intel_dp->train_set[0];
2232 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2233 DP_TRAIN_PRE_EMPHASIS_MASK);
2234 enum port port = dport->port;
2235 uint32_t level;
2236
2237 level = translate_signal_level(signal_levels);
2238
2239 if (IS_SKYLAKE(dev))
2240 skl_ddi_set_iboost(dev, level, port, encoder->type);
2241 else if (IS_BROXTON(dev))
2242 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2243
2244 return DDI_BUF_TRANS_SELECT(level);
2245}
2246
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002247static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002248{
Paulo Zanonic19b0662012-10-15 15:51:41 -03002249 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002250 struct drm_device *dev = encoder->dev;
2251 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002252 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002253 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002254 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302255 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002256
2257 if (type == INTEL_OUTPUT_EDP) {
2258 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01002259 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002260 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002261
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002262 if (IS_SKYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002263 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002264 uint32_t val;
2265
Damien Lespiau5416d872014-11-14 17:24:33 +00002266 /*
2267 * DPLL0 is used for eDP and is the only "private" DPLL (as
2268 * opposed to shared) on SKL
2269 */
2270 if (type == INTEL_OUTPUT_EDP) {
2271 WARN_ON(dpll != SKL_DPLL0);
2272
2273 val = I915_READ(DPLL_CTRL1);
2274
2275 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2276 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002277 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002278 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002279
2280 I915_WRITE(DPLL_CTRL1, val);
2281 POSTING_READ(DPLL_CTRL1);
2282 }
2283
2284 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002285 val = I915_READ(DPLL_CTRL2);
2286
2287 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2288 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2289 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2290 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2291
2292 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002293
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302294 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002295 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2296 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002297 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002298
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002299 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002300 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002301
Dave Airlie44905a272014-05-02 13:36:43 +10002302 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002303
2304 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2305 intel_dp_start_link_train(intel_dp);
2306 intel_dp_complete_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002307 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002308 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002309 } else if (type == INTEL_OUTPUT_HDMI) {
2310 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2311
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302312 if (IS_BROXTON(dev)) {
2313 hdmi_level = dev_priv->vbt.
2314 ddi_port_info[port].hdmi_level_shift;
2315 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2316 INTEL_OUTPUT_HDMI);
2317 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002318 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002319 crtc->config->has_hdmi_sink,
2320 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002321 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002322}
2323
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002324static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002325{
2326 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002327 struct drm_device *dev = encoder->dev;
2328 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002329 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002330 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002331 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002332 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002333
2334 val = I915_READ(DDI_BUF_CTL(port));
2335 if (val & DDI_BUF_CTL_ENABLE) {
2336 val &= ~DDI_BUF_CTL_ENABLE;
2337 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002338 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002339 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002340
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002341 val = I915_READ(DP_TP_CTL(port));
2342 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2343 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2344 I915_WRITE(DP_TP_CTL(port), val);
2345
2346 if (wait)
2347 intel_wait_ddi_buf_idle(dev_priv, port);
2348
Jani Nikula76bb80e2013-11-15 15:29:57 +02002349 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002350 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002351 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002352 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002353 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002354 }
2355
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002356 if (IS_SKYLAKE(dev))
2357 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2358 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302359 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002360 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002361}
2362
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002363static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002364{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002365 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002366 struct drm_crtc *crtc = encoder->crtc;
2367 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002368 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002369 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002370 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2371 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002372
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002373 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002374 struct intel_digital_port *intel_dig_port =
2375 enc_to_dig_port(encoder);
2376
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002377 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2378 * are ignored so nothing special needs to be done besides
2379 * enabling the port.
2380 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002381 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002382 intel_dig_port->saved_port_bits |
2383 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002384 } else if (type == INTEL_OUTPUT_EDP) {
2385 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2386
Vandana Kannan23f08d82014-11-13 14:55:22 +00002387 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002388 intel_dp_stop_link_train(intel_dp);
2389
Daniel Vetter4be73782014-01-17 14:39:48 +01002390 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002391 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302392 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002393 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002394
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002395 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002396 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002397 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002398 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002399}
2400
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002401static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002402{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002403 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002404 struct drm_crtc *crtc = encoder->crtc;
2405 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002406 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002407 struct drm_device *dev = encoder->dev;
2408 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002409
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002410 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002411 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002412 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2413 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002414
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002415 if (type == INTEL_OUTPUT_EDP) {
2416 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2417
Vandana Kannanc3955782015-01-22 15:17:40 +05302418 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002419 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002420 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002421 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002422}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002423
Daniel Vettere0b01be2014-06-25 22:02:01 +03002424static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2425 struct intel_shared_dpll *pll)
2426{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002427 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002428 POSTING_READ(WRPLL_CTL(pll->id));
2429 udelay(20);
2430}
2431
Daniel Vetter12030432014-06-25 22:02:00 +03002432static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2433 struct intel_shared_dpll *pll)
2434{
2435 uint32_t val;
2436
2437 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002438 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2439 POSTING_READ(WRPLL_CTL(pll->id));
2440}
2441
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002442static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2443 struct intel_shared_dpll *pll,
2444 struct intel_dpll_hw_state *hw_state)
2445{
2446 uint32_t val;
2447
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002448 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002449 return false;
2450
2451 val = I915_READ(WRPLL_CTL(pll->id));
2452 hw_state->wrpll = val;
2453
2454 return val & WRPLL_PLL_ENABLE;
2455}
2456
Damien Lespiauca1381b2014-07-15 15:05:33 +01002457static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002458 "WRPLL 1",
2459 "WRPLL 2",
2460};
2461
Damien Lespiau143b3072014-07-29 18:06:19 +01002462static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002463{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002464 int i;
2465
Daniel Vetter716c2e52014-06-25 22:02:02 +03002466 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002467
Daniel Vetter716c2e52014-06-25 22:02:02 +03002468 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002469 dev_priv->shared_dplls[i].id = i;
2470 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002471 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002472 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002473 dev_priv->shared_dplls[i].get_hw_state =
2474 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002475 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002476}
2477
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002478static const char * const skl_ddi_pll_names[] = {
2479 "DPLL 1",
2480 "DPLL 2",
2481 "DPLL 3",
2482};
2483
2484struct skl_dpll_regs {
2485 u32 ctl, cfgcr1, cfgcr2;
2486};
2487
2488/* this array is indexed by the *shared* pll id */
2489static const struct skl_dpll_regs skl_dpll_regs[3] = {
2490 {
2491 /* DPLL 1 */
2492 .ctl = LCPLL2_CTL,
2493 .cfgcr1 = DPLL1_CFGCR1,
2494 .cfgcr2 = DPLL1_CFGCR2,
2495 },
2496 {
2497 /* DPLL 2 */
2498 .ctl = WRPLL_CTL1,
2499 .cfgcr1 = DPLL2_CFGCR1,
2500 .cfgcr2 = DPLL2_CFGCR2,
2501 },
2502 {
2503 /* DPLL 3 */
2504 .ctl = WRPLL_CTL2,
2505 .cfgcr1 = DPLL3_CFGCR1,
2506 .cfgcr2 = DPLL3_CFGCR2,
2507 },
2508};
2509
2510static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2511 struct intel_shared_dpll *pll)
2512{
2513 uint32_t val;
2514 unsigned int dpll;
2515 const struct skl_dpll_regs *regs = skl_dpll_regs;
2516
2517 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2518 dpll = pll->id + 1;
2519
2520 val = I915_READ(DPLL_CTRL1);
2521
2522 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002523 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002524 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2525
2526 I915_WRITE(DPLL_CTRL1, val);
2527 POSTING_READ(DPLL_CTRL1);
2528
2529 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2530 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2531 POSTING_READ(regs[pll->id].cfgcr1);
2532 POSTING_READ(regs[pll->id].cfgcr2);
2533
2534 /* the enable bit is always bit 31 */
2535 I915_WRITE(regs[pll->id].ctl,
2536 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2537
2538 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2539 DRM_ERROR("DPLL %d not locked\n", dpll);
2540}
2541
2542static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2543 struct intel_shared_dpll *pll)
2544{
2545 const struct skl_dpll_regs *regs = skl_dpll_regs;
2546
2547 /* the enable bit is always bit 31 */
2548 I915_WRITE(regs[pll->id].ctl,
2549 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2550 POSTING_READ(regs[pll->id].ctl);
2551}
2552
2553static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2554 struct intel_shared_dpll *pll,
2555 struct intel_dpll_hw_state *hw_state)
2556{
2557 uint32_t val;
2558 unsigned int dpll;
2559 const struct skl_dpll_regs *regs = skl_dpll_regs;
2560
2561 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2562 return false;
2563
2564 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2565 dpll = pll->id + 1;
2566
2567 val = I915_READ(regs[pll->id].ctl);
2568 if (!(val & LCPLL_PLL_ENABLE))
2569 return false;
2570
2571 val = I915_READ(DPLL_CTRL1);
2572 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2573
2574 /* avoid reading back stale values if HDMI mode is not enabled */
2575 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2576 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2577 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2578 }
2579
2580 return true;
2581}
2582
2583static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2584{
2585 int i;
2586
2587 dev_priv->num_shared_dpll = 3;
2588
2589 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2590 dev_priv->shared_dplls[i].id = i;
2591 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2592 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2593 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2594 dev_priv->shared_dplls[i].get_hw_state =
2595 skl_ddi_pll_get_hw_state;
2596 }
2597}
2598
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302599static void broxton_phy_init(struct drm_i915_private *dev_priv,
2600 enum dpio_phy phy)
2601{
2602 enum port port;
2603 uint32_t val;
2604
2605 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2606 val |= GT_DISPLAY_POWER_ON(phy);
2607 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2608
2609 /* Considering 10ms timeout until BSpec is updated */
2610 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2611 DRM_ERROR("timeout during PHY%d power on\n", phy);
2612
2613 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2614 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2615 int lane;
2616
2617 for (lane = 0; lane < 4; lane++) {
2618 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2619 /*
2620 * Note that on CHV this flag is called UPAR, but has
2621 * the same function.
2622 */
2623 val &= ~LATENCY_OPTIM;
2624 if (lane != 1)
2625 val |= LATENCY_OPTIM;
2626
2627 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2628 }
2629 }
2630
2631 /* Program PLL Rcomp code offset */
2632 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2633 val &= ~IREF0RC_OFFSET_MASK;
2634 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2635 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2636
2637 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2638 val &= ~IREF1RC_OFFSET_MASK;
2639 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2640 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2641
2642 /* Program power gating */
2643 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2644 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2645 SUS_CLK_CONFIG;
2646 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2647
2648 if (phy == DPIO_PHY0) {
2649 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2650 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2651 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2652 }
2653
2654 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2655 val &= ~OCL2_LDOFUSE_PWR_DIS;
2656 /*
2657 * On PHY1 disable power on the second channel, since no port is
2658 * connected there. On PHY0 both channels have a port, so leave it
2659 * enabled.
2660 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2661 * power down the second channel on PHY0 as well.
2662 */
2663 if (phy == DPIO_PHY1)
2664 val |= OCL2_LDOFUSE_PWR_DIS;
2665 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2666
2667 if (phy == DPIO_PHY0) {
2668 uint32_t grc_code;
2669 /*
2670 * PHY0 isn't connected to an RCOMP resistor so copy over
2671 * the corresponding calibrated value from PHY1, and disable
2672 * the automatic calibration on PHY0.
2673 */
2674 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2675 10))
2676 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2677
2678 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2679 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2680 grc_code = val << GRC_CODE_FAST_SHIFT |
2681 val << GRC_CODE_SLOW_SHIFT |
2682 val;
2683 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2684
2685 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2686 val |= GRC_DIS | GRC_RDY_OVRD;
2687 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2688 }
2689
2690 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2691 val |= COMMON_RESET_DIS;
2692 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2693}
2694
2695void broxton_ddi_phy_init(struct drm_device *dev)
2696{
2697 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2698 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2699 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2700}
2701
2702static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2703 enum dpio_phy phy)
2704{
2705 uint32_t val;
2706
2707 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2708 val &= ~COMMON_RESET_DIS;
2709 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2710}
2711
2712void broxton_ddi_phy_uninit(struct drm_device *dev)
2713{
2714 struct drm_i915_private *dev_priv = dev->dev_private;
2715
2716 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2717 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2718
2719 /* FIXME: do this in broxton_phy_uninit per phy */
2720 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2721}
2722
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302723static const char * const bxt_ddi_pll_names[] = {
2724 "PORT PLL A",
2725 "PORT PLL B",
2726 "PORT PLL C",
2727};
2728
2729static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2730 struct intel_shared_dpll *pll)
2731{
2732 uint32_t temp;
2733 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2734
2735 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2736 temp &= ~PORT_PLL_REF_SEL;
2737 /* Non-SSC reference */
2738 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2739
2740 /* Disable 10 bit clock */
2741 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2742 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2743 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2744
2745 /* Write P1 & P2 */
2746 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2747 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2748 temp |= pll->config.hw_state.ebb0;
2749 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2750
2751 /* Write M2 integer */
2752 temp = I915_READ(BXT_PORT_PLL(port, 0));
2753 temp &= ~PORT_PLL_M2_MASK;
2754 temp |= pll->config.hw_state.pll0;
2755 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2756
2757 /* Write N */
2758 temp = I915_READ(BXT_PORT_PLL(port, 1));
2759 temp &= ~PORT_PLL_N_MASK;
2760 temp |= pll->config.hw_state.pll1;
2761 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2762
2763 /* Write M2 fraction */
2764 temp = I915_READ(BXT_PORT_PLL(port, 2));
2765 temp &= ~PORT_PLL_M2_FRAC_MASK;
2766 temp |= pll->config.hw_state.pll2;
2767 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2768
2769 /* Write M2 fraction enable */
2770 temp = I915_READ(BXT_PORT_PLL(port, 3));
2771 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2772 temp |= pll->config.hw_state.pll3;
2773 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2774
2775 /* Write coeff */
2776 temp = I915_READ(BXT_PORT_PLL(port, 6));
2777 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2778 temp &= ~PORT_PLL_INT_COEFF_MASK;
2779 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2780 temp |= pll->config.hw_state.pll6;
2781 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2782
2783 /* Write calibration val */
2784 temp = I915_READ(BXT_PORT_PLL(port, 8));
2785 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2786 temp |= pll->config.hw_state.pll8;
2787 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2788
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302789 temp = I915_READ(BXT_PORT_PLL(port, 9));
2790 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002791 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302792 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2793
2794 temp = I915_READ(BXT_PORT_PLL(port, 10));
2795 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2796 temp &= ~PORT_PLL_DCO_AMP_MASK;
2797 temp |= pll->config.hw_state.pll10;
2798 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302799
2800 /* Recalibrate with new settings */
2801 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2802 temp |= PORT_PLL_RECALIBRATE;
2803 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002804 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2805 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302806 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2807
2808 /* Enable PLL */
2809 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2810 temp |= PORT_PLL_ENABLE;
2811 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2812 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2813
2814 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2815 PORT_PLL_LOCK), 200))
2816 DRM_ERROR("PLL %d not locked\n", port);
2817
2818 /*
2819 * While we write to the group register to program all lanes at once we
2820 * can read only lane registers and we pick lanes 0/1 for that.
2821 */
2822 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2823 temp &= ~LANE_STAGGER_MASK;
2824 temp &= ~LANESTAGGER_STRAP_OVRD;
2825 temp |= pll->config.hw_state.pcsdw12;
2826 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2827}
2828
2829static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2830 struct intel_shared_dpll *pll)
2831{
2832 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2833 uint32_t temp;
2834
2835 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2836 temp &= ~PORT_PLL_ENABLE;
2837 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2838 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2839}
2840
2841static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2842 struct intel_shared_dpll *pll,
2843 struct intel_dpll_hw_state *hw_state)
2844{
2845 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2846 uint32_t val;
2847
2848 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2849 return false;
2850
2851 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2852 if (!(val & PORT_PLL_ENABLE))
2853 return false;
2854
2855 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002856 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2857
Imre Deak05712c12015-06-18 17:25:54 +03002858 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2859 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2860
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302861 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002862 hw_state->pll0 &= PORT_PLL_M2_MASK;
2863
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302864 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002865 hw_state->pll1 &= PORT_PLL_N_MASK;
2866
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302867 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002868 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2869
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302870 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002871 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2872
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302873 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002874 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2875 PORT_PLL_INT_COEFF_MASK |
2876 PORT_PLL_GAIN_CTL_MASK;
2877
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302878 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002879 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2880
Imre Deak05712c12015-06-18 17:25:54 +03002881 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2882 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2883
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302884 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002885 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2886 PORT_PLL_DCO_AMP_MASK;
2887
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302888 /*
2889 * While we write to the group register to program all lanes at once we
2890 * can read only lane registers. We configure all lanes the same way, so
2891 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2892 */
2893 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2894 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port) != hw_state->pcsdw12))
2895 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2896 hw_state->pcsdw12,
2897 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002898 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302899
2900 return true;
2901}
2902
2903static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2904{
2905 int i;
2906
2907 dev_priv->num_shared_dpll = 3;
2908
2909 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2910 dev_priv->shared_dplls[i].id = i;
2911 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2912 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2913 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2914 dev_priv->shared_dplls[i].get_hw_state =
2915 bxt_ddi_pll_get_hw_state;
2916 }
2917}
2918
Damien Lespiau143b3072014-07-29 18:06:19 +01002919void intel_ddi_pll_init(struct drm_device *dev)
2920{
2921 struct drm_i915_private *dev_priv = dev->dev_private;
2922 uint32_t val = I915_READ(LCPLL_CTL);
2923
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002924 if (IS_SKYLAKE(dev))
2925 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302926 else if (IS_BROXTON(dev))
2927 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002928 else
2929 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002930
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002931 if (IS_SKYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002932 int cdclk_freq;
2933
2934 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002935 dev_priv->skl_boot_cdclk = cdclk_freq;
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002936 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2937 DRM_ERROR("LCPLL1 is disabled\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002938 else
2939 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302940 } else if (IS_BROXTON(dev)) {
2941 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302942 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002943 } else {
2944 /*
2945 * The LCPLL register should be turned on by the BIOS. For now
2946 * let's just check its state and print errors in case
2947 * something is wrong. Don't even try to turn it on.
2948 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002949
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002950 if (val & LCPLL_CD_SOURCE_FCLK)
2951 DRM_ERROR("CDCLK source is not LCPLL\n");
2952
2953 if (val & LCPLL_PLL_DISABLE)
2954 DRM_ERROR("LCPLL is disabled\n");
2955 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002956}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002957
2958void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
2959{
Paulo Zanoni174edf12012-10-26 19:05:50 -02002960 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
2961 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002962 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02002963 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002964 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302965 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002966
2967 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2968 val = I915_READ(DDI_BUF_CTL(port));
2969 if (val & DDI_BUF_CTL_ENABLE) {
2970 val &= ~DDI_BUF_CTL_ENABLE;
2971 I915_WRITE(DDI_BUF_CTL(port), val);
2972 wait = true;
2973 }
2974
2975 val = I915_READ(DP_TP_CTL(port));
2976 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2977 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2978 I915_WRITE(DP_TP_CTL(port), val);
2979 POSTING_READ(DP_TP_CTL(port));
2980
2981 if (wait)
2982 intel_wait_ddi_buf_idle(dev_priv, port);
2983 }
2984
Dave Airlie0e32b392014-05-02 14:02:48 +10002985 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03002986 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10002987 if (intel_dp->is_mst)
2988 val |= DP_TP_CTL_MODE_MST;
2989 else {
2990 val |= DP_TP_CTL_MODE_SST;
2991 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
2992 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
2993 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002994 I915_WRITE(DP_TP_CTL(port), val);
2995 POSTING_READ(DP_TP_CTL(port));
2996
2997 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
2998 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
2999 POSTING_READ(DDI_BUF_CTL(port));
3000
3001 udelay(600);
3002}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003003
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003004void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3005{
3006 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3007 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3008 uint32_t val;
3009
3010 intel_ddi_post_disable(intel_encoder);
3011
3012 val = I915_READ(_FDI_RXA_CTL);
3013 val &= ~FDI_RX_ENABLE;
3014 I915_WRITE(_FDI_RXA_CTL, val);
3015
3016 val = I915_READ(_FDI_RXA_MISC);
3017 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3018 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
3019 I915_WRITE(_FDI_RXA_MISC, val);
3020
3021 val = I915_READ(_FDI_RXA_CTL);
3022 val &= ~FDI_PCDCLK;
3023 I915_WRITE(_FDI_RXA_CTL, val);
3024
3025 val = I915_READ(_FDI_RXA_CTL);
3026 val &= ~FDI_RX_PLL_ENABLE;
3027 I915_WRITE(_FDI_RXA_CTL, val);
3028}
3029
Ville Syrjälä6801c182013-09-24 14:24:05 +03003030void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003031 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003032{
3033 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3034 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003035 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003036 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003037 u32 temp, flags = 0;
3038
3039 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3040 if (temp & TRANS_DDI_PHSYNC)
3041 flags |= DRM_MODE_FLAG_PHSYNC;
3042 else
3043 flags |= DRM_MODE_FLAG_NHSYNC;
3044 if (temp & TRANS_DDI_PVSYNC)
3045 flags |= DRM_MODE_FLAG_PVSYNC;
3046 else
3047 flags |= DRM_MODE_FLAG_NVSYNC;
3048
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003049 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003050
3051 switch (temp & TRANS_DDI_BPC_MASK) {
3052 case TRANS_DDI_BPC_6:
3053 pipe_config->pipe_bpp = 18;
3054 break;
3055 case TRANS_DDI_BPC_8:
3056 pipe_config->pipe_bpp = 24;
3057 break;
3058 case TRANS_DDI_BPC_10:
3059 pipe_config->pipe_bpp = 30;
3060 break;
3061 case TRANS_DDI_BPC_12:
3062 pipe_config->pipe_bpp = 36;
3063 break;
3064 default:
3065 break;
3066 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003067
3068 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3069 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003070 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003071 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3072
3073 if (intel_hdmi->infoframe_enabled(&encoder->base))
3074 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003075 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003076 case TRANS_DDI_MODE_SELECT_DVI:
3077 case TRANS_DDI_MODE_SELECT_FDI:
3078 break;
3079 case TRANS_DDI_MODE_SELECT_DP_SST:
3080 case TRANS_DDI_MODE_SELECT_DP_MST:
3081 pipe_config->has_dp_encoder = true;
3082 intel_dp_get_m_n(intel_crtc, pipe_config);
3083 break;
3084 default:
3085 break;
3086 }
Daniel Vetter10214422013-11-18 07:38:16 +01003087
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003088 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003089 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003090 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003091 pipe_config->has_audio = true;
3092 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003093
Daniel Vetter10214422013-11-18 07:38:16 +01003094 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3095 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3096 /*
3097 * This is a big fat ugly hack.
3098 *
3099 * Some machines in UEFI boot mode provide us a VBT that has 18
3100 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3101 * unknown we fail to light up. Yet the same BIOS boots up with
3102 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3103 * max, not what it tells us to use.
3104 *
3105 * Note: This will still be broken if the eDP panel is not lit
3106 * up by the BIOS, and thus we can't get the mode at module
3107 * load.
3108 */
3109 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3110 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3111 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3112 }
Jesse Barnes11578552014-01-21 12:42:10 -08003113
Damien Lespiau22606a12014-12-12 14:26:57 +00003114 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003115}
3116
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003117static void intel_ddi_destroy(struct drm_encoder *encoder)
3118{
3119 /* HDMI has nothing special to destroy, so we can go with this. */
3120 intel_dp_encoder_destroy(encoder);
3121}
3122
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003123static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003124 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003125{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003126 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003127 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003128
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003129 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003130
Daniel Vettereccb1402013-05-22 00:50:22 +02003131 if (port == PORT_A)
3132 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3133
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003134 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003135 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003136 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003137 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003138}
3139
3140static const struct drm_encoder_funcs intel_ddi_funcs = {
3141 .destroy = intel_ddi_destroy,
3142};
3143
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003144static struct intel_connector *
3145intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3146{
3147 struct intel_connector *connector;
3148 enum port port = intel_dig_port->port;
3149
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003150 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003151 if (!connector)
3152 return NULL;
3153
3154 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3155 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3156 kfree(connector);
3157 return NULL;
3158 }
3159
3160 return connector;
3161}
3162
3163static struct intel_connector *
3164intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3165{
3166 struct intel_connector *connector;
3167 enum port port = intel_dig_port->port;
3168
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003169 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003170 if (!connector)
3171 return NULL;
3172
3173 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3174 intel_hdmi_init_connector(intel_dig_port, connector);
3175
3176 return connector;
3177}
3178
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003179void intel_ddi_init(struct drm_device *dev, enum port port)
3180{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003181 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003182 struct intel_digital_port *intel_dig_port;
3183 struct intel_encoder *intel_encoder;
3184 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003185 bool init_hdmi, init_dp;
3186
3187 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3188 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3189 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3190 if (!init_dp && !init_hdmi) {
Chris Wilsonf68d6972014-08-04 07:15:09 +01003191 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003192 port_name(port));
3193 init_hdmi = true;
3194 init_dp = true;
3195 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003196
Daniel Vetterb14c5672013-09-19 12:18:32 +02003197 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003198 if (!intel_dig_port)
3199 return;
3200
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003201 intel_encoder = &intel_dig_port->base;
3202 encoder = &intel_encoder->base;
3203
3204 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3205 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003206
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003207 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003208 intel_encoder->enable = intel_enable_ddi;
3209 intel_encoder->pre_enable = intel_ddi_pre_enable;
3210 intel_encoder->disable = intel_disable_ddi;
3211 intel_encoder->post_disable = intel_ddi_post_disable;
3212 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003213 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003214
3215 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003216 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3217 (DDI_BUF_PORT_REVERSAL |
3218 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003219
3220 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003221 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003222 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003223
Chris Wilsonf68d6972014-08-04 07:15:09 +01003224 if (init_dp) {
3225 if (!intel_ddi_init_dp_connector(intel_dig_port))
3226 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003227
Chris Wilsonf68d6972014-08-04 07:15:09 +01003228 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Jani Nikula5fcece82015-05-27 15:03:42 +03003229 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003230 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003231
Paulo Zanoni311a2092013-09-12 17:12:18 -03003232 /* In theory we don't need the encoder->type check, but leave it just in
3233 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003234 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3235 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3236 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003237 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003238
3239 return;
3240
3241err:
3242 drm_encoder_cleanup(encoder);
3243 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003244}