blob: 9a40bfb20e0c8cabb62f425d68da7e7e1cea96bc [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)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300461 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300462 ddi_translations_dp =
463 skl_get_buf_trans_dp(dev, &n_dp_entries);
464 ddi_translations_edp =
465 skl_get_buf_trans_edp(dev, &n_edp_entries);
466 ddi_translations_hdmi =
467 skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
468 hdmi_default_entry = 8;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000469 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700470 ddi_translations_fdi = bdw_ddi_translations_fdi;
471 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700472 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100473 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530474 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
475 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300476 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000477 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700478 } else if (IS_HASWELL(dev)) {
479 ddi_translations_fdi = hsw_ddi_translations_fdi;
480 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700481 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100482 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530483 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300484 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000485 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700486 } else {
487 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700488 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700489 ddi_translations_fdi = bdw_ddi_translations_fdi;
490 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100491 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530492 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
493 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300494 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000495 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700496 }
497
Paulo Zanoni300644c2013-11-02 21:07:42 -0700498 switch (port) {
499 case PORT_A:
500 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530501 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700502 break;
503 case PORT_B:
504 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700505 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530506 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700507 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700508 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530509 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700510 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530511 size = n_edp_entries;
512 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700513 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530514 size = n_dp_entries;
515 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700516 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700517 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000518 if (ddi_translations_fdi)
519 ddi_translations = ddi_translations_fdi;
520 else
521 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530522 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700523 break;
524 default:
525 BUG();
526 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300527
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530528 for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) {
Jani Nikula10122052014-08-27 16:27:30 +0300529 I915_WRITE(reg, ddi_translations[i].trans1);
530 reg += 4;
531 I915_WRITE(reg, ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300532 reg += 4;
533 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100534
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300535 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100536 return;
537
Damien Lespiauce4dd492014-08-01 11:07:54 +0100538 /* Choose a good default if VBT is badly populated */
539 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
540 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000541 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100542
Paulo Zanoni6acab152013-09-12 17:06:24 -0300543 /* Entry 9 is for HDMI: */
Jani Nikula10122052014-08-27 16:27:30 +0300544 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1);
545 reg += 4;
546 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2);
547 reg += 4;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300548}
549
550/* Program DDI buffers translations for DP. By default, program ports A-D in DP
551 * mode and port E for FDI.
552 */
553void intel_prepare_ddi(struct drm_device *dev)
554{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300555 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100556 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300557
Paulo Zanoni0d536cb2012-11-23 16:46:41 -0200558 if (!HAS_DDI(dev))
559 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300560
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300561 for_each_intel_encoder(dev, intel_encoder) {
562 struct intel_digital_port *intel_dig_port;
563 enum port port;
564 bool supports_hdmi;
565
566 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
567
568 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100569 continue;
570
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300571 supports_hdmi = intel_dig_port &&
572 intel_dig_port_supports_hdmi(intel_dig_port);
573
574 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
575 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100576 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300577}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300578
Paulo Zanoni248138b2012-11-29 11:29:31 -0200579static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
580 enum port port)
581{
582 uint32_t reg = DDI_BUF_CTL(port);
583 int i;
584
Vandana Kannan3449ca82015-03-27 14:19:09 +0200585 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200586 udelay(1);
587 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
588 return;
589 }
590 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
591}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300592
593/* Starting with Haswell, different DDI ports can work in FDI mode for
594 * connection to the PCH-located connectors. For this, it is necessary to train
595 * both the DDI port and PCH receiver for the desired DDI buffer settings.
596 *
597 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
598 * please note that when FDI mode is active on DDI E, it shares 2 lines with
599 * DDI A (which is used for eDP)
600 */
601
602void hsw_fdi_link_train(struct drm_crtc *crtc)
603{
604 struct drm_device *dev = crtc->dev;
605 struct drm_i915_private *dev_priv = dev->dev_private;
606 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200607 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300608
Paulo Zanoni04945642012-11-01 21:00:59 -0200609 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
610 * mode set "sequence for CRT port" document:
611 * - TP1 to TP2 time with the default value
612 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100613 *
614 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200615 */
616 I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
617 FDI_RX_PWRDN_LANE0_VAL(2) |
618 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
619
620 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000621 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100622 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200623 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Paulo Zanoni04945642012-11-01 21:00:59 -0200624 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
625 POSTING_READ(_FDI_RXA_CTL);
626 udelay(220);
627
628 /* Switch from Rawclk to PCDclk */
629 rx_ctl_val |= FDI_PCDCLK;
630 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
631
632 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200633 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
634 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200635
636 /* Start the training iterating through available voltages and emphasis,
637 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300638 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300639 /* Configure DP_TP_CTL with auto-training */
640 I915_WRITE(DP_TP_CTL(PORT_E),
641 DP_TP_CTL_FDI_AUTOTRAIN |
642 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
643 DP_TP_CTL_LINK_TRAIN_PAT1 |
644 DP_TP_CTL_ENABLE);
645
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000646 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
647 * DDI E does not support port reversal, the functionality is
648 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
649 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300650 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200651 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200652 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530653 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200654 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300655
656 udelay(600);
657
Paulo Zanoni04945642012-11-01 21:00:59 -0200658 /* Program PCH FDI Receiver TU */
659 I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300660
Paulo Zanoni04945642012-11-01 21:00:59 -0200661 /* Enable PCH FDI Receiver with auto-training */
662 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
663 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
664 POSTING_READ(_FDI_RXA_CTL);
665
666 /* Wait for FDI receiver lane calibration */
667 udelay(30);
668
669 /* Unset FDI_RX_MISC pwrdn lanes */
670 temp = I915_READ(_FDI_RXA_MISC);
671 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
672 I915_WRITE(_FDI_RXA_MISC, temp);
673 POSTING_READ(_FDI_RXA_MISC);
674
675 /* Wait for FDI auto training time */
676 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300677
678 temp = I915_READ(DP_TP_STATUS(PORT_E));
679 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200680 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300681
682 /* Enable normal pixel sending for FDI */
683 I915_WRITE(DP_TP_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200684 DP_TP_CTL_FDI_AUTOTRAIN |
685 DP_TP_CTL_LINK_TRAIN_NORMAL |
686 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
687 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300688
Paulo Zanoni04945642012-11-01 21:00:59 -0200689 return;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300690 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200691
Paulo Zanoni248138b2012-11-29 11:29:31 -0200692 temp = I915_READ(DDI_BUF_CTL(PORT_E));
693 temp &= ~DDI_BUF_CTL_ENABLE;
694 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
695 POSTING_READ(DDI_BUF_CTL(PORT_E));
696
Paulo Zanoni04945642012-11-01 21:00:59 -0200697 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200698 temp = I915_READ(DP_TP_CTL(PORT_E));
699 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
700 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
701 I915_WRITE(DP_TP_CTL(PORT_E), temp);
702 POSTING_READ(DP_TP_CTL(PORT_E));
703
704 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200705
706 rx_ctl_val &= ~FDI_RX_ENABLE;
707 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200708 POSTING_READ(_FDI_RXA_CTL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200709
710 /* Reset FDI_RX_MISC pwrdn lanes */
711 temp = I915_READ(_FDI_RXA_MISC);
712 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
713 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
714 I915_WRITE(_FDI_RXA_MISC, temp);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200715 POSTING_READ(_FDI_RXA_MISC);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300716 }
717
Paulo Zanoni04945642012-11-01 21:00:59 -0200718 DRM_ERROR("FDI link training failed!\n");
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300719}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300720
Dave Airlie44905a22014-05-02 13:36:43 +1000721void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
722{
723 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
724 struct intel_digital_port *intel_dig_port =
725 enc_to_dig_port(&encoder->base);
726
727 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530728 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Dave Airlie44905a22014-05-02 13:36:43 +1000729 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
730
731}
732
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300733static struct intel_encoder *
734intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
735{
736 struct drm_device *dev = crtc->dev;
737 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
738 struct intel_encoder *intel_encoder, *ret = NULL;
739 int num_encoders = 0;
740
741 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
742 ret = intel_encoder;
743 num_encoders++;
744 }
745
746 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300747 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
748 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300749
750 BUG_ON(ret == NULL);
751 return ret;
752}
753
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530754struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200755intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200756{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200757 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
758 struct intel_encoder *ret = NULL;
759 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300760 struct drm_connector *connector;
761 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200762 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200763 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200764
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200765 state = crtc_state->base.state;
766
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300767 for_each_connector_in_state(state, connector, connector_state, i) {
768 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200769 continue;
770
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300771 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200772 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200773 }
774
775 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
776 pipe_name(crtc->pipe));
777
778 BUG_ON(ret == NULL);
779 return ret;
780}
781
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100782#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100783#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100784
785#define P_MIN 2
786#define P_MAX 64
787#define P_INC 2
788
789/* Constraints for PLL good behavior */
790#define REF_MIN 48
791#define REF_MAX 400
792#define VCO_MIN 2400
793#define VCO_MAX 4800
794
Damien Lespiau27893392014-09-04 12:27:23 +0100795#define abs_diff(a, b) ({ \
796 typeof(a) __a = (a); \
797 typeof(b) __b = (b); \
798 (void) (&__a == &__b); \
799 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100800
Damien Lespiau63582982015-05-07 18:38:46 +0100801struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100802 unsigned p, n2, r2;
803};
804
Damien Lespiau63582982015-05-07 18:38:46 +0100805static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300806{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100807 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300808
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100809 switch (clock) {
810 case 25175000:
811 case 25200000:
812 case 27000000:
813 case 27027000:
814 case 37762500:
815 case 37800000:
816 case 40500000:
817 case 40541000:
818 case 54000000:
819 case 54054000:
820 case 59341000:
821 case 59400000:
822 case 72000000:
823 case 74176000:
824 case 74250000:
825 case 81000000:
826 case 81081000:
827 case 89012000:
828 case 89100000:
829 case 108000000:
830 case 108108000:
831 case 111264000:
832 case 111375000:
833 case 148352000:
834 case 148500000:
835 case 162000000:
836 case 162162000:
837 case 222525000:
838 case 222750000:
839 case 296703000:
840 case 297000000:
841 budget = 0;
842 break;
843 case 233500000:
844 case 245250000:
845 case 247750000:
846 case 253250000:
847 case 298000000:
848 budget = 1500;
849 break;
850 case 169128000:
851 case 169500000:
852 case 179500000:
853 case 202000000:
854 budget = 2000;
855 break;
856 case 256250000:
857 case 262500000:
858 case 270000000:
859 case 272500000:
860 case 273750000:
861 case 280750000:
862 case 281250000:
863 case 286000000:
864 case 291750000:
865 budget = 4000;
866 break;
867 case 267250000:
868 case 268500000:
869 budget = 5000;
870 break;
871 default:
872 budget = 1000;
873 break;
874 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300875
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100876 return budget;
877}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300878
Damien Lespiau63582982015-05-07 18:38:46 +0100879static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
880 unsigned r2, unsigned n2, unsigned p,
881 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100882{
883 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300884
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100885 /* No best (r,n,p) yet */
886 if (best->p == 0) {
887 best->p = p;
888 best->n2 = n2;
889 best->r2 = r2;
890 return;
891 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300892
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100893 /*
894 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
895 * freq2k.
896 *
897 * delta = 1e6 *
898 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
899 * freq2k;
900 *
901 * and we would like delta <= budget.
902 *
903 * If the discrepancy is above the PPM-based budget, always prefer to
904 * improve upon the previous solution. However, if you're within the
905 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
906 */
907 a = freq2k * budget * p * r2;
908 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100909 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
910 diff_best = abs_diff(freq2k * best->p * best->r2,
911 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100912 c = 1000000 * diff;
913 d = 1000000 * diff_best;
914
915 if (a < c && b < d) {
916 /* If both are above the budget, pick the closer */
917 if (best->p * best->r2 * diff < p * r2 * diff_best) {
918 best->p = p;
919 best->n2 = n2;
920 best->r2 = r2;
921 }
922 } else if (a >= c && b < d) {
923 /* If A is below the threshold but B is above it? Update. */
924 best->p = p;
925 best->n2 = n2;
926 best->r2 = r2;
927 } else if (a >= c && b >= d) {
928 /* Both are below the limit, so pick the higher n2/(r2*r2) */
929 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
930 best->p = p;
931 best->n2 = n2;
932 best->r2 = r2;
933 }
934 }
935 /* Otherwise a < c && b >= d, do nothing */
936}
937
Damien Lespiau63582982015-05-07 18:38:46 +0100938static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, int reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800939{
940 int refclk = LC_FREQ;
941 int n, p, r;
942 u32 wrpll;
943
944 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300945 switch (wrpll & WRPLL_PLL_REF_MASK) {
946 case WRPLL_PLL_SSC:
947 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800948 /*
949 * We could calculate spread here, but our checking
950 * code only cares about 5% accuracy, and spread is a max of
951 * 0.5% downspread.
952 */
953 refclk = 135;
954 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300955 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800956 refclk = LC_FREQ;
957 break;
958 default:
959 WARN(1, "bad wrpll refclk\n");
960 return 0;
961 }
962
963 r = wrpll & WRPLL_DIVIDER_REF_MASK;
964 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
965 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
966
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800967 /* Convert to KHz, p & r have a fixed point portion */
968 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800969}
970
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000971static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
972 uint32_t dpll)
973{
974 uint32_t cfgcr1_reg, cfgcr2_reg;
975 uint32_t cfgcr1_val, cfgcr2_val;
976 uint32_t p0, p1, p2, dco_freq;
977
978 cfgcr1_reg = GET_CFG_CR1_REG(dpll);
979 cfgcr2_reg = GET_CFG_CR2_REG(dpll);
980
981 cfgcr1_val = I915_READ(cfgcr1_reg);
982 cfgcr2_val = I915_READ(cfgcr2_reg);
983
984 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
985 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
986
987 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
988 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
989 else
990 p1 = 1;
991
992
993 switch (p0) {
994 case DPLL_CFGCR2_PDIV_1:
995 p0 = 1;
996 break;
997 case DPLL_CFGCR2_PDIV_2:
998 p0 = 2;
999 break;
1000 case DPLL_CFGCR2_PDIV_3:
1001 p0 = 3;
1002 break;
1003 case DPLL_CFGCR2_PDIV_7:
1004 p0 = 7;
1005 break;
1006 }
1007
1008 switch (p2) {
1009 case DPLL_CFGCR2_KDIV_5:
1010 p2 = 5;
1011 break;
1012 case DPLL_CFGCR2_KDIV_2:
1013 p2 = 2;
1014 break;
1015 case DPLL_CFGCR2_KDIV_3:
1016 p2 = 3;
1017 break;
1018 case DPLL_CFGCR2_KDIV_1:
1019 p2 = 1;
1020 break;
1021 }
1022
1023 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1024
1025 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1026 1000) / 0x8000;
1027
1028 return dco_freq / (p0 * p1 * p2 * 5);
1029}
1030
Ville Syrjälä398a0172015-06-30 15:33:51 +03001031static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1032{
1033 int dotclock;
1034
1035 if (pipe_config->has_pch_encoder)
1036 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1037 &pipe_config->fdi_m_n);
1038 else if (pipe_config->has_dp_encoder)
1039 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1040 &pipe_config->dp_m_n);
1041 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1042 dotclock = pipe_config->port_clock * 2 / 3;
1043 else
1044 dotclock = pipe_config->port_clock;
1045
1046 if (pipe_config->pixel_multiplier)
1047 dotclock /= pipe_config->pixel_multiplier;
1048
1049 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1050}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001051
1052static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001053 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001054{
1055 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001056 int link_clock = 0;
1057 uint32_t dpll_ctl1, dpll;
1058
Damien Lespiau134ffa42014-11-14 17:24:34 +00001059 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001060
1061 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1062
1063 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1064 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1065 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001066 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1067 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001068
1069 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001070 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001071 link_clock = 81000;
1072 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001073 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301074 link_clock = 108000;
1075 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001076 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001077 link_clock = 135000;
1078 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001079 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301080 link_clock = 162000;
1081 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001082 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301083 link_clock = 216000;
1084 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001085 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001086 link_clock = 270000;
1087 break;
1088 default:
1089 WARN(1, "Unsupported link rate\n");
1090 break;
1091 }
1092 link_clock *= 2;
1093 }
1094
1095 pipe_config->port_clock = link_clock;
1096
Ville Syrjälä398a0172015-06-30 15:33:51 +03001097 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001098}
1099
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001100static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001101 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001102{
1103 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001104 int link_clock = 0;
1105 u32 val, pll;
1106
Daniel Vetter26804af2014-06-25 22:01:55 +03001107 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001108 switch (val & PORT_CLK_SEL_MASK) {
1109 case PORT_CLK_SEL_LCPLL_810:
1110 link_clock = 81000;
1111 break;
1112 case PORT_CLK_SEL_LCPLL_1350:
1113 link_clock = 135000;
1114 break;
1115 case PORT_CLK_SEL_LCPLL_2700:
1116 link_clock = 270000;
1117 break;
1118 case PORT_CLK_SEL_WRPLL1:
Damien Lespiau63582982015-05-07 18:38:46 +01001119 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL1);
Jesse Barnes11578552014-01-21 12:42:10 -08001120 break;
1121 case PORT_CLK_SEL_WRPLL2:
Damien Lespiau63582982015-05-07 18:38:46 +01001122 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL2);
Jesse Barnes11578552014-01-21 12:42:10 -08001123 break;
1124 case PORT_CLK_SEL_SPLL:
1125 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1126 if (pll == SPLL_PLL_FREQ_810MHz)
1127 link_clock = 81000;
1128 else if (pll == SPLL_PLL_FREQ_1350MHz)
1129 link_clock = 135000;
1130 else if (pll == SPLL_PLL_FREQ_2700MHz)
1131 link_clock = 270000;
1132 else {
1133 WARN(1, "bad spll freq\n");
1134 return;
1135 }
1136 break;
1137 default:
1138 WARN(1, "bad port clock sel\n");
1139 return;
1140 }
1141
1142 pipe_config->port_clock = link_clock * 2;
1143
Ville Syrjälä398a0172015-06-30 15:33:51 +03001144 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001145}
1146
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301147static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1148 enum intel_dpll_id dpll)
1149{
Imre Deakaa610dc2015-06-22 23:35:52 +03001150 struct intel_shared_dpll *pll;
1151 struct intel_dpll_hw_state *state;
1152 intel_clock_t clock;
1153
1154 /* For DDI ports we always use a shared PLL. */
1155 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1156 return 0;
1157
1158 pll = &dev_priv->shared_dplls[dpll];
1159 state = &pll->config.hw_state;
1160
1161 clock.m1 = 2;
1162 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1163 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1164 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1165 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1166 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1167 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1168
1169 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301170}
1171
1172static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1173 struct intel_crtc_state *pipe_config)
1174{
1175 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1176 enum port port = intel_ddi_get_encoder_port(encoder);
1177 uint32_t dpll = port;
1178
Ville Syrjälä398a0172015-06-30 15:33:51 +03001179 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301180
Ville Syrjälä398a0172015-06-30 15:33:51 +03001181 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301182}
1183
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001184void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001185 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001186{
Damien Lespiau22606a12014-12-12 14:26:57 +00001187 struct drm_device *dev = encoder->base.dev;
1188
1189 if (INTEL_INFO(dev)->gen <= 8)
1190 hsw_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301191 else if (IS_SKYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001192 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301193 else if (IS_BROXTON(dev))
1194 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001195}
1196
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001197static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001198hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1199 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001200{
1201 uint64_t freq2k;
1202 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001203 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001204 unsigned budget;
1205
1206 freq2k = clock / 100;
1207
Damien Lespiau63582982015-05-07 18:38:46 +01001208 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001209
1210 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1211 * and directly pass the LC PLL to it. */
1212 if (freq2k == 5400000) {
1213 *n2_out = 2;
1214 *p_out = 1;
1215 *r2_out = 2;
1216 return;
1217 }
1218
1219 /*
1220 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1221 * the WR PLL.
1222 *
1223 * We want R so that REF_MIN <= Ref <= REF_MAX.
1224 * Injecting R2 = 2 * R gives:
1225 * REF_MAX * r2 > LC_FREQ * 2 and
1226 * REF_MIN * r2 < LC_FREQ * 2
1227 *
1228 * Which means the desired boundaries for r2 are:
1229 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1230 *
1231 */
1232 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1233 r2 <= LC_FREQ * 2 / REF_MIN;
1234 r2++) {
1235
1236 /*
1237 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1238 *
1239 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1240 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1241 * VCO_MAX * r2 > n2 * LC_FREQ and
1242 * VCO_MIN * r2 < n2 * LC_FREQ)
1243 *
1244 * Which means the desired boundaries for n2 are:
1245 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1246 */
1247 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1248 n2 <= VCO_MAX * r2 / LC_FREQ;
1249 n2++) {
1250
1251 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001252 hsw_wrpll_update_rnp(freq2k, budget,
1253 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001254 }
1255 }
1256
1257 *n2_out = best.n2;
1258 *p_out = best.p;
1259 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001260}
1261
Damien Lespiau0220ab62014-07-29 18:06:22 +01001262static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001263hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001264 struct intel_crtc_state *crtc_state,
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001265 struct intel_encoder *intel_encoder,
1266 int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001267{
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001268 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001269 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001270 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001271 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001272
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001273 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001274
Daniel Vetter114fe482014-06-25 22:01:48 +03001275 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001276 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1277 WRPLL_DIVIDER_POST(p);
1278
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001279 memset(&crtc_state->dpll_hw_state, 0,
1280 sizeof(crtc_state->dpll_hw_state));
1281
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001282 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001283
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001284 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001285 if (pll == NULL) {
1286 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1287 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001288 return false;
1289 }
1290
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001291 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001292 }
1293
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001294 return true;
1295}
1296
Damien Lespiaudc253812015-06-25 16:15:06 +01001297struct skl_wrpll_context {
1298 uint64_t min_deviation; /* current minimal deviation */
1299 uint64_t central_freq; /* chosen central freq */
1300 uint64_t dco_freq; /* chosen dco freq */
1301 unsigned int p; /* chosen divider */
1302};
1303
1304static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1305{
1306 memset(ctx, 0, sizeof(*ctx));
1307
1308 ctx->min_deviation = U64_MAX;
1309}
1310
1311/* DCO freq must be within +1%/-6% of the DCO central freq */
1312#define SKL_DCO_MAX_PDEVIATION 100
1313#define SKL_DCO_MAX_NDEVIATION 600
1314
1315static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1316 uint64_t central_freq,
1317 uint64_t dco_freq,
1318 unsigned int divider)
1319{
1320 uint64_t deviation;
1321
1322 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1323 central_freq);
1324
1325 /* positive deviation */
1326 if (dco_freq >= central_freq) {
1327 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1328 deviation < ctx->min_deviation) {
1329 ctx->min_deviation = deviation;
1330 ctx->central_freq = central_freq;
1331 ctx->dco_freq = dco_freq;
1332 ctx->p = divider;
1333 }
1334 /* negative deviation */
1335 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1336 deviation < ctx->min_deviation) {
1337 ctx->min_deviation = deviation;
1338 ctx->central_freq = central_freq;
1339 ctx->dco_freq = dco_freq;
1340 ctx->p = divider;
1341 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001342}
1343
1344static void skl_wrpll_get_multipliers(unsigned int p,
1345 unsigned int *p0 /* out */,
1346 unsigned int *p1 /* out */,
1347 unsigned int *p2 /* out */)
1348{
1349 /* even dividers */
1350 if (p % 2 == 0) {
1351 unsigned int half = p / 2;
1352
1353 if (half == 1 || half == 2 || half == 3 || half == 5) {
1354 *p0 = 2;
1355 *p1 = 1;
1356 *p2 = half;
1357 } else if (half % 2 == 0) {
1358 *p0 = 2;
1359 *p1 = half / 2;
1360 *p2 = 2;
1361 } else if (half % 3 == 0) {
1362 *p0 = 3;
1363 *p1 = half / 3;
1364 *p2 = 2;
1365 } else if (half % 7 == 0) {
1366 *p0 = 7;
1367 *p1 = half / 7;
1368 *p2 = 2;
1369 }
1370 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1371 *p0 = 3;
1372 *p1 = 1;
1373 *p2 = p / 3;
1374 } else if (p == 5 || p == 7) {
1375 *p0 = p;
1376 *p1 = 1;
1377 *p2 = 1;
1378 } else if (p == 15) {
1379 *p0 = 3;
1380 *p1 = 1;
1381 *p2 = 5;
1382 } else if (p == 21) {
1383 *p0 = 7;
1384 *p1 = 1;
1385 *p2 = 3;
1386 } else if (p == 35) {
1387 *p0 = 7;
1388 *p1 = 1;
1389 *p2 = 5;
1390 }
1391}
1392
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001393struct skl_wrpll_params {
1394 uint32_t dco_fraction;
1395 uint32_t dco_integer;
1396 uint32_t qdiv_ratio;
1397 uint32_t qdiv_mode;
1398 uint32_t kdiv;
1399 uint32_t pdiv;
1400 uint32_t central_freq;
1401};
1402
Damien Lespiau76516fb2015-05-07 18:38:42 +01001403static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1404 uint64_t afe_clock,
1405 uint64_t central_freq,
1406 uint32_t p0, uint32_t p1, uint32_t p2)
1407{
1408 uint64_t dco_freq;
1409
Damien Lespiau76516fb2015-05-07 18:38:42 +01001410 switch (central_freq) {
1411 case 9600000000ULL:
1412 params->central_freq = 0;
1413 break;
1414 case 9000000000ULL:
1415 params->central_freq = 1;
1416 break;
1417 case 8400000000ULL:
1418 params->central_freq = 3;
1419 }
1420
1421 switch (p0) {
1422 case 1:
1423 params->pdiv = 0;
1424 break;
1425 case 2:
1426 params->pdiv = 1;
1427 break;
1428 case 3:
1429 params->pdiv = 2;
1430 break;
1431 case 7:
1432 params->pdiv = 4;
1433 break;
1434 default:
1435 WARN(1, "Incorrect PDiv\n");
1436 }
1437
1438 switch (p2) {
1439 case 5:
1440 params->kdiv = 0;
1441 break;
1442 case 2:
1443 params->kdiv = 1;
1444 break;
1445 case 3:
1446 params->kdiv = 2;
1447 break;
1448 case 1:
1449 params->kdiv = 3;
1450 break;
1451 default:
1452 WARN(1, "Incorrect KDiv\n");
1453 }
1454
1455 params->qdiv_ratio = p1;
1456 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1457
1458 dco_freq = p0 * p1 * p2 * afe_clock;
1459
1460 /*
1461 * Intermediate values are in Hz.
1462 * Divide by MHz to match bsepc
1463 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001464 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001465 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001466 div_u64((div_u64(dco_freq, 24) -
1467 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001468}
1469
Damien Lespiau318bd822015-05-07 18:38:40 +01001470static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001471skl_ddi_calculate_wrpll(int clock /* in Hz */,
1472 struct skl_wrpll_params *wrpll_params)
1473{
1474 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001475 uint64_t dco_central_freq[3] = {8400000000ULL,
1476 9000000000ULL,
1477 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001478 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1479 24, 28, 30, 32, 36, 40, 42, 44,
1480 48, 52, 54, 56, 60, 64, 66, 68,
1481 70, 72, 76, 78, 80, 84, 88, 90,
1482 92, 96, 98 };
1483 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1484 static const struct {
1485 const int *list;
1486 int n_dividers;
1487 } dividers[] = {
1488 { even_dividers, ARRAY_SIZE(even_dividers) },
1489 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1490 };
1491 struct skl_wrpll_context ctx;
1492 unsigned int dco, d, i;
1493 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001494
Damien Lespiaudc253812015-06-25 16:15:06 +01001495 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001496
Damien Lespiaudc253812015-06-25 16:15:06 +01001497 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1498 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1499 for (i = 0; i < dividers[d].n_dividers; i++) {
1500 unsigned int p = dividers[d].list[i];
1501 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001502
Damien Lespiaudc253812015-06-25 16:15:06 +01001503 skl_wrpll_try_divider(&ctx,
1504 dco_central_freq[dco],
1505 dco_freq,
1506 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001507 /*
1508 * Skip the remaining dividers if we're sure to
1509 * have found the definitive divider, we can't
1510 * improve a 0 deviation.
1511 */
1512 if (ctx.min_deviation == 0)
1513 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001514 }
1515 }
Damien Lespiau267db662015-06-25 16:19:24 +01001516
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001517skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001518 /*
1519 * If a solution is found with an even divider, prefer
1520 * this one.
1521 */
1522 if (d == 0 && ctx.p)
1523 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001524 }
1525
Damien Lespiaudc253812015-06-25 16:15:06 +01001526 if (!ctx.p) {
1527 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001528 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001529 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001530
Damien Lespiaudc253812015-06-25 16:15:06 +01001531 /*
1532 * gcc incorrectly analyses that these can be used without being
1533 * initialized. To be fair, it's hard to guess.
1534 */
1535 p0 = p1 = p2 = 0;
1536 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1537 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1538 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001539
Damien Lespiau318bd822015-05-07 18:38:40 +01001540 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001541}
1542
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001543static bool
1544skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001545 struct intel_crtc_state *crtc_state,
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001546 struct intel_encoder *intel_encoder,
1547 int clock)
1548{
1549 struct intel_shared_dpll *pll;
1550 uint32_t ctrl1, cfgcr1, cfgcr2;
1551
1552 /*
1553 * See comment in intel_dpll_hw_state to understand why we always use 0
1554 * as the DPLL id in this function.
1555 */
1556
1557 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1558
1559 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1560 struct skl_wrpll_params wrpll_params = { 0, };
1561
1562 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1563
Damien Lespiau318bd822015-05-07 18:38:40 +01001564 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1565 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001566
1567 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1568 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1569 wrpll_params.dco_integer;
1570
1571 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1572 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1573 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1574 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1575 wrpll_params.central_freq;
1576 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
1577 struct drm_encoder *encoder = &intel_encoder->base;
1578 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1579
1580 switch (intel_dp->link_bw) {
1581 case DP_LINK_BW_1_62:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001582 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001583 break;
1584 case DP_LINK_BW_2_7:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001585 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001586 break;
1587 case DP_LINK_BW_5_4:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001588 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001589 break;
1590 }
1591
1592 cfgcr1 = cfgcr2 = 0;
1593 } else /* eDP */
1594 return true;
1595
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001596 memset(&crtc_state->dpll_hw_state, 0,
1597 sizeof(crtc_state->dpll_hw_state));
1598
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001599 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1600 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1601 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001602
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001603 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001604 if (pll == NULL) {
1605 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1606 pipe_name(intel_crtc->pipe));
1607 return false;
1608 }
1609
1610 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001611 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001612
1613 return true;
1614}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001615
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301616/* bxt clock parameters */
1617struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301618 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301619 uint32_t p1;
1620 uint32_t p2;
1621 uint32_t m2_int;
1622 uint32_t m2_frac;
1623 bool m2_frac_en;
1624 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301625};
1626
1627/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301628static const struct bxt_clk_div bxt_dp_clk_val[] = {
1629 {162000, 4, 2, 32, 1677722, 1, 1},
1630 {270000, 4, 1, 27, 0, 0, 1},
1631 {540000, 2, 1, 27, 0, 0, 1},
1632 {216000, 3, 2, 32, 1677722, 1, 1},
1633 {243000, 4, 1, 24, 1258291, 1, 1},
1634 {324000, 4, 1, 32, 1677722, 1, 1},
1635 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301636};
1637
1638static bool
1639bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1640 struct intel_crtc_state *crtc_state,
1641 struct intel_encoder *intel_encoder,
1642 int clock)
1643{
1644 struct intel_shared_dpll *pll;
1645 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301646 int vco = 0;
1647 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301648 uint32_t lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301649
1650 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1651 intel_clock_t best_clock;
1652
1653 /* Calculate HDMI div */
1654 /*
1655 * FIXME: tie the following calculation into
1656 * i9xx_crtc_compute_clock
1657 */
1658 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1659 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1660 clock, pipe_name(intel_crtc->pipe));
1661 return false;
1662 }
1663
1664 clk_div.p1 = best_clock.p1;
1665 clk_div.p2 = best_clock.p2;
1666 WARN_ON(best_clock.m1 != 2);
1667 clk_div.n = best_clock.n;
1668 clk_div.m2_int = best_clock.m2 >> 22;
1669 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1670 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1671
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301672 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301673 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1674 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301675 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301676
Sonika Jindal64987fc2015-05-26 17:50:13 +05301677 clk_div = bxt_dp_clk_val[0];
1678 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1679 if (bxt_dp_clk_val[i].clock == clock) {
1680 clk_div = bxt_dp_clk_val[i];
1681 break;
1682 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301683 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301684 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1685 }
1686
Vandana Kannane6292552015-07-01 17:02:57 +05301687 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301688 prop_coef = 4;
1689 int_coef = 9;
1690 gain_ctl = 3;
1691 targ_cnt = 8;
1692 } else if ((vco > 5400000 && vco < 6200000) ||
1693 (vco >= 4800000 && vco < 5400000)) {
1694 prop_coef = 5;
1695 int_coef = 11;
1696 gain_ctl = 3;
1697 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301698 } else if (vco == 5400000) {
1699 prop_coef = 3;
1700 int_coef = 8;
1701 gain_ctl = 1;
1702 targ_cnt = 9;
1703 } else {
1704 DRM_ERROR("Invalid VCO\n");
1705 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301706 }
1707
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001708 memset(&crtc_state->dpll_hw_state, 0,
1709 sizeof(crtc_state->dpll_hw_state));
1710
Vandana Kannane0681e32015-05-13 12:20:35 +05301711 if (clock > 270000)
1712 lanestagger = 0x18;
1713 else if (clock > 135000)
1714 lanestagger = 0x0d;
1715 else if (clock > 67000)
1716 lanestagger = 0x07;
1717 else if (clock > 33000)
1718 lanestagger = 0x04;
1719 else
1720 lanestagger = 0x02;
1721
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301722 crtc_state->dpll_hw_state.ebb0 =
1723 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1724 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1725 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1726 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1727
1728 if (clk_div.m2_frac_en)
1729 crtc_state->dpll_hw_state.pll3 =
1730 PORT_PLL_M2_FRAC_ENABLE;
1731
1732 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301733 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301734 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301735 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301736
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301737 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1738
Imre Deak05712c12015-06-18 17:25:54 +03001739 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1740
Vandana Kannane6292552015-07-01 17:02:57 +05301741 crtc_state->dpll_hw_state.pll10 =
1742 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1743 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301744
Imre Deak05712c12015-06-18 17:25:54 +03001745 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1746
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301747 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301748 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301749
1750 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1751 if (pll == NULL) {
1752 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1753 pipe_name(intel_crtc->pipe));
1754 return false;
1755 }
1756
1757 /* shared DPLL id 0 is DPLL A */
1758 crtc_state->ddi_pll_sel = pll->id;
1759
1760 return true;
1761}
1762
Damien Lespiau0220ab62014-07-29 18:06:22 +01001763/*
1764 * Tries to find a *shared* PLL for the CRTC and store it in
1765 * intel_crtc->ddi_pll_sel.
1766 *
1767 * For private DPLLs, compute_config() should do the selection for us. This
1768 * function should be folded into compute_config() eventually.
1769 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001770bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1771 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001772{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001773 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001774 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001775 intel_ddi_get_crtc_new_encoder(crtc_state);
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001776 int clock = crtc_state->port_clock;
Damien Lespiau0220ab62014-07-29 18:06:22 +01001777
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001778 if (IS_SKYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001779 return skl_ddi_pll_select(intel_crtc, crtc_state,
1780 intel_encoder, clock);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301781 else if (IS_BROXTON(dev))
1782 return bxt_ddi_pll_select(intel_crtc, crtc_state,
1783 intel_encoder, clock);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001784 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001785 return hsw_ddi_pll_select(intel_crtc, crtc_state,
1786 intel_encoder, clock);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001787}
1788
Paulo Zanonidae84792012-10-15 15:51:30 -03001789void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1790{
1791 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1792 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1793 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001794 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001795 int type = intel_encoder->type;
1796 uint32_t temp;
1797
Dave Airlie0e32b392014-05-02 14:02:48 +10001798 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001799 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001800 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001801 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001802 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001803 break;
1804 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001805 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001806 break;
1807 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001808 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001809 break;
1810 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001811 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001812 break;
1813 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001814 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001815 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001816 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001817 }
1818}
1819
Dave Airlie0e32b392014-05-02 14:02:48 +10001820void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1821{
1822 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1823 struct drm_device *dev = crtc->dev;
1824 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001825 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001826 uint32_t temp;
1827 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1828 if (state == true)
1829 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1830 else
1831 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1832 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1833}
1834
Damien Lespiau8228c252013-03-07 15:30:27 +00001835void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001836{
1837 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1838 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001839 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001840 struct drm_device *dev = crtc->dev;
1841 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001842 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001843 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001844 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001845 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001846 uint32_t temp;
1847
Paulo Zanoniad80a812012-10-24 16:06:19 -02001848 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1849 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001850 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001851
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001852 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001853 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001854 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001855 break;
1856 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001857 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001858 break;
1859 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001860 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001861 break;
1862 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001863 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001864 break;
1865 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001866 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001867 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001868
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001869 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001870 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001871 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001872 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c2012-08-08 14:15:28 -03001873
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001874 if (cpu_transcoder == TRANSCODER_EDP) {
1875 switch (pipe) {
1876 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001877 /* On Haswell, can only use the always-on power well for
1878 * eDP when not using the panel fitter, and when not
1879 * using motion blur mitigation (which we don't
1880 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001881 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001882 (intel_crtc->config->pch_pfit.enabled ||
1883 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001884 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1885 else
1886 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001887 break;
1888 case PIPE_B:
1889 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1890 break;
1891 case PIPE_C:
1892 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1893 break;
1894 default:
1895 BUG();
1896 break;
1897 }
1898 }
1899
Paulo Zanoni7739c332012-10-15 15:51:29 -03001900 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001901 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001902 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001903 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001904 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001905
Paulo Zanoni7739c332012-10-15 15:51:29 -03001906 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001907 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001908 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001909
1910 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1911 type == INTEL_OUTPUT_EDP) {
1912 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1913
Dave Airlie0e32b392014-05-02 14:02:48 +10001914 if (intel_dp->is_mst) {
1915 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1916 } else
1917 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1918
1919 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
1920 } else if (type == INTEL_OUTPUT_DP_MST) {
1921 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1922
1923 if (intel_dp->is_mst) {
1924 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1925 } else
1926 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001927
Daniel Vetter17aa6be2013-04-30 14:01:40 +02001928 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001929 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001930 WARN(1, "Invalid encoder type %d for pipe %c\n",
1931 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001932 }
1933
Paulo Zanoniad80a812012-10-24 16:06:19 -02001934 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001935}
1936
Paulo Zanoniad80a812012-10-24 16:06:19 -02001937void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1938 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001939{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001940 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001941 uint32_t val = I915_READ(reg);
1942
Dave Airlie0e32b392014-05-02 14:02:48 +10001943 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001944 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001945 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001946}
1947
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001948bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1949{
1950 struct drm_device *dev = intel_connector->base.dev;
1951 struct drm_i915_private *dev_priv = dev->dev_private;
1952 struct intel_encoder *intel_encoder = intel_connector->encoder;
1953 int type = intel_connector->base.connector_type;
1954 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1955 enum pipe pipe = 0;
1956 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001957 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001958 uint32_t tmp;
1959
Paulo Zanoni882244a2014-04-01 14:55:12 -03001960 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001961 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001962 return false;
1963
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001964 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1965 return false;
1966
1967 if (port == PORT_A)
1968 cpu_transcoder = TRANSCODER_EDP;
1969 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001970 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001971
1972 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1973
1974 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1975 case TRANS_DDI_MODE_SELECT_HDMI:
1976 case TRANS_DDI_MODE_SELECT_DVI:
1977 return (type == DRM_MODE_CONNECTOR_HDMIA);
1978
1979 case TRANS_DDI_MODE_SELECT_DP_SST:
1980 if (type == DRM_MODE_CONNECTOR_eDP)
1981 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001982 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001983 case TRANS_DDI_MODE_SELECT_DP_MST:
1984 /* if the transcoder is in MST state then
1985 * connector isn't connected */
1986 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001987
1988 case TRANS_DDI_MODE_SELECT_FDI:
1989 return (type == DRM_MODE_CONNECTOR_VGA);
1990
1991 default:
1992 return false;
1993 }
1994}
1995
Daniel Vetter85234cd2012-07-02 13:27:29 +02001996bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1997 enum pipe *pipe)
1998{
1999 struct drm_device *dev = encoder->base.dev;
2000 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002001 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02002002 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002003 u32 tmp;
2004 int i;
2005
Imre Deak6d129be2014-03-05 16:20:54 +02002006 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002007 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02002008 return false;
2009
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002010 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002011
2012 if (!(tmp & DDI_BUF_CTL_ENABLE))
2013 return false;
2014
Paulo Zanoniad80a812012-10-24 16:06:19 -02002015 if (port == PORT_A) {
2016 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002017
Paulo Zanoniad80a812012-10-24 16:06:19 -02002018 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2019 case TRANS_DDI_EDP_INPUT_A_ON:
2020 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2021 *pipe = PIPE_A;
2022 break;
2023 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2024 *pipe = PIPE_B;
2025 break;
2026 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2027 *pipe = PIPE_C;
2028 break;
2029 }
2030
2031 return true;
2032 } else {
2033 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2034 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2035
2036 if ((tmp & TRANS_DDI_PORT_MASK)
2037 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002038 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2039 return false;
2040
Paulo Zanoniad80a812012-10-24 16:06:19 -02002041 *pipe = i;
2042 return true;
2043 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002044 }
2045 }
2046
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002047 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002048
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002049 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002050}
2051
Paulo Zanonifc914632012-10-05 12:05:54 -03002052void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2053{
2054 struct drm_crtc *crtc = &intel_crtc->base;
2055 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2056 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2057 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002058 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002059
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002060 if (cpu_transcoder != TRANSCODER_EDP)
2061 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2062 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002063}
2064
2065void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2066{
2067 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002068 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002069
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002070 if (cpu_transcoder != TRANSCODER_EDP)
2071 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2072 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002073}
2074
David Weinehallf8896f52015-06-25 11:11:03 +03002075static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2076 enum port port, int type)
2077{
2078 struct drm_i915_private *dev_priv = dev->dev_private;
2079 const struct ddi_buf_trans *ddi_translations;
2080 uint8_t iboost;
2081 int n_entries;
2082 u32 reg;
2083
2084 if (type == INTEL_OUTPUT_DISPLAYPORT) {
2085 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2086 iboost = ddi_translations[port].i_boost;
2087 } else if (type == INTEL_OUTPUT_EDP) {
2088 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2089 iboost = ddi_translations[port].i_boost;
2090 } else if (type == INTEL_OUTPUT_HDMI) {
2091 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2092 iboost = ddi_translations[port].i_boost;
2093 } else {
2094 return;
2095 }
2096
2097 /* Make sure that the requested I_boost is valid */
2098 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2099 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2100 return;
2101 }
2102
2103 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2104 reg &= ~BALANCE_LEG_MASK(port);
2105 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2106
2107 if (iboost)
2108 reg |= iboost << BALANCE_LEG_SHIFT(port);
2109 else
2110 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2111
2112 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2113}
2114
2115static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2116 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302117{
2118 struct drm_i915_private *dev_priv = dev->dev_private;
2119 const struct bxt_ddi_buf_trans *ddi_translations;
2120 u32 n_entries, i;
2121 uint32_t val;
2122
2123 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
2124 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2125 ddi_translations = bxt_ddi_translations_dp;
2126 } else if (type == INTEL_OUTPUT_HDMI) {
2127 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2128 ddi_translations = bxt_ddi_translations_hdmi;
2129 } else {
2130 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2131 type);
2132 return;
2133 }
2134
2135 /* Check if default value has to be used */
2136 if (level >= n_entries ||
2137 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2138 for (i = 0; i < n_entries; i++) {
2139 if (ddi_translations[i].default_index) {
2140 level = i;
2141 break;
2142 }
2143 }
2144 }
2145
2146 /*
2147 * While we write to the group register to program all lanes at once we
2148 * can read only lane registers and we pick lanes 0/1 for that.
2149 */
2150 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2151 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2152 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2153
2154 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2155 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2156 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2157 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2158 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2159
2160 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
2161 val &= ~UNIQE_TRANGE_EN_METHOD;
2162 if (ddi_translations[level].enable)
2163 val |= UNIQE_TRANGE_EN_METHOD;
2164 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2165
2166 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2167 val &= ~DE_EMPHASIS;
2168 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2169 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2170
2171 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2172 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2173 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2174}
2175
David Weinehallf8896f52015-06-25 11:11:03 +03002176static uint32_t translate_signal_level(int signal_levels)
2177{
2178 uint32_t level;
2179
2180 switch (signal_levels) {
2181 default:
2182 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2183 signal_levels);
2184 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2185 level = 0;
2186 break;
2187 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2188 level = 1;
2189 break;
2190 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2191 level = 2;
2192 break;
2193 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2194 level = 3;
2195 break;
2196
2197 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2198 level = 4;
2199 break;
2200 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2201 level = 5;
2202 break;
2203 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2204 level = 6;
2205 break;
2206
2207 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2208 level = 7;
2209 break;
2210 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2211 level = 8;
2212 break;
2213
2214 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2215 level = 9;
2216 break;
2217 }
2218
2219 return level;
2220}
2221
2222uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2223{
2224 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2225 struct drm_device *dev = dport->base.base.dev;
2226 struct intel_encoder *encoder = &dport->base;
2227 uint8_t train_set = intel_dp->train_set[0];
2228 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2229 DP_TRAIN_PRE_EMPHASIS_MASK);
2230 enum port port = dport->port;
2231 uint32_t level;
2232
2233 level = translate_signal_level(signal_levels);
2234
2235 if (IS_SKYLAKE(dev))
2236 skl_ddi_set_iboost(dev, level, port, encoder->type);
2237 else if (IS_BROXTON(dev))
2238 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2239
2240 return DDI_BUF_TRANS_SELECT(level);
2241}
2242
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002243static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002244{
Paulo Zanonic19b0662012-10-15 15:51:41 -03002245 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002246 struct drm_device *dev = encoder->dev;
2247 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002248 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002249 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002250 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302251 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002252
2253 if (type == INTEL_OUTPUT_EDP) {
2254 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01002255 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002256 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002257
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002258 if (IS_SKYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002259 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002260 uint32_t val;
2261
Damien Lespiau5416d872014-11-14 17:24:33 +00002262 /*
2263 * DPLL0 is used for eDP and is the only "private" DPLL (as
2264 * opposed to shared) on SKL
2265 */
2266 if (type == INTEL_OUTPUT_EDP) {
2267 WARN_ON(dpll != SKL_DPLL0);
2268
2269 val = I915_READ(DPLL_CTRL1);
2270
2271 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2272 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002273 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002274 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002275
2276 I915_WRITE(DPLL_CTRL1, val);
2277 POSTING_READ(DPLL_CTRL1);
2278 }
2279
2280 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002281 val = I915_READ(DPLL_CTRL2);
2282
2283 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2284 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2285 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2286 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2287
2288 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002289
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302290 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002291 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2292 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002293 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002294
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002295 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002296 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002297
Dave Airlie44905a22014-05-02 13:36:43 +10002298 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002299
2300 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2301 intel_dp_start_link_train(intel_dp);
2302 intel_dp_complete_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002303 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002304 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002305 } else if (type == INTEL_OUTPUT_HDMI) {
2306 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2307
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302308 if (IS_BROXTON(dev)) {
2309 hdmi_level = dev_priv->vbt.
2310 ddi_port_info[port].hdmi_level_shift;
2311 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2312 INTEL_OUTPUT_HDMI);
2313 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002314 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002315 crtc->config->has_hdmi_sink,
2316 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002317 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002318}
2319
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002320static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002321{
2322 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002323 struct drm_device *dev = encoder->dev;
2324 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002325 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002326 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002327 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002328 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002329
2330 val = I915_READ(DDI_BUF_CTL(port));
2331 if (val & DDI_BUF_CTL_ENABLE) {
2332 val &= ~DDI_BUF_CTL_ENABLE;
2333 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002334 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002335 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002336
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002337 val = I915_READ(DP_TP_CTL(port));
2338 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2339 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2340 I915_WRITE(DP_TP_CTL(port), val);
2341
2342 if (wait)
2343 intel_wait_ddi_buf_idle(dev_priv, port);
2344
Jani Nikula76bb80e2013-11-15 15:29:57 +02002345 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002346 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002347 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002348 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002349 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002350 }
2351
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002352 if (IS_SKYLAKE(dev))
2353 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2354 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302355 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002356 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002357}
2358
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002359static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002360{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002361 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002362 struct drm_crtc *crtc = encoder->crtc;
2363 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002364 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002365 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002366 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2367 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002368
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002369 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002370 struct intel_digital_port *intel_dig_port =
2371 enc_to_dig_port(encoder);
2372
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002373 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2374 * are ignored so nothing special needs to be done besides
2375 * enabling the port.
2376 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002377 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002378 intel_dig_port->saved_port_bits |
2379 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002380 } else if (type == INTEL_OUTPUT_EDP) {
2381 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2382
Vandana Kannan23f08d82014-11-13 14:55:22 +00002383 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002384 intel_dp_stop_link_train(intel_dp);
2385
Daniel Vetter4be73782014-01-17 14:39:48 +01002386 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002387 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302388 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002389 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002390
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002391 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002392 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002393 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002394 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002395}
2396
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002397static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002398{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002399 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002400 struct drm_crtc *crtc = encoder->crtc;
2401 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002402 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002403 struct drm_device *dev = encoder->dev;
2404 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002405
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002406 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002407 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002408 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2409 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002410
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002411 if (type == INTEL_OUTPUT_EDP) {
2412 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2413
Vandana Kannanc3955782015-01-22 15:17:40 +05302414 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002415 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002416 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002417 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002418}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002419
Daniel Vettere0b01be2014-06-25 22:02:01 +03002420static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2421 struct intel_shared_dpll *pll)
2422{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002423 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002424 POSTING_READ(WRPLL_CTL(pll->id));
2425 udelay(20);
2426}
2427
Daniel Vetter12030432014-06-25 22:02:00 +03002428static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2429 struct intel_shared_dpll *pll)
2430{
2431 uint32_t val;
2432
2433 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002434 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2435 POSTING_READ(WRPLL_CTL(pll->id));
2436}
2437
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002438static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2439 struct intel_shared_dpll *pll,
2440 struct intel_dpll_hw_state *hw_state)
2441{
2442 uint32_t val;
2443
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002444 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002445 return false;
2446
2447 val = I915_READ(WRPLL_CTL(pll->id));
2448 hw_state->wrpll = val;
2449
2450 return val & WRPLL_PLL_ENABLE;
2451}
2452
Damien Lespiauca1381b2014-07-15 15:05:33 +01002453static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002454 "WRPLL 1",
2455 "WRPLL 2",
2456};
2457
Damien Lespiau143b3072014-07-29 18:06:19 +01002458static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002459{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002460 int i;
2461
Daniel Vetter716c2e52014-06-25 22:02:02 +03002462 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002463
Daniel Vetter716c2e52014-06-25 22:02:02 +03002464 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002465 dev_priv->shared_dplls[i].id = i;
2466 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002467 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002468 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002469 dev_priv->shared_dplls[i].get_hw_state =
2470 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002471 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002472}
2473
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002474static const char * const skl_ddi_pll_names[] = {
2475 "DPLL 1",
2476 "DPLL 2",
2477 "DPLL 3",
2478};
2479
2480struct skl_dpll_regs {
2481 u32 ctl, cfgcr1, cfgcr2;
2482};
2483
2484/* this array is indexed by the *shared* pll id */
2485static const struct skl_dpll_regs skl_dpll_regs[3] = {
2486 {
2487 /* DPLL 1 */
2488 .ctl = LCPLL2_CTL,
2489 .cfgcr1 = DPLL1_CFGCR1,
2490 .cfgcr2 = DPLL1_CFGCR2,
2491 },
2492 {
2493 /* DPLL 2 */
2494 .ctl = WRPLL_CTL1,
2495 .cfgcr1 = DPLL2_CFGCR1,
2496 .cfgcr2 = DPLL2_CFGCR2,
2497 },
2498 {
2499 /* DPLL 3 */
2500 .ctl = WRPLL_CTL2,
2501 .cfgcr1 = DPLL3_CFGCR1,
2502 .cfgcr2 = DPLL3_CFGCR2,
2503 },
2504};
2505
2506static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2507 struct intel_shared_dpll *pll)
2508{
2509 uint32_t val;
2510 unsigned int dpll;
2511 const struct skl_dpll_regs *regs = skl_dpll_regs;
2512
2513 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2514 dpll = pll->id + 1;
2515
2516 val = I915_READ(DPLL_CTRL1);
2517
2518 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002519 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002520 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2521
2522 I915_WRITE(DPLL_CTRL1, val);
2523 POSTING_READ(DPLL_CTRL1);
2524
2525 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2526 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2527 POSTING_READ(regs[pll->id].cfgcr1);
2528 POSTING_READ(regs[pll->id].cfgcr2);
2529
2530 /* the enable bit is always bit 31 */
2531 I915_WRITE(regs[pll->id].ctl,
2532 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2533
2534 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2535 DRM_ERROR("DPLL %d not locked\n", dpll);
2536}
2537
2538static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2539 struct intel_shared_dpll *pll)
2540{
2541 const struct skl_dpll_regs *regs = skl_dpll_regs;
2542
2543 /* the enable bit is always bit 31 */
2544 I915_WRITE(regs[pll->id].ctl,
2545 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2546 POSTING_READ(regs[pll->id].ctl);
2547}
2548
2549static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2550 struct intel_shared_dpll *pll,
2551 struct intel_dpll_hw_state *hw_state)
2552{
2553 uint32_t val;
2554 unsigned int dpll;
2555 const struct skl_dpll_regs *regs = skl_dpll_regs;
2556
2557 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2558 return false;
2559
2560 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2561 dpll = pll->id + 1;
2562
2563 val = I915_READ(regs[pll->id].ctl);
2564 if (!(val & LCPLL_PLL_ENABLE))
2565 return false;
2566
2567 val = I915_READ(DPLL_CTRL1);
2568 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2569
2570 /* avoid reading back stale values if HDMI mode is not enabled */
2571 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2572 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2573 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2574 }
2575
2576 return true;
2577}
2578
2579static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2580{
2581 int i;
2582
2583 dev_priv->num_shared_dpll = 3;
2584
2585 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2586 dev_priv->shared_dplls[i].id = i;
2587 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2588 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2589 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2590 dev_priv->shared_dplls[i].get_hw_state =
2591 skl_ddi_pll_get_hw_state;
2592 }
2593}
2594
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302595static void broxton_phy_init(struct drm_i915_private *dev_priv,
2596 enum dpio_phy phy)
2597{
2598 enum port port;
2599 uint32_t val;
2600
2601 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2602 val |= GT_DISPLAY_POWER_ON(phy);
2603 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2604
2605 /* Considering 10ms timeout until BSpec is updated */
2606 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2607 DRM_ERROR("timeout during PHY%d power on\n", phy);
2608
2609 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2610 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2611 int lane;
2612
2613 for (lane = 0; lane < 4; lane++) {
2614 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2615 /*
2616 * Note that on CHV this flag is called UPAR, but has
2617 * the same function.
2618 */
2619 val &= ~LATENCY_OPTIM;
2620 if (lane != 1)
2621 val |= LATENCY_OPTIM;
2622
2623 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2624 }
2625 }
2626
2627 /* Program PLL Rcomp code offset */
2628 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2629 val &= ~IREF0RC_OFFSET_MASK;
2630 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2631 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2632
2633 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2634 val &= ~IREF1RC_OFFSET_MASK;
2635 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2636 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2637
2638 /* Program power gating */
2639 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2640 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2641 SUS_CLK_CONFIG;
2642 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2643
2644 if (phy == DPIO_PHY0) {
2645 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2646 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2647 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2648 }
2649
2650 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2651 val &= ~OCL2_LDOFUSE_PWR_DIS;
2652 /*
2653 * On PHY1 disable power on the second channel, since no port is
2654 * connected there. On PHY0 both channels have a port, so leave it
2655 * enabled.
2656 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2657 * power down the second channel on PHY0 as well.
2658 */
2659 if (phy == DPIO_PHY1)
2660 val |= OCL2_LDOFUSE_PWR_DIS;
2661 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2662
2663 if (phy == DPIO_PHY0) {
2664 uint32_t grc_code;
2665 /*
2666 * PHY0 isn't connected to an RCOMP resistor so copy over
2667 * the corresponding calibrated value from PHY1, and disable
2668 * the automatic calibration on PHY0.
2669 */
2670 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2671 10))
2672 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2673
2674 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2675 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2676 grc_code = val << GRC_CODE_FAST_SHIFT |
2677 val << GRC_CODE_SLOW_SHIFT |
2678 val;
2679 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2680
2681 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2682 val |= GRC_DIS | GRC_RDY_OVRD;
2683 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2684 }
2685
2686 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2687 val |= COMMON_RESET_DIS;
2688 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2689}
2690
2691void broxton_ddi_phy_init(struct drm_device *dev)
2692{
2693 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2694 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2695 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2696}
2697
2698static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2699 enum dpio_phy phy)
2700{
2701 uint32_t val;
2702
2703 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2704 val &= ~COMMON_RESET_DIS;
2705 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2706}
2707
2708void broxton_ddi_phy_uninit(struct drm_device *dev)
2709{
2710 struct drm_i915_private *dev_priv = dev->dev_private;
2711
2712 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2713 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2714
2715 /* FIXME: do this in broxton_phy_uninit per phy */
2716 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2717}
2718
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302719static const char * const bxt_ddi_pll_names[] = {
2720 "PORT PLL A",
2721 "PORT PLL B",
2722 "PORT PLL C",
2723};
2724
2725static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2726 struct intel_shared_dpll *pll)
2727{
2728 uint32_t temp;
2729 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2730
2731 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2732 temp &= ~PORT_PLL_REF_SEL;
2733 /* Non-SSC reference */
2734 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2735
2736 /* Disable 10 bit clock */
2737 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2738 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2739 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2740
2741 /* Write P1 & P2 */
2742 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2743 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2744 temp |= pll->config.hw_state.ebb0;
2745 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2746
2747 /* Write M2 integer */
2748 temp = I915_READ(BXT_PORT_PLL(port, 0));
2749 temp &= ~PORT_PLL_M2_MASK;
2750 temp |= pll->config.hw_state.pll0;
2751 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2752
2753 /* Write N */
2754 temp = I915_READ(BXT_PORT_PLL(port, 1));
2755 temp &= ~PORT_PLL_N_MASK;
2756 temp |= pll->config.hw_state.pll1;
2757 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2758
2759 /* Write M2 fraction */
2760 temp = I915_READ(BXT_PORT_PLL(port, 2));
2761 temp &= ~PORT_PLL_M2_FRAC_MASK;
2762 temp |= pll->config.hw_state.pll2;
2763 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2764
2765 /* Write M2 fraction enable */
2766 temp = I915_READ(BXT_PORT_PLL(port, 3));
2767 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2768 temp |= pll->config.hw_state.pll3;
2769 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2770
2771 /* Write coeff */
2772 temp = I915_READ(BXT_PORT_PLL(port, 6));
2773 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2774 temp &= ~PORT_PLL_INT_COEFF_MASK;
2775 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2776 temp |= pll->config.hw_state.pll6;
2777 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2778
2779 /* Write calibration val */
2780 temp = I915_READ(BXT_PORT_PLL(port, 8));
2781 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2782 temp |= pll->config.hw_state.pll8;
2783 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2784
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302785 temp = I915_READ(BXT_PORT_PLL(port, 9));
2786 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002787 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302788 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2789
2790 temp = I915_READ(BXT_PORT_PLL(port, 10));
2791 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2792 temp &= ~PORT_PLL_DCO_AMP_MASK;
2793 temp |= pll->config.hw_state.pll10;
2794 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302795
2796 /* Recalibrate with new settings */
2797 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2798 temp |= PORT_PLL_RECALIBRATE;
2799 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002800 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2801 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302802 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2803
2804 /* Enable PLL */
2805 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2806 temp |= PORT_PLL_ENABLE;
2807 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2808 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2809
2810 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2811 PORT_PLL_LOCK), 200))
2812 DRM_ERROR("PLL %d not locked\n", port);
2813
2814 /*
2815 * While we write to the group register to program all lanes at once we
2816 * can read only lane registers and we pick lanes 0/1 for that.
2817 */
2818 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2819 temp &= ~LANE_STAGGER_MASK;
2820 temp &= ~LANESTAGGER_STRAP_OVRD;
2821 temp |= pll->config.hw_state.pcsdw12;
2822 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2823}
2824
2825static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2826 struct intel_shared_dpll *pll)
2827{
2828 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2829 uint32_t temp;
2830
2831 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2832 temp &= ~PORT_PLL_ENABLE;
2833 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2834 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2835}
2836
2837static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2838 struct intel_shared_dpll *pll,
2839 struct intel_dpll_hw_state *hw_state)
2840{
2841 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2842 uint32_t val;
2843
2844 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2845 return false;
2846
2847 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2848 if (!(val & PORT_PLL_ENABLE))
2849 return false;
2850
2851 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002852 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2853
Imre Deak05712c12015-06-18 17:25:54 +03002854 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2855 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2856
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302857 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002858 hw_state->pll0 &= PORT_PLL_M2_MASK;
2859
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302860 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002861 hw_state->pll1 &= PORT_PLL_N_MASK;
2862
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302863 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002864 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2865
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302866 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002867 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2868
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302869 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002870 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2871 PORT_PLL_INT_COEFF_MASK |
2872 PORT_PLL_GAIN_CTL_MASK;
2873
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302874 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002875 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2876
Imre Deak05712c12015-06-18 17:25:54 +03002877 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2878 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2879
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302880 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002881 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2882 PORT_PLL_DCO_AMP_MASK;
2883
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302884 /*
2885 * While we write to the group register to program all lanes at once we
2886 * can read only lane registers. We configure all lanes the same way, so
2887 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2888 */
2889 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2890 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port) != hw_state->pcsdw12))
2891 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2892 hw_state->pcsdw12,
2893 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002894 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302895
2896 return true;
2897}
2898
2899static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2900{
2901 int i;
2902
2903 dev_priv->num_shared_dpll = 3;
2904
2905 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2906 dev_priv->shared_dplls[i].id = i;
2907 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2908 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2909 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2910 dev_priv->shared_dplls[i].get_hw_state =
2911 bxt_ddi_pll_get_hw_state;
2912 }
2913}
2914
Damien Lespiau143b3072014-07-29 18:06:19 +01002915void intel_ddi_pll_init(struct drm_device *dev)
2916{
2917 struct drm_i915_private *dev_priv = dev->dev_private;
2918 uint32_t val = I915_READ(LCPLL_CTL);
2919
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002920 if (IS_SKYLAKE(dev))
2921 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302922 else if (IS_BROXTON(dev))
2923 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002924 else
2925 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002926
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002927 if (IS_SKYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002928 int cdclk_freq;
2929
2930 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002931 dev_priv->skl_boot_cdclk = cdclk_freq;
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002932 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2933 DRM_ERROR("LCPLL1 is disabled\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002934 else
2935 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302936 } else if (IS_BROXTON(dev)) {
2937 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302938 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002939 } else {
2940 /*
2941 * The LCPLL register should be turned on by the BIOS. For now
2942 * let's just check its state and print errors in case
2943 * something is wrong. Don't even try to turn it on.
2944 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002945
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002946 if (val & LCPLL_CD_SOURCE_FCLK)
2947 DRM_ERROR("CDCLK source is not LCPLL\n");
2948
2949 if (val & LCPLL_PLL_DISABLE)
2950 DRM_ERROR("LCPLL is disabled\n");
2951 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002952}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002953
2954void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
2955{
Paulo Zanoni174edf12012-10-26 19:05:50 -02002956 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
2957 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002958 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02002959 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002960 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302961 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002962
2963 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2964 val = I915_READ(DDI_BUF_CTL(port));
2965 if (val & DDI_BUF_CTL_ENABLE) {
2966 val &= ~DDI_BUF_CTL_ENABLE;
2967 I915_WRITE(DDI_BUF_CTL(port), val);
2968 wait = true;
2969 }
2970
2971 val = I915_READ(DP_TP_CTL(port));
2972 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2973 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2974 I915_WRITE(DP_TP_CTL(port), val);
2975 POSTING_READ(DP_TP_CTL(port));
2976
2977 if (wait)
2978 intel_wait_ddi_buf_idle(dev_priv, port);
2979 }
2980
Dave Airlie0e32b392014-05-02 14:02:48 +10002981 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03002982 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10002983 if (intel_dp->is_mst)
2984 val |= DP_TP_CTL_MODE_MST;
2985 else {
2986 val |= DP_TP_CTL_MODE_SST;
2987 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
2988 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
2989 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002990 I915_WRITE(DP_TP_CTL(port), val);
2991 POSTING_READ(DP_TP_CTL(port));
2992
2993 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
2994 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
2995 POSTING_READ(DDI_BUF_CTL(port));
2996
2997 udelay(600);
2998}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002999
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003000void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3001{
3002 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3003 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3004 uint32_t val;
3005
3006 intel_ddi_post_disable(intel_encoder);
3007
3008 val = I915_READ(_FDI_RXA_CTL);
3009 val &= ~FDI_RX_ENABLE;
3010 I915_WRITE(_FDI_RXA_CTL, val);
3011
3012 val = I915_READ(_FDI_RXA_MISC);
3013 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3014 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
3015 I915_WRITE(_FDI_RXA_MISC, val);
3016
3017 val = I915_READ(_FDI_RXA_CTL);
3018 val &= ~FDI_PCDCLK;
3019 I915_WRITE(_FDI_RXA_CTL, val);
3020
3021 val = I915_READ(_FDI_RXA_CTL);
3022 val &= ~FDI_RX_PLL_ENABLE;
3023 I915_WRITE(_FDI_RXA_CTL, val);
3024}
3025
Ville Syrjälä6801c182013-09-24 14:24:05 +03003026void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003027 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003028{
3029 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3030 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003031 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003032 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003033 u32 temp, flags = 0;
3034
3035 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3036 if (temp & TRANS_DDI_PHSYNC)
3037 flags |= DRM_MODE_FLAG_PHSYNC;
3038 else
3039 flags |= DRM_MODE_FLAG_NHSYNC;
3040 if (temp & TRANS_DDI_PVSYNC)
3041 flags |= DRM_MODE_FLAG_PVSYNC;
3042 else
3043 flags |= DRM_MODE_FLAG_NVSYNC;
3044
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003045 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003046
3047 switch (temp & TRANS_DDI_BPC_MASK) {
3048 case TRANS_DDI_BPC_6:
3049 pipe_config->pipe_bpp = 18;
3050 break;
3051 case TRANS_DDI_BPC_8:
3052 pipe_config->pipe_bpp = 24;
3053 break;
3054 case TRANS_DDI_BPC_10:
3055 pipe_config->pipe_bpp = 30;
3056 break;
3057 case TRANS_DDI_BPC_12:
3058 pipe_config->pipe_bpp = 36;
3059 break;
3060 default:
3061 break;
3062 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003063
3064 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3065 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003066 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003067 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3068
3069 if (intel_hdmi->infoframe_enabled(&encoder->base))
3070 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003071 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003072 case TRANS_DDI_MODE_SELECT_DVI:
3073 case TRANS_DDI_MODE_SELECT_FDI:
3074 break;
3075 case TRANS_DDI_MODE_SELECT_DP_SST:
3076 case TRANS_DDI_MODE_SELECT_DP_MST:
3077 pipe_config->has_dp_encoder = true;
3078 intel_dp_get_m_n(intel_crtc, pipe_config);
3079 break;
3080 default:
3081 break;
3082 }
Daniel Vetter10214422013-11-18 07:38:16 +01003083
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003084 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003085 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003086 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003087 pipe_config->has_audio = true;
3088 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003089
Daniel Vetter10214422013-11-18 07:38:16 +01003090 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3091 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3092 /*
3093 * This is a big fat ugly hack.
3094 *
3095 * Some machines in UEFI boot mode provide us a VBT that has 18
3096 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3097 * unknown we fail to light up. Yet the same BIOS boots up with
3098 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3099 * max, not what it tells us to use.
3100 *
3101 * Note: This will still be broken if the eDP panel is not lit
3102 * up by the BIOS, and thus we can't get the mode at module
3103 * load.
3104 */
3105 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3106 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3107 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3108 }
Jesse Barnes11578552014-01-21 12:42:10 -08003109
Damien Lespiau22606a12014-12-12 14:26:57 +00003110 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003111}
3112
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003113static void intel_ddi_destroy(struct drm_encoder *encoder)
3114{
3115 /* HDMI has nothing special to destroy, so we can go with this. */
3116 intel_dp_encoder_destroy(encoder);
3117}
3118
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003119static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003120 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003121{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003122 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003123 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003124
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003125 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003126
Daniel Vettereccb1402013-05-22 00:50:22 +02003127 if (port == PORT_A)
3128 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3129
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003130 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003131 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003132 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003133 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003134}
3135
3136static const struct drm_encoder_funcs intel_ddi_funcs = {
3137 .destroy = intel_ddi_destroy,
3138};
3139
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003140static struct intel_connector *
3141intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3142{
3143 struct intel_connector *connector;
3144 enum port port = intel_dig_port->port;
3145
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003146 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003147 if (!connector)
3148 return NULL;
3149
3150 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3151 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3152 kfree(connector);
3153 return NULL;
3154 }
3155
3156 return connector;
3157}
3158
3159static struct intel_connector *
3160intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3161{
3162 struct intel_connector *connector;
3163 enum port port = intel_dig_port->port;
3164
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003165 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003166 if (!connector)
3167 return NULL;
3168
3169 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3170 intel_hdmi_init_connector(intel_dig_port, connector);
3171
3172 return connector;
3173}
3174
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003175void intel_ddi_init(struct drm_device *dev, enum port port)
3176{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003177 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003178 struct intel_digital_port *intel_dig_port;
3179 struct intel_encoder *intel_encoder;
3180 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003181 bool init_hdmi, init_dp;
3182
3183 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3184 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3185 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3186 if (!init_dp && !init_hdmi) {
Chris Wilsonf68d6972014-08-04 07:15:09 +01003187 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003188 port_name(port));
3189 init_hdmi = true;
3190 init_dp = true;
3191 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003192
Daniel Vetterb14c5672013-09-19 12:18:32 +02003193 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003194 if (!intel_dig_port)
3195 return;
3196
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003197 intel_encoder = &intel_dig_port->base;
3198 encoder = &intel_encoder->base;
3199
3200 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3201 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003202
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003203 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003204 intel_encoder->enable = intel_enable_ddi;
3205 intel_encoder->pre_enable = intel_ddi_pre_enable;
3206 intel_encoder->disable = intel_disable_ddi;
3207 intel_encoder->post_disable = intel_ddi_post_disable;
3208 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003209 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003210
3211 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003212 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3213 (DDI_BUF_PORT_REVERSAL |
3214 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003215
3216 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003217 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003218 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003219
Chris Wilsonf68d6972014-08-04 07:15:09 +01003220 if (init_dp) {
3221 if (!intel_ddi_init_dp_connector(intel_dig_port))
3222 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003223
Chris Wilsonf68d6972014-08-04 07:15:09 +01003224 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Jani Nikula5fcece82015-05-27 15:03:42 +03003225 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003226 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003227
Paulo Zanoni311a2092013-09-12 17:12:18 -03003228 /* In theory we don't need the encoder->type check, but leave it just in
3229 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003230 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3231 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3232 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003233 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003234
3235 return;
3236
3237err:
3238 drm_encoder_cleanup(encoder);
3239 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003240}