blob: b6d1ab27e5baa90f716174ef9fa1926de17f2f68 [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;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300443 u32 iboost_bit = 0;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000444 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530445 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300446 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300447 const struct ddi_buf_trans *ddi_translations_fdi;
448 const struct ddi_buf_trans *ddi_translations_dp;
449 const struct ddi_buf_trans *ddi_translations_edp;
450 const struct ddi_buf_trans *ddi_translations_hdmi;
451 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700452
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530453 if (IS_BROXTON(dev)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300454 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530455 return;
456
457 /* Vswing programming for HDMI */
458 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
459 INTEL_OUTPUT_HDMI);
460 return;
461 } else if (IS_SKYLAKE(dev)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300462 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300463 ddi_translations_dp =
464 skl_get_buf_trans_dp(dev, &n_dp_entries);
465 ddi_translations_edp =
466 skl_get_buf_trans_edp(dev, &n_edp_entries);
467 ddi_translations_hdmi =
468 skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
469 hdmi_default_entry = 8;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300470 /* If we're boosting the current, set bit 31 of trans1 */
471 if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
472 dev_priv->vbt.ddi_port_info[port].dp_boost_level)
473 iboost_bit = 1<<31;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000474 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700475 ddi_translations_fdi = bdw_ddi_translations_fdi;
476 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700477 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100478 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530479 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
480 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300481 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000482 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700483 } else if (IS_HASWELL(dev)) {
484 ddi_translations_fdi = hsw_ddi_translations_fdi;
485 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700486 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100487 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530488 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300489 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000490 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700491 } else {
492 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700493 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700494 ddi_translations_fdi = bdw_ddi_translations_fdi;
495 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100496 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530497 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
498 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300499 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000500 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700501 }
502
Paulo Zanoni300644c2013-11-02 21:07:42 -0700503 switch (port) {
504 case PORT_A:
505 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530506 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700507 break;
508 case PORT_B:
509 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700510 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530511 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700512 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700513 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530514 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700515 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530516 size = n_edp_entries;
517 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700518 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530519 size = n_dp_entries;
520 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700521 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700522 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000523 if (ddi_translations_fdi)
524 ddi_translations = ddi_translations_fdi;
525 else
526 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530527 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700528 break;
529 default:
530 BUG();
531 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300532
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530533 for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300534 I915_WRITE(reg, ddi_translations[i].trans1 | iboost_bit);
Jani Nikula10122052014-08-27 16:27:30 +0300535 reg += 4;
536 I915_WRITE(reg, ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300537 reg += 4;
538 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100539
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300540 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100541 return;
542
Damien Lespiauce4dd492014-08-01 11:07:54 +0100543 /* Choose a good default if VBT is badly populated */
544 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
545 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000546 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100547
Paulo Zanoni6acab152013-09-12 17:06:24 -0300548 /* Entry 9 is for HDMI: */
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300549 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
Jani Nikula10122052014-08-27 16:27:30 +0300550 reg += 4;
551 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2);
552 reg += 4;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300553}
554
555/* Program DDI buffers translations for DP. By default, program ports A-D in DP
556 * mode and port E for FDI.
557 */
558void intel_prepare_ddi(struct drm_device *dev)
559{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300560 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100561 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300562
Paulo Zanoni0d536cb2012-11-23 16:46:41 -0200563 if (!HAS_DDI(dev))
564 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300565
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300566 for_each_intel_encoder(dev, intel_encoder) {
567 struct intel_digital_port *intel_dig_port;
568 enum port port;
569 bool supports_hdmi;
570
571 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
572
573 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100574 continue;
575
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300576 supports_hdmi = intel_dig_port &&
577 intel_dig_port_supports_hdmi(intel_dig_port);
578
579 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
580 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100581 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300582}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300583
Paulo Zanoni248138b2012-11-29 11:29:31 -0200584static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
585 enum port port)
586{
587 uint32_t reg = DDI_BUF_CTL(port);
588 int i;
589
Vandana Kannan3449ca82015-03-27 14:19:09 +0200590 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200591 udelay(1);
592 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
593 return;
594 }
595 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
596}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300597
598/* Starting with Haswell, different DDI ports can work in FDI mode for
599 * connection to the PCH-located connectors. For this, it is necessary to train
600 * both the DDI port and PCH receiver for the desired DDI buffer settings.
601 *
602 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
603 * please note that when FDI mode is active on DDI E, it shares 2 lines with
604 * DDI A (which is used for eDP)
605 */
606
607void hsw_fdi_link_train(struct drm_crtc *crtc)
608{
609 struct drm_device *dev = crtc->dev;
610 struct drm_i915_private *dev_priv = dev->dev_private;
611 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200612 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300613
Paulo Zanoni04945642012-11-01 21:00:59 -0200614 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
615 * mode set "sequence for CRT port" document:
616 * - TP1 to TP2 time with the default value
617 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100618 *
619 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200620 */
621 I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
622 FDI_RX_PWRDN_LANE0_VAL(2) |
623 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
624
625 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000626 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100627 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200628 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Paulo Zanoni04945642012-11-01 21:00:59 -0200629 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
630 POSTING_READ(_FDI_RXA_CTL);
631 udelay(220);
632
633 /* Switch from Rawclk to PCDclk */
634 rx_ctl_val |= FDI_PCDCLK;
635 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
636
637 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200638 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
639 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200640
641 /* Start the training iterating through available voltages and emphasis,
642 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300643 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300644 /* Configure DP_TP_CTL with auto-training */
645 I915_WRITE(DP_TP_CTL(PORT_E),
646 DP_TP_CTL_FDI_AUTOTRAIN |
647 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
648 DP_TP_CTL_LINK_TRAIN_PAT1 |
649 DP_TP_CTL_ENABLE);
650
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000651 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
652 * DDI E does not support port reversal, the functionality is
653 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
654 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300655 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200656 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200657 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530658 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200659 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300660
661 udelay(600);
662
Paulo Zanoni04945642012-11-01 21:00:59 -0200663 /* Program PCH FDI Receiver TU */
664 I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300665
Paulo Zanoni04945642012-11-01 21:00:59 -0200666 /* Enable PCH FDI Receiver with auto-training */
667 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
668 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
669 POSTING_READ(_FDI_RXA_CTL);
670
671 /* Wait for FDI receiver lane calibration */
672 udelay(30);
673
674 /* Unset FDI_RX_MISC pwrdn lanes */
675 temp = I915_READ(_FDI_RXA_MISC);
676 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
677 I915_WRITE(_FDI_RXA_MISC, temp);
678 POSTING_READ(_FDI_RXA_MISC);
679
680 /* Wait for FDI auto training time */
681 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300682
683 temp = I915_READ(DP_TP_STATUS(PORT_E));
684 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200685 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300686
687 /* Enable normal pixel sending for FDI */
688 I915_WRITE(DP_TP_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200689 DP_TP_CTL_FDI_AUTOTRAIN |
690 DP_TP_CTL_LINK_TRAIN_NORMAL |
691 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
692 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300693
Paulo Zanoni04945642012-11-01 21:00:59 -0200694 return;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300695 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200696
Paulo Zanoni248138b2012-11-29 11:29:31 -0200697 temp = I915_READ(DDI_BUF_CTL(PORT_E));
698 temp &= ~DDI_BUF_CTL_ENABLE;
699 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
700 POSTING_READ(DDI_BUF_CTL(PORT_E));
701
Paulo Zanoni04945642012-11-01 21:00:59 -0200702 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200703 temp = I915_READ(DP_TP_CTL(PORT_E));
704 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
705 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
706 I915_WRITE(DP_TP_CTL(PORT_E), temp);
707 POSTING_READ(DP_TP_CTL(PORT_E));
708
709 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200710
711 rx_ctl_val &= ~FDI_RX_ENABLE;
712 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200713 POSTING_READ(_FDI_RXA_CTL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200714
715 /* Reset FDI_RX_MISC pwrdn lanes */
716 temp = I915_READ(_FDI_RXA_MISC);
717 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
718 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
719 I915_WRITE(_FDI_RXA_MISC, temp);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200720 POSTING_READ(_FDI_RXA_MISC);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300721 }
722
Paulo Zanoni04945642012-11-01 21:00:59 -0200723 DRM_ERROR("FDI link training failed!\n");
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300724}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300725
Dave Airlie44905a272014-05-02 13:36:43 +1000726void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
727{
728 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
729 struct intel_digital_port *intel_dig_port =
730 enc_to_dig_port(&encoder->base);
731
732 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530733 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Dave Airlie44905a272014-05-02 13:36:43 +1000734 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
735
736}
737
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300738static struct intel_encoder *
739intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
740{
741 struct drm_device *dev = crtc->dev;
742 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
743 struct intel_encoder *intel_encoder, *ret = NULL;
744 int num_encoders = 0;
745
746 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
747 ret = intel_encoder;
748 num_encoders++;
749 }
750
751 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300752 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
753 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300754
755 BUG_ON(ret == NULL);
756 return ret;
757}
758
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530759struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200760intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200761{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200762 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
763 struct intel_encoder *ret = NULL;
764 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300765 struct drm_connector *connector;
766 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200767 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200768 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200769
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200770 state = crtc_state->base.state;
771
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300772 for_each_connector_in_state(state, connector, connector_state, i) {
773 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200774 continue;
775
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300776 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200777 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200778 }
779
780 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
781 pipe_name(crtc->pipe));
782
783 BUG_ON(ret == NULL);
784 return ret;
785}
786
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100787#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100788#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100789
790#define P_MIN 2
791#define P_MAX 64
792#define P_INC 2
793
794/* Constraints for PLL good behavior */
795#define REF_MIN 48
796#define REF_MAX 400
797#define VCO_MIN 2400
798#define VCO_MAX 4800
799
Damien Lespiau27893392014-09-04 12:27:23 +0100800#define abs_diff(a, b) ({ \
801 typeof(a) __a = (a); \
802 typeof(b) __b = (b); \
803 (void) (&__a == &__b); \
804 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100805
Damien Lespiau63582982015-05-07 18:38:46 +0100806struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100807 unsigned p, n2, r2;
808};
809
Damien Lespiau63582982015-05-07 18:38:46 +0100810static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300811{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100812 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300813
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100814 switch (clock) {
815 case 25175000:
816 case 25200000:
817 case 27000000:
818 case 27027000:
819 case 37762500:
820 case 37800000:
821 case 40500000:
822 case 40541000:
823 case 54000000:
824 case 54054000:
825 case 59341000:
826 case 59400000:
827 case 72000000:
828 case 74176000:
829 case 74250000:
830 case 81000000:
831 case 81081000:
832 case 89012000:
833 case 89100000:
834 case 108000000:
835 case 108108000:
836 case 111264000:
837 case 111375000:
838 case 148352000:
839 case 148500000:
840 case 162000000:
841 case 162162000:
842 case 222525000:
843 case 222750000:
844 case 296703000:
845 case 297000000:
846 budget = 0;
847 break;
848 case 233500000:
849 case 245250000:
850 case 247750000:
851 case 253250000:
852 case 298000000:
853 budget = 1500;
854 break;
855 case 169128000:
856 case 169500000:
857 case 179500000:
858 case 202000000:
859 budget = 2000;
860 break;
861 case 256250000:
862 case 262500000:
863 case 270000000:
864 case 272500000:
865 case 273750000:
866 case 280750000:
867 case 281250000:
868 case 286000000:
869 case 291750000:
870 budget = 4000;
871 break;
872 case 267250000:
873 case 268500000:
874 budget = 5000;
875 break;
876 default:
877 budget = 1000;
878 break;
879 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300880
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100881 return budget;
882}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300883
Damien Lespiau63582982015-05-07 18:38:46 +0100884static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
885 unsigned r2, unsigned n2, unsigned p,
886 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100887{
888 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300889
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100890 /* No best (r,n,p) yet */
891 if (best->p == 0) {
892 best->p = p;
893 best->n2 = n2;
894 best->r2 = r2;
895 return;
896 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300897
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100898 /*
899 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
900 * freq2k.
901 *
902 * delta = 1e6 *
903 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
904 * freq2k;
905 *
906 * and we would like delta <= budget.
907 *
908 * If the discrepancy is above the PPM-based budget, always prefer to
909 * improve upon the previous solution. However, if you're within the
910 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
911 */
912 a = freq2k * budget * p * r2;
913 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100914 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
915 diff_best = abs_diff(freq2k * best->p * best->r2,
916 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100917 c = 1000000 * diff;
918 d = 1000000 * diff_best;
919
920 if (a < c && b < d) {
921 /* If both are above the budget, pick the closer */
922 if (best->p * best->r2 * diff < p * r2 * diff_best) {
923 best->p = p;
924 best->n2 = n2;
925 best->r2 = r2;
926 }
927 } else if (a >= c && b < d) {
928 /* If A is below the threshold but B is above it? Update. */
929 best->p = p;
930 best->n2 = n2;
931 best->r2 = r2;
932 } else if (a >= c && b >= d) {
933 /* Both are below the limit, so pick the higher n2/(r2*r2) */
934 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
935 best->p = p;
936 best->n2 = n2;
937 best->r2 = r2;
938 }
939 }
940 /* Otherwise a < c && b >= d, do nothing */
941}
942
Damien Lespiau63582982015-05-07 18:38:46 +0100943static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, int reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800944{
945 int refclk = LC_FREQ;
946 int n, p, r;
947 u32 wrpll;
948
949 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300950 switch (wrpll & WRPLL_PLL_REF_MASK) {
951 case WRPLL_PLL_SSC:
952 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800953 /*
954 * We could calculate spread here, but our checking
955 * code only cares about 5% accuracy, and spread is a max of
956 * 0.5% downspread.
957 */
958 refclk = 135;
959 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300960 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800961 refclk = LC_FREQ;
962 break;
963 default:
964 WARN(1, "bad wrpll refclk\n");
965 return 0;
966 }
967
968 r = wrpll & WRPLL_DIVIDER_REF_MASK;
969 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
970 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
971
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800972 /* Convert to KHz, p & r have a fixed point portion */
973 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800974}
975
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000976static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
977 uint32_t dpll)
978{
979 uint32_t cfgcr1_reg, cfgcr2_reg;
980 uint32_t cfgcr1_val, cfgcr2_val;
981 uint32_t p0, p1, p2, dco_freq;
982
983 cfgcr1_reg = GET_CFG_CR1_REG(dpll);
984 cfgcr2_reg = GET_CFG_CR2_REG(dpll);
985
986 cfgcr1_val = I915_READ(cfgcr1_reg);
987 cfgcr2_val = I915_READ(cfgcr2_reg);
988
989 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
990 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
991
992 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
993 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
994 else
995 p1 = 1;
996
997
998 switch (p0) {
999 case DPLL_CFGCR2_PDIV_1:
1000 p0 = 1;
1001 break;
1002 case DPLL_CFGCR2_PDIV_2:
1003 p0 = 2;
1004 break;
1005 case DPLL_CFGCR2_PDIV_3:
1006 p0 = 3;
1007 break;
1008 case DPLL_CFGCR2_PDIV_7:
1009 p0 = 7;
1010 break;
1011 }
1012
1013 switch (p2) {
1014 case DPLL_CFGCR2_KDIV_5:
1015 p2 = 5;
1016 break;
1017 case DPLL_CFGCR2_KDIV_2:
1018 p2 = 2;
1019 break;
1020 case DPLL_CFGCR2_KDIV_3:
1021 p2 = 3;
1022 break;
1023 case DPLL_CFGCR2_KDIV_1:
1024 p2 = 1;
1025 break;
1026 }
1027
1028 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1029
1030 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1031 1000) / 0x8000;
1032
1033 return dco_freq / (p0 * p1 * p2 * 5);
1034}
1035
Ville Syrjälä398a0172015-06-30 15:33:51 +03001036static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1037{
1038 int dotclock;
1039
1040 if (pipe_config->has_pch_encoder)
1041 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1042 &pipe_config->fdi_m_n);
1043 else if (pipe_config->has_dp_encoder)
1044 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1045 &pipe_config->dp_m_n);
1046 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1047 dotclock = pipe_config->port_clock * 2 / 3;
1048 else
1049 dotclock = pipe_config->port_clock;
1050
1051 if (pipe_config->pixel_multiplier)
1052 dotclock /= pipe_config->pixel_multiplier;
1053
1054 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1055}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001056
1057static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001058 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001059{
1060 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001061 int link_clock = 0;
1062 uint32_t dpll_ctl1, dpll;
1063
Damien Lespiau134ffa42014-11-14 17:24:34 +00001064 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001065
1066 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1067
1068 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1069 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1070 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001071 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1072 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001073
1074 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001075 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001076 link_clock = 81000;
1077 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001078 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301079 link_clock = 108000;
1080 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001081 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001082 link_clock = 135000;
1083 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001084 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301085 link_clock = 162000;
1086 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001087 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301088 link_clock = 216000;
1089 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001090 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001091 link_clock = 270000;
1092 break;
1093 default:
1094 WARN(1, "Unsupported link rate\n");
1095 break;
1096 }
1097 link_clock *= 2;
1098 }
1099
1100 pipe_config->port_clock = link_clock;
1101
Ville Syrjälä398a0172015-06-30 15:33:51 +03001102 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001103}
1104
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001105static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001106 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001107{
1108 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001109 int link_clock = 0;
1110 u32 val, pll;
1111
Daniel Vetter26804af2014-06-25 22:01:55 +03001112 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001113 switch (val & PORT_CLK_SEL_MASK) {
1114 case PORT_CLK_SEL_LCPLL_810:
1115 link_clock = 81000;
1116 break;
1117 case PORT_CLK_SEL_LCPLL_1350:
1118 link_clock = 135000;
1119 break;
1120 case PORT_CLK_SEL_LCPLL_2700:
1121 link_clock = 270000;
1122 break;
1123 case PORT_CLK_SEL_WRPLL1:
Damien Lespiau63582982015-05-07 18:38:46 +01001124 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL1);
Jesse Barnes11578552014-01-21 12:42:10 -08001125 break;
1126 case PORT_CLK_SEL_WRPLL2:
Damien Lespiau63582982015-05-07 18:38:46 +01001127 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL2);
Jesse Barnes11578552014-01-21 12:42:10 -08001128 break;
1129 case PORT_CLK_SEL_SPLL:
1130 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1131 if (pll == SPLL_PLL_FREQ_810MHz)
1132 link_clock = 81000;
1133 else if (pll == SPLL_PLL_FREQ_1350MHz)
1134 link_clock = 135000;
1135 else if (pll == SPLL_PLL_FREQ_2700MHz)
1136 link_clock = 270000;
1137 else {
1138 WARN(1, "bad spll freq\n");
1139 return;
1140 }
1141 break;
1142 default:
1143 WARN(1, "bad port clock sel\n");
1144 return;
1145 }
1146
1147 pipe_config->port_clock = link_clock * 2;
1148
Ville Syrjälä398a0172015-06-30 15:33:51 +03001149 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001150}
1151
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301152static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1153 enum intel_dpll_id dpll)
1154{
Imre Deakaa610dc2015-06-22 23:35:52 +03001155 struct intel_shared_dpll *pll;
1156 struct intel_dpll_hw_state *state;
1157 intel_clock_t clock;
1158
1159 /* For DDI ports we always use a shared PLL. */
1160 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1161 return 0;
1162
1163 pll = &dev_priv->shared_dplls[dpll];
1164 state = &pll->config.hw_state;
1165
1166 clock.m1 = 2;
1167 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1168 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1169 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1170 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1171 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1172 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1173
1174 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301175}
1176
1177static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1178 struct intel_crtc_state *pipe_config)
1179{
1180 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1181 enum port port = intel_ddi_get_encoder_port(encoder);
1182 uint32_t dpll = port;
1183
Ville Syrjälä398a0172015-06-30 15:33:51 +03001184 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301185
Ville Syrjälä398a0172015-06-30 15:33:51 +03001186 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301187}
1188
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001189void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001190 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001191{
Damien Lespiau22606a12014-12-12 14:26:57 +00001192 struct drm_device *dev = encoder->base.dev;
1193
1194 if (INTEL_INFO(dev)->gen <= 8)
1195 hsw_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301196 else if (IS_SKYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001197 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301198 else if (IS_BROXTON(dev))
1199 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001200}
1201
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001202static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001203hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1204 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001205{
1206 uint64_t freq2k;
1207 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001208 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001209 unsigned budget;
1210
1211 freq2k = clock / 100;
1212
Damien Lespiau63582982015-05-07 18:38:46 +01001213 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001214
1215 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1216 * and directly pass the LC PLL to it. */
1217 if (freq2k == 5400000) {
1218 *n2_out = 2;
1219 *p_out = 1;
1220 *r2_out = 2;
1221 return;
1222 }
1223
1224 /*
1225 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1226 * the WR PLL.
1227 *
1228 * We want R so that REF_MIN <= Ref <= REF_MAX.
1229 * Injecting R2 = 2 * R gives:
1230 * REF_MAX * r2 > LC_FREQ * 2 and
1231 * REF_MIN * r2 < LC_FREQ * 2
1232 *
1233 * Which means the desired boundaries for r2 are:
1234 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1235 *
1236 */
1237 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1238 r2 <= LC_FREQ * 2 / REF_MIN;
1239 r2++) {
1240
1241 /*
1242 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1243 *
1244 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1245 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1246 * VCO_MAX * r2 > n2 * LC_FREQ and
1247 * VCO_MIN * r2 < n2 * LC_FREQ)
1248 *
1249 * Which means the desired boundaries for n2 are:
1250 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1251 */
1252 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1253 n2 <= VCO_MAX * r2 / LC_FREQ;
1254 n2++) {
1255
1256 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001257 hsw_wrpll_update_rnp(freq2k, budget,
1258 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001259 }
1260 }
1261
1262 *n2_out = best.n2;
1263 *p_out = best.p;
1264 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001265}
1266
Damien Lespiau0220ab62014-07-29 18:06:22 +01001267static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001268hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001269 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001270 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001271{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001272 int clock = crtc_state->port_clock;
1273
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001274 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001275 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001276 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001277 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001278
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001279 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001280
Daniel Vetter114fe482014-06-25 22:01:48 +03001281 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001282 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1283 WRPLL_DIVIDER_POST(p);
1284
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001285 memset(&crtc_state->dpll_hw_state, 0,
1286 sizeof(crtc_state->dpll_hw_state));
1287
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001288 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001289
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001290 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001291 if (pll == NULL) {
1292 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1293 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001294 return false;
1295 }
1296
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001297 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001298 }
1299
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001300 return true;
1301}
1302
Damien Lespiaudc253812015-06-25 16:15:06 +01001303struct skl_wrpll_context {
1304 uint64_t min_deviation; /* current minimal deviation */
1305 uint64_t central_freq; /* chosen central freq */
1306 uint64_t dco_freq; /* chosen dco freq */
1307 unsigned int p; /* chosen divider */
1308};
1309
1310static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1311{
1312 memset(ctx, 0, sizeof(*ctx));
1313
1314 ctx->min_deviation = U64_MAX;
1315}
1316
1317/* DCO freq must be within +1%/-6% of the DCO central freq */
1318#define SKL_DCO_MAX_PDEVIATION 100
1319#define SKL_DCO_MAX_NDEVIATION 600
1320
1321static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1322 uint64_t central_freq,
1323 uint64_t dco_freq,
1324 unsigned int divider)
1325{
1326 uint64_t deviation;
1327
1328 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1329 central_freq);
1330
1331 /* positive deviation */
1332 if (dco_freq >= central_freq) {
1333 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1334 deviation < ctx->min_deviation) {
1335 ctx->min_deviation = deviation;
1336 ctx->central_freq = central_freq;
1337 ctx->dco_freq = dco_freq;
1338 ctx->p = divider;
1339 }
1340 /* negative deviation */
1341 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1342 deviation < ctx->min_deviation) {
1343 ctx->min_deviation = deviation;
1344 ctx->central_freq = central_freq;
1345 ctx->dco_freq = dco_freq;
1346 ctx->p = divider;
1347 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001348}
1349
1350static void skl_wrpll_get_multipliers(unsigned int p,
1351 unsigned int *p0 /* out */,
1352 unsigned int *p1 /* out */,
1353 unsigned int *p2 /* out */)
1354{
1355 /* even dividers */
1356 if (p % 2 == 0) {
1357 unsigned int half = p / 2;
1358
1359 if (half == 1 || half == 2 || half == 3 || half == 5) {
1360 *p0 = 2;
1361 *p1 = 1;
1362 *p2 = half;
1363 } else if (half % 2 == 0) {
1364 *p0 = 2;
1365 *p1 = half / 2;
1366 *p2 = 2;
1367 } else if (half % 3 == 0) {
1368 *p0 = 3;
1369 *p1 = half / 3;
1370 *p2 = 2;
1371 } else if (half % 7 == 0) {
1372 *p0 = 7;
1373 *p1 = half / 7;
1374 *p2 = 2;
1375 }
1376 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1377 *p0 = 3;
1378 *p1 = 1;
1379 *p2 = p / 3;
1380 } else if (p == 5 || p == 7) {
1381 *p0 = p;
1382 *p1 = 1;
1383 *p2 = 1;
1384 } else if (p == 15) {
1385 *p0 = 3;
1386 *p1 = 1;
1387 *p2 = 5;
1388 } else if (p == 21) {
1389 *p0 = 7;
1390 *p1 = 1;
1391 *p2 = 3;
1392 } else if (p == 35) {
1393 *p0 = 7;
1394 *p1 = 1;
1395 *p2 = 5;
1396 }
1397}
1398
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001399struct skl_wrpll_params {
1400 uint32_t dco_fraction;
1401 uint32_t dco_integer;
1402 uint32_t qdiv_ratio;
1403 uint32_t qdiv_mode;
1404 uint32_t kdiv;
1405 uint32_t pdiv;
1406 uint32_t central_freq;
1407};
1408
Damien Lespiau76516fb2015-05-07 18:38:42 +01001409static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1410 uint64_t afe_clock,
1411 uint64_t central_freq,
1412 uint32_t p0, uint32_t p1, uint32_t p2)
1413{
1414 uint64_t dco_freq;
1415
Damien Lespiau76516fb2015-05-07 18:38:42 +01001416 switch (central_freq) {
1417 case 9600000000ULL:
1418 params->central_freq = 0;
1419 break;
1420 case 9000000000ULL:
1421 params->central_freq = 1;
1422 break;
1423 case 8400000000ULL:
1424 params->central_freq = 3;
1425 }
1426
1427 switch (p0) {
1428 case 1:
1429 params->pdiv = 0;
1430 break;
1431 case 2:
1432 params->pdiv = 1;
1433 break;
1434 case 3:
1435 params->pdiv = 2;
1436 break;
1437 case 7:
1438 params->pdiv = 4;
1439 break;
1440 default:
1441 WARN(1, "Incorrect PDiv\n");
1442 }
1443
1444 switch (p2) {
1445 case 5:
1446 params->kdiv = 0;
1447 break;
1448 case 2:
1449 params->kdiv = 1;
1450 break;
1451 case 3:
1452 params->kdiv = 2;
1453 break;
1454 case 1:
1455 params->kdiv = 3;
1456 break;
1457 default:
1458 WARN(1, "Incorrect KDiv\n");
1459 }
1460
1461 params->qdiv_ratio = p1;
1462 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1463
1464 dco_freq = p0 * p1 * p2 * afe_clock;
1465
1466 /*
1467 * Intermediate values are in Hz.
1468 * Divide by MHz to match bsepc
1469 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001470 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001471 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001472 div_u64((div_u64(dco_freq, 24) -
1473 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001474}
1475
Damien Lespiau318bd822015-05-07 18:38:40 +01001476static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001477skl_ddi_calculate_wrpll(int clock /* in Hz */,
1478 struct skl_wrpll_params *wrpll_params)
1479{
1480 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001481 uint64_t dco_central_freq[3] = {8400000000ULL,
1482 9000000000ULL,
1483 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001484 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1485 24, 28, 30, 32, 36, 40, 42, 44,
1486 48, 52, 54, 56, 60, 64, 66, 68,
1487 70, 72, 76, 78, 80, 84, 88, 90,
1488 92, 96, 98 };
1489 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1490 static const struct {
1491 const int *list;
1492 int n_dividers;
1493 } dividers[] = {
1494 { even_dividers, ARRAY_SIZE(even_dividers) },
1495 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1496 };
1497 struct skl_wrpll_context ctx;
1498 unsigned int dco, d, i;
1499 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001500
Damien Lespiaudc253812015-06-25 16:15:06 +01001501 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001502
Damien Lespiaudc253812015-06-25 16:15:06 +01001503 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1504 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1505 for (i = 0; i < dividers[d].n_dividers; i++) {
1506 unsigned int p = dividers[d].list[i];
1507 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001508
Damien Lespiaudc253812015-06-25 16:15:06 +01001509 skl_wrpll_try_divider(&ctx,
1510 dco_central_freq[dco],
1511 dco_freq,
1512 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001513 /*
1514 * Skip the remaining dividers if we're sure to
1515 * have found the definitive divider, we can't
1516 * improve a 0 deviation.
1517 */
1518 if (ctx.min_deviation == 0)
1519 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001520 }
1521 }
Damien Lespiau267db662015-06-25 16:19:24 +01001522
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001523skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001524 /*
1525 * If a solution is found with an even divider, prefer
1526 * this one.
1527 */
1528 if (d == 0 && ctx.p)
1529 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001530 }
1531
Damien Lespiaudc253812015-06-25 16:15:06 +01001532 if (!ctx.p) {
1533 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001534 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001535 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001536
Damien Lespiaudc253812015-06-25 16:15:06 +01001537 /*
1538 * gcc incorrectly analyses that these can be used without being
1539 * initialized. To be fair, it's hard to guess.
1540 */
1541 p0 = p1 = p2 = 0;
1542 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1543 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1544 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001545
Damien Lespiau318bd822015-05-07 18:38:40 +01001546 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001547}
1548
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001549static bool
1550skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001551 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001552 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001553{
1554 struct intel_shared_dpll *pll;
1555 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001556 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001557
1558 /*
1559 * See comment in intel_dpll_hw_state to understand why we always use 0
1560 * as the DPLL id in this function.
1561 */
1562
1563 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1564
1565 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1566 struct skl_wrpll_params wrpll_params = { 0, };
1567
1568 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1569
Damien Lespiau318bd822015-05-07 18:38:40 +01001570 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1571 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001572
1573 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1574 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1575 wrpll_params.dco_integer;
1576
1577 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1578 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1579 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1580 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1581 wrpll_params.central_freq;
1582 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001583 switch (crtc_state->port_clock / 2) {
1584 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001585 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001586 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001587 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001588 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001589 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001590 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001591 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001592 break;
1593 }
1594
1595 cfgcr1 = cfgcr2 = 0;
1596 } else /* eDP */
1597 return true;
1598
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001599 memset(&crtc_state->dpll_hw_state, 0,
1600 sizeof(crtc_state->dpll_hw_state));
1601
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001602 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1603 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1604 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001605
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001606 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001607 if (pll == NULL) {
1608 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1609 pipe_name(intel_crtc->pipe));
1610 return false;
1611 }
1612
1613 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001614 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001615
1616 return true;
1617}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001618
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301619/* bxt clock parameters */
1620struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301621 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301622 uint32_t p1;
1623 uint32_t p2;
1624 uint32_t m2_int;
1625 uint32_t m2_frac;
1626 bool m2_frac_en;
1627 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301628};
1629
1630/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301631static const struct bxt_clk_div bxt_dp_clk_val[] = {
1632 {162000, 4, 2, 32, 1677722, 1, 1},
1633 {270000, 4, 1, 27, 0, 0, 1},
1634 {540000, 2, 1, 27, 0, 0, 1},
1635 {216000, 3, 2, 32, 1677722, 1, 1},
1636 {243000, 4, 1, 24, 1258291, 1, 1},
1637 {324000, 4, 1, 32, 1677722, 1, 1},
1638 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301639};
1640
1641static bool
1642bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1643 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001644 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301645{
1646 struct intel_shared_dpll *pll;
1647 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301648 int vco = 0;
1649 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301650 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001651 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301652
1653 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1654 intel_clock_t best_clock;
1655
1656 /* Calculate HDMI div */
1657 /*
1658 * FIXME: tie the following calculation into
1659 * i9xx_crtc_compute_clock
1660 */
1661 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1662 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1663 clock, pipe_name(intel_crtc->pipe));
1664 return false;
1665 }
1666
1667 clk_div.p1 = best_clock.p1;
1668 clk_div.p2 = best_clock.p2;
1669 WARN_ON(best_clock.m1 != 2);
1670 clk_div.n = best_clock.n;
1671 clk_div.m2_int = best_clock.m2 >> 22;
1672 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1673 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1674
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301675 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301676 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1677 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301678 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301679
Sonika Jindal64987fc2015-05-26 17:50:13 +05301680 clk_div = bxt_dp_clk_val[0];
1681 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1682 if (bxt_dp_clk_val[i].clock == clock) {
1683 clk_div = bxt_dp_clk_val[i];
1684 break;
1685 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301686 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301687 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1688 }
1689
Vandana Kannane6292552015-07-01 17:02:57 +05301690 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301691 prop_coef = 4;
1692 int_coef = 9;
1693 gain_ctl = 3;
1694 targ_cnt = 8;
1695 } else if ((vco > 5400000 && vco < 6200000) ||
1696 (vco >= 4800000 && vco < 5400000)) {
1697 prop_coef = 5;
1698 int_coef = 11;
1699 gain_ctl = 3;
1700 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301701 } else if (vco == 5400000) {
1702 prop_coef = 3;
1703 int_coef = 8;
1704 gain_ctl = 1;
1705 targ_cnt = 9;
1706 } else {
1707 DRM_ERROR("Invalid VCO\n");
1708 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301709 }
1710
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001711 memset(&crtc_state->dpll_hw_state, 0,
1712 sizeof(crtc_state->dpll_hw_state));
1713
Vandana Kannane0681e32015-05-13 12:20:35 +05301714 if (clock > 270000)
1715 lanestagger = 0x18;
1716 else if (clock > 135000)
1717 lanestagger = 0x0d;
1718 else if (clock > 67000)
1719 lanestagger = 0x07;
1720 else if (clock > 33000)
1721 lanestagger = 0x04;
1722 else
1723 lanestagger = 0x02;
1724
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301725 crtc_state->dpll_hw_state.ebb0 =
1726 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1727 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1728 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1729 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1730
1731 if (clk_div.m2_frac_en)
1732 crtc_state->dpll_hw_state.pll3 =
1733 PORT_PLL_M2_FRAC_ENABLE;
1734
1735 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301736 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301737 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301738 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301739
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301740 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1741
Imre Deak05712c12015-06-18 17:25:54 +03001742 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1743
Vandana Kannane6292552015-07-01 17:02:57 +05301744 crtc_state->dpll_hw_state.pll10 =
1745 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1746 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301747
Imre Deak05712c12015-06-18 17:25:54 +03001748 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1749
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301750 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301751 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301752
1753 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1754 if (pll == NULL) {
1755 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1756 pipe_name(intel_crtc->pipe));
1757 return false;
1758 }
1759
1760 /* shared DPLL id 0 is DPLL A */
1761 crtc_state->ddi_pll_sel = pll->id;
1762
1763 return true;
1764}
1765
Damien Lespiau0220ab62014-07-29 18:06:22 +01001766/*
1767 * Tries to find a *shared* PLL for the CRTC and store it in
1768 * intel_crtc->ddi_pll_sel.
1769 *
1770 * For private DPLLs, compute_config() should do the selection for us. This
1771 * function should be folded into compute_config() eventually.
1772 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001773bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1774 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001775{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001776 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001777 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001778 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001779
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001780 if (IS_SKYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001781 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001782 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301783 else if (IS_BROXTON(dev))
1784 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001785 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001786 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001787 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001788 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001789}
1790
Paulo Zanonidae84792012-10-15 15:51:30 -03001791void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1792{
1793 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1794 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1795 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001796 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001797 int type = intel_encoder->type;
1798 uint32_t temp;
1799
Dave Airlie0e32b392014-05-02 14:02:48 +10001800 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001801 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001802 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001803 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001804 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001805 break;
1806 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001807 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001808 break;
1809 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001810 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001811 break;
1812 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001813 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001814 break;
1815 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001816 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001817 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001818 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001819 }
1820}
1821
Dave Airlie0e32b392014-05-02 14:02:48 +10001822void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1823{
1824 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1825 struct drm_device *dev = crtc->dev;
1826 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001827 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001828 uint32_t temp;
1829 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1830 if (state == true)
1831 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1832 else
1833 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1834 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1835}
1836
Damien Lespiau8228c252013-03-07 15:30:27 +00001837void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001838{
1839 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1840 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001841 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001842 struct drm_device *dev = crtc->dev;
1843 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001844 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001845 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001846 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001847 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001848 uint32_t temp;
1849
Paulo Zanoniad80a812012-10-24 16:06:19 -02001850 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1851 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001852 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001853
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001854 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001855 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001856 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001857 break;
1858 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001859 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001860 break;
1861 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001862 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001863 break;
1864 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001865 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001866 break;
1867 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001868 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001869 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001870
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001871 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001872 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001873 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001874 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001875
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001876 if (cpu_transcoder == TRANSCODER_EDP) {
1877 switch (pipe) {
1878 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001879 /* On Haswell, can only use the always-on power well for
1880 * eDP when not using the panel fitter, and when not
1881 * using motion blur mitigation (which we don't
1882 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001883 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001884 (intel_crtc->config->pch_pfit.enabled ||
1885 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001886 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1887 else
1888 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001889 break;
1890 case PIPE_B:
1891 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1892 break;
1893 case PIPE_C:
1894 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1895 break;
1896 default:
1897 BUG();
1898 break;
1899 }
1900 }
1901
Paulo Zanoni7739c332012-10-15 15:51:29 -03001902 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001903 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001904 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001905 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001906 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001907
Paulo Zanoni7739c332012-10-15 15:51:29 -03001908 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001909 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001910 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001911
1912 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1913 type == INTEL_OUTPUT_EDP) {
1914 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1915
Dave Airlie0e32b392014-05-02 14:02:48 +10001916 if (intel_dp->is_mst) {
1917 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1918 } else
1919 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1920
1921 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
1922 } else if (type == INTEL_OUTPUT_DP_MST) {
1923 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1924
1925 if (intel_dp->is_mst) {
1926 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1927 } else
1928 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001929
Daniel Vetter17aa6be2013-04-30 14:01:40 +02001930 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001931 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001932 WARN(1, "Invalid encoder type %d for pipe %c\n",
1933 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001934 }
1935
Paulo Zanoniad80a812012-10-24 16:06:19 -02001936 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001937}
1938
Paulo Zanoniad80a812012-10-24 16:06:19 -02001939void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1940 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001941{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001942 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001943 uint32_t val = I915_READ(reg);
1944
Dave Airlie0e32b392014-05-02 14:02:48 +10001945 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001946 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001947 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001948}
1949
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001950bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1951{
1952 struct drm_device *dev = intel_connector->base.dev;
1953 struct drm_i915_private *dev_priv = dev->dev_private;
1954 struct intel_encoder *intel_encoder = intel_connector->encoder;
1955 int type = intel_connector->base.connector_type;
1956 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1957 enum pipe pipe = 0;
1958 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001959 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001960 uint32_t tmp;
1961
Paulo Zanoni882244a2014-04-01 14:55:12 -03001962 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001963 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001964 return false;
1965
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001966 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1967 return false;
1968
1969 if (port == PORT_A)
1970 cpu_transcoder = TRANSCODER_EDP;
1971 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001972 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001973
1974 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1975
1976 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1977 case TRANS_DDI_MODE_SELECT_HDMI:
1978 case TRANS_DDI_MODE_SELECT_DVI:
1979 return (type == DRM_MODE_CONNECTOR_HDMIA);
1980
1981 case TRANS_DDI_MODE_SELECT_DP_SST:
1982 if (type == DRM_MODE_CONNECTOR_eDP)
1983 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001984 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001985 case TRANS_DDI_MODE_SELECT_DP_MST:
1986 /* if the transcoder is in MST state then
1987 * connector isn't connected */
1988 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001989
1990 case TRANS_DDI_MODE_SELECT_FDI:
1991 return (type == DRM_MODE_CONNECTOR_VGA);
1992
1993 default:
1994 return false;
1995 }
1996}
1997
Daniel Vetter85234cd2012-07-02 13:27:29 +02001998bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1999 enum pipe *pipe)
2000{
2001 struct drm_device *dev = encoder->base.dev;
2002 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002003 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02002004 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002005 u32 tmp;
2006 int i;
2007
Imre Deak6d129be2014-03-05 16:20:54 +02002008 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002009 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02002010 return false;
2011
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002012 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002013
2014 if (!(tmp & DDI_BUF_CTL_ENABLE))
2015 return false;
2016
Paulo Zanoniad80a812012-10-24 16:06:19 -02002017 if (port == PORT_A) {
2018 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002019
Paulo Zanoniad80a812012-10-24 16:06:19 -02002020 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2021 case TRANS_DDI_EDP_INPUT_A_ON:
2022 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2023 *pipe = PIPE_A;
2024 break;
2025 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2026 *pipe = PIPE_B;
2027 break;
2028 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2029 *pipe = PIPE_C;
2030 break;
2031 }
2032
2033 return true;
2034 } else {
2035 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2036 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2037
2038 if ((tmp & TRANS_DDI_PORT_MASK)
2039 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002040 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2041 return false;
2042
Paulo Zanoniad80a812012-10-24 16:06:19 -02002043 *pipe = i;
2044 return true;
2045 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002046 }
2047 }
2048
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002049 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002050
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002051 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002052}
2053
Paulo Zanonifc914632012-10-05 12:05:54 -03002054void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2055{
2056 struct drm_crtc *crtc = &intel_crtc->base;
2057 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2058 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2059 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002060 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002061
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002062 if (cpu_transcoder != TRANSCODER_EDP)
2063 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2064 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002065}
2066
2067void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2068{
2069 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002070 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002071
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002072 if (cpu_transcoder != TRANSCODER_EDP)
2073 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2074 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002075}
2076
David Weinehallf8896f52015-06-25 11:11:03 +03002077static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2078 enum port port, int type)
2079{
2080 struct drm_i915_private *dev_priv = dev->dev_private;
2081 const struct ddi_buf_trans *ddi_translations;
2082 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002083 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002084 int n_entries;
2085 u32 reg;
2086
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002087 /* VBT may override standard boost values */
2088 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2089 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2090
David Weinehallf8896f52015-06-25 11:11:03 +03002091 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002092 if (dp_iboost) {
2093 iboost = dp_iboost;
2094 } else {
2095 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2096 iboost = ddi_translations[port].i_boost;
2097 }
David Weinehallf8896f52015-06-25 11:11:03 +03002098 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002099 if (dp_iboost) {
2100 iboost = dp_iboost;
2101 } else {
2102 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2103 iboost = ddi_translations[port].i_boost;
2104 }
David Weinehallf8896f52015-06-25 11:11:03 +03002105 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002106 if (hdmi_iboost) {
2107 iboost = hdmi_iboost;
2108 } else {
2109 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2110 iboost = ddi_translations[port].i_boost;
2111 }
David Weinehallf8896f52015-06-25 11:11:03 +03002112 } else {
2113 return;
2114 }
2115
2116 /* Make sure that the requested I_boost is valid */
2117 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2118 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2119 return;
2120 }
2121
2122 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2123 reg &= ~BALANCE_LEG_MASK(port);
2124 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2125
2126 if (iboost)
2127 reg |= iboost << BALANCE_LEG_SHIFT(port);
2128 else
2129 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2130
2131 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2132}
2133
2134static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2135 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302136{
2137 struct drm_i915_private *dev_priv = dev->dev_private;
2138 const struct bxt_ddi_buf_trans *ddi_translations;
2139 u32 n_entries, i;
2140 uint32_t val;
2141
2142 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
2143 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2144 ddi_translations = bxt_ddi_translations_dp;
2145 } else if (type == INTEL_OUTPUT_HDMI) {
2146 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2147 ddi_translations = bxt_ddi_translations_hdmi;
2148 } else {
2149 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2150 type);
2151 return;
2152 }
2153
2154 /* Check if default value has to be used */
2155 if (level >= n_entries ||
2156 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2157 for (i = 0; i < n_entries; i++) {
2158 if (ddi_translations[i].default_index) {
2159 level = i;
2160 break;
2161 }
2162 }
2163 }
2164
2165 /*
2166 * While we write to the group register to program all lanes at once we
2167 * can read only lane registers and we pick lanes 0/1 for that.
2168 */
2169 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2170 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2171 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2172
2173 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2174 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2175 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2176 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2177 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2178
2179 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
2180 val &= ~UNIQE_TRANGE_EN_METHOD;
2181 if (ddi_translations[level].enable)
2182 val |= UNIQE_TRANGE_EN_METHOD;
2183 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2184
2185 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2186 val &= ~DE_EMPHASIS;
2187 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2188 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2189
2190 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2191 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2192 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2193}
2194
David Weinehallf8896f52015-06-25 11:11:03 +03002195static uint32_t translate_signal_level(int signal_levels)
2196{
2197 uint32_t level;
2198
2199 switch (signal_levels) {
2200 default:
2201 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2202 signal_levels);
2203 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2204 level = 0;
2205 break;
2206 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2207 level = 1;
2208 break;
2209 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2210 level = 2;
2211 break;
2212 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2213 level = 3;
2214 break;
2215
2216 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2217 level = 4;
2218 break;
2219 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2220 level = 5;
2221 break;
2222 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2223 level = 6;
2224 break;
2225
2226 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2227 level = 7;
2228 break;
2229 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2230 level = 8;
2231 break;
2232
2233 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2234 level = 9;
2235 break;
2236 }
2237
2238 return level;
2239}
2240
2241uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2242{
2243 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2244 struct drm_device *dev = dport->base.base.dev;
2245 struct intel_encoder *encoder = &dport->base;
2246 uint8_t train_set = intel_dp->train_set[0];
2247 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2248 DP_TRAIN_PRE_EMPHASIS_MASK);
2249 enum port port = dport->port;
2250 uint32_t level;
2251
2252 level = translate_signal_level(signal_levels);
2253
2254 if (IS_SKYLAKE(dev))
2255 skl_ddi_set_iboost(dev, level, port, encoder->type);
2256 else if (IS_BROXTON(dev))
2257 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2258
2259 return DDI_BUF_TRANS_SELECT(level);
2260}
2261
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002262static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002263{
Paulo Zanonic19b0662012-10-15 15:51:41 -03002264 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002265 struct drm_device *dev = encoder->dev;
2266 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002267 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002268 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002269 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302270 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002271
2272 if (type == INTEL_OUTPUT_EDP) {
2273 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01002274 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002275 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002276
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002277 if (IS_SKYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002278 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002279 uint32_t val;
2280
Damien Lespiau5416d872014-11-14 17:24:33 +00002281 /*
2282 * DPLL0 is used for eDP and is the only "private" DPLL (as
2283 * opposed to shared) on SKL
2284 */
2285 if (type == INTEL_OUTPUT_EDP) {
2286 WARN_ON(dpll != SKL_DPLL0);
2287
2288 val = I915_READ(DPLL_CTRL1);
2289
2290 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2291 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002292 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002293 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002294
2295 I915_WRITE(DPLL_CTRL1, val);
2296 POSTING_READ(DPLL_CTRL1);
2297 }
2298
2299 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002300 val = I915_READ(DPLL_CTRL2);
2301
2302 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2303 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2304 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2305 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2306
2307 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002308
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302309 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002310 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2311 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002312 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002313
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002314 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002315 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002316
Dave Airlie44905a272014-05-02 13:36:43 +10002317 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002318
2319 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2320 intel_dp_start_link_train(intel_dp);
2321 intel_dp_complete_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002322 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002323 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002324 } else if (type == INTEL_OUTPUT_HDMI) {
2325 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2326
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302327 if (IS_BROXTON(dev)) {
2328 hdmi_level = dev_priv->vbt.
2329 ddi_port_info[port].hdmi_level_shift;
2330 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2331 INTEL_OUTPUT_HDMI);
2332 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002333 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002334 crtc->config->has_hdmi_sink,
2335 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002336 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002337}
2338
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002339static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002340{
2341 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002342 struct drm_device *dev = encoder->dev;
2343 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002344 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002345 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002346 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002347 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002348
2349 val = I915_READ(DDI_BUF_CTL(port));
2350 if (val & DDI_BUF_CTL_ENABLE) {
2351 val &= ~DDI_BUF_CTL_ENABLE;
2352 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002353 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002354 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002355
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002356 val = I915_READ(DP_TP_CTL(port));
2357 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2358 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2359 I915_WRITE(DP_TP_CTL(port), val);
2360
2361 if (wait)
2362 intel_wait_ddi_buf_idle(dev_priv, port);
2363
Jani Nikula76bb80e2013-11-15 15:29:57 +02002364 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002365 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002366 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002367 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002368 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002369 }
2370
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002371 if (IS_SKYLAKE(dev))
2372 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2373 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302374 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002375 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002376}
2377
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002378static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002379{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002380 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002381 struct drm_crtc *crtc = encoder->crtc;
2382 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002383 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002384 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002385 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2386 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002387
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002388 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002389 struct intel_digital_port *intel_dig_port =
2390 enc_to_dig_port(encoder);
2391
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002392 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2393 * are ignored so nothing special needs to be done besides
2394 * enabling the port.
2395 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002396 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002397 intel_dig_port->saved_port_bits |
2398 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002399 } else if (type == INTEL_OUTPUT_EDP) {
2400 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2401
Vandana Kannan23f08d82014-11-13 14:55:22 +00002402 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002403 intel_dp_stop_link_train(intel_dp);
2404
Daniel Vetter4be73782014-01-17 14:39:48 +01002405 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002406 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302407 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002408 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002409
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002410 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002411 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002412 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002413 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002414}
2415
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002416static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002417{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002418 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002419 struct drm_crtc *crtc = encoder->crtc;
2420 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002421 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002422 struct drm_device *dev = encoder->dev;
2423 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002424
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002425 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002426 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002427 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2428 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002429
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002430 if (type == INTEL_OUTPUT_EDP) {
2431 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2432
Vandana Kannanc3955782015-01-22 15:17:40 +05302433 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002434 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002435 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002436 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002437}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002438
Daniel Vettere0b01be2014-06-25 22:02:01 +03002439static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2440 struct intel_shared_dpll *pll)
2441{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002442 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002443 POSTING_READ(WRPLL_CTL(pll->id));
2444 udelay(20);
2445}
2446
Daniel Vetter12030432014-06-25 22:02:00 +03002447static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2448 struct intel_shared_dpll *pll)
2449{
2450 uint32_t val;
2451
2452 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002453 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2454 POSTING_READ(WRPLL_CTL(pll->id));
2455}
2456
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002457static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2458 struct intel_shared_dpll *pll,
2459 struct intel_dpll_hw_state *hw_state)
2460{
2461 uint32_t val;
2462
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002463 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002464 return false;
2465
2466 val = I915_READ(WRPLL_CTL(pll->id));
2467 hw_state->wrpll = val;
2468
2469 return val & WRPLL_PLL_ENABLE;
2470}
2471
Damien Lespiauca1381b2014-07-15 15:05:33 +01002472static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002473 "WRPLL 1",
2474 "WRPLL 2",
2475};
2476
Damien Lespiau143b3072014-07-29 18:06:19 +01002477static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002478{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002479 int i;
2480
Daniel Vetter716c2e52014-06-25 22:02:02 +03002481 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002482
Daniel Vetter716c2e52014-06-25 22:02:02 +03002483 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002484 dev_priv->shared_dplls[i].id = i;
2485 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002486 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002487 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002488 dev_priv->shared_dplls[i].get_hw_state =
2489 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002490 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002491}
2492
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002493static const char * const skl_ddi_pll_names[] = {
2494 "DPLL 1",
2495 "DPLL 2",
2496 "DPLL 3",
2497};
2498
2499struct skl_dpll_regs {
2500 u32 ctl, cfgcr1, cfgcr2;
2501};
2502
2503/* this array is indexed by the *shared* pll id */
2504static const struct skl_dpll_regs skl_dpll_regs[3] = {
2505 {
2506 /* DPLL 1 */
2507 .ctl = LCPLL2_CTL,
2508 .cfgcr1 = DPLL1_CFGCR1,
2509 .cfgcr2 = DPLL1_CFGCR2,
2510 },
2511 {
2512 /* DPLL 2 */
2513 .ctl = WRPLL_CTL1,
2514 .cfgcr1 = DPLL2_CFGCR1,
2515 .cfgcr2 = DPLL2_CFGCR2,
2516 },
2517 {
2518 /* DPLL 3 */
2519 .ctl = WRPLL_CTL2,
2520 .cfgcr1 = DPLL3_CFGCR1,
2521 .cfgcr2 = DPLL3_CFGCR2,
2522 },
2523};
2524
2525static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2526 struct intel_shared_dpll *pll)
2527{
2528 uint32_t val;
2529 unsigned int dpll;
2530 const struct skl_dpll_regs *regs = skl_dpll_regs;
2531
2532 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2533 dpll = pll->id + 1;
2534
2535 val = I915_READ(DPLL_CTRL1);
2536
2537 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002538 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002539 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2540
2541 I915_WRITE(DPLL_CTRL1, val);
2542 POSTING_READ(DPLL_CTRL1);
2543
2544 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2545 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2546 POSTING_READ(regs[pll->id].cfgcr1);
2547 POSTING_READ(regs[pll->id].cfgcr2);
2548
2549 /* the enable bit is always bit 31 */
2550 I915_WRITE(regs[pll->id].ctl,
2551 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2552
2553 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2554 DRM_ERROR("DPLL %d not locked\n", dpll);
2555}
2556
2557static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2558 struct intel_shared_dpll *pll)
2559{
2560 const struct skl_dpll_regs *regs = skl_dpll_regs;
2561
2562 /* the enable bit is always bit 31 */
2563 I915_WRITE(regs[pll->id].ctl,
2564 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2565 POSTING_READ(regs[pll->id].ctl);
2566}
2567
2568static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2569 struct intel_shared_dpll *pll,
2570 struct intel_dpll_hw_state *hw_state)
2571{
2572 uint32_t val;
2573 unsigned int dpll;
2574 const struct skl_dpll_regs *regs = skl_dpll_regs;
2575
2576 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2577 return false;
2578
2579 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2580 dpll = pll->id + 1;
2581
2582 val = I915_READ(regs[pll->id].ctl);
2583 if (!(val & LCPLL_PLL_ENABLE))
2584 return false;
2585
2586 val = I915_READ(DPLL_CTRL1);
2587 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2588
2589 /* avoid reading back stale values if HDMI mode is not enabled */
2590 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2591 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2592 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2593 }
2594
2595 return true;
2596}
2597
2598static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2599{
2600 int i;
2601
2602 dev_priv->num_shared_dpll = 3;
2603
2604 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2605 dev_priv->shared_dplls[i].id = i;
2606 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2607 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2608 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2609 dev_priv->shared_dplls[i].get_hw_state =
2610 skl_ddi_pll_get_hw_state;
2611 }
2612}
2613
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302614static void broxton_phy_init(struct drm_i915_private *dev_priv,
2615 enum dpio_phy phy)
2616{
2617 enum port port;
2618 uint32_t val;
2619
2620 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2621 val |= GT_DISPLAY_POWER_ON(phy);
2622 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2623
2624 /* Considering 10ms timeout until BSpec is updated */
2625 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2626 DRM_ERROR("timeout during PHY%d power on\n", phy);
2627
2628 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2629 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2630 int lane;
2631
2632 for (lane = 0; lane < 4; lane++) {
2633 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2634 /*
2635 * Note that on CHV this flag is called UPAR, but has
2636 * the same function.
2637 */
2638 val &= ~LATENCY_OPTIM;
2639 if (lane != 1)
2640 val |= LATENCY_OPTIM;
2641
2642 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2643 }
2644 }
2645
2646 /* Program PLL Rcomp code offset */
2647 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2648 val &= ~IREF0RC_OFFSET_MASK;
2649 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2650 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2651
2652 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2653 val &= ~IREF1RC_OFFSET_MASK;
2654 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2655 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2656
2657 /* Program power gating */
2658 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2659 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2660 SUS_CLK_CONFIG;
2661 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2662
2663 if (phy == DPIO_PHY0) {
2664 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2665 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2666 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2667 }
2668
2669 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2670 val &= ~OCL2_LDOFUSE_PWR_DIS;
2671 /*
2672 * On PHY1 disable power on the second channel, since no port is
2673 * connected there. On PHY0 both channels have a port, so leave it
2674 * enabled.
2675 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2676 * power down the second channel on PHY0 as well.
2677 */
2678 if (phy == DPIO_PHY1)
2679 val |= OCL2_LDOFUSE_PWR_DIS;
2680 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2681
2682 if (phy == DPIO_PHY0) {
2683 uint32_t grc_code;
2684 /*
2685 * PHY0 isn't connected to an RCOMP resistor so copy over
2686 * the corresponding calibrated value from PHY1, and disable
2687 * the automatic calibration on PHY0.
2688 */
2689 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2690 10))
2691 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2692
2693 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2694 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2695 grc_code = val << GRC_CODE_FAST_SHIFT |
2696 val << GRC_CODE_SLOW_SHIFT |
2697 val;
2698 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2699
2700 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2701 val |= GRC_DIS | GRC_RDY_OVRD;
2702 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2703 }
2704
2705 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2706 val |= COMMON_RESET_DIS;
2707 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2708}
2709
2710void broxton_ddi_phy_init(struct drm_device *dev)
2711{
2712 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2713 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2714 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2715}
2716
2717static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2718 enum dpio_phy phy)
2719{
2720 uint32_t val;
2721
2722 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2723 val &= ~COMMON_RESET_DIS;
2724 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2725}
2726
2727void broxton_ddi_phy_uninit(struct drm_device *dev)
2728{
2729 struct drm_i915_private *dev_priv = dev->dev_private;
2730
2731 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2732 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2733
2734 /* FIXME: do this in broxton_phy_uninit per phy */
2735 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2736}
2737
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302738static const char * const bxt_ddi_pll_names[] = {
2739 "PORT PLL A",
2740 "PORT PLL B",
2741 "PORT PLL C",
2742};
2743
2744static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2745 struct intel_shared_dpll *pll)
2746{
2747 uint32_t temp;
2748 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2749
2750 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2751 temp &= ~PORT_PLL_REF_SEL;
2752 /* Non-SSC reference */
2753 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2754
2755 /* Disable 10 bit clock */
2756 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2757 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2758 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2759
2760 /* Write P1 & P2 */
2761 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2762 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2763 temp |= pll->config.hw_state.ebb0;
2764 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2765
2766 /* Write M2 integer */
2767 temp = I915_READ(BXT_PORT_PLL(port, 0));
2768 temp &= ~PORT_PLL_M2_MASK;
2769 temp |= pll->config.hw_state.pll0;
2770 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2771
2772 /* Write N */
2773 temp = I915_READ(BXT_PORT_PLL(port, 1));
2774 temp &= ~PORT_PLL_N_MASK;
2775 temp |= pll->config.hw_state.pll1;
2776 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2777
2778 /* Write M2 fraction */
2779 temp = I915_READ(BXT_PORT_PLL(port, 2));
2780 temp &= ~PORT_PLL_M2_FRAC_MASK;
2781 temp |= pll->config.hw_state.pll2;
2782 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2783
2784 /* Write M2 fraction enable */
2785 temp = I915_READ(BXT_PORT_PLL(port, 3));
2786 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2787 temp |= pll->config.hw_state.pll3;
2788 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2789
2790 /* Write coeff */
2791 temp = I915_READ(BXT_PORT_PLL(port, 6));
2792 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2793 temp &= ~PORT_PLL_INT_COEFF_MASK;
2794 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2795 temp |= pll->config.hw_state.pll6;
2796 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2797
2798 /* Write calibration val */
2799 temp = I915_READ(BXT_PORT_PLL(port, 8));
2800 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2801 temp |= pll->config.hw_state.pll8;
2802 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2803
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302804 temp = I915_READ(BXT_PORT_PLL(port, 9));
2805 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002806 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302807 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2808
2809 temp = I915_READ(BXT_PORT_PLL(port, 10));
2810 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2811 temp &= ~PORT_PLL_DCO_AMP_MASK;
2812 temp |= pll->config.hw_state.pll10;
2813 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302814
2815 /* Recalibrate with new settings */
2816 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2817 temp |= PORT_PLL_RECALIBRATE;
2818 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002819 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2820 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302821 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2822
2823 /* Enable PLL */
2824 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2825 temp |= PORT_PLL_ENABLE;
2826 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2827 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2828
2829 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2830 PORT_PLL_LOCK), 200))
2831 DRM_ERROR("PLL %d not locked\n", port);
2832
2833 /*
2834 * While we write to the group register to program all lanes at once we
2835 * can read only lane registers and we pick lanes 0/1 for that.
2836 */
2837 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2838 temp &= ~LANE_STAGGER_MASK;
2839 temp &= ~LANESTAGGER_STRAP_OVRD;
2840 temp |= pll->config.hw_state.pcsdw12;
2841 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2842}
2843
2844static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2845 struct intel_shared_dpll *pll)
2846{
2847 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2848 uint32_t temp;
2849
2850 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2851 temp &= ~PORT_PLL_ENABLE;
2852 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2853 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2854}
2855
2856static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2857 struct intel_shared_dpll *pll,
2858 struct intel_dpll_hw_state *hw_state)
2859{
2860 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2861 uint32_t val;
2862
2863 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2864 return false;
2865
2866 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2867 if (!(val & PORT_PLL_ENABLE))
2868 return false;
2869
2870 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002871 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2872
Imre Deak05712c12015-06-18 17:25:54 +03002873 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2874 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2875
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302876 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002877 hw_state->pll0 &= PORT_PLL_M2_MASK;
2878
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302879 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002880 hw_state->pll1 &= PORT_PLL_N_MASK;
2881
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302882 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002883 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2884
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302885 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002886 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2887
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302888 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002889 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2890 PORT_PLL_INT_COEFF_MASK |
2891 PORT_PLL_GAIN_CTL_MASK;
2892
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302893 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002894 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2895
Imre Deak05712c12015-06-18 17:25:54 +03002896 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2897 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2898
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302899 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002900 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2901 PORT_PLL_DCO_AMP_MASK;
2902
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302903 /*
2904 * While we write to the group register to program all lanes at once we
2905 * can read only lane registers. We configure all lanes the same way, so
2906 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2907 */
2908 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2909 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port) != hw_state->pcsdw12))
2910 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2911 hw_state->pcsdw12,
2912 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002913 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302914
2915 return true;
2916}
2917
2918static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2919{
2920 int i;
2921
2922 dev_priv->num_shared_dpll = 3;
2923
2924 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2925 dev_priv->shared_dplls[i].id = i;
2926 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2927 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2928 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2929 dev_priv->shared_dplls[i].get_hw_state =
2930 bxt_ddi_pll_get_hw_state;
2931 }
2932}
2933
Damien Lespiau143b3072014-07-29 18:06:19 +01002934void intel_ddi_pll_init(struct drm_device *dev)
2935{
2936 struct drm_i915_private *dev_priv = dev->dev_private;
2937 uint32_t val = I915_READ(LCPLL_CTL);
2938
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002939 if (IS_SKYLAKE(dev))
2940 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302941 else if (IS_BROXTON(dev))
2942 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002943 else
2944 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002945
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002946 if (IS_SKYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002947 int cdclk_freq;
2948
2949 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002950 dev_priv->skl_boot_cdclk = cdclk_freq;
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002951 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2952 DRM_ERROR("LCPLL1 is disabled\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002953 else
2954 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302955 } else if (IS_BROXTON(dev)) {
2956 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302957 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002958 } else {
2959 /*
2960 * The LCPLL register should be turned on by the BIOS. For now
2961 * let's just check its state and print errors in case
2962 * something is wrong. Don't even try to turn it on.
2963 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002964
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002965 if (val & LCPLL_CD_SOURCE_FCLK)
2966 DRM_ERROR("CDCLK source is not LCPLL\n");
2967
2968 if (val & LCPLL_PLL_DISABLE)
2969 DRM_ERROR("LCPLL is disabled\n");
2970 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002971}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002972
2973void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
2974{
Paulo Zanoni174edf12012-10-26 19:05:50 -02002975 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
2976 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002977 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02002978 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002979 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302980 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002981
2982 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2983 val = I915_READ(DDI_BUF_CTL(port));
2984 if (val & DDI_BUF_CTL_ENABLE) {
2985 val &= ~DDI_BUF_CTL_ENABLE;
2986 I915_WRITE(DDI_BUF_CTL(port), val);
2987 wait = true;
2988 }
2989
2990 val = I915_READ(DP_TP_CTL(port));
2991 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2992 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2993 I915_WRITE(DP_TP_CTL(port), val);
2994 POSTING_READ(DP_TP_CTL(port));
2995
2996 if (wait)
2997 intel_wait_ddi_buf_idle(dev_priv, port);
2998 }
2999
Dave Airlie0e32b392014-05-02 14:02:48 +10003000 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003001 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003002 if (intel_dp->is_mst)
3003 val |= DP_TP_CTL_MODE_MST;
3004 else {
3005 val |= DP_TP_CTL_MODE_SST;
3006 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3007 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3008 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003009 I915_WRITE(DP_TP_CTL(port), val);
3010 POSTING_READ(DP_TP_CTL(port));
3011
3012 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3013 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3014 POSTING_READ(DDI_BUF_CTL(port));
3015
3016 udelay(600);
3017}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003018
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003019void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3020{
3021 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3022 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3023 uint32_t val;
3024
3025 intel_ddi_post_disable(intel_encoder);
3026
3027 val = I915_READ(_FDI_RXA_CTL);
3028 val &= ~FDI_RX_ENABLE;
3029 I915_WRITE(_FDI_RXA_CTL, val);
3030
3031 val = I915_READ(_FDI_RXA_MISC);
3032 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3033 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
3034 I915_WRITE(_FDI_RXA_MISC, val);
3035
3036 val = I915_READ(_FDI_RXA_CTL);
3037 val &= ~FDI_PCDCLK;
3038 I915_WRITE(_FDI_RXA_CTL, val);
3039
3040 val = I915_READ(_FDI_RXA_CTL);
3041 val &= ~FDI_RX_PLL_ENABLE;
3042 I915_WRITE(_FDI_RXA_CTL, val);
3043}
3044
Ville Syrjälä6801c182013-09-24 14:24:05 +03003045void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003046 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003047{
3048 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3049 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003050 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003051 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003052 u32 temp, flags = 0;
3053
3054 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3055 if (temp & TRANS_DDI_PHSYNC)
3056 flags |= DRM_MODE_FLAG_PHSYNC;
3057 else
3058 flags |= DRM_MODE_FLAG_NHSYNC;
3059 if (temp & TRANS_DDI_PVSYNC)
3060 flags |= DRM_MODE_FLAG_PVSYNC;
3061 else
3062 flags |= DRM_MODE_FLAG_NVSYNC;
3063
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003064 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003065
3066 switch (temp & TRANS_DDI_BPC_MASK) {
3067 case TRANS_DDI_BPC_6:
3068 pipe_config->pipe_bpp = 18;
3069 break;
3070 case TRANS_DDI_BPC_8:
3071 pipe_config->pipe_bpp = 24;
3072 break;
3073 case TRANS_DDI_BPC_10:
3074 pipe_config->pipe_bpp = 30;
3075 break;
3076 case TRANS_DDI_BPC_12:
3077 pipe_config->pipe_bpp = 36;
3078 break;
3079 default:
3080 break;
3081 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003082
3083 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3084 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003085 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003086 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3087
3088 if (intel_hdmi->infoframe_enabled(&encoder->base))
3089 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003090 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003091 case TRANS_DDI_MODE_SELECT_DVI:
3092 case TRANS_DDI_MODE_SELECT_FDI:
3093 break;
3094 case TRANS_DDI_MODE_SELECT_DP_SST:
3095 case TRANS_DDI_MODE_SELECT_DP_MST:
3096 pipe_config->has_dp_encoder = true;
3097 intel_dp_get_m_n(intel_crtc, pipe_config);
3098 break;
3099 default:
3100 break;
3101 }
Daniel Vetter10214422013-11-18 07:38:16 +01003102
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003103 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003104 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003105 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003106 pipe_config->has_audio = true;
3107 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003108
Daniel Vetter10214422013-11-18 07:38:16 +01003109 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3110 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3111 /*
3112 * This is a big fat ugly hack.
3113 *
3114 * Some machines in UEFI boot mode provide us a VBT that has 18
3115 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3116 * unknown we fail to light up. Yet the same BIOS boots up with
3117 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3118 * max, not what it tells us to use.
3119 *
3120 * Note: This will still be broken if the eDP panel is not lit
3121 * up by the BIOS, and thus we can't get the mode at module
3122 * load.
3123 */
3124 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3125 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3126 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3127 }
Jesse Barnes11578552014-01-21 12:42:10 -08003128
Damien Lespiau22606a12014-12-12 14:26:57 +00003129 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003130}
3131
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003132static void intel_ddi_destroy(struct drm_encoder *encoder)
3133{
3134 /* HDMI has nothing special to destroy, so we can go with this. */
3135 intel_dp_encoder_destroy(encoder);
3136}
3137
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003138static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003139 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003140{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003141 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003142 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003143
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003144 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003145
Daniel Vettereccb1402013-05-22 00:50:22 +02003146 if (port == PORT_A)
3147 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3148
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003149 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003150 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003151 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003152 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003153}
3154
3155static const struct drm_encoder_funcs intel_ddi_funcs = {
3156 .destroy = intel_ddi_destroy,
3157};
3158
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003159static struct intel_connector *
3160intel_ddi_init_dp_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->dp.output_reg = DDI_BUF_CTL(port);
3170 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3171 kfree(connector);
3172 return NULL;
3173 }
3174
3175 return connector;
3176}
3177
3178static struct intel_connector *
3179intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3180{
3181 struct intel_connector *connector;
3182 enum port port = intel_dig_port->port;
3183
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003184 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003185 if (!connector)
3186 return NULL;
3187
3188 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3189 intel_hdmi_init_connector(intel_dig_port, connector);
3190
3191 return connector;
3192}
3193
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003194void intel_ddi_init(struct drm_device *dev, enum port port)
3195{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003196 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003197 struct intel_digital_port *intel_dig_port;
3198 struct intel_encoder *intel_encoder;
3199 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003200 bool init_hdmi, init_dp;
3201
3202 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3203 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3204 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3205 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003206 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003207 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003208 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003209 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003210
Daniel Vetterb14c5672013-09-19 12:18:32 +02003211 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003212 if (!intel_dig_port)
3213 return;
3214
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003215 intel_encoder = &intel_dig_port->base;
3216 encoder = &intel_encoder->base;
3217
3218 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3219 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003220
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003221 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003222 intel_encoder->enable = intel_enable_ddi;
3223 intel_encoder->pre_enable = intel_ddi_pre_enable;
3224 intel_encoder->disable = intel_disable_ddi;
3225 intel_encoder->post_disable = intel_ddi_post_disable;
3226 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003227 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003228
3229 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003230 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3231 (DDI_BUF_PORT_REVERSAL |
3232 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003233
3234 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003235 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003236 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003237
Chris Wilsonf68d6972014-08-04 07:15:09 +01003238 if (init_dp) {
3239 if (!intel_ddi_init_dp_connector(intel_dig_port))
3240 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003241
Chris Wilsonf68d6972014-08-04 07:15:09 +01003242 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303243 /*
3244 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3245 * interrupts to check the external panel connection.
3246 */
3247 if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)
3248 && port == PORT_B)
3249 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3250 else
3251 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003252 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003253
Paulo Zanoni311a2092013-09-12 17:12:18 -03003254 /* In theory we don't need the encoder->type check, but leave it just in
3255 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003256 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3257 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3258 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003259 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003260
3261 return;
3262
3263err:
3264 drm_encoder_cleanup(encoder);
3265 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003266}