blob: cf2896da8ad80681a503ca8aea203d6f52f9b191 [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{
1143 /* FIXME formula not available in bspec */
1144 return 0;
1145}
1146
1147static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1148 struct intel_crtc_state *pipe_config)
1149{
1150 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1151 enum port port = intel_ddi_get_encoder_port(encoder);
1152 uint32_t dpll = port;
1153
1154 pipe_config->port_clock =
1155 bxt_calc_pll_link(dev_priv, dpll);
1156
1157 if (pipe_config->has_dp_encoder)
1158 pipe_config->base.adjusted_mode.crtc_clock =
1159 intel_dotclock_calculate(pipe_config->port_clock,
1160 &pipe_config->dp_m_n);
1161 else
1162 pipe_config->base.adjusted_mode.crtc_clock =
1163 pipe_config->port_clock;
1164}
1165
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001166void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001167 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001168{
Damien Lespiau22606a12014-12-12 14:26:57 +00001169 struct drm_device *dev = encoder->base.dev;
1170
1171 if (INTEL_INFO(dev)->gen <= 8)
1172 hsw_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301173 else if (IS_SKYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001174 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301175 else if (IS_BROXTON(dev))
1176 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001177}
1178
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001179static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001180hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1181 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001182{
1183 uint64_t freq2k;
1184 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001185 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001186 unsigned budget;
1187
1188 freq2k = clock / 100;
1189
Damien Lespiau63582982015-05-07 18:38:46 +01001190 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001191
1192 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1193 * and directly pass the LC PLL to it. */
1194 if (freq2k == 5400000) {
1195 *n2_out = 2;
1196 *p_out = 1;
1197 *r2_out = 2;
1198 return;
1199 }
1200
1201 /*
1202 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1203 * the WR PLL.
1204 *
1205 * We want R so that REF_MIN <= Ref <= REF_MAX.
1206 * Injecting R2 = 2 * R gives:
1207 * REF_MAX * r2 > LC_FREQ * 2 and
1208 * REF_MIN * r2 < LC_FREQ * 2
1209 *
1210 * Which means the desired boundaries for r2 are:
1211 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1212 *
1213 */
1214 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1215 r2 <= LC_FREQ * 2 / REF_MIN;
1216 r2++) {
1217
1218 /*
1219 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1220 *
1221 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1222 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1223 * VCO_MAX * r2 > n2 * LC_FREQ and
1224 * VCO_MIN * r2 < n2 * LC_FREQ)
1225 *
1226 * Which means the desired boundaries for n2 are:
1227 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1228 */
1229 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1230 n2 <= VCO_MAX * r2 / LC_FREQ;
1231 n2++) {
1232
1233 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001234 hsw_wrpll_update_rnp(freq2k, budget,
1235 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001236 }
1237 }
1238
1239 *n2_out = best.n2;
1240 *p_out = best.p;
1241 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001242}
1243
Damien Lespiau0220ab62014-07-29 18:06:22 +01001244static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001245hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001246 struct intel_crtc_state *crtc_state,
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001247 struct intel_encoder *intel_encoder,
1248 int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001249{
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001250 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001251 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001252 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001253 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001254
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001255 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001256
Daniel Vetter114fe482014-06-25 22:01:48 +03001257 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001258 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1259 WRPLL_DIVIDER_POST(p);
1260
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001261 memset(&crtc_state->dpll_hw_state, 0,
1262 sizeof(crtc_state->dpll_hw_state));
1263
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001264 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001265
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001266 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001267 if (pll == NULL) {
1268 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1269 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001270 return false;
1271 }
1272
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001273 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001274 }
1275
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001276 return true;
1277}
1278
Damien Lespiaudc253812015-06-25 16:15:06 +01001279struct skl_wrpll_context {
1280 uint64_t min_deviation; /* current minimal deviation */
1281 uint64_t central_freq; /* chosen central freq */
1282 uint64_t dco_freq; /* chosen dco freq */
1283 unsigned int p; /* chosen divider */
1284};
1285
1286static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1287{
1288 memset(ctx, 0, sizeof(*ctx));
1289
1290 ctx->min_deviation = U64_MAX;
1291}
1292
1293/* DCO freq must be within +1%/-6% of the DCO central freq */
1294#define SKL_DCO_MAX_PDEVIATION 100
1295#define SKL_DCO_MAX_NDEVIATION 600
1296
1297static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1298 uint64_t central_freq,
1299 uint64_t dco_freq,
1300 unsigned int divider)
1301{
1302 uint64_t deviation;
1303
1304 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1305 central_freq);
1306
1307 /* positive deviation */
1308 if (dco_freq >= central_freq) {
1309 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1310 deviation < ctx->min_deviation) {
1311 ctx->min_deviation = deviation;
1312 ctx->central_freq = central_freq;
1313 ctx->dco_freq = dco_freq;
1314 ctx->p = divider;
1315 }
1316 /* negative deviation */
1317 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1318 deviation < ctx->min_deviation) {
1319 ctx->min_deviation = deviation;
1320 ctx->central_freq = central_freq;
1321 ctx->dco_freq = dco_freq;
1322 ctx->p = divider;
1323 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001324}
1325
1326static void skl_wrpll_get_multipliers(unsigned int p,
1327 unsigned int *p0 /* out */,
1328 unsigned int *p1 /* out */,
1329 unsigned int *p2 /* out */)
1330{
1331 /* even dividers */
1332 if (p % 2 == 0) {
1333 unsigned int half = p / 2;
1334
1335 if (half == 1 || half == 2 || half == 3 || half == 5) {
1336 *p0 = 2;
1337 *p1 = 1;
1338 *p2 = half;
1339 } else if (half % 2 == 0) {
1340 *p0 = 2;
1341 *p1 = half / 2;
1342 *p2 = 2;
1343 } else if (half % 3 == 0) {
1344 *p0 = 3;
1345 *p1 = half / 3;
1346 *p2 = 2;
1347 } else if (half % 7 == 0) {
1348 *p0 = 7;
1349 *p1 = half / 7;
1350 *p2 = 2;
1351 }
1352 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1353 *p0 = 3;
1354 *p1 = 1;
1355 *p2 = p / 3;
1356 } else if (p == 5 || p == 7) {
1357 *p0 = p;
1358 *p1 = 1;
1359 *p2 = 1;
1360 } else if (p == 15) {
1361 *p0 = 3;
1362 *p1 = 1;
1363 *p2 = 5;
1364 } else if (p == 21) {
1365 *p0 = 7;
1366 *p1 = 1;
1367 *p2 = 3;
1368 } else if (p == 35) {
1369 *p0 = 7;
1370 *p1 = 1;
1371 *p2 = 5;
1372 }
1373}
1374
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001375struct skl_wrpll_params {
1376 uint32_t dco_fraction;
1377 uint32_t dco_integer;
1378 uint32_t qdiv_ratio;
1379 uint32_t qdiv_mode;
1380 uint32_t kdiv;
1381 uint32_t pdiv;
1382 uint32_t central_freq;
1383};
1384
Damien Lespiau76516fb2015-05-07 18:38:42 +01001385static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1386 uint64_t afe_clock,
1387 uint64_t central_freq,
1388 uint32_t p0, uint32_t p1, uint32_t p2)
1389{
1390 uint64_t dco_freq;
1391
Damien Lespiau76516fb2015-05-07 18:38:42 +01001392 switch (central_freq) {
1393 case 9600000000ULL:
1394 params->central_freq = 0;
1395 break;
1396 case 9000000000ULL:
1397 params->central_freq = 1;
1398 break;
1399 case 8400000000ULL:
1400 params->central_freq = 3;
1401 }
1402
1403 switch (p0) {
1404 case 1:
1405 params->pdiv = 0;
1406 break;
1407 case 2:
1408 params->pdiv = 1;
1409 break;
1410 case 3:
1411 params->pdiv = 2;
1412 break;
1413 case 7:
1414 params->pdiv = 4;
1415 break;
1416 default:
1417 WARN(1, "Incorrect PDiv\n");
1418 }
1419
1420 switch (p2) {
1421 case 5:
1422 params->kdiv = 0;
1423 break;
1424 case 2:
1425 params->kdiv = 1;
1426 break;
1427 case 3:
1428 params->kdiv = 2;
1429 break;
1430 case 1:
1431 params->kdiv = 3;
1432 break;
1433 default:
1434 WARN(1, "Incorrect KDiv\n");
1435 }
1436
1437 params->qdiv_ratio = p1;
1438 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1439
1440 dco_freq = p0 * p1 * p2 * afe_clock;
1441
1442 /*
1443 * Intermediate values are in Hz.
1444 * Divide by MHz to match bsepc
1445 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001446 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001447 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001448 div_u64((div_u64(dco_freq, 24) -
1449 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001450}
1451
Damien Lespiau318bd822015-05-07 18:38:40 +01001452static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001453skl_ddi_calculate_wrpll(int clock /* in Hz */,
1454 struct skl_wrpll_params *wrpll_params)
1455{
1456 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001457 uint64_t dco_central_freq[3] = {8400000000ULL,
1458 9000000000ULL,
1459 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001460 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1461 24, 28, 30, 32, 36, 40, 42, 44,
1462 48, 52, 54, 56, 60, 64, 66, 68,
1463 70, 72, 76, 78, 80, 84, 88, 90,
1464 92, 96, 98 };
1465 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1466 static const struct {
1467 const int *list;
1468 int n_dividers;
1469 } dividers[] = {
1470 { even_dividers, ARRAY_SIZE(even_dividers) },
1471 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1472 };
1473 struct skl_wrpll_context ctx;
1474 unsigned int dco, d, i;
1475 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001476
Damien Lespiaudc253812015-06-25 16:15:06 +01001477 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001478
Damien Lespiaudc253812015-06-25 16:15:06 +01001479 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1480 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1481 for (i = 0; i < dividers[d].n_dividers; i++) {
1482 unsigned int p = dividers[d].list[i];
1483 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001484
Damien Lespiaudc253812015-06-25 16:15:06 +01001485 skl_wrpll_try_divider(&ctx,
1486 dco_central_freq[dco],
1487 dco_freq,
1488 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001489 /*
1490 * Skip the remaining dividers if we're sure to
1491 * have found the definitive divider, we can't
1492 * improve a 0 deviation.
1493 */
1494 if (ctx.min_deviation == 0)
1495 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001496 }
1497 }
Damien Lespiau267db662015-06-25 16:19:24 +01001498
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001499skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001500 /*
1501 * If a solution is found with an even divider, prefer
1502 * this one.
1503 */
1504 if (d == 0 && ctx.p)
1505 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001506 }
1507
Damien Lespiaudc253812015-06-25 16:15:06 +01001508 if (!ctx.p) {
1509 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001510 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001511 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001512
Damien Lespiaudc253812015-06-25 16:15:06 +01001513 /*
1514 * gcc incorrectly analyses that these can be used without being
1515 * initialized. To be fair, it's hard to guess.
1516 */
1517 p0 = p1 = p2 = 0;
1518 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1519 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1520 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001521
Damien Lespiau318bd822015-05-07 18:38:40 +01001522 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001523}
1524
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001525static bool
1526skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001527 struct intel_crtc_state *crtc_state,
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001528 struct intel_encoder *intel_encoder,
1529 int clock)
1530{
1531 struct intel_shared_dpll *pll;
1532 uint32_t ctrl1, cfgcr1, cfgcr2;
1533
1534 /*
1535 * See comment in intel_dpll_hw_state to understand why we always use 0
1536 * as the DPLL id in this function.
1537 */
1538
1539 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1540
1541 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1542 struct skl_wrpll_params wrpll_params = { 0, };
1543
1544 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1545
Damien Lespiau318bd822015-05-07 18:38:40 +01001546 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1547 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001548
1549 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1550 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1551 wrpll_params.dco_integer;
1552
1553 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1554 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1555 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1556 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1557 wrpll_params.central_freq;
1558 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
1559 struct drm_encoder *encoder = &intel_encoder->base;
1560 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1561
1562 switch (intel_dp->link_bw) {
1563 case DP_LINK_BW_1_62:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001564 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001565 break;
1566 case DP_LINK_BW_2_7:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001567 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001568 break;
1569 case DP_LINK_BW_5_4:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001570 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001571 break;
1572 }
1573
1574 cfgcr1 = cfgcr2 = 0;
1575 } else /* eDP */
1576 return true;
1577
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001578 memset(&crtc_state->dpll_hw_state, 0,
1579 sizeof(crtc_state->dpll_hw_state));
1580
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001581 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1582 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1583 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001584
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001585 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001586 if (pll == NULL) {
1587 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1588 pipe_name(intel_crtc->pipe));
1589 return false;
1590 }
1591
1592 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001593 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001594
1595 return true;
1596}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001597
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301598/* bxt clock parameters */
1599struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301600 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301601 uint32_t p1;
1602 uint32_t p2;
1603 uint32_t m2_int;
1604 uint32_t m2_frac;
1605 bool m2_frac_en;
1606 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301607};
1608
1609/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301610static const struct bxt_clk_div bxt_dp_clk_val[] = {
1611 {162000, 4, 2, 32, 1677722, 1, 1},
1612 {270000, 4, 1, 27, 0, 0, 1},
1613 {540000, 2, 1, 27, 0, 0, 1},
1614 {216000, 3, 2, 32, 1677722, 1, 1},
1615 {243000, 4, 1, 24, 1258291, 1, 1},
1616 {324000, 4, 1, 32, 1677722, 1, 1},
1617 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301618};
1619
1620static bool
1621bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1622 struct intel_crtc_state *crtc_state,
1623 struct intel_encoder *intel_encoder,
1624 int clock)
1625{
1626 struct intel_shared_dpll *pll;
1627 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301628 int vco = 0;
1629 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane0681e32015-05-13 12:20:35 +05301630 uint32_t dcoampovr_en_h, dco_amp, lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301631
1632 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1633 intel_clock_t best_clock;
1634
1635 /* Calculate HDMI div */
1636 /*
1637 * FIXME: tie the following calculation into
1638 * i9xx_crtc_compute_clock
1639 */
1640 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1641 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1642 clock, pipe_name(intel_crtc->pipe));
1643 return false;
1644 }
1645
1646 clk_div.p1 = best_clock.p1;
1647 clk_div.p2 = best_clock.p2;
1648 WARN_ON(best_clock.m1 != 2);
1649 clk_div.n = best_clock.n;
1650 clk_div.m2_int = best_clock.m2 >> 22;
1651 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1652 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1653
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301654 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301655 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1656 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301657 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301658
Sonika Jindal64987fc2015-05-26 17:50:13 +05301659 clk_div = bxt_dp_clk_val[0];
1660 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1661 if (bxt_dp_clk_val[i].clock == clock) {
1662 clk_div = bxt_dp_clk_val[i];
1663 break;
1664 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301665 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301666 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1667 }
1668
1669 dco_amp = 15;
1670 dcoampovr_en_h = 0;
1671 if (vco >= 6200000 && vco <= 6480000) {
1672 prop_coef = 4;
1673 int_coef = 9;
1674 gain_ctl = 3;
1675 targ_cnt = 8;
1676 } else if ((vco > 5400000 && vco < 6200000) ||
1677 (vco >= 4800000 && vco < 5400000)) {
1678 prop_coef = 5;
1679 int_coef = 11;
1680 gain_ctl = 3;
1681 targ_cnt = 9;
1682 if (vco >= 4800000 && vco < 5400000)
1683 dcoampovr_en_h = 1;
1684 } else if (vco == 5400000) {
1685 prop_coef = 3;
1686 int_coef = 8;
1687 gain_ctl = 1;
1688 targ_cnt = 9;
1689 } else {
1690 DRM_ERROR("Invalid VCO\n");
1691 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301692 }
1693
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001694 memset(&crtc_state->dpll_hw_state, 0,
1695 sizeof(crtc_state->dpll_hw_state));
1696
Vandana Kannane0681e32015-05-13 12:20:35 +05301697 if (clock > 270000)
1698 lanestagger = 0x18;
1699 else if (clock > 135000)
1700 lanestagger = 0x0d;
1701 else if (clock > 67000)
1702 lanestagger = 0x07;
1703 else if (clock > 33000)
1704 lanestagger = 0x04;
1705 else
1706 lanestagger = 0x02;
1707
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301708 crtc_state->dpll_hw_state.ebb0 =
1709 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1710 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1711 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1712 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1713
1714 if (clk_div.m2_frac_en)
1715 crtc_state->dpll_hw_state.pll3 =
1716 PORT_PLL_M2_FRAC_ENABLE;
1717
1718 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301719 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301720 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301721 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301722
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301723 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1724
Imre Deak05712c12015-06-18 17:25:54 +03001725 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1726
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301727 if (dcoampovr_en_h)
1728 crtc_state->dpll_hw_state.pll10 = PORT_PLL_DCO_AMP_OVR_EN_H;
1729
1730 crtc_state->dpll_hw_state.pll10 |= PORT_PLL_DCO_AMP(dco_amp);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301731
Imre Deak05712c12015-06-18 17:25:54 +03001732 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1733
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301734 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301735 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301736
1737 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1738 if (pll == NULL) {
1739 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1740 pipe_name(intel_crtc->pipe));
1741 return false;
1742 }
1743
1744 /* shared DPLL id 0 is DPLL A */
1745 crtc_state->ddi_pll_sel = pll->id;
1746
1747 return true;
1748}
1749
Damien Lespiau0220ab62014-07-29 18:06:22 +01001750/*
1751 * Tries to find a *shared* PLL for the CRTC and store it in
1752 * intel_crtc->ddi_pll_sel.
1753 *
1754 * For private DPLLs, compute_config() should do the selection for us. This
1755 * function should be folded into compute_config() eventually.
1756 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001757bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1758 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001759{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001760 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001761 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001762 intel_ddi_get_crtc_new_encoder(crtc_state);
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001763 int clock = crtc_state->port_clock;
Damien Lespiau0220ab62014-07-29 18:06:22 +01001764
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001765 if (IS_SKYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001766 return skl_ddi_pll_select(intel_crtc, crtc_state,
1767 intel_encoder, clock);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301768 else if (IS_BROXTON(dev))
1769 return bxt_ddi_pll_select(intel_crtc, crtc_state,
1770 intel_encoder, clock);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001771 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001772 return hsw_ddi_pll_select(intel_crtc, crtc_state,
1773 intel_encoder, clock);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001774}
1775
Paulo Zanonidae84792012-10-15 15:51:30 -03001776void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1777{
1778 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1779 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1780 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001781 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001782 int type = intel_encoder->type;
1783 uint32_t temp;
1784
Dave Airlie0e32b392014-05-02 14:02:48 +10001785 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001786 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001787 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001788 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001789 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001790 break;
1791 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001792 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001793 break;
1794 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001795 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001796 break;
1797 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001798 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001799 break;
1800 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001801 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001802 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001803 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001804 }
1805}
1806
Dave Airlie0e32b392014-05-02 14:02:48 +10001807void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1808{
1809 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1810 struct drm_device *dev = crtc->dev;
1811 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001812 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001813 uint32_t temp;
1814 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1815 if (state == true)
1816 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1817 else
1818 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1819 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1820}
1821
Damien Lespiau8228c252013-03-07 15:30:27 +00001822void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001823{
1824 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1825 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001826 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001827 struct drm_device *dev = crtc->dev;
1828 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001829 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001830 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001831 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001832 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001833 uint32_t temp;
1834
Paulo Zanoniad80a812012-10-24 16:06:19 -02001835 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1836 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001837 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001838
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001839 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001840 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001841 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001842 break;
1843 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001844 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001845 break;
1846 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001847 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001848 break;
1849 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001850 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001851 break;
1852 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001853 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001854 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001855
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001856 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001857 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001858 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001859 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001860
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001861 if (cpu_transcoder == TRANSCODER_EDP) {
1862 switch (pipe) {
1863 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001864 /* On Haswell, can only use the always-on power well for
1865 * eDP when not using the panel fitter, and when not
1866 * using motion blur mitigation (which we don't
1867 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001868 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001869 (intel_crtc->config->pch_pfit.enabled ||
1870 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001871 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1872 else
1873 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001874 break;
1875 case PIPE_B:
1876 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1877 break;
1878 case PIPE_C:
1879 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1880 break;
1881 default:
1882 BUG();
1883 break;
1884 }
1885 }
1886
Paulo Zanoni7739c332012-10-15 15:51:29 -03001887 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001888 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001889 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001890 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001891 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001892
Paulo Zanoni7739c332012-10-15 15:51:29 -03001893 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001894 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001895 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001896
1897 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1898 type == INTEL_OUTPUT_EDP) {
1899 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1900
Dave Airlie0e32b392014-05-02 14:02:48 +10001901 if (intel_dp->is_mst) {
1902 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1903 } else
1904 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1905
1906 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
1907 } else if (type == INTEL_OUTPUT_DP_MST) {
1908 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1909
1910 if (intel_dp->is_mst) {
1911 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1912 } else
1913 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001914
Daniel Vetter17aa6be2013-04-30 14:01:40 +02001915 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001916 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001917 WARN(1, "Invalid encoder type %d for pipe %c\n",
1918 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001919 }
1920
Paulo Zanoniad80a812012-10-24 16:06:19 -02001921 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001922}
1923
Paulo Zanoniad80a812012-10-24 16:06:19 -02001924void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1925 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001926{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001927 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001928 uint32_t val = I915_READ(reg);
1929
Dave Airlie0e32b392014-05-02 14:02:48 +10001930 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001931 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001932 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001933}
1934
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001935bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1936{
1937 struct drm_device *dev = intel_connector->base.dev;
1938 struct drm_i915_private *dev_priv = dev->dev_private;
1939 struct intel_encoder *intel_encoder = intel_connector->encoder;
1940 int type = intel_connector->base.connector_type;
1941 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1942 enum pipe pipe = 0;
1943 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001944 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001945 uint32_t tmp;
1946
Paulo Zanoni882244a2014-04-01 14:55:12 -03001947 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001948 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001949 return false;
1950
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001951 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1952 return false;
1953
1954 if (port == PORT_A)
1955 cpu_transcoder = TRANSCODER_EDP;
1956 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001957 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001958
1959 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1960
1961 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1962 case TRANS_DDI_MODE_SELECT_HDMI:
1963 case TRANS_DDI_MODE_SELECT_DVI:
1964 return (type == DRM_MODE_CONNECTOR_HDMIA);
1965
1966 case TRANS_DDI_MODE_SELECT_DP_SST:
1967 if (type == DRM_MODE_CONNECTOR_eDP)
1968 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001969 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001970 case TRANS_DDI_MODE_SELECT_DP_MST:
1971 /* if the transcoder is in MST state then
1972 * connector isn't connected */
1973 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001974
1975 case TRANS_DDI_MODE_SELECT_FDI:
1976 return (type == DRM_MODE_CONNECTOR_VGA);
1977
1978 default:
1979 return false;
1980 }
1981}
1982
Daniel Vetter85234cd2012-07-02 13:27:29 +02001983bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1984 enum pipe *pipe)
1985{
1986 struct drm_device *dev = encoder->base.dev;
1987 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001988 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001989 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001990 u32 tmp;
1991 int i;
1992
Imre Deak6d129be2014-03-05 16:20:54 +02001993 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001994 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02001995 return false;
1996
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001997 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001998
1999 if (!(tmp & DDI_BUF_CTL_ENABLE))
2000 return false;
2001
Paulo Zanoniad80a812012-10-24 16:06:19 -02002002 if (port == PORT_A) {
2003 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002004
Paulo Zanoniad80a812012-10-24 16:06:19 -02002005 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2006 case TRANS_DDI_EDP_INPUT_A_ON:
2007 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2008 *pipe = PIPE_A;
2009 break;
2010 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2011 *pipe = PIPE_B;
2012 break;
2013 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2014 *pipe = PIPE_C;
2015 break;
2016 }
2017
2018 return true;
2019 } else {
2020 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2021 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2022
2023 if ((tmp & TRANS_DDI_PORT_MASK)
2024 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002025 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2026 return false;
2027
Paulo Zanoniad80a812012-10-24 16:06:19 -02002028 *pipe = i;
2029 return true;
2030 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002031 }
2032 }
2033
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002034 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002035
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002036 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002037}
2038
Paulo Zanonifc914632012-10-05 12:05:54 -03002039void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2040{
2041 struct drm_crtc *crtc = &intel_crtc->base;
2042 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2043 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2044 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002045 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002046
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002047 if (cpu_transcoder != TRANSCODER_EDP)
2048 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2049 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002050}
2051
2052void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2053{
2054 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002055 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002056
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002057 if (cpu_transcoder != TRANSCODER_EDP)
2058 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2059 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002060}
2061
David Weinehallf8896f52015-06-25 11:11:03 +03002062static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2063 enum port port, int type)
2064{
2065 struct drm_i915_private *dev_priv = dev->dev_private;
2066 const struct ddi_buf_trans *ddi_translations;
2067 uint8_t iboost;
2068 int n_entries;
2069 u32 reg;
2070
2071 if (type == INTEL_OUTPUT_DISPLAYPORT) {
2072 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2073 iboost = ddi_translations[port].i_boost;
2074 } else if (type == INTEL_OUTPUT_EDP) {
2075 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2076 iboost = ddi_translations[port].i_boost;
2077 } else if (type == INTEL_OUTPUT_HDMI) {
2078 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2079 iboost = ddi_translations[port].i_boost;
2080 } else {
2081 return;
2082 }
2083
2084 /* Make sure that the requested I_boost is valid */
2085 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2086 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2087 return;
2088 }
2089
2090 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2091 reg &= ~BALANCE_LEG_MASK(port);
2092 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2093
2094 if (iboost)
2095 reg |= iboost << BALANCE_LEG_SHIFT(port);
2096 else
2097 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2098
2099 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2100}
2101
2102static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2103 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302104{
2105 struct drm_i915_private *dev_priv = dev->dev_private;
2106 const struct bxt_ddi_buf_trans *ddi_translations;
2107 u32 n_entries, i;
2108 uint32_t val;
2109
2110 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
2111 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2112 ddi_translations = bxt_ddi_translations_dp;
2113 } else if (type == INTEL_OUTPUT_HDMI) {
2114 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2115 ddi_translations = bxt_ddi_translations_hdmi;
2116 } else {
2117 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2118 type);
2119 return;
2120 }
2121
2122 /* Check if default value has to be used */
2123 if (level >= n_entries ||
2124 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2125 for (i = 0; i < n_entries; i++) {
2126 if (ddi_translations[i].default_index) {
2127 level = i;
2128 break;
2129 }
2130 }
2131 }
2132
2133 /*
2134 * While we write to the group register to program all lanes at once we
2135 * can read only lane registers and we pick lanes 0/1 for that.
2136 */
2137 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2138 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2139 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2140
2141 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2142 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2143 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2144 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2145 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2146
2147 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
2148 val &= ~UNIQE_TRANGE_EN_METHOD;
2149 if (ddi_translations[level].enable)
2150 val |= UNIQE_TRANGE_EN_METHOD;
2151 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2152
2153 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2154 val &= ~DE_EMPHASIS;
2155 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2156 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2157
2158 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2159 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2160 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2161}
2162
David Weinehallf8896f52015-06-25 11:11:03 +03002163static uint32_t translate_signal_level(int signal_levels)
2164{
2165 uint32_t level;
2166
2167 switch (signal_levels) {
2168 default:
2169 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2170 signal_levels);
2171 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2172 level = 0;
2173 break;
2174 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2175 level = 1;
2176 break;
2177 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2178 level = 2;
2179 break;
2180 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2181 level = 3;
2182 break;
2183
2184 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2185 level = 4;
2186 break;
2187 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2188 level = 5;
2189 break;
2190 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2191 level = 6;
2192 break;
2193
2194 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2195 level = 7;
2196 break;
2197 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2198 level = 8;
2199 break;
2200
2201 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2202 level = 9;
2203 break;
2204 }
2205
2206 return level;
2207}
2208
2209uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2210{
2211 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2212 struct drm_device *dev = dport->base.base.dev;
2213 struct intel_encoder *encoder = &dport->base;
2214 uint8_t train_set = intel_dp->train_set[0];
2215 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2216 DP_TRAIN_PRE_EMPHASIS_MASK);
2217 enum port port = dport->port;
2218 uint32_t level;
2219
2220 level = translate_signal_level(signal_levels);
2221
2222 if (IS_SKYLAKE(dev))
2223 skl_ddi_set_iboost(dev, level, port, encoder->type);
2224 else if (IS_BROXTON(dev))
2225 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2226
2227 return DDI_BUF_TRANS_SELECT(level);
2228}
2229
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002230static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002231{
Paulo Zanonic19b0662012-10-15 15:51:41 -03002232 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002233 struct drm_device *dev = encoder->dev;
2234 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002235 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002236 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002237 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302238 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002239
2240 if (type == INTEL_OUTPUT_EDP) {
2241 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01002242 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002243 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002244
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002245 if (IS_SKYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002246 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002247 uint32_t val;
2248
Damien Lespiau5416d872014-11-14 17:24:33 +00002249 /*
2250 * DPLL0 is used for eDP and is the only "private" DPLL (as
2251 * opposed to shared) on SKL
2252 */
2253 if (type == INTEL_OUTPUT_EDP) {
2254 WARN_ON(dpll != SKL_DPLL0);
2255
2256 val = I915_READ(DPLL_CTRL1);
2257
2258 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2259 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002260 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002261 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002262
2263 I915_WRITE(DPLL_CTRL1, val);
2264 POSTING_READ(DPLL_CTRL1);
2265 }
2266
2267 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002268 val = I915_READ(DPLL_CTRL2);
2269
2270 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2271 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2272 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2273 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2274
2275 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002276
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302277 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002278 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2279 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002280 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002281
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002282 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002283 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002284
Dave Airlie44905a272014-05-02 13:36:43 +10002285 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002286
2287 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2288 intel_dp_start_link_train(intel_dp);
2289 intel_dp_complete_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002290 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002291 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002292 } else if (type == INTEL_OUTPUT_HDMI) {
2293 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2294
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302295 if (IS_BROXTON(dev)) {
2296 hdmi_level = dev_priv->vbt.
2297 ddi_port_info[port].hdmi_level_shift;
2298 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2299 INTEL_OUTPUT_HDMI);
2300 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002301 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002302 crtc->config->has_hdmi_sink,
2303 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002304 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002305}
2306
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002307static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002308{
2309 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002310 struct drm_device *dev = encoder->dev;
2311 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002312 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002313 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002314 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002315 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002316
2317 val = I915_READ(DDI_BUF_CTL(port));
2318 if (val & DDI_BUF_CTL_ENABLE) {
2319 val &= ~DDI_BUF_CTL_ENABLE;
2320 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002321 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002322 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002323
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002324 val = I915_READ(DP_TP_CTL(port));
2325 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2326 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2327 I915_WRITE(DP_TP_CTL(port), val);
2328
2329 if (wait)
2330 intel_wait_ddi_buf_idle(dev_priv, port);
2331
Jani Nikula76bb80e2013-11-15 15:29:57 +02002332 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002333 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002334 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002335 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002336 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002337 }
2338
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002339 if (IS_SKYLAKE(dev))
2340 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2341 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302342 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002343 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002344}
2345
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002346static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002347{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002348 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002349 struct drm_crtc *crtc = encoder->crtc;
2350 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002351 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002352 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002353 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2354 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002355
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002356 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002357 struct intel_digital_port *intel_dig_port =
2358 enc_to_dig_port(encoder);
2359
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002360 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2361 * are ignored so nothing special needs to be done besides
2362 * enabling the port.
2363 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002364 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002365 intel_dig_port->saved_port_bits |
2366 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002367 } else if (type == INTEL_OUTPUT_EDP) {
2368 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2369
Vandana Kannan23f08d82014-11-13 14:55:22 +00002370 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002371 intel_dp_stop_link_train(intel_dp);
2372
Daniel Vetter4be73782014-01-17 14:39:48 +01002373 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002374 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302375 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002376 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002377
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002378 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002379 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002380 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002381 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002382}
2383
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002384static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002385{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002386 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002387 struct drm_crtc *crtc = encoder->crtc;
2388 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002389 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002390 struct drm_device *dev = encoder->dev;
2391 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002392
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002393 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002394 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002395 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2396 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002397
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002398 if (type == INTEL_OUTPUT_EDP) {
2399 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2400
Vandana Kannanc3955782015-01-22 15:17:40 +05302401 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002402 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002403 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002404 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002405}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002406
Daniel Vettere0b01be2014-06-25 22:02:01 +03002407static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2408 struct intel_shared_dpll *pll)
2409{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002410 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002411 POSTING_READ(WRPLL_CTL(pll->id));
2412 udelay(20);
2413}
2414
Daniel Vetter12030432014-06-25 22:02:00 +03002415static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2416 struct intel_shared_dpll *pll)
2417{
2418 uint32_t val;
2419
2420 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002421 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2422 POSTING_READ(WRPLL_CTL(pll->id));
2423}
2424
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002425static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2426 struct intel_shared_dpll *pll,
2427 struct intel_dpll_hw_state *hw_state)
2428{
2429 uint32_t val;
2430
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002431 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002432 return false;
2433
2434 val = I915_READ(WRPLL_CTL(pll->id));
2435 hw_state->wrpll = val;
2436
2437 return val & WRPLL_PLL_ENABLE;
2438}
2439
Damien Lespiauca1381b2014-07-15 15:05:33 +01002440static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002441 "WRPLL 1",
2442 "WRPLL 2",
2443};
2444
Damien Lespiau143b3072014-07-29 18:06:19 +01002445static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002446{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002447 int i;
2448
Daniel Vetter716c2e52014-06-25 22:02:02 +03002449 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002450
Daniel Vetter716c2e52014-06-25 22:02:02 +03002451 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002452 dev_priv->shared_dplls[i].id = i;
2453 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002454 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002455 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002456 dev_priv->shared_dplls[i].get_hw_state =
2457 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002458 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002459}
2460
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002461static const char * const skl_ddi_pll_names[] = {
2462 "DPLL 1",
2463 "DPLL 2",
2464 "DPLL 3",
2465};
2466
2467struct skl_dpll_regs {
2468 u32 ctl, cfgcr1, cfgcr2;
2469};
2470
2471/* this array is indexed by the *shared* pll id */
2472static const struct skl_dpll_regs skl_dpll_regs[3] = {
2473 {
2474 /* DPLL 1 */
2475 .ctl = LCPLL2_CTL,
2476 .cfgcr1 = DPLL1_CFGCR1,
2477 .cfgcr2 = DPLL1_CFGCR2,
2478 },
2479 {
2480 /* DPLL 2 */
2481 .ctl = WRPLL_CTL1,
2482 .cfgcr1 = DPLL2_CFGCR1,
2483 .cfgcr2 = DPLL2_CFGCR2,
2484 },
2485 {
2486 /* DPLL 3 */
2487 .ctl = WRPLL_CTL2,
2488 .cfgcr1 = DPLL3_CFGCR1,
2489 .cfgcr2 = DPLL3_CFGCR2,
2490 },
2491};
2492
2493static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2494 struct intel_shared_dpll *pll)
2495{
2496 uint32_t val;
2497 unsigned int dpll;
2498 const struct skl_dpll_regs *regs = skl_dpll_regs;
2499
2500 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2501 dpll = pll->id + 1;
2502
2503 val = I915_READ(DPLL_CTRL1);
2504
2505 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002506 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002507 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2508
2509 I915_WRITE(DPLL_CTRL1, val);
2510 POSTING_READ(DPLL_CTRL1);
2511
2512 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2513 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2514 POSTING_READ(regs[pll->id].cfgcr1);
2515 POSTING_READ(regs[pll->id].cfgcr2);
2516
2517 /* the enable bit is always bit 31 */
2518 I915_WRITE(regs[pll->id].ctl,
2519 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2520
2521 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2522 DRM_ERROR("DPLL %d not locked\n", dpll);
2523}
2524
2525static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2526 struct intel_shared_dpll *pll)
2527{
2528 const struct skl_dpll_regs *regs = skl_dpll_regs;
2529
2530 /* the enable bit is always bit 31 */
2531 I915_WRITE(regs[pll->id].ctl,
2532 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2533 POSTING_READ(regs[pll->id].ctl);
2534}
2535
2536static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2537 struct intel_shared_dpll *pll,
2538 struct intel_dpll_hw_state *hw_state)
2539{
2540 uint32_t val;
2541 unsigned int dpll;
2542 const struct skl_dpll_regs *regs = skl_dpll_regs;
2543
2544 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2545 return false;
2546
2547 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2548 dpll = pll->id + 1;
2549
2550 val = I915_READ(regs[pll->id].ctl);
2551 if (!(val & LCPLL_PLL_ENABLE))
2552 return false;
2553
2554 val = I915_READ(DPLL_CTRL1);
2555 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2556
2557 /* avoid reading back stale values if HDMI mode is not enabled */
2558 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2559 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2560 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2561 }
2562
2563 return true;
2564}
2565
2566static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2567{
2568 int i;
2569
2570 dev_priv->num_shared_dpll = 3;
2571
2572 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2573 dev_priv->shared_dplls[i].id = i;
2574 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2575 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2576 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2577 dev_priv->shared_dplls[i].get_hw_state =
2578 skl_ddi_pll_get_hw_state;
2579 }
2580}
2581
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302582static void broxton_phy_init(struct drm_i915_private *dev_priv,
2583 enum dpio_phy phy)
2584{
2585 enum port port;
2586 uint32_t val;
2587
2588 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2589 val |= GT_DISPLAY_POWER_ON(phy);
2590 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2591
2592 /* Considering 10ms timeout until BSpec is updated */
2593 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2594 DRM_ERROR("timeout during PHY%d power on\n", phy);
2595
2596 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2597 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2598 int lane;
2599
2600 for (lane = 0; lane < 4; lane++) {
2601 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2602 /*
2603 * Note that on CHV this flag is called UPAR, but has
2604 * the same function.
2605 */
2606 val &= ~LATENCY_OPTIM;
2607 if (lane != 1)
2608 val |= LATENCY_OPTIM;
2609
2610 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2611 }
2612 }
2613
2614 /* Program PLL Rcomp code offset */
2615 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2616 val &= ~IREF0RC_OFFSET_MASK;
2617 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2618 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2619
2620 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2621 val &= ~IREF1RC_OFFSET_MASK;
2622 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2623 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2624
2625 /* Program power gating */
2626 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2627 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2628 SUS_CLK_CONFIG;
2629 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2630
2631 if (phy == DPIO_PHY0) {
2632 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2633 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2634 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2635 }
2636
2637 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2638 val &= ~OCL2_LDOFUSE_PWR_DIS;
2639 /*
2640 * On PHY1 disable power on the second channel, since no port is
2641 * connected there. On PHY0 both channels have a port, so leave it
2642 * enabled.
2643 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2644 * power down the second channel on PHY0 as well.
2645 */
2646 if (phy == DPIO_PHY1)
2647 val |= OCL2_LDOFUSE_PWR_DIS;
2648 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2649
2650 if (phy == DPIO_PHY0) {
2651 uint32_t grc_code;
2652 /*
2653 * PHY0 isn't connected to an RCOMP resistor so copy over
2654 * the corresponding calibrated value from PHY1, and disable
2655 * the automatic calibration on PHY0.
2656 */
2657 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2658 10))
2659 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2660
2661 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2662 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2663 grc_code = val << GRC_CODE_FAST_SHIFT |
2664 val << GRC_CODE_SLOW_SHIFT |
2665 val;
2666 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2667
2668 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2669 val |= GRC_DIS | GRC_RDY_OVRD;
2670 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2671 }
2672
2673 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2674 val |= COMMON_RESET_DIS;
2675 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2676}
2677
2678void broxton_ddi_phy_init(struct drm_device *dev)
2679{
2680 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2681 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2682 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2683}
2684
2685static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2686 enum dpio_phy phy)
2687{
2688 uint32_t val;
2689
2690 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2691 val &= ~COMMON_RESET_DIS;
2692 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2693}
2694
2695void broxton_ddi_phy_uninit(struct drm_device *dev)
2696{
2697 struct drm_i915_private *dev_priv = dev->dev_private;
2698
2699 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2700 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2701
2702 /* FIXME: do this in broxton_phy_uninit per phy */
2703 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2704}
2705
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302706static const char * const bxt_ddi_pll_names[] = {
2707 "PORT PLL A",
2708 "PORT PLL B",
2709 "PORT PLL C",
2710};
2711
2712static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2713 struct intel_shared_dpll *pll)
2714{
2715 uint32_t temp;
2716 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2717
2718 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2719 temp &= ~PORT_PLL_REF_SEL;
2720 /* Non-SSC reference */
2721 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2722
2723 /* Disable 10 bit clock */
2724 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2725 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2726 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2727
2728 /* Write P1 & P2 */
2729 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2730 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2731 temp |= pll->config.hw_state.ebb0;
2732 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2733
2734 /* Write M2 integer */
2735 temp = I915_READ(BXT_PORT_PLL(port, 0));
2736 temp &= ~PORT_PLL_M2_MASK;
2737 temp |= pll->config.hw_state.pll0;
2738 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2739
2740 /* Write N */
2741 temp = I915_READ(BXT_PORT_PLL(port, 1));
2742 temp &= ~PORT_PLL_N_MASK;
2743 temp |= pll->config.hw_state.pll1;
2744 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2745
2746 /* Write M2 fraction */
2747 temp = I915_READ(BXT_PORT_PLL(port, 2));
2748 temp &= ~PORT_PLL_M2_FRAC_MASK;
2749 temp |= pll->config.hw_state.pll2;
2750 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2751
2752 /* Write M2 fraction enable */
2753 temp = I915_READ(BXT_PORT_PLL(port, 3));
2754 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2755 temp |= pll->config.hw_state.pll3;
2756 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2757
2758 /* Write coeff */
2759 temp = I915_READ(BXT_PORT_PLL(port, 6));
2760 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2761 temp &= ~PORT_PLL_INT_COEFF_MASK;
2762 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2763 temp |= pll->config.hw_state.pll6;
2764 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2765
2766 /* Write calibration val */
2767 temp = I915_READ(BXT_PORT_PLL(port, 8));
2768 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2769 temp |= pll->config.hw_state.pll8;
2770 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2771
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302772 temp = I915_READ(BXT_PORT_PLL(port, 9));
2773 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002774 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302775 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2776
2777 temp = I915_READ(BXT_PORT_PLL(port, 10));
2778 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2779 temp &= ~PORT_PLL_DCO_AMP_MASK;
2780 temp |= pll->config.hw_state.pll10;
2781 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302782
2783 /* Recalibrate with new settings */
2784 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2785 temp |= PORT_PLL_RECALIBRATE;
2786 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002787 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2788 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302789 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2790
2791 /* Enable PLL */
2792 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2793 temp |= PORT_PLL_ENABLE;
2794 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2795 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2796
2797 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2798 PORT_PLL_LOCK), 200))
2799 DRM_ERROR("PLL %d not locked\n", port);
2800
2801 /*
2802 * While we write to the group register to program all lanes at once we
2803 * can read only lane registers and we pick lanes 0/1 for that.
2804 */
2805 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2806 temp &= ~LANE_STAGGER_MASK;
2807 temp &= ~LANESTAGGER_STRAP_OVRD;
2808 temp |= pll->config.hw_state.pcsdw12;
2809 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2810}
2811
2812static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2813 struct intel_shared_dpll *pll)
2814{
2815 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2816 uint32_t temp;
2817
2818 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2819 temp &= ~PORT_PLL_ENABLE;
2820 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2821 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2822}
2823
2824static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2825 struct intel_shared_dpll *pll,
2826 struct intel_dpll_hw_state *hw_state)
2827{
2828 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2829 uint32_t val;
2830
2831 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2832 return false;
2833
2834 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2835 if (!(val & PORT_PLL_ENABLE))
2836 return false;
2837
2838 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak05712c12015-06-18 17:25:54 +03002839 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2840 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2841
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302842 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
2843 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
2844 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
2845 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
2846 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
2847 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak05712c12015-06-18 17:25:54 +03002848 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2849 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2850
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302851 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302852 /*
2853 * While we write to the group register to program all lanes at once we
2854 * can read only lane registers. We configure all lanes the same way, so
2855 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2856 */
2857 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2858 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port) != hw_state->pcsdw12))
2859 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2860 hw_state->pcsdw12,
2861 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
2862
2863 return true;
2864}
2865
2866static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2867{
2868 int i;
2869
2870 dev_priv->num_shared_dpll = 3;
2871
2872 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2873 dev_priv->shared_dplls[i].id = i;
2874 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2875 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2876 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2877 dev_priv->shared_dplls[i].get_hw_state =
2878 bxt_ddi_pll_get_hw_state;
2879 }
2880}
2881
Damien Lespiau143b3072014-07-29 18:06:19 +01002882void intel_ddi_pll_init(struct drm_device *dev)
2883{
2884 struct drm_i915_private *dev_priv = dev->dev_private;
2885 uint32_t val = I915_READ(LCPLL_CTL);
2886
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002887 if (IS_SKYLAKE(dev))
2888 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302889 else if (IS_BROXTON(dev))
2890 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002891 else
2892 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002893
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002894 if (IS_SKYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002895 int cdclk_freq;
2896
2897 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002898 dev_priv->skl_boot_cdclk = cdclk_freq;
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002899 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2900 DRM_ERROR("LCPLL1 is disabled\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002901 else
2902 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302903 } else if (IS_BROXTON(dev)) {
2904 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302905 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002906 } else {
2907 /*
2908 * The LCPLL register should be turned on by the BIOS. For now
2909 * let's just check its state and print errors in case
2910 * something is wrong. Don't even try to turn it on.
2911 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002912
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002913 if (val & LCPLL_CD_SOURCE_FCLK)
2914 DRM_ERROR("CDCLK source is not LCPLL\n");
2915
2916 if (val & LCPLL_PLL_DISABLE)
2917 DRM_ERROR("LCPLL is disabled\n");
2918 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002919}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002920
2921void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
2922{
Paulo Zanoni174edf12012-10-26 19:05:50 -02002923 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
2924 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002925 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02002926 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002927 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302928 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002929
2930 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2931 val = I915_READ(DDI_BUF_CTL(port));
2932 if (val & DDI_BUF_CTL_ENABLE) {
2933 val &= ~DDI_BUF_CTL_ENABLE;
2934 I915_WRITE(DDI_BUF_CTL(port), val);
2935 wait = true;
2936 }
2937
2938 val = I915_READ(DP_TP_CTL(port));
2939 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2940 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2941 I915_WRITE(DP_TP_CTL(port), val);
2942 POSTING_READ(DP_TP_CTL(port));
2943
2944 if (wait)
2945 intel_wait_ddi_buf_idle(dev_priv, port);
2946 }
2947
Dave Airlie0e32b392014-05-02 14:02:48 +10002948 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03002949 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10002950 if (intel_dp->is_mst)
2951 val |= DP_TP_CTL_MODE_MST;
2952 else {
2953 val |= DP_TP_CTL_MODE_SST;
2954 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
2955 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
2956 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002957 I915_WRITE(DP_TP_CTL(port), val);
2958 POSTING_READ(DP_TP_CTL(port));
2959
2960 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
2961 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
2962 POSTING_READ(DDI_BUF_CTL(port));
2963
2964 udelay(600);
2965}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002966
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02002967void intel_ddi_fdi_disable(struct drm_crtc *crtc)
2968{
2969 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2970 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2971 uint32_t val;
2972
2973 intel_ddi_post_disable(intel_encoder);
2974
2975 val = I915_READ(_FDI_RXA_CTL);
2976 val &= ~FDI_RX_ENABLE;
2977 I915_WRITE(_FDI_RXA_CTL, val);
2978
2979 val = I915_READ(_FDI_RXA_MISC);
2980 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
2981 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
2982 I915_WRITE(_FDI_RXA_MISC, val);
2983
2984 val = I915_READ(_FDI_RXA_CTL);
2985 val &= ~FDI_PCDCLK;
2986 I915_WRITE(_FDI_RXA_CTL, val);
2987
2988 val = I915_READ(_FDI_RXA_CTL);
2989 val &= ~FDI_RX_PLL_ENABLE;
2990 I915_WRITE(_FDI_RXA_CTL, val);
2991}
2992
Ville Syrjälä6801c182013-09-24 14:24:05 +03002993void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02002994 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07002995{
2996 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
2997 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02002998 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01002999 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003000 u32 temp, flags = 0;
3001
3002 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3003 if (temp & TRANS_DDI_PHSYNC)
3004 flags |= DRM_MODE_FLAG_PHSYNC;
3005 else
3006 flags |= DRM_MODE_FLAG_NHSYNC;
3007 if (temp & TRANS_DDI_PVSYNC)
3008 flags |= DRM_MODE_FLAG_PVSYNC;
3009 else
3010 flags |= DRM_MODE_FLAG_NVSYNC;
3011
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003012 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003013
3014 switch (temp & TRANS_DDI_BPC_MASK) {
3015 case TRANS_DDI_BPC_6:
3016 pipe_config->pipe_bpp = 18;
3017 break;
3018 case TRANS_DDI_BPC_8:
3019 pipe_config->pipe_bpp = 24;
3020 break;
3021 case TRANS_DDI_BPC_10:
3022 pipe_config->pipe_bpp = 30;
3023 break;
3024 case TRANS_DDI_BPC_12:
3025 pipe_config->pipe_bpp = 36;
3026 break;
3027 default:
3028 break;
3029 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003030
3031 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3032 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b52014-04-24 23:54:47 +02003033 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003034 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3035
3036 if (intel_hdmi->infoframe_enabled(&encoder->base))
3037 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003038 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003039 case TRANS_DDI_MODE_SELECT_DVI:
3040 case TRANS_DDI_MODE_SELECT_FDI:
3041 break;
3042 case TRANS_DDI_MODE_SELECT_DP_SST:
3043 case TRANS_DDI_MODE_SELECT_DP_MST:
3044 pipe_config->has_dp_encoder = true;
3045 intel_dp_get_m_n(intel_crtc, pipe_config);
3046 break;
3047 default:
3048 break;
3049 }
Daniel Vetter10214422013-11-18 07:38:16 +01003050
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003051 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003052 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003053 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003054 pipe_config->has_audio = true;
3055 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003056
Daniel Vetter10214422013-11-18 07:38:16 +01003057 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3058 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3059 /*
3060 * This is a big fat ugly hack.
3061 *
3062 * Some machines in UEFI boot mode provide us a VBT that has 18
3063 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3064 * unknown we fail to light up. Yet the same BIOS boots up with
3065 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3066 * max, not what it tells us to use.
3067 *
3068 * Note: This will still be broken if the eDP panel is not lit
3069 * up by the BIOS, and thus we can't get the mode at module
3070 * load.
3071 */
3072 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3073 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3074 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3075 }
Jesse Barnes11578552014-01-21 12:42:10 -08003076
Damien Lespiau22606a12014-12-12 14:26:57 +00003077 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003078}
3079
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003080static void intel_ddi_destroy(struct drm_encoder *encoder)
3081{
3082 /* HDMI has nothing special to destroy, so we can go with this. */
3083 intel_dp_encoder_destroy(encoder);
3084}
3085
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003086static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003087 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003088{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003089 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003090 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003091
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003092 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003093
Daniel Vettereccb1402013-05-22 00:50:22 +02003094 if (port == PORT_A)
3095 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3096
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003097 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003098 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003099 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003100 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003101}
3102
3103static const struct drm_encoder_funcs intel_ddi_funcs = {
3104 .destroy = intel_ddi_destroy,
3105};
3106
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003107static struct intel_connector *
3108intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3109{
3110 struct intel_connector *connector;
3111 enum port port = intel_dig_port->port;
3112
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003113 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003114 if (!connector)
3115 return NULL;
3116
3117 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3118 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3119 kfree(connector);
3120 return NULL;
3121 }
3122
3123 return connector;
3124}
3125
3126static struct intel_connector *
3127intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3128{
3129 struct intel_connector *connector;
3130 enum port port = intel_dig_port->port;
3131
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003132 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003133 if (!connector)
3134 return NULL;
3135
3136 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3137 intel_hdmi_init_connector(intel_dig_port, connector);
3138
3139 return connector;
3140}
3141
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003142void intel_ddi_init(struct drm_device *dev, enum port port)
3143{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003144 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003145 struct intel_digital_port *intel_dig_port;
3146 struct intel_encoder *intel_encoder;
3147 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003148 bool init_hdmi, init_dp;
3149
3150 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3151 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3152 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3153 if (!init_dp && !init_hdmi) {
Chris Wilsonf68d6972014-08-04 07:15:09 +01003154 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003155 port_name(port));
3156 init_hdmi = true;
3157 init_dp = true;
3158 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003159
Daniel Vetterb14c5672013-09-19 12:18:32 +02003160 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003161 if (!intel_dig_port)
3162 return;
3163
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003164 intel_encoder = &intel_dig_port->base;
3165 encoder = &intel_encoder->base;
3166
3167 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3168 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003169
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003170 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003171 intel_encoder->enable = intel_enable_ddi;
3172 intel_encoder->pre_enable = intel_ddi_pre_enable;
3173 intel_encoder->disable = intel_disable_ddi;
3174 intel_encoder->post_disable = intel_ddi_post_disable;
3175 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003176 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003177
3178 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003179 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3180 (DDI_BUF_PORT_REVERSAL |
3181 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003182
3183 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003184 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003185 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003186
Chris Wilsonf68d6972014-08-04 07:15:09 +01003187 if (init_dp) {
3188 if (!intel_ddi_init_dp_connector(intel_dig_port))
3189 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003190
Chris Wilsonf68d6972014-08-04 07:15:09 +01003191 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Jani Nikula5fcece82015-05-27 15:03:42 +03003192 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003193 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003194
Paulo Zanoni311a2092013-09-12 17:12:18 -03003195 /* In theory we don't need the encoder->type check, but leave it just in
3196 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003197 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3198 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3199 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003200 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003201
3202 return;
3203
3204err:
3205 drm_encoder_cleanup(encoder);
3206 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003207}