blob: cef9709fa2baecdf5679d7faadd82bea4bb31a84 [file] [log] [blame]
Eugeni Dodonov45244b82012-05-09 15:37:20 -03001/*
2 * Copyright © 2012 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eugeni Dodonov <eugeni.dodonov@intel.com>
25 *
26 */
27
28#include "i915_drv.h"
29#include "intel_drv.h"
30
Jani Nikula10122052014-08-27 16:27:30 +030031struct ddi_buf_trans {
32 u32 trans1; /* balance leg enable, de-emph level */
33 u32 trans2; /* vref sel, vswing */
David Weinehallf8896f52015-06-25 11:11:03 +030034 u8 i_boost; /* SKL: I_boost; valid: 0x0, 0x1, 0x3, 0x7 */
Jani Nikula10122052014-08-27 16:27:30 +030035};
36
Eugeni Dodonov45244b82012-05-09 15:37:20 -030037/* HDMI/DVI modes ignore everything but the last 2 items. So we share
38 * them for both DP and FDI transports, allowing those ports to
39 * automatically adapt to HDMI connections as well
40 */
Jani Nikula10122052014-08-27 16:27:30 +030041static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030042 { 0x00FFFFFF, 0x0006000E, 0x0 },
43 { 0x00D75FFF, 0x0005000A, 0x0 },
44 { 0x00C30FFF, 0x00040006, 0x0 },
45 { 0x80AAAFFF, 0x000B0000, 0x0 },
46 { 0x00FFFFFF, 0x0005000A, 0x0 },
47 { 0x00D75FFF, 0x000C0004, 0x0 },
48 { 0x80C30FFF, 0x000B0000, 0x0 },
49 { 0x00FFFFFF, 0x00040006, 0x0 },
50 { 0x80D75FFF, 0x000B0000, 0x0 },
Eugeni Dodonov45244b82012-05-09 15:37:20 -030051};
52
Jani Nikula10122052014-08-27 16:27:30 +030053static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030054 { 0x00FFFFFF, 0x0007000E, 0x0 },
55 { 0x00D75FFF, 0x000F000A, 0x0 },
56 { 0x00C30FFF, 0x00060006, 0x0 },
57 { 0x00AAAFFF, 0x001E0000, 0x0 },
58 { 0x00FFFFFF, 0x000F000A, 0x0 },
59 { 0x00D75FFF, 0x00160004, 0x0 },
60 { 0x00C30FFF, 0x001E0000, 0x0 },
61 { 0x00FFFFFF, 0x00060006, 0x0 },
62 { 0x00D75FFF, 0x001E0000, 0x0 },
Paulo Zanoni6acab152013-09-12 17:06:24 -030063};
64
Jani Nikula10122052014-08-27 16:27:30 +030065static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
66 /* Idx NT mV d T mV d db */
David Weinehallf8896f52015-06-25 11:11:03 +030067 { 0x00FFFFFF, 0x0006000E, 0x0 },/* 0: 400 400 0 */
68 { 0x00E79FFF, 0x000E000C, 0x0 },/* 1: 400 500 2 */
69 { 0x00D75FFF, 0x0005000A, 0x0 },/* 2: 400 600 3.5 */
70 { 0x00FFFFFF, 0x0005000A, 0x0 },/* 3: 600 600 0 */
71 { 0x00E79FFF, 0x001D0007, 0x0 },/* 4: 600 750 2 */
72 { 0x00D75FFF, 0x000C0004, 0x0 },/* 5: 600 900 3.5 */
73 { 0x00FFFFFF, 0x00040006, 0x0 },/* 6: 800 800 0 */
74 { 0x80E79FFF, 0x00030002, 0x0 },/* 7: 800 1000 2 */
75 { 0x00FFFFFF, 0x00140005, 0x0 },/* 8: 850 850 0 */
76 { 0x00FFFFFF, 0x000C0004, 0x0 },/* 9: 900 900 0 */
77 { 0x00FFFFFF, 0x001C0003, 0x0 },/* 10: 950 950 0 */
78 { 0x80FFFFFF, 0x00030002, 0x0 },/* 11: 1000 1000 0 */
Eugeni Dodonov45244b82012-05-09 15:37:20 -030079};
80
Jani Nikula10122052014-08-27 16:27:30 +030081static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030082 { 0x00FFFFFF, 0x00000012, 0x0 },
83 { 0x00EBAFFF, 0x00020011, 0x0 },
84 { 0x00C71FFF, 0x0006000F, 0x0 },
85 { 0x00AAAFFF, 0x000E000A, 0x0 },
86 { 0x00FFFFFF, 0x00020011, 0x0 },
87 { 0x00DB6FFF, 0x0005000F, 0x0 },
88 { 0x00BEEFFF, 0x000A000C, 0x0 },
89 { 0x00FFFFFF, 0x0005000F, 0x0 },
90 { 0x00DB6FFF, 0x000A000C, 0x0 },
Paulo Zanoni300644c2013-11-02 21:07:42 -070091};
92
Jani Nikula10122052014-08-27 16:27:30 +030093static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030094 { 0x00FFFFFF, 0x0007000E, 0x0 },
95 { 0x00D75FFF, 0x000E000A, 0x0 },
96 { 0x00BEFFFF, 0x00140006, 0x0 },
97 { 0x80B2CFFF, 0x001B0002, 0x0 },
98 { 0x00FFFFFF, 0x000E000A, 0x0 },
99 { 0x00DB6FFF, 0x00160005, 0x0 },
100 { 0x80C71FFF, 0x001A0002, 0x0 },
101 { 0x00F7DFFF, 0x00180004, 0x0 },
102 { 0x80D75FFF, 0x001B0002, 0x0 },
Art Runyane58623c2013-11-02 21:07:41 -0700103};
104
Jani Nikula10122052014-08-27 16:27:30 +0300105static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300106 { 0x00FFFFFF, 0x0001000E, 0x0 },
107 { 0x00D75FFF, 0x0004000A, 0x0 },
108 { 0x00C30FFF, 0x00070006, 0x0 },
109 { 0x00AAAFFF, 0x000C0000, 0x0 },
110 { 0x00FFFFFF, 0x0004000A, 0x0 },
111 { 0x00D75FFF, 0x00090004, 0x0 },
112 { 0x00C30FFF, 0x000C0000, 0x0 },
113 { 0x00FFFFFF, 0x00070006, 0x0 },
114 { 0x00D75FFF, 0x000C0000, 0x0 },
Art Runyane58623c2013-11-02 21:07:41 -0700115};
116
Jani Nikula10122052014-08-27 16:27:30 +0300117static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
118 /* Idx NT mV d T mV df db */
David Weinehallf8896f52015-06-25 11:11:03 +0300119 { 0x00FFFFFF, 0x0007000E, 0x0 },/* 0: 400 400 0 */
120 { 0x00D75FFF, 0x000E000A, 0x0 },/* 1: 400 600 3.5 */
121 { 0x00BEFFFF, 0x00140006, 0x0 },/* 2: 400 800 6 */
122 { 0x00FFFFFF, 0x0009000D, 0x0 },/* 3: 450 450 0 */
123 { 0x00FFFFFF, 0x000E000A, 0x0 },/* 4: 600 600 0 */
124 { 0x00D7FFFF, 0x00140006, 0x0 },/* 5: 600 800 2.5 */
125 { 0x80CB2FFF, 0x001B0002, 0x0 },/* 6: 600 1000 4.5 */
126 { 0x00FFFFFF, 0x00140006, 0x0 },/* 7: 800 800 0 */
127 { 0x80E79FFF, 0x001B0002, 0x0 },/* 8: 800 1000 2 */
128 { 0x80FFFFFF, 0x001B0002, 0x0 },/* 9: 1000 1000 0 */
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100129};
130
David Weinehallf8896f52015-06-25 11:11:03 +0300131/* Skylake H, S, and Skylake Y with 0.95V VccIO */
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000132static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300133 { 0x00002016, 0x000000A0, 0x0 },
134 { 0x00005012, 0x0000009B, 0x0 },
135 { 0x00007011, 0x00000088, 0x0 },
136 { 0x00009010, 0x000000C7, 0x0 },
137 { 0x00002016, 0x0000009B, 0x0 },
138 { 0x00005012, 0x00000088, 0x0 },
139 { 0x00007011, 0x000000C7, 0x0 },
140 { 0x00002016, 0x000000DF, 0x0 },
141 { 0x00005012, 0x000000C7, 0x0 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000142};
143
David Weinehallf8896f52015-06-25 11:11:03 +0300144/* Skylake U */
145static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
146 { 0x00002016, 0x000000A2, 0x0 },
147 { 0x00005012, 0x00000088, 0x0 },
148 { 0x00007011, 0x00000087, 0x0 },
149 { 0x80009010, 0x000000C7, 0x1 }, /* Uses I_boost */
150 { 0x00002016, 0x0000009D, 0x0 },
151 { 0x00005012, 0x000000C7, 0x0 },
152 { 0x00007011, 0x000000C7, 0x0 },
153 { 0x00002016, 0x00000088, 0x0 },
154 { 0x00005012, 0x000000C7, 0x0 },
155};
156
157/* Skylake Y with 0.85V VccIO */
158static const struct ddi_buf_trans skl_y_085v_ddi_translations_dp[] = {
159 { 0x00000018, 0x000000A2, 0x0 },
160 { 0x00005012, 0x00000088, 0x0 },
161 { 0x00007011, 0x00000087, 0x0 },
162 { 0x80009010, 0x000000C7, 0x1 }, /* Uses I_boost */
163 { 0x00000018, 0x0000009D, 0x0 },
164 { 0x00005012, 0x000000C7, 0x0 },
165 { 0x00007011, 0x000000C7, 0x0 },
166 { 0x00000018, 0x00000088, 0x0 },
167 { 0x00005012, 0x000000C7, 0x0 },
168};
169
170/*
171 * Skylake H and S, and Skylake Y with 0.95V VccIO
172 * eDP 1.4 low vswing translation parameters
173 */
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530174static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300175 { 0x00000018, 0x000000A8, 0x0 },
176 { 0x00004013, 0x000000A9, 0x0 },
177 { 0x00007011, 0x000000A2, 0x0 },
178 { 0x00009010, 0x0000009C, 0x0 },
179 { 0x00000018, 0x000000A9, 0x0 },
180 { 0x00006013, 0x000000A2, 0x0 },
181 { 0x00007011, 0x000000A6, 0x0 },
182 { 0x00000018, 0x000000AB, 0x0 },
183 { 0x00007013, 0x0000009F, 0x0 },
184 { 0x00000018, 0x000000DF, 0x0 },
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530185};
186
David Weinehallf8896f52015-06-25 11:11:03 +0300187/*
188 * Skylake U
189 * eDP 1.4 low vswing translation parameters
190 */
191static const struct ddi_buf_trans skl_u_ddi_translations_edp[] = {
192 { 0x00000018, 0x000000A8, 0x0 },
193 { 0x00004013, 0x000000A9, 0x0 },
194 { 0x00007011, 0x000000A2, 0x0 },
195 { 0x00009010, 0x0000009C, 0x0 },
196 { 0x00000018, 0x000000A9, 0x0 },
197 { 0x00006013, 0x000000A2, 0x0 },
198 { 0x00007011, 0x000000A6, 0x0 },
199 { 0x00002016, 0x000000AB, 0x0 },
200 { 0x00005013, 0x0000009F, 0x0 },
201 { 0x00000018, 0x000000DF, 0x0 },
202};
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530203
David Weinehallf8896f52015-06-25 11:11:03 +0300204/*
205 * Skylake Y with 0.95V VccIO
206 * eDP 1.4 low vswing translation parameters
207 */
208static const struct ddi_buf_trans skl_y_085v_ddi_translations_edp[] = {
209 { 0x00000018, 0x000000A8, 0x0 },
210 { 0x00004013, 0x000000AB, 0x0 },
211 { 0x00007011, 0x000000A4, 0x0 },
212 { 0x00009010, 0x000000DF, 0x0 },
213 { 0x00000018, 0x000000AA, 0x0 },
214 { 0x00006013, 0x000000A4, 0x0 },
215 { 0x00007011, 0x0000009D, 0x0 },
216 { 0x00000018, 0x000000A0, 0x0 },
217 { 0x00006012, 0x000000DF, 0x0 },
218 { 0x00000018, 0x0000008A, 0x0 },
219};
220
221/* Skylake H, S and U, and Skylake Y with 0.95V VccIO */
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000222static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300223 { 0x00000018, 0x000000AC, 0x0 },
224 { 0x00005012, 0x0000009D, 0x0 },
225 { 0x00007011, 0x00000088, 0x0 },
226 { 0x00000018, 0x000000A1, 0x0 },
227 { 0x00000018, 0x00000098, 0x0 },
228 { 0x00004013, 0x00000088, 0x0 },
229 { 0x00006012, 0x00000087, 0x0 },
230 { 0x00000018, 0x000000DF, 0x0 },
231 { 0x00003015, 0x00000087, 0x0 }, /* Default */
232 { 0x00003015, 0x000000C7, 0x0 },
233 { 0x00000018, 0x000000C7, 0x0 },
234};
235
236/* Skylake Y with 0.85V VccIO */
237static const struct ddi_buf_trans skl_y_085v_ddi_translations_hdmi[] = {
238 { 0x00000018, 0x000000A1, 0x0 },
239 { 0x00005012, 0x000000DF, 0x0 },
240 { 0x00007011, 0x00000084, 0x0 },
241 { 0x00000018, 0x000000A4, 0x0 },
242 { 0x00000018, 0x0000009D, 0x0 },
243 { 0x00004013, 0x00000080, 0x0 },
244 { 0x00006013, 0x000000C7, 0x0 },
245 { 0x00000018, 0x0000008A, 0x0 },
246 { 0x00003015, 0x000000C7, 0x0 }, /* Default */
247 { 0x80003015, 0x000000C7, 0x7 }, /* Uses I_boost */
248 { 0x00000018, 0x000000C7, 0x0 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000249};
250
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530251struct bxt_ddi_buf_trans {
252 u32 margin; /* swing value */
253 u32 scale; /* scale value */
254 u32 enable; /* scale enable */
255 u32 deemphasis;
256 bool default_index; /* true if the entry represents default value */
257};
258
259/* BSpec does not define separate vswing/pre-emphasis values for eDP.
260 * Using DP values for eDP as well.
261 */
262static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
263 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300264 { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */
265 { 78, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
266 { 104, 0x9A, 0, 64, false }, /* 2: 400 6 */
267 { 154, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
268 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
269 { 116, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
270 { 154, 0x9A, 0, 64, false }, /* 6: 600 6 */
271 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
272 { 154, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
David Weinehallf8896f52015-06-25 11:11:03 +0300273 { 154, 0x9A, 1, 128, false }, /* 9: 1200 0 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530274};
275
276/* BSpec has 2 recommended values - entries 0 and 8.
277 * Using the entry with higher vswing.
278 */
279static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
280 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300281 { 52, 0x9A, 0, 128, false }, /* 0: 400 0 */
282 { 52, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
283 { 52, 0x9A, 0, 64, false }, /* 2: 400 6 */
284 { 42, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
285 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
286 { 77, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
287 { 77, 0x9A, 0, 64, false }, /* 6: 600 6 */
288 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
289 { 102, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530290 { 154, 0x9A, 1, 128, true }, /* 9: 1200 0 */
291};
292
David Weinehallf8896f52015-06-25 11:11:03 +0300293static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
294 enum port port, int type);
295
Imre Deaka1e6ad62015-04-17 19:31:21 +0300296static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
297 struct intel_digital_port **dig_port,
298 enum port *port)
Paulo Zanonifc914632012-10-05 12:05:54 -0300299{
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300300 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonifc914632012-10-05 12:05:54 -0300301 int type = intel_encoder->type;
302
Dave Airlie0e32b392014-05-02 14:02:48 +1000303 if (type == INTEL_OUTPUT_DP_MST) {
Imre Deaka1e6ad62015-04-17 19:31:21 +0300304 *dig_port = enc_to_mst(encoder)->primary;
305 *port = (*dig_port)->port;
Dave Airlie0e32b392014-05-02 14:02:48 +1000306 } else if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP ||
Paulo Zanoni00c09d72012-10-26 19:05:52 -0200307 type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_UNKNOWN) {
Imre Deaka1e6ad62015-04-17 19:31:21 +0300308 *dig_port = enc_to_dig_port(encoder);
309 *port = (*dig_port)->port;
Paulo Zanonifc914632012-10-05 12:05:54 -0300310 } else if (type == INTEL_OUTPUT_ANALOG) {
Imre Deaka1e6ad62015-04-17 19:31:21 +0300311 *dig_port = NULL;
312 *port = PORT_E;
Paulo Zanonifc914632012-10-05 12:05:54 -0300313 } else {
314 DRM_ERROR("Invalid DDI encoder type %d\n", type);
315 BUG();
316 }
317}
318
Imre Deaka1e6ad62015-04-17 19:31:21 +0300319enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
320{
321 struct intel_digital_port *dig_port;
322 enum port port;
323
324 ddi_get_encoder_port(intel_encoder, &dig_port, &port);
325
326 return port;
327}
328
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100329static bool
330intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
331{
332 return intel_dig_port->hdmi.hdmi_reg;
333}
334
David Weinehallf8896f52015-06-25 11:11:03 +0300335static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,
336 int *n_entries)
337{
338 struct drm_i915_private *dev_priv = dev->dev_private;
339 const struct ddi_buf_trans *ddi_translations;
340 static int is_095v = -1;
341
342 if (is_095v == -1) {
343 u32 spr1 = I915_READ(UAIMI_SPR1);
344
345 is_095v = spr1 & SKL_VCCIO_MASK;
346 }
347
348 if (IS_SKL_ULX(dev) && !is_095v) {
349 ddi_translations = skl_y_085v_ddi_translations_dp;
350 *n_entries = ARRAY_SIZE(skl_y_085v_ddi_translations_dp);
351 } else if (IS_SKL_ULT(dev)) {
352 ddi_translations = skl_u_ddi_translations_dp;
353 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
354 } else {
355 ddi_translations = skl_ddi_translations_dp;
356 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
357 }
358
359 return ddi_translations;
360}
361
362static const struct ddi_buf_trans *skl_get_buf_trans_edp(struct drm_device *dev,
363 int *n_entries)
364{
365 struct drm_i915_private *dev_priv = dev->dev_private;
366 const struct ddi_buf_trans *ddi_translations;
367 static int is_095v = -1;
368
369 if (is_095v == -1) {
370 u32 spr1 = I915_READ(UAIMI_SPR1);
371
372 is_095v = spr1 & SKL_VCCIO_MASK;
373 }
374
375 if (IS_SKL_ULX(dev) && !is_095v) {
376 if (dev_priv->edp_low_vswing) {
377 ddi_translations = skl_y_085v_ddi_translations_edp;
378 *n_entries =
379 ARRAY_SIZE(skl_y_085v_ddi_translations_edp);
380 } else {
381 ddi_translations = skl_y_085v_ddi_translations_dp;
382 *n_entries =
383 ARRAY_SIZE(skl_y_085v_ddi_translations_dp);
384 }
385 } else if (IS_SKL_ULT(dev)) {
386 if (dev_priv->edp_low_vswing) {
387 ddi_translations = skl_u_ddi_translations_edp;
388 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
389 } else {
390 ddi_translations = skl_u_ddi_translations_dp;
391 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
392 }
393 } else {
394 if (dev_priv->edp_low_vswing) {
395 ddi_translations = skl_ddi_translations_edp;
396 *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
397 } else {
398 ddi_translations = skl_ddi_translations_dp;
399 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
400 }
401 }
402
403 return ddi_translations;
404}
405
406static const struct ddi_buf_trans *
407skl_get_buf_trans_hdmi(struct drm_device *dev,
408 int *n_entries)
409{
410 struct drm_i915_private *dev_priv = dev->dev_private;
411 const struct ddi_buf_trans *ddi_translations;
412 static int is_095v = -1;
413
414 if (is_095v == -1) {
415 u32 spr1 = I915_READ(UAIMI_SPR1);
416
417 is_095v = spr1 & SKL_VCCIO_MASK;
418 }
419
420 if (IS_SKL_ULX(dev) && !is_095v) {
421 ddi_translations = skl_y_085v_ddi_translations_hdmi;
422 *n_entries = ARRAY_SIZE(skl_y_085v_ddi_translations_hdmi);
423 } else {
424 ddi_translations = skl_ddi_translations_hdmi;
425 *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
426 }
427
428 return ddi_translations;
429}
430
Art Runyane58623c2013-11-02 21:07:41 -0700431/*
432 * Starting with Haswell, DDI port buffers must be programmed with correct
433 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300434 * but the HDMI/DVI fields are shared among those. So we program the DDI
435 * in either FDI or DP modes only, as HDMI connections will work with both
436 * of those
437 */
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300438static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
439 bool supports_hdmi)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300440{
441 struct drm_i915_private *dev_priv = dev->dev_private;
442 u32 reg;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000443 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530444 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300445 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300446 const struct ddi_buf_trans *ddi_translations_fdi;
447 const struct ddi_buf_trans *ddi_translations_dp;
448 const struct ddi_buf_trans *ddi_translations_edp;
449 const struct ddi_buf_trans *ddi_translations_hdmi;
450 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700451
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530452 if (IS_BROXTON(dev)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300453 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530454 return;
455
456 /* Vswing programming for HDMI */
457 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
458 INTEL_OUTPUT_HDMI);
459 return;
460 } else if (IS_SKYLAKE(dev)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300461 ddi_translations_dp =
462 skl_get_buf_trans_dp(dev, &n_dp_entries);
463 ddi_translations_edp =
464 skl_get_buf_trans_edp(dev, &n_edp_entries);
465 ddi_translations_hdmi =
466 skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
467 hdmi_default_entry = 8;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000468 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700469 ddi_translations_fdi = bdw_ddi_translations_fdi;
470 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700471 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100472 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530473 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
474 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300475 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000476 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700477 } else if (IS_HASWELL(dev)) {
478 ddi_translations_fdi = hsw_ddi_translations_fdi;
479 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700480 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100481 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530482 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300483 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000484 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700485 } else {
486 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700487 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700488 ddi_translations_fdi = bdw_ddi_translations_fdi;
489 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100490 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530491 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
492 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300493 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000494 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700495 }
496
Paulo Zanoni300644c2013-11-02 21:07:42 -0700497 switch (port) {
498 case PORT_A:
499 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530500 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700501 break;
502 case PORT_B:
503 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700504 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530505 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700506 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700507 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530508 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700509 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530510 size = n_edp_entries;
511 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700512 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530513 size = n_dp_entries;
514 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700515 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700516 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000517 if (ddi_translations_fdi)
518 ddi_translations = ddi_translations_fdi;
519 else
520 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530521 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700522 break;
523 default:
524 BUG();
525 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300526
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530527 for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) {
Jani Nikula10122052014-08-27 16:27:30 +0300528 I915_WRITE(reg, ddi_translations[i].trans1);
529 reg += 4;
530 I915_WRITE(reg, ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300531 reg += 4;
532 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100533
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300534 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100535 return;
536
Damien Lespiauce4dd492014-08-01 11:07:54 +0100537 /* Choose a good default if VBT is badly populated */
538 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
539 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000540 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100541
Paulo Zanoni6acab152013-09-12 17:06:24 -0300542 /* Entry 9 is for HDMI: */
Jani Nikula10122052014-08-27 16:27:30 +0300543 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1);
544 reg += 4;
545 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2);
546 reg += 4;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300547}
548
549/* Program DDI buffers translations for DP. By default, program ports A-D in DP
550 * mode and port E for FDI.
551 */
552void intel_prepare_ddi(struct drm_device *dev)
553{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300554 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100555 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300556
Paulo Zanoni0d536cb42012-11-23 16:46:41 -0200557 if (!HAS_DDI(dev))
558 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300559
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300560 for_each_intel_encoder(dev, intel_encoder) {
561 struct intel_digital_port *intel_dig_port;
562 enum port port;
563 bool supports_hdmi;
564
565 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
566
567 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100568 continue;
569
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300570 supports_hdmi = intel_dig_port &&
571 intel_dig_port_supports_hdmi(intel_dig_port);
572
573 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
574 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100575 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300576}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300577
Paulo Zanoni248138b2012-11-29 11:29:31 -0200578static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
579 enum port port)
580{
581 uint32_t reg = DDI_BUF_CTL(port);
582 int i;
583
Vandana Kannan3449ca82015-03-27 14:19:09 +0200584 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200585 udelay(1);
586 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
587 return;
588 }
589 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
590}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300591
592/* Starting with Haswell, different DDI ports can work in FDI mode for
593 * connection to the PCH-located connectors. For this, it is necessary to train
594 * both the DDI port and PCH receiver for the desired DDI buffer settings.
595 *
596 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
597 * please note that when FDI mode is active on DDI E, it shares 2 lines with
598 * DDI A (which is used for eDP)
599 */
600
601void hsw_fdi_link_train(struct drm_crtc *crtc)
602{
603 struct drm_device *dev = crtc->dev;
604 struct drm_i915_private *dev_priv = dev->dev_private;
605 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200606 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300607
Paulo Zanoni04945642012-11-01 21:00:59 -0200608 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
609 * mode set "sequence for CRT port" document:
610 * - TP1 to TP2 time with the default value
611 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100612 *
613 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200614 */
615 I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
616 FDI_RX_PWRDN_LANE0_VAL(2) |
617 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
618
619 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000620 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100621 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200622 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Paulo Zanoni04945642012-11-01 21:00:59 -0200623 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
624 POSTING_READ(_FDI_RXA_CTL);
625 udelay(220);
626
627 /* Switch from Rawclk to PCDclk */
628 rx_ctl_val |= FDI_PCDCLK;
629 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
630
631 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200632 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
633 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200634
635 /* Start the training iterating through available voltages and emphasis,
636 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300637 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300638 /* Configure DP_TP_CTL with auto-training */
639 I915_WRITE(DP_TP_CTL(PORT_E),
640 DP_TP_CTL_FDI_AUTOTRAIN |
641 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
642 DP_TP_CTL_LINK_TRAIN_PAT1 |
643 DP_TP_CTL_ENABLE);
644
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000645 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
646 * DDI E does not support port reversal, the functionality is
647 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
648 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300649 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200650 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200651 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530652 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200653 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300654
655 udelay(600);
656
Paulo Zanoni04945642012-11-01 21:00:59 -0200657 /* Program PCH FDI Receiver TU */
658 I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300659
Paulo Zanoni04945642012-11-01 21:00:59 -0200660 /* Enable PCH FDI Receiver with auto-training */
661 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
662 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
663 POSTING_READ(_FDI_RXA_CTL);
664
665 /* Wait for FDI receiver lane calibration */
666 udelay(30);
667
668 /* Unset FDI_RX_MISC pwrdn lanes */
669 temp = I915_READ(_FDI_RXA_MISC);
670 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
671 I915_WRITE(_FDI_RXA_MISC, temp);
672 POSTING_READ(_FDI_RXA_MISC);
673
674 /* Wait for FDI auto training time */
675 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300676
677 temp = I915_READ(DP_TP_STATUS(PORT_E));
678 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200679 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300680
681 /* Enable normal pixel sending for FDI */
682 I915_WRITE(DP_TP_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200683 DP_TP_CTL_FDI_AUTOTRAIN |
684 DP_TP_CTL_LINK_TRAIN_NORMAL |
685 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
686 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300687
Paulo Zanoni04945642012-11-01 21:00:59 -0200688 return;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300689 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200690
Paulo Zanoni248138b2012-11-29 11:29:31 -0200691 temp = I915_READ(DDI_BUF_CTL(PORT_E));
692 temp &= ~DDI_BUF_CTL_ENABLE;
693 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
694 POSTING_READ(DDI_BUF_CTL(PORT_E));
695
Paulo Zanoni04945642012-11-01 21:00:59 -0200696 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200697 temp = I915_READ(DP_TP_CTL(PORT_E));
698 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
699 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
700 I915_WRITE(DP_TP_CTL(PORT_E), temp);
701 POSTING_READ(DP_TP_CTL(PORT_E));
702
703 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200704
705 rx_ctl_val &= ~FDI_RX_ENABLE;
706 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200707 POSTING_READ(_FDI_RXA_CTL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200708
709 /* Reset FDI_RX_MISC pwrdn lanes */
710 temp = I915_READ(_FDI_RXA_MISC);
711 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
712 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
713 I915_WRITE(_FDI_RXA_MISC, temp);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200714 POSTING_READ(_FDI_RXA_MISC);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300715 }
716
Paulo Zanoni04945642012-11-01 21:00:59 -0200717 DRM_ERROR("FDI link training failed!\n");
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300718}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300719
Dave Airlie44905a272014-05-02 13:36:43 +1000720void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
721{
722 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
723 struct intel_digital_port *intel_dig_port =
724 enc_to_dig_port(&encoder->base);
725
726 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530727 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Dave Airlie44905a272014-05-02 13:36:43 +1000728 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
729
730}
731
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300732static struct intel_encoder *
733intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
734{
735 struct drm_device *dev = crtc->dev;
736 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
737 struct intel_encoder *intel_encoder, *ret = NULL;
738 int num_encoders = 0;
739
740 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
741 ret = intel_encoder;
742 num_encoders++;
743 }
744
745 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300746 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
747 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300748
749 BUG_ON(ret == NULL);
750 return ret;
751}
752
Satheeshakrishna Mbcddf6102014-08-22 09:49:10 +0530753struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200754intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200755{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200756 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
757 struct intel_encoder *ret = NULL;
758 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300759 struct drm_connector *connector;
760 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200761 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200762 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200763
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200764 state = crtc_state->base.state;
765
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300766 for_each_connector_in_state(state, connector, connector_state, i) {
767 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200768 continue;
769
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300770 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200771 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200772 }
773
774 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
775 pipe_name(crtc->pipe));
776
777 BUG_ON(ret == NULL);
778 return ret;
779}
780
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100781#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100782#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100783
784#define P_MIN 2
785#define P_MAX 64
786#define P_INC 2
787
788/* Constraints for PLL good behavior */
789#define REF_MIN 48
790#define REF_MAX 400
791#define VCO_MIN 2400
792#define VCO_MAX 4800
793
Damien Lespiau27893392014-09-04 12:27:23 +0100794#define abs_diff(a, b) ({ \
795 typeof(a) __a = (a); \
796 typeof(b) __b = (b); \
797 (void) (&__a == &__b); \
798 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100799
Damien Lespiau63582982015-05-07 18:38:46 +0100800struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100801 unsigned p, n2, r2;
802};
803
Damien Lespiau63582982015-05-07 18:38:46 +0100804static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300805{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100806 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300807
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100808 switch (clock) {
809 case 25175000:
810 case 25200000:
811 case 27000000:
812 case 27027000:
813 case 37762500:
814 case 37800000:
815 case 40500000:
816 case 40541000:
817 case 54000000:
818 case 54054000:
819 case 59341000:
820 case 59400000:
821 case 72000000:
822 case 74176000:
823 case 74250000:
824 case 81000000:
825 case 81081000:
826 case 89012000:
827 case 89100000:
828 case 108000000:
829 case 108108000:
830 case 111264000:
831 case 111375000:
832 case 148352000:
833 case 148500000:
834 case 162000000:
835 case 162162000:
836 case 222525000:
837 case 222750000:
838 case 296703000:
839 case 297000000:
840 budget = 0;
841 break;
842 case 233500000:
843 case 245250000:
844 case 247750000:
845 case 253250000:
846 case 298000000:
847 budget = 1500;
848 break;
849 case 169128000:
850 case 169500000:
851 case 179500000:
852 case 202000000:
853 budget = 2000;
854 break;
855 case 256250000:
856 case 262500000:
857 case 270000000:
858 case 272500000:
859 case 273750000:
860 case 280750000:
861 case 281250000:
862 case 286000000:
863 case 291750000:
864 budget = 4000;
865 break;
866 case 267250000:
867 case 268500000:
868 budget = 5000;
869 break;
870 default:
871 budget = 1000;
872 break;
873 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300874
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100875 return budget;
876}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300877
Damien Lespiau63582982015-05-07 18:38:46 +0100878static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
879 unsigned r2, unsigned n2, unsigned p,
880 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100881{
882 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300883
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100884 /* No best (r,n,p) yet */
885 if (best->p == 0) {
886 best->p = p;
887 best->n2 = n2;
888 best->r2 = r2;
889 return;
890 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300891
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100892 /*
893 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
894 * freq2k.
895 *
896 * delta = 1e6 *
897 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
898 * freq2k;
899 *
900 * and we would like delta <= budget.
901 *
902 * If the discrepancy is above the PPM-based budget, always prefer to
903 * improve upon the previous solution. However, if you're within the
904 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
905 */
906 a = freq2k * budget * p * r2;
907 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100908 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
909 diff_best = abs_diff(freq2k * best->p * best->r2,
910 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100911 c = 1000000 * diff;
912 d = 1000000 * diff_best;
913
914 if (a < c && b < d) {
915 /* If both are above the budget, pick the closer */
916 if (best->p * best->r2 * diff < p * r2 * diff_best) {
917 best->p = p;
918 best->n2 = n2;
919 best->r2 = r2;
920 }
921 } else if (a >= c && b < d) {
922 /* If A is below the threshold but B is above it? Update. */
923 best->p = p;
924 best->n2 = n2;
925 best->r2 = r2;
926 } else if (a >= c && b >= d) {
927 /* Both are below the limit, so pick the higher n2/(r2*r2) */
928 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
929 best->p = p;
930 best->n2 = n2;
931 best->r2 = r2;
932 }
933 }
934 /* Otherwise a < c && b >= d, do nothing */
935}
936
Damien Lespiau63582982015-05-07 18:38:46 +0100937static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, int reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800938{
939 int refclk = LC_FREQ;
940 int n, p, r;
941 u32 wrpll;
942
943 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300944 switch (wrpll & WRPLL_PLL_REF_MASK) {
945 case WRPLL_PLL_SSC:
946 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800947 /*
948 * We could calculate spread here, but our checking
949 * code only cares about 5% accuracy, and spread is a max of
950 * 0.5% downspread.
951 */
952 refclk = 135;
953 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300954 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800955 refclk = LC_FREQ;
956 break;
957 default:
958 WARN(1, "bad wrpll refclk\n");
959 return 0;
960 }
961
962 r = wrpll & WRPLL_DIVIDER_REF_MASK;
963 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
964 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
965
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800966 /* Convert to KHz, p & r have a fixed point portion */
967 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800968}
969
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000970static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
971 uint32_t dpll)
972{
973 uint32_t cfgcr1_reg, cfgcr2_reg;
974 uint32_t cfgcr1_val, cfgcr2_val;
975 uint32_t p0, p1, p2, dco_freq;
976
977 cfgcr1_reg = GET_CFG_CR1_REG(dpll);
978 cfgcr2_reg = GET_CFG_CR2_REG(dpll);
979
980 cfgcr1_val = I915_READ(cfgcr1_reg);
981 cfgcr2_val = I915_READ(cfgcr2_reg);
982
983 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
984 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
985
986 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
987 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
988 else
989 p1 = 1;
990
991
992 switch (p0) {
993 case DPLL_CFGCR2_PDIV_1:
994 p0 = 1;
995 break;
996 case DPLL_CFGCR2_PDIV_2:
997 p0 = 2;
998 break;
999 case DPLL_CFGCR2_PDIV_3:
1000 p0 = 3;
1001 break;
1002 case DPLL_CFGCR2_PDIV_7:
1003 p0 = 7;
1004 break;
1005 }
1006
1007 switch (p2) {
1008 case DPLL_CFGCR2_KDIV_5:
1009 p2 = 5;
1010 break;
1011 case DPLL_CFGCR2_KDIV_2:
1012 p2 = 2;
1013 break;
1014 case DPLL_CFGCR2_KDIV_3:
1015 p2 = 3;
1016 break;
1017 case DPLL_CFGCR2_KDIV_1:
1018 p2 = 1;
1019 break;
1020 }
1021
1022 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1023
1024 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1025 1000) / 0x8000;
1026
1027 return dco_freq / (p0 * p1 * p2 * 5);
1028}
1029
1030
1031static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001032 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001033{
1034 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001035 int link_clock = 0;
1036 uint32_t dpll_ctl1, dpll;
1037
Damien Lespiau134ffa42014-11-14 17:24:34 +00001038 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001039
1040 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1041
1042 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1043 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1044 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001045 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1046 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001047
1048 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001049 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001050 link_clock = 81000;
1051 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001052 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301053 link_clock = 108000;
1054 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001055 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001056 link_clock = 135000;
1057 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001058 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301059 link_clock = 162000;
1060 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001061 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301062 link_clock = 216000;
1063 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001064 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001065 link_clock = 270000;
1066 break;
1067 default:
1068 WARN(1, "Unsupported link rate\n");
1069 break;
1070 }
1071 link_clock *= 2;
1072 }
1073
1074 pipe_config->port_clock = link_clock;
1075
1076 if (pipe_config->has_dp_encoder)
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02001077 pipe_config->base.adjusted_mode.crtc_clock =
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001078 intel_dotclock_calculate(pipe_config->port_clock,
1079 &pipe_config->dp_m_n);
1080 else
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02001081 pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001082}
1083
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001084static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001085 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001086{
1087 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001088 int link_clock = 0;
1089 u32 val, pll;
1090
Daniel Vetter26804af2014-06-25 22:01:55 +03001091 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001092 switch (val & PORT_CLK_SEL_MASK) {
1093 case PORT_CLK_SEL_LCPLL_810:
1094 link_clock = 81000;
1095 break;
1096 case PORT_CLK_SEL_LCPLL_1350:
1097 link_clock = 135000;
1098 break;
1099 case PORT_CLK_SEL_LCPLL_2700:
1100 link_clock = 270000;
1101 break;
1102 case PORT_CLK_SEL_WRPLL1:
Damien Lespiau63582982015-05-07 18:38:46 +01001103 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL1);
Jesse Barnes11578552014-01-21 12:42:10 -08001104 break;
1105 case PORT_CLK_SEL_WRPLL2:
Damien Lespiau63582982015-05-07 18:38:46 +01001106 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL2);
Jesse Barnes11578552014-01-21 12:42:10 -08001107 break;
1108 case PORT_CLK_SEL_SPLL:
1109 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1110 if (pll == SPLL_PLL_FREQ_810MHz)
1111 link_clock = 81000;
1112 else if (pll == SPLL_PLL_FREQ_1350MHz)
1113 link_clock = 135000;
1114 else if (pll == SPLL_PLL_FREQ_2700MHz)
1115 link_clock = 270000;
1116 else {
1117 WARN(1, "bad spll freq\n");
1118 return;
1119 }
1120 break;
1121 default:
1122 WARN(1, "bad port clock sel\n");
1123 return;
1124 }
1125
1126 pipe_config->port_clock = link_clock * 2;
1127
1128 if (pipe_config->has_pch_encoder)
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02001129 pipe_config->base.adjusted_mode.crtc_clock =
Jesse Barnes11578552014-01-21 12:42:10 -08001130 intel_dotclock_calculate(pipe_config->port_clock,
1131 &pipe_config->fdi_m_n);
1132 else if (pipe_config->has_dp_encoder)
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02001133 pipe_config->base.adjusted_mode.crtc_clock =
Jesse Barnes11578552014-01-21 12:42:10 -08001134 intel_dotclock_calculate(pipe_config->port_clock,
1135 &pipe_config->dp_m_n);
1136 else
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02001137 pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
Jesse Barnes11578552014-01-21 12:42:10 -08001138}
1139
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301140static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1141 enum intel_dpll_id dpll)
1142{
Imre Deakaa610dc2015-06-22 23:35:52 +03001143 struct intel_shared_dpll *pll;
1144 struct intel_dpll_hw_state *state;
1145 intel_clock_t clock;
1146
1147 /* For DDI ports we always use a shared PLL. */
1148 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1149 return 0;
1150
1151 pll = &dev_priv->shared_dplls[dpll];
1152 state = &pll->config.hw_state;
1153
1154 clock.m1 = 2;
1155 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1156 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1157 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1158 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1159 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1160 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1161
1162 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301163}
1164
1165static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1166 struct intel_crtc_state *pipe_config)
1167{
1168 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1169 enum port port = intel_ddi_get_encoder_port(encoder);
1170 uint32_t dpll = port;
1171
1172 pipe_config->port_clock =
1173 bxt_calc_pll_link(dev_priv, dpll);
1174
1175 if (pipe_config->has_dp_encoder)
1176 pipe_config->base.adjusted_mode.crtc_clock =
1177 intel_dotclock_calculate(pipe_config->port_clock,
1178 &pipe_config->dp_m_n);
1179 else
1180 pipe_config->base.adjusted_mode.crtc_clock =
1181 pipe_config->port_clock;
1182}
1183
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001184void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001185 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001186{
Damien Lespiau22606a12014-12-12 14:26:57 +00001187 struct drm_device *dev = encoder->base.dev;
1188
1189 if (INTEL_INFO(dev)->gen <= 8)
1190 hsw_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301191 else if (IS_SKYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001192 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301193 else if (IS_BROXTON(dev))
1194 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001195}
1196
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001197static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001198hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1199 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001200{
1201 uint64_t freq2k;
1202 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001203 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001204 unsigned budget;
1205
1206 freq2k = clock / 100;
1207
Damien Lespiau63582982015-05-07 18:38:46 +01001208 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001209
1210 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1211 * and directly pass the LC PLL to it. */
1212 if (freq2k == 5400000) {
1213 *n2_out = 2;
1214 *p_out = 1;
1215 *r2_out = 2;
1216 return;
1217 }
1218
1219 /*
1220 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1221 * the WR PLL.
1222 *
1223 * We want R so that REF_MIN <= Ref <= REF_MAX.
1224 * Injecting R2 = 2 * R gives:
1225 * REF_MAX * r2 > LC_FREQ * 2 and
1226 * REF_MIN * r2 < LC_FREQ * 2
1227 *
1228 * Which means the desired boundaries for r2 are:
1229 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1230 *
1231 */
1232 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1233 r2 <= LC_FREQ * 2 / REF_MIN;
1234 r2++) {
1235
1236 /*
1237 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1238 *
1239 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1240 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1241 * VCO_MAX * r2 > n2 * LC_FREQ and
1242 * VCO_MIN * r2 < n2 * LC_FREQ)
1243 *
1244 * Which means the desired boundaries for n2 are:
1245 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1246 */
1247 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1248 n2 <= VCO_MAX * r2 / LC_FREQ;
1249 n2++) {
1250
1251 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001252 hsw_wrpll_update_rnp(freq2k, budget,
1253 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001254 }
1255 }
1256
1257 *n2_out = best.n2;
1258 *p_out = best.p;
1259 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001260}
1261
Damien Lespiau0220ab62014-07-29 18:06:22 +01001262static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001263hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001264 struct intel_crtc_state *crtc_state,
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001265 struct intel_encoder *intel_encoder,
1266 int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001267{
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001268 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001269 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001270 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001271 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001272
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001273 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001274
Daniel Vetter114fe482014-06-25 22:01:48 +03001275 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001276 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1277 WRPLL_DIVIDER_POST(p);
1278
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001279 memset(&crtc_state->dpll_hw_state, 0,
1280 sizeof(crtc_state->dpll_hw_state));
1281
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001282 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001283
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001284 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001285 if (pll == NULL) {
1286 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1287 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001288 return false;
1289 }
1290
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001291 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001292 }
1293
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001294 return true;
1295}
1296
Damien Lespiaudc253812015-06-25 16:15:06 +01001297struct skl_wrpll_context {
1298 uint64_t min_deviation; /* current minimal deviation */
1299 uint64_t central_freq; /* chosen central freq */
1300 uint64_t dco_freq; /* chosen dco freq */
1301 unsigned int p; /* chosen divider */
1302};
1303
1304static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1305{
1306 memset(ctx, 0, sizeof(*ctx));
1307
1308 ctx->min_deviation = U64_MAX;
1309}
1310
1311/* DCO freq must be within +1%/-6% of the DCO central freq */
1312#define SKL_DCO_MAX_PDEVIATION 100
1313#define SKL_DCO_MAX_NDEVIATION 600
1314
1315static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1316 uint64_t central_freq,
1317 uint64_t dco_freq,
1318 unsigned int divider)
1319{
1320 uint64_t deviation;
1321
1322 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1323 central_freq);
1324
1325 /* positive deviation */
1326 if (dco_freq >= central_freq) {
1327 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1328 deviation < ctx->min_deviation) {
1329 ctx->min_deviation = deviation;
1330 ctx->central_freq = central_freq;
1331 ctx->dco_freq = dco_freq;
1332 ctx->p = divider;
1333 }
1334 /* negative deviation */
1335 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1336 deviation < ctx->min_deviation) {
1337 ctx->min_deviation = deviation;
1338 ctx->central_freq = central_freq;
1339 ctx->dco_freq = dco_freq;
1340 ctx->p = divider;
1341 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001342}
1343
1344static void skl_wrpll_get_multipliers(unsigned int p,
1345 unsigned int *p0 /* out */,
1346 unsigned int *p1 /* out */,
1347 unsigned int *p2 /* out */)
1348{
1349 /* even dividers */
1350 if (p % 2 == 0) {
1351 unsigned int half = p / 2;
1352
1353 if (half == 1 || half == 2 || half == 3 || half == 5) {
1354 *p0 = 2;
1355 *p1 = 1;
1356 *p2 = half;
1357 } else if (half % 2 == 0) {
1358 *p0 = 2;
1359 *p1 = half / 2;
1360 *p2 = 2;
1361 } else if (half % 3 == 0) {
1362 *p0 = 3;
1363 *p1 = half / 3;
1364 *p2 = 2;
1365 } else if (half % 7 == 0) {
1366 *p0 = 7;
1367 *p1 = half / 7;
1368 *p2 = 2;
1369 }
1370 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1371 *p0 = 3;
1372 *p1 = 1;
1373 *p2 = p / 3;
1374 } else if (p == 5 || p == 7) {
1375 *p0 = p;
1376 *p1 = 1;
1377 *p2 = 1;
1378 } else if (p == 15) {
1379 *p0 = 3;
1380 *p1 = 1;
1381 *p2 = 5;
1382 } else if (p == 21) {
1383 *p0 = 7;
1384 *p1 = 1;
1385 *p2 = 3;
1386 } else if (p == 35) {
1387 *p0 = 7;
1388 *p1 = 1;
1389 *p2 = 5;
1390 }
1391}
1392
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001393struct skl_wrpll_params {
1394 uint32_t dco_fraction;
1395 uint32_t dco_integer;
1396 uint32_t qdiv_ratio;
1397 uint32_t qdiv_mode;
1398 uint32_t kdiv;
1399 uint32_t pdiv;
1400 uint32_t central_freq;
1401};
1402
Damien Lespiau76516fb2015-05-07 18:38:42 +01001403static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1404 uint64_t afe_clock,
1405 uint64_t central_freq,
1406 uint32_t p0, uint32_t p1, uint32_t p2)
1407{
1408 uint64_t dco_freq;
1409
Damien Lespiau76516fb2015-05-07 18:38:42 +01001410 switch (central_freq) {
1411 case 9600000000ULL:
1412 params->central_freq = 0;
1413 break;
1414 case 9000000000ULL:
1415 params->central_freq = 1;
1416 break;
1417 case 8400000000ULL:
1418 params->central_freq = 3;
1419 }
1420
1421 switch (p0) {
1422 case 1:
1423 params->pdiv = 0;
1424 break;
1425 case 2:
1426 params->pdiv = 1;
1427 break;
1428 case 3:
1429 params->pdiv = 2;
1430 break;
1431 case 7:
1432 params->pdiv = 4;
1433 break;
1434 default:
1435 WARN(1, "Incorrect PDiv\n");
1436 }
1437
1438 switch (p2) {
1439 case 5:
1440 params->kdiv = 0;
1441 break;
1442 case 2:
1443 params->kdiv = 1;
1444 break;
1445 case 3:
1446 params->kdiv = 2;
1447 break;
1448 case 1:
1449 params->kdiv = 3;
1450 break;
1451 default:
1452 WARN(1, "Incorrect KDiv\n");
1453 }
1454
1455 params->qdiv_ratio = p1;
1456 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1457
1458 dco_freq = p0 * p1 * p2 * afe_clock;
1459
1460 /*
1461 * Intermediate values are in Hz.
1462 * Divide by MHz to match bsepc
1463 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001464 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001465 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001466 div_u64((div_u64(dco_freq, 24) -
1467 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001468}
1469
Damien Lespiau318bd822015-05-07 18:38:40 +01001470static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001471skl_ddi_calculate_wrpll(int clock /* in Hz */,
1472 struct skl_wrpll_params *wrpll_params)
1473{
1474 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001475 uint64_t dco_central_freq[3] = {8400000000ULL,
1476 9000000000ULL,
1477 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001478 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1479 24, 28, 30, 32, 36, 40, 42, 44,
1480 48, 52, 54, 56, 60, 64, 66, 68,
1481 70, 72, 76, 78, 80, 84, 88, 90,
1482 92, 96, 98 };
1483 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1484 static const struct {
1485 const int *list;
1486 int n_dividers;
1487 } dividers[] = {
1488 { even_dividers, ARRAY_SIZE(even_dividers) },
1489 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1490 };
1491 struct skl_wrpll_context ctx;
1492 unsigned int dco, d, i;
1493 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001494
Damien Lespiaudc253812015-06-25 16:15:06 +01001495 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001496
Damien Lespiaudc253812015-06-25 16:15:06 +01001497 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1498 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1499 for (i = 0; i < dividers[d].n_dividers; i++) {
1500 unsigned int p = dividers[d].list[i];
1501 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001502
Damien Lespiaudc253812015-06-25 16:15:06 +01001503 skl_wrpll_try_divider(&ctx,
1504 dco_central_freq[dco],
1505 dco_freq,
1506 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001507 /*
1508 * Skip the remaining dividers if we're sure to
1509 * have found the definitive divider, we can't
1510 * improve a 0 deviation.
1511 */
1512 if (ctx.min_deviation == 0)
1513 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001514 }
1515 }
Damien Lespiau267db662015-06-25 16:19:24 +01001516
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001517skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001518 /*
1519 * If a solution is found with an even divider, prefer
1520 * this one.
1521 */
1522 if (d == 0 && ctx.p)
1523 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001524 }
1525
Damien Lespiaudc253812015-06-25 16:15:06 +01001526 if (!ctx.p) {
1527 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001528 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001529 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001530
Damien Lespiaudc253812015-06-25 16:15:06 +01001531 /*
1532 * gcc incorrectly analyses that these can be used without being
1533 * initialized. To be fair, it's hard to guess.
1534 */
1535 p0 = p1 = p2 = 0;
1536 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1537 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1538 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001539
Damien Lespiau318bd822015-05-07 18:38:40 +01001540 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001541}
1542
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001543static bool
1544skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001545 struct intel_crtc_state *crtc_state,
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001546 struct intel_encoder *intel_encoder,
1547 int clock)
1548{
1549 struct intel_shared_dpll *pll;
1550 uint32_t ctrl1, cfgcr1, cfgcr2;
1551
1552 /*
1553 * See comment in intel_dpll_hw_state to understand why we always use 0
1554 * as the DPLL id in this function.
1555 */
1556
1557 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1558
1559 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1560 struct skl_wrpll_params wrpll_params = { 0, };
1561
1562 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1563
Damien Lespiau318bd822015-05-07 18:38:40 +01001564 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1565 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001566
1567 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1568 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1569 wrpll_params.dco_integer;
1570
1571 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1572 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1573 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1574 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1575 wrpll_params.central_freq;
1576 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
1577 struct drm_encoder *encoder = &intel_encoder->base;
1578 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1579
1580 switch (intel_dp->link_bw) {
1581 case DP_LINK_BW_1_62:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001582 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001583 break;
1584 case DP_LINK_BW_2_7:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001585 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001586 break;
1587 case DP_LINK_BW_5_4:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001588 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001589 break;
1590 }
1591
1592 cfgcr1 = cfgcr2 = 0;
1593 } else /* eDP */
1594 return true;
1595
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001596 memset(&crtc_state->dpll_hw_state, 0,
1597 sizeof(crtc_state->dpll_hw_state));
1598
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001599 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1600 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1601 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001602
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001603 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001604 if (pll == NULL) {
1605 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1606 pipe_name(intel_crtc->pipe));
1607 return false;
1608 }
1609
1610 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001611 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001612
1613 return true;
1614}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001615
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301616/* bxt clock parameters */
1617struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301618 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301619 uint32_t p1;
1620 uint32_t p2;
1621 uint32_t m2_int;
1622 uint32_t m2_frac;
1623 bool m2_frac_en;
1624 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301625};
1626
1627/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301628static const struct bxt_clk_div bxt_dp_clk_val[] = {
1629 {162000, 4, 2, 32, 1677722, 1, 1},
1630 {270000, 4, 1, 27, 0, 0, 1},
1631 {540000, 2, 1, 27, 0, 0, 1},
1632 {216000, 3, 2, 32, 1677722, 1, 1},
1633 {243000, 4, 1, 24, 1258291, 1, 1},
1634 {324000, 4, 1, 32, 1677722, 1, 1},
1635 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301636};
1637
1638static bool
1639bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1640 struct intel_crtc_state *crtc_state,
1641 struct intel_encoder *intel_encoder,
1642 int clock)
1643{
1644 struct intel_shared_dpll *pll;
1645 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301646 int vco = 0;
1647 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane0681e32015-05-13 12:20:35 +05301648 uint32_t dcoampovr_en_h, dco_amp, lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301649
1650 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1651 intel_clock_t best_clock;
1652
1653 /* Calculate HDMI div */
1654 /*
1655 * FIXME: tie the following calculation into
1656 * i9xx_crtc_compute_clock
1657 */
1658 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1659 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1660 clock, pipe_name(intel_crtc->pipe));
1661 return false;
1662 }
1663
1664 clk_div.p1 = best_clock.p1;
1665 clk_div.p2 = best_clock.p2;
1666 WARN_ON(best_clock.m1 != 2);
1667 clk_div.n = best_clock.n;
1668 clk_div.m2_int = best_clock.m2 >> 22;
1669 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1670 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1671
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301672 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301673 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1674 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301675 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301676
Sonika Jindal64987fc2015-05-26 17:50:13 +05301677 clk_div = bxt_dp_clk_val[0];
1678 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1679 if (bxt_dp_clk_val[i].clock == clock) {
1680 clk_div = bxt_dp_clk_val[i];
1681 break;
1682 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301683 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301684 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1685 }
1686
1687 dco_amp = 15;
1688 dcoampovr_en_h = 0;
1689 if (vco >= 6200000 && vco <= 6480000) {
1690 prop_coef = 4;
1691 int_coef = 9;
1692 gain_ctl = 3;
1693 targ_cnt = 8;
1694 } else if ((vco > 5400000 && vco < 6200000) ||
1695 (vco >= 4800000 && vco < 5400000)) {
1696 prop_coef = 5;
1697 int_coef = 11;
1698 gain_ctl = 3;
1699 targ_cnt = 9;
1700 if (vco >= 4800000 && vco < 5400000)
1701 dcoampovr_en_h = 1;
1702 } else if (vco == 5400000) {
1703 prop_coef = 3;
1704 int_coef = 8;
1705 gain_ctl = 1;
1706 targ_cnt = 9;
1707 } else {
1708 DRM_ERROR("Invalid VCO\n");
1709 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301710 }
1711
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001712 memset(&crtc_state->dpll_hw_state, 0,
1713 sizeof(crtc_state->dpll_hw_state));
1714
Vandana Kannane0681e32015-05-13 12:20:35 +05301715 if (clock > 270000)
1716 lanestagger = 0x18;
1717 else if (clock > 135000)
1718 lanestagger = 0x0d;
1719 else if (clock > 67000)
1720 lanestagger = 0x07;
1721 else if (clock > 33000)
1722 lanestagger = 0x04;
1723 else
1724 lanestagger = 0x02;
1725
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301726 crtc_state->dpll_hw_state.ebb0 =
1727 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1728 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1729 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1730 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1731
1732 if (clk_div.m2_frac_en)
1733 crtc_state->dpll_hw_state.pll3 =
1734 PORT_PLL_M2_FRAC_ENABLE;
1735
1736 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301737 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301738 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301739 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301740
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301741 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1742
Imre Deak05712c12015-06-18 17:25:54 +03001743 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1744
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301745 if (dcoampovr_en_h)
1746 crtc_state->dpll_hw_state.pll10 = PORT_PLL_DCO_AMP_OVR_EN_H;
1747
1748 crtc_state->dpll_hw_state.pll10 |= PORT_PLL_DCO_AMP(dco_amp);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301749
Imre Deak05712c12015-06-18 17:25:54 +03001750 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1751
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301752 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301753 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301754
1755 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1756 if (pll == NULL) {
1757 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1758 pipe_name(intel_crtc->pipe));
1759 return false;
1760 }
1761
1762 /* shared DPLL id 0 is DPLL A */
1763 crtc_state->ddi_pll_sel = pll->id;
1764
1765 return true;
1766}
1767
Damien Lespiau0220ab62014-07-29 18:06:22 +01001768/*
1769 * Tries to find a *shared* PLL for the CRTC and store it in
1770 * intel_crtc->ddi_pll_sel.
1771 *
1772 * For private DPLLs, compute_config() should do the selection for us. This
1773 * function should be folded into compute_config() eventually.
1774 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001775bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1776 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001777{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001778 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001779 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001780 intel_ddi_get_crtc_new_encoder(crtc_state);
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001781 int clock = crtc_state->port_clock;
Damien Lespiau0220ab62014-07-29 18:06:22 +01001782
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001783 if (IS_SKYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001784 return skl_ddi_pll_select(intel_crtc, crtc_state,
1785 intel_encoder, clock);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301786 else if (IS_BROXTON(dev))
1787 return bxt_ddi_pll_select(intel_crtc, crtc_state,
1788 intel_encoder, clock);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001789 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001790 return hsw_ddi_pll_select(intel_crtc, crtc_state,
1791 intel_encoder, clock);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001792}
1793
Paulo Zanonidae84792012-10-15 15:51:30 -03001794void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1795{
1796 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1797 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1798 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001799 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001800 int type = intel_encoder->type;
1801 uint32_t temp;
1802
Dave Airlie0e32b392014-05-02 14:02:48 +10001803 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001804 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001805 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001806 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001807 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001808 break;
1809 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001810 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001811 break;
1812 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001813 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001814 break;
1815 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001816 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001817 break;
1818 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001819 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001820 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001821 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001822 }
1823}
1824
Dave Airlie0e32b392014-05-02 14:02:48 +10001825void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1826{
1827 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1828 struct drm_device *dev = crtc->dev;
1829 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001830 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001831 uint32_t temp;
1832 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1833 if (state == true)
1834 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1835 else
1836 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1837 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1838}
1839
Damien Lespiau8228c252013-03-07 15:30:27 +00001840void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001841{
1842 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1843 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001844 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001845 struct drm_device *dev = crtc->dev;
1846 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001847 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001848 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001849 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001850 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001851 uint32_t temp;
1852
Paulo Zanoniad80a812012-10-24 16:06:19 -02001853 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1854 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001855 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001856
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001857 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001858 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001859 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001860 break;
1861 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001862 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001863 break;
1864 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001865 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001866 break;
1867 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001868 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001869 break;
1870 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001871 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001872 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001873
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001874 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001875 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001876 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001877 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001878
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001879 if (cpu_transcoder == TRANSCODER_EDP) {
1880 switch (pipe) {
1881 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001882 /* On Haswell, can only use the always-on power well for
1883 * eDP when not using the panel fitter, and when not
1884 * using motion blur mitigation (which we don't
1885 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001886 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001887 (intel_crtc->config->pch_pfit.enabled ||
1888 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001889 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1890 else
1891 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001892 break;
1893 case PIPE_B:
1894 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1895 break;
1896 case PIPE_C:
1897 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1898 break;
1899 default:
1900 BUG();
1901 break;
1902 }
1903 }
1904
Paulo Zanoni7739c332012-10-15 15:51:29 -03001905 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001906 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001907 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001908 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001909 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001910
Paulo Zanoni7739c332012-10-15 15:51:29 -03001911 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001912 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001913 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001914
1915 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1916 type == INTEL_OUTPUT_EDP) {
1917 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1918
Dave Airlie0e32b392014-05-02 14:02:48 +10001919 if (intel_dp->is_mst) {
1920 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1921 } else
1922 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1923
1924 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
1925 } else if (type == INTEL_OUTPUT_DP_MST) {
1926 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1927
1928 if (intel_dp->is_mst) {
1929 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1930 } else
1931 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001932
Daniel Vetter17aa6be2013-04-30 14:01:40 +02001933 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001934 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001935 WARN(1, "Invalid encoder type %d for pipe %c\n",
1936 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001937 }
1938
Paulo Zanoniad80a812012-10-24 16:06:19 -02001939 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001940}
1941
Paulo Zanoniad80a812012-10-24 16:06:19 -02001942void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1943 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001944{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001945 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001946 uint32_t val = I915_READ(reg);
1947
Dave Airlie0e32b392014-05-02 14:02:48 +10001948 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001949 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001950 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001951}
1952
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001953bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1954{
1955 struct drm_device *dev = intel_connector->base.dev;
1956 struct drm_i915_private *dev_priv = dev->dev_private;
1957 struct intel_encoder *intel_encoder = intel_connector->encoder;
1958 int type = intel_connector->base.connector_type;
1959 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1960 enum pipe pipe = 0;
1961 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001962 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001963 uint32_t tmp;
1964
Paulo Zanoni882244a2014-04-01 14:55:12 -03001965 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001966 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001967 return false;
1968
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001969 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1970 return false;
1971
1972 if (port == PORT_A)
1973 cpu_transcoder = TRANSCODER_EDP;
1974 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001975 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001976
1977 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1978
1979 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1980 case TRANS_DDI_MODE_SELECT_HDMI:
1981 case TRANS_DDI_MODE_SELECT_DVI:
1982 return (type == DRM_MODE_CONNECTOR_HDMIA);
1983
1984 case TRANS_DDI_MODE_SELECT_DP_SST:
1985 if (type == DRM_MODE_CONNECTOR_eDP)
1986 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001987 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001988 case TRANS_DDI_MODE_SELECT_DP_MST:
1989 /* if the transcoder is in MST state then
1990 * connector isn't connected */
1991 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001992
1993 case TRANS_DDI_MODE_SELECT_FDI:
1994 return (type == DRM_MODE_CONNECTOR_VGA);
1995
1996 default:
1997 return false;
1998 }
1999}
2000
Daniel Vetter85234cd2012-07-02 13:27:29 +02002001bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
2002 enum pipe *pipe)
2003{
2004 struct drm_device *dev = encoder->base.dev;
2005 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002006 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02002007 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002008 u32 tmp;
2009 int i;
2010
Imre Deak6d129be2014-03-05 16:20:54 +02002011 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002012 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02002013 return false;
2014
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002015 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002016
2017 if (!(tmp & DDI_BUF_CTL_ENABLE))
2018 return false;
2019
Paulo Zanoniad80a812012-10-24 16:06:19 -02002020 if (port == PORT_A) {
2021 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002022
Paulo Zanoniad80a812012-10-24 16:06:19 -02002023 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2024 case TRANS_DDI_EDP_INPUT_A_ON:
2025 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2026 *pipe = PIPE_A;
2027 break;
2028 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2029 *pipe = PIPE_B;
2030 break;
2031 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2032 *pipe = PIPE_C;
2033 break;
2034 }
2035
2036 return true;
2037 } else {
2038 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2039 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2040
2041 if ((tmp & TRANS_DDI_PORT_MASK)
2042 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002043 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2044 return false;
2045
Paulo Zanoniad80a812012-10-24 16:06:19 -02002046 *pipe = i;
2047 return true;
2048 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002049 }
2050 }
2051
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002052 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002053
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002054 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002055}
2056
Paulo Zanonifc914632012-10-05 12:05:54 -03002057void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2058{
2059 struct drm_crtc *crtc = &intel_crtc->base;
2060 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2061 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2062 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002063 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002064
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002065 if (cpu_transcoder != TRANSCODER_EDP)
2066 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2067 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002068}
2069
2070void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2071{
2072 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002073 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002074
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002075 if (cpu_transcoder != TRANSCODER_EDP)
2076 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2077 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002078}
2079
David Weinehallf8896f52015-06-25 11:11:03 +03002080static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2081 enum port port, int type)
2082{
2083 struct drm_i915_private *dev_priv = dev->dev_private;
2084 const struct ddi_buf_trans *ddi_translations;
2085 uint8_t iboost;
2086 int n_entries;
2087 u32 reg;
2088
2089 if (type == INTEL_OUTPUT_DISPLAYPORT) {
2090 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2091 iboost = ddi_translations[port].i_boost;
2092 } else if (type == INTEL_OUTPUT_EDP) {
2093 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2094 iboost = ddi_translations[port].i_boost;
2095 } else if (type == INTEL_OUTPUT_HDMI) {
2096 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2097 iboost = ddi_translations[port].i_boost;
2098 } else {
2099 return;
2100 }
2101
2102 /* Make sure that the requested I_boost is valid */
2103 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2104 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2105 return;
2106 }
2107
2108 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2109 reg &= ~BALANCE_LEG_MASK(port);
2110 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2111
2112 if (iboost)
2113 reg |= iboost << BALANCE_LEG_SHIFT(port);
2114 else
2115 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2116
2117 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2118}
2119
2120static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2121 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302122{
2123 struct drm_i915_private *dev_priv = dev->dev_private;
2124 const struct bxt_ddi_buf_trans *ddi_translations;
2125 u32 n_entries, i;
2126 uint32_t val;
2127
2128 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
2129 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2130 ddi_translations = bxt_ddi_translations_dp;
2131 } else if (type == INTEL_OUTPUT_HDMI) {
2132 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2133 ddi_translations = bxt_ddi_translations_hdmi;
2134 } else {
2135 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2136 type);
2137 return;
2138 }
2139
2140 /* Check if default value has to be used */
2141 if (level >= n_entries ||
2142 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2143 for (i = 0; i < n_entries; i++) {
2144 if (ddi_translations[i].default_index) {
2145 level = i;
2146 break;
2147 }
2148 }
2149 }
2150
2151 /*
2152 * While we write to the group register to program all lanes at once we
2153 * can read only lane registers and we pick lanes 0/1 for that.
2154 */
2155 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2156 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2157 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2158
2159 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2160 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2161 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2162 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2163 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2164
2165 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
2166 val &= ~UNIQE_TRANGE_EN_METHOD;
2167 if (ddi_translations[level].enable)
2168 val |= UNIQE_TRANGE_EN_METHOD;
2169 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2170
2171 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2172 val &= ~DE_EMPHASIS;
2173 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2174 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2175
2176 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2177 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2178 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2179}
2180
David Weinehallf8896f52015-06-25 11:11:03 +03002181static uint32_t translate_signal_level(int signal_levels)
2182{
2183 uint32_t level;
2184
2185 switch (signal_levels) {
2186 default:
2187 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2188 signal_levels);
2189 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2190 level = 0;
2191 break;
2192 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2193 level = 1;
2194 break;
2195 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2196 level = 2;
2197 break;
2198 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2199 level = 3;
2200 break;
2201
2202 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2203 level = 4;
2204 break;
2205 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2206 level = 5;
2207 break;
2208 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2209 level = 6;
2210 break;
2211
2212 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2213 level = 7;
2214 break;
2215 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2216 level = 8;
2217 break;
2218
2219 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2220 level = 9;
2221 break;
2222 }
2223
2224 return level;
2225}
2226
2227uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2228{
2229 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2230 struct drm_device *dev = dport->base.base.dev;
2231 struct intel_encoder *encoder = &dport->base;
2232 uint8_t train_set = intel_dp->train_set[0];
2233 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2234 DP_TRAIN_PRE_EMPHASIS_MASK);
2235 enum port port = dport->port;
2236 uint32_t level;
2237
2238 level = translate_signal_level(signal_levels);
2239
2240 if (IS_SKYLAKE(dev))
2241 skl_ddi_set_iboost(dev, level, port, encoder->type);
2242 else if (IS_BROXTON(dev))
2243 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2244
2245 return DDI_BUF_TRANS_SELECT(level);
2246}
2247
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002248static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002249{
Paulo Zanonic19b0662012-10-15 15:51:41 -03002250 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002251 struct drm_device *dev = encoder->dev;
2252 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002253 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002254 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002255 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302256 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002257
2258 if (type == INTEL_OUTPUT_EDP) {
2259 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01002260 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002261 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002262
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002263 if (IS_SKYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002264 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002265 uint32_t val;
2266
Damien Lespiau5416d872014-11-14 17:24:33 +00002267 /*
2268 * DPLL0 is used for eDP and is the only "private" DPLL (as
2269 * opposed to shared) on SKL
2270 */
2271 if (type == INTEL_OUTPUT_EDP) {
2272 WARN_ON(dpll != SKL_DPLL0);
2273
2274 val = I915_READ(DPLL_CTRL1);
2275
2276 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2277 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002278 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002279 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002280
2281 I915_WRITE(DPLL_CTRL1, val);
2282 POSTING_READ(DPLL_CTRL1);
2283 }
2284
2285 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002286 val = I915_READ(DPLL_CTRL2);
2287
2288 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2289 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2290 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2291 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2292
2293 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002294
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302295 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002296 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2297 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002298 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002299
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002300 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002301 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002302
Dave Airlie44905a272014-05-02 13:36:43 +10002303 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002304
2305 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2306 intel_dp_start_link_train(intel_dp);
2307 intel_dp_complete_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002308 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002309 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002310 } else if (type == INTEL_OUTPUT_HDMI) {
2311 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2312
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302313 if (IS_BROXTON(dev)) {
2314 hdmi_level = dev_priv->vbt.
2315 ddi_port_info[port].hdmi_level_shift;
2316 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2317 INTEL_OUTPUT_HDMI);
2318 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002319 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002320 crtc->config->has_hdmi_sink,
2321 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002322 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002323}
2324
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002325static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002326{
2327 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002328 struct drm_device *dev = encoder->dev;
2329 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002330 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002331 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002332 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002333 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002334
2335 val = I915_READ(DDI_BUF_CTL(port));
2336 if (val & DDI_BUF_CTL_ENABLE) {
2337 val &= ~DDI_BUF_CTL_ENABLE;
2338 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002339 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002340 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002341
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002342 val = I915_READ(DP_TP_CTL(port));
2343 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2344 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2345 I915_WRITE(DP_TP_CTL(port), val);
2346
2347 if (wait)
2348 intel_wait_ddi_buf_idle(dev_priv, port);
2349
Jani Nikula76bb80e2013-11-15 15:29:57 +02002350 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002351 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002352 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002353 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002354 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002355 }
2356
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002357 if (IS_SKYLAKE(dev))
2358 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2359 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302360 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002361 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002362}
2363
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002364static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002365{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002366 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002367 struct drm_crtc *crtc = encoder->crtc;
2368 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002369 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002370 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002371 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2372 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002373
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002374 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002375 struct intel_digital_port *intel_dig_port =
2376 enc_to_dig_port(encoder);
2377
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002378 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2379 * are ignored so nothing special needs to be done besides
2380 * enabling the port.
2381 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002382 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002383 intel_dig_port->saved_port_bits |
2384 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002385 } else if (type == INTEL_OUTPUT_EDP) {
2386 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2387
Vandana Kannan23f08d82014-11-13 14:55:22 +00002388 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002389 intel_dp_stop_link_train(intel_dp);
2390
Daniel Vetter4be73782014-01-17 14:39:48 +01002391 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002392 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302393 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002394 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002395
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002396 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002397 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002398 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002399 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002400}
2401
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002402static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002403{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002404 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002405 struct drm_crtc *crtc = encoder->crtc;
2406 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002407 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002408 struct drm_device *dev = encoder->dev;
2409 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002410
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002411 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002412 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002413 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2414 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002415
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002416 if (type == INTEL_OUTPUT_EDP) {
2417 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2418
Vandana Kannanc3955782015-01-22 15:17:40 +05302419 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002420 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002421 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002422 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002423}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002424
Daniel Vettere0b01be2014-06-25 22:02:01 +03002425static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2426 struct intel_shared_dpll *pll)
2427{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002428 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002429 POSTING_READ(WRPLL_CTL(pll->id));
2430 udelay(20);
2431}
2432
Daniel Vetter12030432014-06-25 22:02:00 +03002433static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2434 struct intel_shared_dpll *pll)
2435{
2436 uint32_t val;
2437
2438 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002439 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2440 POSTING_READ(WRPLL_CTL(pll->id));
2441}
2442
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002443static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2444 struct intel_shared_dpll *pll,
2445 struct intel_dpll_hw_state *hw_state)
2446{
2447 uint32_t val;
2448
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002449 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002450 return false;
2451
2452 val = I915_READ(WRPLL_CTL(pll->id));
2453 hw_state->wrpll = val;
2454
2455 return val & WRPLL_PLL_ENABLE;
2456}
2457
Damien Lespiauca1381b2014-07-15 15:05:33 +01002458static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002459 "WRPLL 1",
2460 "WRPLL 2",
2461};
2462
Damien Lespiau143b3072014-07-29 18:06:19 +01002463static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002464{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002465 int i;
2466
Daniel Vetter716c2e52014-06-25 22:02:02 +03002467 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002468
Daniel Vetter716c2e52014-06-25 22:02:02 +03002469 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002470 dev_priv->shared_dplls[i].id = i;
2471 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002472 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002473 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002474 dev_priv->shared_dplls[i].get_hw_state =
2475 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002476 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002477}
2478
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002479static const char * const skl_ddi_pll_names[] = {
2480 "DPLL 1",
2481 "DPLL 2",
2482 "DPLL 3",
2483};
2484
2485struct skl_dpll_regs {
2486 u32 ctl, cfgcr1, cfgcr2;
2487};
2488
2489/* this array is indexed by the *shared* pll id */
2490static const struct skl_dpll_regs skl_dpll_regs[3] = {
2491 {
2492 /* DPLL 1 */
2493 .ctl = LCPLL2_CTL,
2494 .cfgcr1 = DPLL1_CFGCR1,
2495 .cfgcr2 = DPLL1_CFGCR2,
2496 },
2497 {
2498 /* DPLL 2 */
2499 .ctl = WRPLL_CTL1,
2500 .cfgcr1 = DPLL2_CFGCR1,
2501 .cfgcr2 = DPLL2_CFGCR2,
2502 },
2503 {
2504 /* DPLL 3 */
2505 .ctl = WRPLL_CTL2,
2506 .cfgcr1 = DPLL3_CFGCR1,
2507 .cfgcr2 = DPLL3_CFGCR2,
2508 },
2509};
2510
2511static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2512 struct intel_shared_dpll *pll)
2513{
2514 uint32_t val;
2515 unsigned int dpll;
2516 const struct skl_dpll_regs *regs = skl_dpll_regs;
2517
2518 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2519 dpll = pll->id + 1;
2520
2521 val = I915_READ(DPLL_CTRL1);
2522
2523 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002524 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002525 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2526
2527 I915_WRITE(DPLL_CTRL1, val);
2528 POSTING_READ(DPLL_CTRL1);
2529
2530 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2531 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2532 POSTING_READ(regs[pll->id].cfgcr1);
2533 POSTING_READ(regs[pll->id].cfgcr2);
2534
2535 /* the enable bit is always bit 31 */
2536 I915_WRITE(regs[pll->id].ctl,
2537 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2538
2539 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2540 DRM_ERROR("DPLL %d not locked\n", dpll);
2541}
2542
2543static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2544 struct intel_shared_dpll *pll)
2545{
2546 const struct skl_dpll_regs *regs = skl_dpll_regs;
2547
2548 /* the enable bit is always bit 31 */
2549 I915_WRITE(regs[pll->id].ctl,
2550 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2551 POSTING_READ(regs[pll->id].ctl);
2552}
2553
2554static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2555 struct intel_shared_dpll *pll,
2556 struct intel_dpll_hw_state *hw_state)
2557{
2558 uint32_t val;
2559 unsigned int dpll;
2560 const struct skl_dpll_regs *regs = skl_dpll_regs;
2561
2562 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2563 return false;
2564
2565 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2566 dpll = pll->id + 1;
2567
2568 val = I915_READ(regs[pll->id].ctl);
2569 if (!(val & LCPLL_PLL_ENABLE))
2570 return false;
2571
2572 val = I915_READ(DPLL_CTRL1);
2573 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2574
2575 /* avoid reading back stale values if HDMI mode is not enabled */
2576 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2577 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2578 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2579 }
2580
2581 return true;
2582}
2583
2584static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2585{
2586 int i;
2587
2588 dev_priv->num_shared_dpll = 3;
2589
2590 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2591 dev_priv->shared_dplls[i].id = i;
2592 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2593 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2594 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2595 dev_priv->shared_dplls[i].get_hw_state =
2596 skl_ddi_pll_get_hw_state;
2597 }
2598}
2599
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302600static void broxton_phy_init(struct drm_i915_private *dev_priv,
2601 enum dpio_phy phy)
2602{
2603 enum port port;
2604 uint32_t val;
2605
2606 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2607 val |= GT_DISPLAY_POWER_ON(phy);
2608 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2609
2610 /* Considering 10ms timeout until BSpec is updated */
2611 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2612 DRM_ERROR("timeout during PHY%d power on\n", phy);
2613
2614 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2615 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2616 int lane;
2617
2618 for (lane = 0; lane < 4; lane++) {
2619 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2620 /*
2621 * Note that on CHV this flag is called UPAR, but has
2622 * the same function.
2623 */
2624 val &= ~LATENCY_OPTIM;
2625 if (lane != 1)
2626 val |= LATENCY_OPTIM;
2627
2628 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2629 }
2630 }
2631
2632 /* Program PLL Rcomp code offset */
2633 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2634 val &= ~IREF0RC_OFFSET_MASK;
2635 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2636 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2637
2638 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2639 val &= ~IREF1RC_OFFSET_MASK;
2640 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2641 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2642
2643 /* Program power gating */
2644 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2645 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2646 SUS_CLK_CONFIG;
2647 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2648
2649 if (phy == DPIO_PHY0) {
2650 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2651 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2652 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2653 }
2654
2655 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2656 val &= ~OCL2_LDOFUSE_PWR_DIS;
2657 /*
2658 * On PHY1 disable power on the second channel, since no port is
2659 * connected there. On PHY0 both channels have a port, so leave it
2660 * enabled.
2661 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2662 * power down the second channel on PHY0 as well.
2663 */
2664 if (phy == DPIO_PHY1)
2665 val |= OCL2_LDOFUSE_PWR_DIS;
2666 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2667
2668 if (phy == DPIO_PHY0) {
2669 uint32_t grc_code;
2670 /*
2671 * PHY0 isn't connected to an RCOMP resistor so copy over
2672 * the corresponding calibrated value from PHY1, and disable
2673 * the automatic calibration on PHY0.
2674 */
2675 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2676 10))
2677 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2678
2679 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2680 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2681 grc_code = val << GRC_CODE_FAST_SHIFT |
2682 val << GRC_CODE_SLOW_SHIFT |
2683 val;
2684 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2685
2686 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2687 val |= GRC_DIS | GRC_RDY_OVRD;
2688 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2689 }
2690
2691 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2692 val |= COMMON_RESET_DIS;
2693 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2694}
2695
2696void broxton_ddi_phy_init(struct drm_device *dev)
2697{
2698 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2699 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2700 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2701}
2702
2703static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2704 enum dpio_phy phy)
2705{
2706 uint32_t val;
2707
2708 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2709 val &= ~COMMON_RESET_DIS;
2710 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2711}
2712
2713void broxton_ddi_phy_uninit(struct drm_device *dev)
2714{
2715 struct drm_i915_private *dev_priv = dev->dev_private;
2716
2717 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2718 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2719
2720 /* FIXME: do this in broxton_phy_uninit per phy */
2721 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2722}
2723
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302724static const char * const bxt_ddi_pll_names[] = {
2725 "PORT PLL A",
2726 "PORT PLL B",
2727 "PORT PLL C",
2728};
2729
2730static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2731 struct intel_shared_dpll *pll)
2732{
2733 uint32_t temp;
2734 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2735
2736 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2737 temp &= ~PORT_PLL_REF_SEL;
2738 /* Non-SSC reference */
2739 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2740
2741 /* Disable 10 bit clock */
2742 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2743 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2744 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2745
2746 /* Write P1 & P2 */
2747 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2748 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2749 temp |= pll->config.hw_state.ebb0;
2750 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2751
2752 /* Write M2 integer */
2753 temp = I915_READ(BXT_PORT_PLL(port, 0));
2754 temp &= ~PORT_PLL_M2_MASK;
2755 temp |= pll->config.hw_state.pll0;
2756 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2757
2758 /* Write N */
2759 temp = I915_READ(BXT_PORT_PLL(port, 1));
2760 temp &= ~PORT_PLL_N_MASK;
2761 temp |= pll->config.hw_state.pll1;
2762 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2763
2764 /* Write M2 fraction */
2765 temp = I915_READ(BXT_PORT_PLL(port, 2));
2766 temp &= ~PORT_PLL_M2_FRAC_MASK;
2767 temp |= pll->config.hw_state.pll2;
2768 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2769
2770 /* Write M2 fraction enable */
2771 temp = I915_READ(BXT_PORT_PLL(port, 3));
2772 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2773 temp |= pll->config.hw_state.pll3;
2774 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2775
2776 /* Write coeff */
2777 temp = I915_READ(BXT_PORT_PLL(port, 6));
2778 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2779 temp &= ~PORT_PLL_INT_COEFF_MASK;
2780 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2781 temp |= pll->config.hw_state.pll6;
2782 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2783
2784 /* Write calibration val */
2785 temp = I915_READ(BXT_PORT_PLL(port, 8));
2786 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2787 temp |= pll->config.hw_state.pll8;
2788 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2789
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302790 temp = I915_READ(BXT_PORT_PLL(port, 9));
2791 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002792 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302793 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2794
2795 temp = I915_READ(BXT_PORT_PLL(port, 10));
2796 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2797 temp &= ~PORT_PLL_DCO_AMP_MASK;
2798 temp |= pll->config.hw_state.pll10;
2799 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302800
2801 /* Recalibrate with new settings */
2802 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2803 temp |= PORT_PLL_RECALIBRATE;
2804 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002805 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2806 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302807 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2808
2809 /* Enable PLL */
2810 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2811 temp |= PORT_PLL_ENABLE;
2812 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2813 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2814
2815 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2816 PORT_PLL_LOCK), 200))
2817 DRM_ERROR("PLL %d not locked\n", port);
2818
2819 /*
2820 * While we write to the group register to program all lanes at once we
2821 * can read only lane registers and we pick lanes 0/1 for that.
2822 */
2823 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2824 temp &= ~LANE_STAGGER_MASK;
2825 temp &= ~LANESTAGGER_STRAP_OVRD;
2826 temp |= pll->config.hw_state.pcsdw12;
2827 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2828}
2829
2830static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2831 struct intel_shared_dpll *pll)
2832{
2833 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2834 uint32_t temp;
2835
2836 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2837 temp &= ~PORT_PLL_ENABLE;
2838 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2839 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2840}
2841
2842static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2843 struct intel_shared_dpll *pll,
2844 struct intel_dpll_hw_state *hw_state)
2845{
2846 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2847 uint32_t val;
2848
2849 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2850 return false;
2851
2852 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2853 if (!(val & PORT_PLL_ENABLE))
2854 return false;
2855
2856 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak05712c12015-06-18 17:25:54 +03002857 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2858 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2859
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302860 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
2861 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
2862 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
2863 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
2864 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
2865 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak05712c12015-06-18 17:25:54 +03002866 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2867 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2868
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302869 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302870 /*
2871 * While we write to the group register to program all lanes at once we
2872 * can read only lane registers. We configure all lanes the same way, so
2873 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2874 */
2875 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2876 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port) != hw_state->pcsdw12))
2877 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2878 hw_state->pcsdw12,
2879 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
2880
2881 return true;
2882}
2883
2884static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2885{
2886 int i;
2887
2888 dev_priv->num_shared_dpll = 3;
2889
2890 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2891 dev_priv->shared_dplls[i].id = i;
2892 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2893 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2894 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2895 dev_priv->shared_dplls[i].get_hw_state =
2896 bxt_ddi_pll_get_hw_state;
2897 }
2898}
2899
Damien Lespiau143b3072014-07-29 18:06:19 +01002900void intel_ddi_pll_init(struct drm_device *dev)
2901{
2902 struct drm_i915_private *dev_priv = dev->dev_private;
2903 uint32_t val = I915_READ(LCPLL_CTL);
2904
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002905 if (IS_SKYLAKE(dev))
2906 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302907 else if (IS_BROXTON(dev))
2908 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002909 else
2910 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002911
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002912 if (IS_SKYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002913 int cdclk_freq;
2914
2915 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002916 dev_priv->skl_boot_cdclk = cdclk_freq;
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002917 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2918 DRM_ERROR("LCPLL1 is disabled\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002919 else
2920 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302921 } else if (IS_BROXTON(dev)) {
2922 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302923 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002924 } else {
2925 /*
2926 * The LCPLL register should be turned on by the BIOS. For now
2927 * let's just check its state and print errors in case
2928 * something is wrong. Don't even try to turn it on.
2929 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002930
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002931 if (val & LCPLL_CD_SOURCE_FCLK)
2932 DRM_ERROR("CDCLK source is not LCPLL\n");
2933
2934 if (val & LCPLL_PLL_DISABLE)
2935 DRM_ERROR("LCPLL is disabled\n");
2936 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002937}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002938
2939void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
2940{
Paulo Zanoni174edf12012-10-26 19:05:50 -02002941 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
2942 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002943 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02002944 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002945 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302946 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002947
2948 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2949 val = I915_READ(DDI_BUF_CTL(port));
2950 if (val & DDI_BUF_CTL_ENABLE) {
2951 val &= ~DDI_BUF_CTL_ENABLE;
2952 I915_WRITE(DDI_BUF_CTL(port), val);
2953 wait = true;
2954 }
2955
2956 val = I915_READ(DP_TP_CTL(port));
2957 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2958 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2959 I915_WRITE(DP_TP_CTL(port), val);
2960 POSTING_READ(DP_TP_CTL(port));
2961
2962 if (wait)
2963 intel_wait_ddi_buf_idle(dev_priv, port);
2964 }
2965
Dave Airlie0e32b392014-05-02 14:02:48 +10002966 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03002967 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10002968 if (intel_dp->is_mst)
2969 val |= DP_TP_CTL_MODE_MST;
2970 else {
2971 val |= DP_TP_CTL_MODE_SST;
2972 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
2973 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
2974 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002975 I915_WRITE(DP_TP_CTL(port), val);
2976 POSTING_READ(DP_TP_CTL(port));
2977
2978 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
2979 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
2980 POSTING_READ(DDI_BUF_CTL(port));
2981
2982 udelay(600);
2983}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002984
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02002985void intel_ddi_fdi_disable(struct drm_crtc *crtc)
2986{
2987 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2988 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2989 uint32_t val;
2990
2991 intel_ddi_post_disable(intel_encoder);
2992
2993 val = I915_READ(_FDI_RXA_CTL);
2994 val &= ~FDI_RX_ENABLE;
2995 I915_WRITE(_FDI_RXA_CTL, val);
2996
2997 val = I915_READ(_FDI_RXA_MISC);
2998 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
2999 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
3000 I915_WRITE(_FDI_RXA_MISC, val);
3001
3002 val = I915_READ(_FDI_RXA_CTL);
3003 val &= ~FDI_PCDCLK;
3004 I915_WRITE(_FDI_RXA_CTL, val);
3005
3006 val = I915_READ(_FDI_RXA_CTL);
3007 val &= ~FDI_RX_PLL_ENABLE;
3008 I915_WRITE(_FDI_RXA_CTL, val);
3009}
3010
Ville Syrjälä6801c182013-09-24 14:24:05 +03003011void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003012 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003013{
3014 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3015 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003016 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003017 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003018 u32 temp, flags = 0;
3019
3020 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3021 if (temp & TRANS_DDI_PHSYNC)
3022 flags |= DRM_MODE_FLAG_PHSYNC;
3023 else
3024 flags |= DRM_MODE_FLAG_NHSYNC;
3025 if (temp & TRANS_DDI_PVSYNC)
3026 flags |= DRM_MODE_FLAG_PVSYNC;
3027 else
3028 flags |= DRM_MODE_FLAG_NVSYNC;
3029
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003030 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003031
3032 switch (temp & TRANS_DDI_BPC_MASK) {
3033 case TRANS_DDI_BPC_6:
3034 pipe_config->pipe_bpp = 18;
3035 break;
3036 case TRANS_DDI_BPC_8:
3037 pipe_config->pipe_bpp = 24;
3038 break;
3039 case TRANS_DDI_BPC_10:
3040 pipe_config->pipe_bpp = 30;
3041 break;
3042 case TRANS_DDI_BPC_12:
3043 pipe_config->pipe_bpp = 36;
3044 break;
3045 default:
3046 break;
3047 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003048
3049 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3050 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b52014-04-24 23:54:47 +02003051 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003052 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3053
3054 if (intel_hdmi->infoframe_enabled(&encoder->base))
3055 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003056 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003057 case TRANS_DDI_MODE_SELECT_DVI:
3058 case TRANS_DDI_MODE_SELECT_FDI:
3059 break;
3060 case TRANS_DDI_MODE_SELECT_DP_SST:
3061 case TRANS_DDI_MODE_SELECT_DP_MST:
3062 pipe_config->has_dp_encoder = true;
3063 intel_dp_get_m_n(intel_crtc, pipe_config);
3064 break;
3065 default:
3066 break;
3067 }
Daniel Vetter10214422013-11-18 07:38:16 +01003068
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003069 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003070 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003071 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003072 pipe_config->has_audio = true;
3073 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003074
Daniel Vetter10214422013-11-18 07:38:16 +01003075 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3076 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3077 /*
3078 * This is a big fat ugly hack.
3079 *
3080 * Some machines in UEFI boot mode provide us a VBT that has 18
3081 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3082 * unknown we fail to light up. Yet the same BIOS boots up with
3083 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3084 * max, not what it tells us to use.
3085 *
3086 * Note: This will still be broken if the eDP panel is not lit
3087 * up by the BIOS, and thus we can't get the mode at module
3088 * load.
3089 */
3090 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3091 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3092 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3093 }
Jesse Barnes11578552014-01-21 12:42:10 -08003094
Damien Lespiau22606a12014-12-12 14:26:57 +00003095 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003096}
3097
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003098static void intel_ddi_destroy(struct drm_encoder *encoder)
3099{
3100 /* HDMI has nothing special to destroy, so we can go with this. */
3101 intel_dp_encoder_destroy(encoder);
3102}
3103
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003104static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003105 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003106{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003107 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003108 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003109
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003110 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003111
Daniel Vettereccb1402013-05-22 00:50:22 +02003112 if (port == PORT_A)
3113 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3114
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003115 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003116 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003117 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003118 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003119}
3120
3121static const struct drm_encoder_funcs intel_ddi_funcs = {
3122 .destroy = intel_ddi_destroy,
3123};
3124
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003125static struct intel_connector *
3126intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3127{
3128 struct intel_connector *connector;
3129 enum port port = intel_dig_port->port;
3130
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003131 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003132 if (!connector)
3133 return NULL;
3134
3135 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3136 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3137 kfree(connector);
3138 return NULL;
3139 }
3140
3141 return connector;
3142}
3143
3144static struct intel_connector *
3145intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3146{
3147 struct intel_connector *connector;
3148 enum port port = intel_dig_port->port;
3149
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003150 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003151 if (!connector)
3152 return NULL;
3153
3154 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3155 intel_hdmi_init_connector(intel_dig_port, connector);
3156
3157 return connector;
3158}
3159
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003160void intel_ddi_init(struct drm_device *dev, enum port port)
3161{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003162 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003163 struct intel_digital_port *intel_dig_port;
3164 struct intel_encoder *intel_encoder;
3165 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003166 bool init_hdmi, init_dp;
3167
3168 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3169 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3170 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3171 if (!init_dp && !init_hdmi) {
Chris Wilsonf68d6972014-08-04 07:15:09 +01003172 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003173 port_name(port));
3174 init_hdmi = true;
3175 init_dp = true;
3176 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003177
Daniel Vetterb14c5672013-09-19 12:18:32 +02003178 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003179 if (!intel_dig_port)
3180 return;
3181
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003182 intel_encoder = &intel_dig_port->base;
3183 encoder = &intel_encoder->base;
3184
3185 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3186 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003187
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003188 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003189 intel_encoder->enable = intel_enable_ddi;
3190 intel_encoder->pre_enable = intel_ddi_pre_enable;
3191 intel_encoder->disable = intel_disable_ddi;
3192 intel_encoder->post_disable = intel_ddi_post_disable;
3193 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003194 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003195
3196 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003197 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3198 (DDI_BUF_PORT_REVERSAL |
3199 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003200
3201 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003202 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003203 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003204
Chris Wilsonf68d6972014-08-04 07:15:09 +01003205 if (init_dp) {
3206 if (!intel_ddi_init_dp_connector(intel_dig_port))
3207 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003208
Chris Wilsonf68d6972014-08-04 07:15:09 +01003209 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Jani Nikula5fcece82015-05-27 15:03:42 +03003210 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003211 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003212
Paulo Zanoni311a2092013-09-12 17:12:18 -03003213 /* In theory we don't need the encoder->type check, but leave it just in
3214 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003215 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3216 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3217 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003218 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003219
3220 return;
3221
3222err:
3223 drm_encoder_cleanup(encoder);
3224 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003225}