blob: 4823184258a0b8a49806f0cf85ce12480e2fa38a [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
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700131/* Skylake H and S */
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[] = {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700146 { 0x0000201B, 0x000000A2, 0x0 },
David Weinehallf8896f52015-06-25 11:11:03 +0300147 { 0x00005012, 0x00000088, 0x0 },
148 { 0x00007011, 0x00000087, 0x0 },
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700149 { 0x80009010, 0x000000C7, 0x1 }, /* Uses I_boost level 0x1 */
150 { 0x0000201B, 0x0000009D, 0x0 },
David Weinehallf8896f52015-06-25 11:11:03 +0300151 { 0x00005012, 0x000000C7, 0x0 },
152 { 0x00007011, 0x000000C7, 0x0 },
153 { 0x00002016, 0x00000088, 0x0 },
154 { 0x00005012, 0x000000C7, 0x0 },
155};
156
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700157/* Skylake Y */
158static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300159 { 0x00000018, 0x000000A2, 0x0 },
160 { 0x00005012, 0x00000088, 0x0 },
161 { 0x00007011, 0x00000087, 0x0 },
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700162 { 0x80009010, 0x000000C7, 0x3 }, /* Uses I_boost level 0x3 */
David Weinehallf8896f52015-06-25 11:11:03 +0300163 { 0x00000018, 0x0000009D, 0x0 },
164 { 0x00005012, 0x000000C7, 0x0 },
165 { 0x00007011, 0x000000C7, 0x0 },
166 { 0x00000018, 0x00000088, 0x0 },
167 { 0x00005012, 0x000000C7, 0x0 },
168};
169
170/*
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700171 * Skylake H and S
David Weinehallf8896f52015-06-25 11:11:03 +0300172 * 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/*
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700205 * Skylake Y
David Weinehallf8896f52015-06-25 11:11:03 +0300206 * eDP 1.4 low vswing translation parameters
207 */
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700208static const struct ddi_buf_trans skl_y_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300209 { 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
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700221/* Skylake U, H and S */
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
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700236/* Skylake Y */
237static const struct ddi_buf_trans skl_y_ddi_translations_hdmi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300238 { 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 */
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700247 { 0x80003015, 0x000000C7, 0x7 }, /* Uses I_boost level 0x7 */
David Weinehallf8896f52015-06-25 11:11:03 +0300248 { 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{
David Weinehallf8896f52015-06-25 11:11:03 +0300338 const struct ddi_buf_trans *ddi_translations;
David Weinehallf8896f52015-06-25 11:11:03 +0300339
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700340 if (IS_SKL_ULX(dev)) {
341 ddi_translations = skl_y_ddi_translations_dp;
342 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
David Weinehallf8896f52015-06-25 11:11:03 +0300343 } else if (IS_SKL_ULT(dev)) {
344 ddi_translations = skl_u_ddi_translations_dp;
345 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
346 } else {
347 ddi_translations = skl_ddi_translations_dp;
348 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
349 }
350
351 return ddi_translations;
352}
353
354static const struct ddi_buf_trans *skl_get_buf_trans_edp(struct drm_device *dev,
355 int *n_entries)
356{
357 struct drm_i915_private *dev_priv = dev->dev_private;
358 const struct ddi_buf_trans *ddi_translations;
David Weinehallf8896f52015-06-25 11:11:03 +0300359
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700360 if (IS_SKL_ULX(dev)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300361 if (dev_priv->edp_low_vswing) {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700362 ddi_translations = skl_y_ddi_translations_edp;
363 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
David Weinehallf8896f52015-06-25 11:11:03 +0300364 } else {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700365 ddi_translations = skl_y_ddi_translations_dp;
366 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
David Weinehallf8896f52015-06-25 11:11:03 +0300367 }
368 } else if (IS_SKL_ULT(dev)) {
369 if (dev_priv->edp_low_vswing) {
370 ddi_translations = skl_u_ddi_translations_edp;
371 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
372 } else {
373 ddi_translations = skl_u_ddi_translations_dp;
374 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
375 }
376 } else {
377 if (dev_priv->edp_low_vswing) {
378 ddi_translations = skl_ddi_translations_edp;
379 *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
380 } else {
381 ddi_translations = skl_ddi_translations_dp;
382 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
383 }
384 }
385
386 return ddi_translations;
387}
388
389static const struct ddi_buf_trans *
390skl_get_buf_trans_hdmi(struct drm_device *dev,
391 int *n_entries)
392{
David Weinehallf8896f52015-06-25 11:11:03 +0300393 const struct ddi_buf_trans *ddi_translations;
David Weinehallf8896f52015-06-25 11:11:03 +0300394
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700395 if (IS_SKL_ULX(dev)) {
396 ddi_translations = skl_y_ddi_translations_hdmi;
397 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
David Weinehallf8896f52015-06-25 11:11:03 +0300398 } else {
399 ddi_translations = skl_ddi_translations_hdmi;
400 *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
401 }
402
403 return ddi_translations;
404}
405
Art Runyane58623c2013-11-02 21:07:41 -0700406/*
407 * Starting with Haswell, DDI port buffers must be programmed with correct
408 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300409 * but the HDMI/DVI fields are shared among those. So we program the DDI
410 * in either FDI or DP modes only, as HDMI connections will work with both
411 * of those
412 */
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300413static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
414 bool supports_hdmi)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300415{
416 struct drm_i915_private *dev_priv = dev->dev_private;
417 u32 reg;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300418 u32 iboost_bit = 0;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000419 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530420 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300421 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300422 const struct ddi_buf_trans *ddi_translations_fdi;
423 const struct ddi_buf_trans *ddi_translations_dp;
424 const struct ddi_buf_trans *ddi_translations_edp;
425 const struct ddi_buf_trans *ddi_translations_hdmi;
426 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700427
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530428 if (IS_BROXTON(dev)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300429 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530430 return;
431
432 /* Vswing programming for HDMI */
433 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
434 INTEL_OUTPUT_HDMI);
435 return;
436 } else if (IS_SKYLAKE(dev)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300437 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300438 ddi_translations_dp =
439 skl_get_buf_trans_dp(dev, &n_dp_entries);
440 ddi_translations_edp =
441 skl_get_buf_trans_edp(dev, &n_edp_entries);
442 ddi_translations_hdmi =
443 skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
444 hdmi_default_entry = 8;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300445 /* If we're boosting the current, set bit 31 of trans1 */
446 if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
447 dev_priv->vbt.ddi_port_info[port].dp_boost_level)
448 iboost_bit = 1<<31;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000449 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700450 ddi_translations_fdi = bdw_ddi_translations_fdi;
451 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700452 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100453 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530454 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
455 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300456 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000457 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700458 } else if (IS_HASWELL(dev)) {
459 ddi_translations_fdi = hsw_ddi_translations_fdi;
460 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700461 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100462 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530463 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300464 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000465 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700466 } else {
467 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700468 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700469 ddi_translations_fdi = bdw_ddi_translations_fdi;
470 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100471 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530472 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
473 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300474 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000475 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700476 }
477
Paulo Zanoni300644c2013-11-02 21:07:42 -0700478 switch (port) {
479 case PORT_A:
480 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530481 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700482 break;
483 case PORT_B:
484 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700485 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530486 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700487 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700488 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530489 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700490 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530491 size = n_edp_entries;
492 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700493 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530494 size = n_dp_entries;
495 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700496 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700497 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000498 if (ddi_translations_fdi)
499 ddi_translations = ddi_translations_fdi;
500 else
501 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530502 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700503 break;
504 default:
505 BUG();
506 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300507
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530508 for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300509 I915_WRITE(reg, ddi_translations[i].trans1 | iboost_bit);
Jani Nikula10122052014-08-27 16:27:30 +0300510 reg += 4;
511 I915_WRITE(reg, ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300512 reg += 4;
513 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100514
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300515 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100516 return;
517
Damien Lespiauce4dd492014-08-01 11:07:54 +0100518 /* Choose a good default if VBT is badly populated */
519 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
520 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000521 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100522
Paulo Zanoni6acab152013-09-12 17:06:24 -0300523 /* Entry 9 is for HDMI: */
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300524 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
Jani Nikula10122052014-08-27 16:27:30 +0300525 reg += 4;
526 I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2);
527 reg += 4;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300528}
529
530/* Program DDI buffers translations for DP. By default, program ports A-D in DP
531 * mode and port E for FDI.
532 */
533void intel_prepare_ddi(struct drm_device *dev)
534{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300535 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100536 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300537
Paulo Zanoni0d536cb42012-11-23 16:46:41 -0200538 if (!HAS_DDI(dev))
539 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300540
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300541 for_each_intel_encoder(dev, intel_encoder) {
542 struct intel_digital_port *intel_dig_port;
543 enum port port;
544 bool supports_hdmi;
545
546 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
547
548 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100549 continue;
550
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300551 supports_hdmi = intel_dig_port &&
552 intel_dig_port_supports_hdmi(intel_dig_port);
553
554 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
555 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100556 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300557}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300558
Paulo Zanoni248138b2012-11-29 11:29:31 -0200559static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
560 enum port port)
561{
562 uint32_t reg = DDI_BUF_CTL(port);
563 int i;
564
Vandana Kannan3449ca82015-03-27 14:19:09 +0200565 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200566 udelay(1);
567 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
568 return;
569 }
570 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
571}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300572
573/* Starting with Haswell, different DDI ports can work in FDI mode for
574 * connection to the PCH-located connectors. For this, it is necessary to train
575 * both the DDI port and PCH receiver for the desired DDI buffer settings.
576 *
577 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
578 * please note that when FDI mode is active on DDI E, it shares 2 lines with
579 * DDI A (which is used for eDP)
580 */
581
582void hsw_fdi_link_train(struct drm_crtc *crtc)
583{
584 struct drm_device *dev = crtc->dev;
585 struct drm_i915_private *dev_priv = dev->dev_private;
586 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200587 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300588
Paulo Zanoni04945642012-11-01 21:00:59 -0200589 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
590 * mode set "sequence for CRT port" document:
591 * - TP1 to TP2 time with the default value
592 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100593 *
594 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200595 */
596 I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
597 FDI_RX_PWRDN_LANE0_VAL(2) |
598 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
599
600 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000601 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100602 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200603 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Paulo Zanoni04945642012-11-01 21:00:59 -0200604 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
605 POSTING_READ(_FDI_RXA_CTL);
606 udelay(220);
607
608 /* Switch from Rawclk to PCDclk */
609 rx_ctl_val |= FDI_PCDCLK;
610 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
611
612 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200613 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
614 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200615
616 /* Start the training iterating through available voltages and emphasis,
617 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300618 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300619 /* Configure DP_TP_CTL with auto-training */
620 I915_WRITE(DP_TP_CTL(PORT_E),
621 DP_TP_CTL_FDI_AUTOTRAIN |
622 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
623 DP_TP_CTL_LINK_TRAIN_PAT1 |
624 DP_TP_CTL_ENABLE);
625
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000626 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
627 * DDI E does not support port reversal, the functionality is
628 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
629 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300630 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200631 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200632 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530633 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200634 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300635
636 udelay(600);
637
Paulo Zanoni04945642012-11-01 21:00:59 -0200638 /* Program PCH FDI Receiver TU */
639 I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300640
Paulo Zanoni04945642012-11-01 21:00:59 -0200641 /* Enable PCH FDI Receiver with auto-training */
642 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
643 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
644 POSTING_READ(_FDI_RXA_CTL);
645
646 /* Wait for FDI receiver lane calibration */
647 udelay(30);
648
649 /* Unset FDI_RX_MISC pwrdn lanes */
650 temp = I915_READ(_FDI_RXA_MISC);
651 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
652 I915_WRITE(_FDI_RXA_MISC, temp);
653 POSTING_READ(_FDI_RXA_MISC);
654
655 /* Wait for FDI auto training time */
656 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300657
658 temp = I915_READ(DP_TP_STATUS(PORT_E));
659 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200660 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300661
662 /* Enable normal pixel sending for FDI */
663 I915_WRITE(DP_TP_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200664 DP_TP_CTL_FDI_AUTOTRAIN |
665 DP_TP_CTL_LINK_TRAIN_NORMAL |
666 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
667 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300668
Paulo Zanoni04945642012-11-01 21:00:59 -0200669 return;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300670 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200671
Paulo Zanoni248138b2012-11-29 11:29:31 -0200672 temp = I915_READ(DDI_BUF_CTL(PORT_E));
673 temp &= ~DDI_BUF_CTL_ENABLE;
674 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
675 POSTING_READ(DDI_BUF_CTL(PORT_E));
676
Paulo Zanoni04945642012-11-01 21:00:59 -0200677 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200678 temp = I915_READ(DP_TP_CTL(PORT_E));
679 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
680 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
681 I915_WRITE(DP_TP_CTL(PORT_E), temp);
682 POSTING_READ(DP_TP_CTL(PORT_E));
683
684 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200685
686 rx_ctl_val &= ~FDI_RX_ENABLE;
687 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200688 POSTING_READ(_FDI_RXA_CTL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200689
690 /* Reset FDI_RX_MISC pwrdn lanes */
691 temp = I915_READ(_FDI_RXA_MISC);
692 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
693 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
694 I915_WRITE(_FDI_RXA_MISC, temp);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200695 POSTING_READ(_FDI_RXA_MISC);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300696 }
697
Paulo Zanoni04945642012-11-01 21:00:59 -0200698 DRM_ERROR("FDI link training failed!\n");
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300699}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300700
Dave Airlie44905a272014-05-02 13:36:43 +1000701void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
702{
703 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
704 struct intel_digital_port *intel_dig_port =
705 enc_to_dig_port(&encoder->base);
706
707 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530708 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300709 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a272014-05-02 13:36:43 +1000710}
711
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300712static struct intel_encoder *
713intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
714{
715 struct drm_device *dev = crtc->dev;
716 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
717 struct intel_encoder *intel_encoder, *ret = NULL;
718 int num_encoders = 0;
719
720 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
721 ret = intel_encoder;
722 num_encoders++;
723 }
724
725 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300726 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
727 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300728
729 BUG_ON(ret == NULL);
730 return ret;
731}
732
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530733struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200734intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200735{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200736 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
737 struct intel_encoder *ret = NULL;
738 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300739 struct drm_connector *connector;
740 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200741 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200742 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200743
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200744 state = crtc_state->base.state;
745
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300746 for_each_connector_in_state(state, connector, connector_state, i) {
747 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200748 continue;
749
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300750 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200751 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200752 }
753
754 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
755 pipe_name(crtc->pipe));
756
757 BUG_ON(ret == NULL);
758 return ret;
759}
760
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100761#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100762#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100763
764#define P_MIN 2
765#define P_MAX 64
766#define P_INC 2
767
768/* Constraints for PLL good behavior */
769#define REF_MIN 48
770#define REF_MAX 400
771#define VCO_MIN 2400
772#define VCO_MAX 4800
773
Damien Lespiau27893392014-09-04 12:27:23 +0100774#define abs_diff(a, b) ({ \
775 typeof(a) __a = (a); \
776 typeof(b) __b = (b); \
777 (void) (&__a == &__b); \
778 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100779
Damien Lespiau63582982015-05-07 18:38:46 +0100780struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100781 unsigned p, n2, r2;
782};
783
Damien Lespiau63582982015-05-07 18:38:46 +0100784static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300785{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100786 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300787
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100788 switch (clock) {
789 case 25175000:
790 case 25200000:
791 case 27000000:
792 case 27027000:
793 case 37762500:
794 case 37800000:
795 case 40500000:
796 case 40541000:
797 case 54000000:
798 case 54054000:
799 case 59341000:
800 case 59400000:
801 case 72000000:
802 case 74176000:
803 case 74250000:
804 case 81000000:
805 case 81081000:
806 case 89012000:
807 case 89100000:
808 case 108000000:
809 case 108108000:
810 case 111264000:
811 case 111375000:
812 case 148352000:
813 case 148500000:
814 case 162000000:
815 case 162162000:
816 case 222525000:
817 case 222750000:
818 case 296703000:
819 case 297000000:
820 budget = 0;
821 break;
822 case 233500000:
823 case 245250000:
824 case 247750000:
825 case 253250000:
826 case 298000000:
827 budget = 1500;
828 break;
829 case 169128000:
830 case 169500000:
831 case 179500000:
832 case 202000000:
833 budget = 2000;
834 break;
835 case 256250000:
836 case 262500000:
837 case 270000000:
838 case 272500000:
839 case 273750000:
840 case 280750000:
841 case 281250000:
842 case 286000000:
843 case 291750000:
844 budget = 4000;
845 break;
846 case 267250000:
847 case 268500000:
848 budget = 5000;
849 break;
850 default:
851 budget = 1000;
852 break;
853 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300854
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100855 return budget;
856}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300857
Damien Lespiau63582982015-05-07 18:38:46 +0100858static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
859 unsigned r2, unsigned n2, unsigned p,
860 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100861{
862 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300863
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100864 /* No best (r,n,p) yet */
865 if (best->p == 0) {
866 best->p = p;
867 best->n2 = n2;
868 best->r2 = r2;
869 return;
870 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300871
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100872 /*
873 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
874 * freq2k.
875 *
876 * delta = 1e6 *
877 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
878 * freq2k;
879 *
880 * and we would like delta <= budget.
881 *
882 * If the discrepancy is above the PPM-based budget, always prefer to
883 * improve upon the previous solution. However, if you're within the
884 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
885 */
886 a = freq2k * budget * p * r2;
887 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100888 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
889 diff_best = abs_diff(freq2k * best->p * best->r2,
890 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100891 c = 1000000 * diff;
892 d = 1000000 * diff_best;
893
894 if (a < c && b < d) {
895 /* If both are above the budget, pick the closer */
896 if (best->p * best->r2 * diff < p * r2 * diff_best) {
897 best->p = p;
898 best->n2 = n2;
899 best->r2 = r2;
900 }
901 } else if (a >= c && b < d) {
902 /* If A is below the threshold but B is above it? Update. */
903 best->p = p;
904 best->n2 = n2;
905 best->r2 = r2;
906 } else if (a >= c && b >= d) {
907 /* Both are below the limit, so pick the higher n2/(r2*r2) */
908 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
909 best->p = p;
910 best->n2 = n2;
911 best->r2 = r2;
912 }
913 }
914 /* Otherwise a < c && b >= d, do nothing */
915}
916
Damien Lespiau63582982015-05-07 18:38:46 +0100917static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, int reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800918{
919 int refclk = LC_FREQ;
920 int n, p, r;
921 u32 wrpll;
922
923 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300924 switch (wrpll & WRPLL_PLL_REF_MASK) {
925 case WRPLL_PLL_SSC:
926 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800927 /*
928 * We could calculate spread here, but our checking
929 * code only cares about 5% accuracy, and spread is a max of
930 * 0.5% downspread.
931 */
932 refclk = 135;
933 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300934 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800935 refclk = LC_FREQ;
936 break;
937 default:
938 WARN(1, "bad wrpll refclk\n");
939 return 0;
940 }
941
942 r = wrpll & WRPLL_DIVIDER_REF_MASK;
943 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
944 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
945
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800946 /* Convert to KHz, p & r have a fixed point portion */
947 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800948}
949
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000950static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
951 uint32_t dpll)
952{
953 uint32_t cfgcr1_reg, cfgcr2_reg;
954 uint32_t cfgcr1_val, cfgcr2_val;
955 uint32_t p0, p1, p2, dco_freq;
956
957 cfgcr1_reg = GET_CFG_CR1_REG(dpll);
958 cfgcr2_reg = GET_CFG_CR2_REG(dpll);
959
960 cfgcr1_val = I915_READ(cfgcr1_reg);
961 cfgcr2_val = I915_READ(cfgcr2_reg);
962
963 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
964 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
965
966 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
967 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
968 else
969 p1 = 1;
970
971
972 switch (p0) {
973 case DPLL_CFGCR2_PDIV_1:
974 p0 = 1;
975 break;
976 case DPLL_CFGCR2_PDIV_2:
977 p0 = 2;
978 break;
979 case DPLL_CFGCR2_PDIV_3:
980 p0 = 3;
981 break;
982 case DPLL_CFGCR2_PDIV_7:
983 p0 = 7;
984 break;
985 }
986
987 switch (p2) {
988 case DPLL_CFGCR2_KDIV_5:
989 p2 = 5;
990 break;
991 case DPLL_CFGCR2_KDIV_2:
992 p2 = 2;
993 break;
994 case DPLL_CFGCR2_KDIV_3:
995 p2 = 3;
996 break;
997 case DPLL_CFGCR2_KDIV_1:
998 p2 = 1;
999 break;
1000 }
1001
1002 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1003
1004 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1005 1000) / 0x8000;
1006
1007 return dco_freq / (p0 * p1 * p2 * 5);
1008}
1009
Ville Syrjälä398a0172015-06-30 15:33:51 +03001010static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1011{
1012 int dotclock;
1013
1014 if (pipe_config->has_pch_encoder)
1015 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1016 &pipe_config->fdi_m_n);
1017 else if (pipe_config->has_dp_encoder)
1018 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1019 &pipe_config->dp_m_n);
1020 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1021 dotclock = pipe_config->port_clock * 2 / 3;
1022 else
1023 dotclock = pipe_config->port_clock;
1024
1025 if (pipe_config->pixel_multiplier)
1026 dotclock /= pipe_config->pixel_multiplier;
1027
1028 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1029}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001030
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
Ville Syrjälä398a0172015-06-30 15:33:51 +03001076 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001077}
1078
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001079static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001080 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001081{
1082 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001083 int link_clock = 0;
1084 u32 val, pll;
1085
Daniel Vetter26804af2014-06-25 22:01:55 +03001086 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001087 switch (val & PORT_CLK_SEL_MASK) {
1088 case PORT_CLK_SEL_LCPLL_810:
1089 link_clock = 81000;
1090 break;
1091 case PORT_CLK_SEL_LCPLL_1350:
1092 link_clock = 135000;
1093 break;
1094 case PORT_CLK_SEL_LCPLL_2700:
1095 link_clock = 270000;
1096 break;
1097 case PORT_CLK_SEL_WRPLL1:
Damien Lespiau63582982015-05-07 18:38:46 +01001098 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL1);
Jesse Barnes11578552014-01-21 12:42:10 -08001099 break;
1100 case PORT_CLK_SEL_WRPLL2:
Damien Lespiau63582982015-05-07 18:38:46 +01001101 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL2);
Jesse Barnes11578552014-01-21 12:42:10 -08001102 break;
1103 case PORT_CLK_SEL_SPLL:
1104 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1105 if (pll == SPLL_PLL_FREQ_810MHz)
1106 link_clock = 81000;
1107 else if (pll == SPLL_PLL_FREQ_1350MHz)
1108 link_clock = 135000;
1109 else if (pll == SPLL_PLL_FREQ_2700MHz)
1110 link_clock = 270000;
1111 else {
1112 WARN(1, "bad spll freq\n");
1113 return;
1114 }
1115 break;
1116 default:
1117 WARN(1, "bad port clock sel\n");
1118 return;
1119 }
1120
1121 pipe_config->port_clock = link_clock * 2;
1122
Ville Syrjälä398a0172015-06-30 15:33:51 +03001123 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001124}
1125
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301126static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1127 enum intel_dpll_id dpll)
1128{
Imre Deakaa610dc2015-06-22 23:35:52 +03001129 struct intel_shared_dpll *pll;
1130 struct intel_dpll_hw_state *state;
1131 intel_clock_t clock;
1132
1133 /* For DDI ports we always use a shared PLL. */
1134 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1135 return 0;
1136
1137 pll = &dev_priv->shared_dplls[dpll];
1138 state = &pll->config.hw_state;
1139
1140 clock.m1 = 2;
1141 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1142 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1143 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1144 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1145 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1146 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1147
1148 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301149}
1150
1151static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1152 struct intel_crtc_state *pipe_config)
1153{
1154 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1155 enum port port = intel_ddi_get_encoder_port(encoder);
1156 uint32_t dpll = port;
1157
Ville Syrjälä398a0172015-06-30 15:33:51 +03001158 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301159
Ville Syrjälä398a0172015-06-30 15:33:51 +03001160 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301161}
1162
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001163void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001164 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001165{
Damien Lespiau22606a12014-12-12 14:26:57 +00001166 struct drm_device *dev = encoder->base.dev;
1167
1168 if (INTEL_INFO(dev)->gen <= 8)
1169 hsw_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301170 else if (IS_SKYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001171 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301172 else if (IS_BROXTON(dev))
1173 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001174}
1175
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001176static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001177hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1178 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001179{
1180 uint64_t freq2k;
1181 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001182 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001183 unsigned budget;
1184
1185 freq2k = clock / 100;
1186
Damien Lespiau63582982015-05-07 18:38:46 +01001187 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001188
1189 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1190 * and directly pass the LC PLL to it. */
1191 if (freq2k == 5400000) {
1192 *n2_out = 2;
1193 *p_out = 1;
1194 *r2_out = 2;
1195 return;
1196 }
1197
1198 /*
1199 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1200 * the WR PLL.
1201 *
1202 * We want R so that REF_MIN <= Ref <= REF_MAX.
1203 * Injecting R2 = 2 * R gives:
1204 * REF_MAX * r2 > LC_FREQ * 2 and
1205 * REF_MIN * r2 < LC_FREQ * 2
1206 *
1207 * Which means the desired boundaries for r2 are:
1208 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1209 *
1210 */
1211 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1212 r2 <= LC_FREQ * 2 / REF_MIN;
1213 r2++) {
1214
1215 /*
1216 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1217 *
1218 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1219 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1220 * VCO_MAX * r2 > n2 * LC_FREQ and
1221 * VCO_MIN * r2 < n2 * LC_FREQ)
1222 *
1223 * Which means the desired boundaries for n2 are:
1224 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1225 */
1226 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1227 n2 <= VCO_MAX * r2 / LC_FREQ;
1228 n2++) {
1229
1230 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001231 hsw_wrpll_update_rnp(freq2k, budget,
1232 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001233 }
1234 }
1235
1236 *n2_out = best.n2;
1237 *p_out = best.p;
1238 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001239}
1240
Damien Lespiau0220ab62014-07-29 18:06:22 +01001241static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001242hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001243 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001244 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001245{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001246 int clock = crtc_state->port_clock;
1247
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001248 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001249 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001250 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001251 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001252
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001253 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001254
Daniel Vetter114fe482014-06-25 22:01:48 +03001255 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001256 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1257 WRPLL_DIVIDER_POST(p);
1258
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001259 memset(&crtc_state->dpll_hw_state, 0,
1260 sizeof(crtc_state->dpll_hw_state));
1261
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001262 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001263
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001264 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001265 if (pll == NULL) {
1266 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1267 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001268 return false;
1269 }
1270
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001271 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001272 }
1273
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001274 return true;
1275}
1276
Damien Lespiaudc253812015-06-25 16:15:06 +01001277struct skl_wrpll_context {
1278 uint64_t min_deviation; /* current minimal deviation */
1279 uint64_t central_freq; /* chosen central freq */
1280 uint64_t dco_freq; /* chosen dco freq */
1281 unsigned int p; /* chosen divider */
1282};
1283
1284static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1285{
1286 memset(ctx, 0, sizeof(*ctx));
1287
1288 ctx->min_deviation = U64_MAX;
1289}
1290
1291/* DCO freq must be within +1%/-6% of the DCO central freq */
1292#define SKL_DCO_MAX_PDEVIATION 100
1293#define SKL_DCO_MAX_NDEVIATION 600
1294
1295static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1296 uint64_t central_freq,
1297 uint64_t dco_freq,
1298 unsigned int divider)
1299{
1300 uint64_t deviation;
1301
1302 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1303 central_freq);
1304
1305 /* positive deviation */
1306 if (dco_freq >= central_freq) {
1307 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1308 deviation < ctx->min_deviation) {
1309 ctx->min_deviation = deviation;
1310 ctx->central_freq = central_freq;
1311 ctx->dco_freq = dco_freq;
1312 ctx->p = divider;
1313 }
1314 /* negative deviation */
1315 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1316 deviation < ctx->min_deviation) {
1317 ctx->min_deviation = deviation;
1318 ctx->central_freq = central_freq;
1319 ctx->dco_freq = dco_freq;
1320 ctx->p = divider;
1321 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001322}
1323
1324static void skl_wrpll_get_multipliers(unsigned int p,
1325 unsigned int *p0 /* out */,
1326 unsigned int *p1 /* out */,
1327 unsigned int *p2 /* out */)
1328{
1329 /* even dividers */
1330 if (p % 2 == 0) {
1331 unsigned int half = p / 2;
1332
1333 if (half == 1 || half == 2 || half == 3 || half == 5) {
1334 *p0 = 2;
1335 *p1 = 1;
1336 *p2 = half;
1337 } else if (half % 2 == 0) {
1338 *p0 = 2;
1339 *p1 = half / 2;
1340 *p2 = 2;
1341 } else if (half % 3 == 0) {
1342 *p0 = 3;
1343 *p1 = half / 3;
1344 *p2 = 2;
1345 } else if (half % 7 == 0) {
1346 *p0 = 7;
1347 *p1 = half / 7;
1348 *p2 = 2;
1349 }
1350 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1351 *p0 = 3;
1352 *p1 = 1;
1353 *p2 = p / 3;
1354 } else if (p == 5 || p == 7) {
1355 *p0 = p;
1356 *p1 = 1;
1357 *p2 = 1;
1358 } else if (p == 15) {
1359 *p0 = 3;
1360 *p1 = 1;
1361 *p2 = 5;
1362 } else if (p == 21) {
1363 *p0 = 7;
1364 *p1 = 1;
1365 *p2 = 3;
1366 } else if (p == 35) {
1367 *p0 = 7;
1368 *p1 = 1;
1369 *p2 = 5;
1370 }
1371}
1372
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001373struct skl_wrpll_params {
1374 uint32_t dco_fraction;
1375 uint32_t dco_integer;
1376 uint32_t qdiv_ratio;
1377 uint32_t qdiv_mode;
1378 uint32_t kdiv;
1379 uint32_t pdiv;
1380 uint32_t central_freq;
1381};
1382
Damien Lespiau76516fb2015-05-07 18:38:42 +01001383static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1384 uint64_t afe_clock,
1385 uint64_t central_freq,
1386 uint32_t p0, uint32_t p1, uint32_t p2)
1387{
1388 uint64_t dco_freq;
1389
Damien Lespiau76516fb2015-05-07 18:38:42 +01001390 switch (central_freq) {
1391 case 9600000000ULL:
1392 params->central_freq = 0;
1393 break;
1394 case 9000000000ULL:
1395 params->central_freq = 1;
1396 break;
1397 case 8400000000ULL:
1398 params->central_freq = 3;
1399 }
1400
1401 switch (p0) {
1402 case 1:
1403 params->pdiv = 0;
1404 break;
1405 case 2:
1406 params->pdiv = 1;
1407 break;
1408 case 3:
1409 params->pdiv = 2;
1410 break;
1411 case 7:
1412 params->pdiv = 4;
1413 break;
1414 default:
1415 WARN(1, "Incorrect PDiv\n");
1416 }
1417
1418 switch (p2) {
1419 case 5:
1420 params->kdiv = 0;
1421 break;
1422 case 2:
1423 params->kdiv = 1;
1424 break;
1425 case 3:
1426 params->kdiv = 2;
1427 break;
1428 case 1:
1429 params->kdiv = 3;
1430 break;
1431 default:
1432 WARN(1, "Incorrect KDiv\n");
1433 }
1434
1435 params->qdiv_ratio = p1;
1436 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1437
1438 dco_freq = p0 * p1 * p2 * afe_clock;
1439
1440 /*
1441 * Intermediate values are in Hz.
1442 * Divide by MHz to match bsepc
1443 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001444 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001445 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001446 div_u64((div_u64(dco_freq, 24) -
1447 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001448}
1449
Damien Lespiau318bd822015-05-07 18:38:40 +01001450static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001451skl_ddi_calculate_wrpll(int clock /* in Hz */,
1452 struct skl_wrpll_params *wrpll_params)
1453{
1454 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001455 uint64_t dco_central_freq[3] = {8400000000ULL,
1456 9000000000ULL,
1457 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001458 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1459 24, 28, 30, 32, 36, 40, 42, 44,
1460 48, 52, 54, 56, 60, 64, 66, 68,
1461 70, 72, 76, 78, 80, 84, 88, 90,
1462 92, 96, 98 };
1463 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1464 static const struct {
1465 const int *list;
1466 int n_dividers;
1467 } dividers[] = {
1468 { even_dividers, ARRAY_SIZE(even_dividers) },
1469 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1470 };
1471 struct skl_wrpll_context ctx;
1472 unsigned int dco, d, i;
1473 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001474
Damien Lespiaudc253812015-06-25 16:15:06 +01001475 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001476
Damien Lespiaudc253812015-06-25 16:15:06 +01001477 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1478 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1479 for (i = 0; i < dividers[d].n_dividers; i++) {
1480 unsigned int p = dividers[d].list[i];
1481 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001482
Damien Lespiaudc253812015-06-25 16:15:06 +01001483 skl_wrpll_try_divider(&ctx,
1484 dco_central_freq[dco],
1485 dco_freq,
1486 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001487 /*
1488 * Skip the remaining dividers if we're sure to
1489 * have found the definitive divider, we can't
1490 * improve a 0 deviation.
1491 */
1492 if (ctx.min_deviation == 0)
1493 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001494 }
1495 }
Damien Lespiau267db662015-06-25 16:19:24 +01001496
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001497skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001498 /*
1499 * If a solution is found with an even divider, prefer
1500 * this one.
1501 */
1502 if (d == 0 && ctx.p)
1503 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001504 }
1505
Damien Lespiaudc253812015-06-25 16:15:06 +01001506 if (!ctx.p) {
1507 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001508 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001509 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001510
Damien Lespiaudc253812015-06-25 16:15:06 +01001511 /*
1512 * gcc incorrectly analyses that these can be used without being
1513 * initialized. To be fair, it's hard to guess.
1514 */
1515 p0 = p1 = p2 = 0;
1516 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1517 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1518 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001519
Damien Lespiau318bd822015-05-07 18:38:40 +01001520 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001521}
1522
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001523static bool
1524skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001525 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001526 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001527{
1528 struct intel_shared_dpll *pll;
1529 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001530 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001531
1532 /*
1533 * See comment in intel_dpll_hw_state to understand why we always use 0
1534 * as the DPLL id in this function.
1535 */
1536
1537 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1538
1539 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1540 struct skl_wrpll_params wrpll_params = { 0, };
1541
1542 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1543
Damien Lespiau318bd822015-05-07 18:38:40 +01001544 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1545 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001546
1547 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1548 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1549 wrpll_params.dco_integer;
1550
1551 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1552 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1553 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1554 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1555 wrpll_params.central_freq;
1556 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001557 switch (crtc_state->port_clock / 2) {
1558 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001559 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001560 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001561 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001562 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001563 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001564 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001565 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001566 break;
1567 }
1568
1569 cfgcr1 = cfgcr2 = 0;
1570 } else /* eDP */
1571 return true;
1572
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001573 memset(&crtc_state->dpll_hw_state, 0,
1574 sizeof(crtc_state->dpll_hw_state));
1575
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001576 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1577 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1578 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001579
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001580 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001581 if (pll == NULL) {
1582 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1583 pipe_name(intel_crtc->pipe));
1584 return false;
1585 }
1586
1587 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001588 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001589
1590 return true;
1591}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001592
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301593/* bxt clock parameters */
1594struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301595 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301596 uint32_t p1;
1597 uint32_t p2;
1598 uint32_t m2_int;
1599 uint32_t m2_frac;
1600 bool m2_frac_en;
1601 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301602};
1603
1604/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301605static const struct bxt_clk_div bxt_dp_clk_val[] = {
1606 {162000, 4, 2, 32, 1677722, 1, 1},
1607 {270000, 4, 1, 27, 0, 0, 1},
1608 {540000, 2, 1, 27, 0, 0, 1},
1609 {216000, 3, 2, 32, 1677722, 1, 1},
1610 {243000, 4, 1, 24, 1258291, 1, 1},
1611 {324000, 4, 1, 32, 1677722, 1, 1},
1612 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301613};
1614
1615static bool
1616bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1617 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001618 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301619{
1620 struct intel_shared_dpll *pll;
1621 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301622 int vco = 0;
1623 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301624 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001625 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301626
1627 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1628 intel_clock_t best_clock;
1629
1630 /* Calculate HDMI div */
1631 /*
1632 * FIXME: tie the following calculation into
1633 * i9xx_crtc_compute_clock
1634 */
1635 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1636 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1637 clock, pipe_name(intel_crtc->pipe));
1638 return false;
1639 }
1640
1641 clk_div.p1 = best_clock.p1;
1642 clk_div.p2 = best_clock.p2;
1643 WARN_ON(best_clock.m1 != 2);
1644 clk_div.n = best_clock.n;
1645 clk_div.m2_int = best_clock.m2 >> 22;
1646 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1647 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1648
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301649 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301650 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1651 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301652 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301653
Sonika Jindal64987fc2015-05-26 17:50:13 +05301654 clk_div = bxt_dp_clk_val[0];
1655 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1656 if (bxt_dp_clk_val[i].clock == clock) {
1657 clk_div = bxt_dp_clk_val[i];
1658 break;
1659 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301660 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301661 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1662 }
1663
Vandana Kannane6292552015-07-01 17:02:57 +05301664 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301665 prop_coef = 4;
1666 int_coef = 9;
1667 gain_ctl = 3;
1668 targ_cnt = 8;
1669 } else if ((vco > 5400000 && vco < 6200000) ||
1670 (vco >= 4800000 && vco < 5400000)) {
1671 prop_coef = 5;
1672 int_coef = 11;
1673 gain_ctl = 3;
1674 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301675 } else if (vco == 5400000) {
1676 prop_coef = 3;
1677 int_coef = 8;
1678 gain_ctl = 1;
1679 targ_cnt = 9;
1680 } else {
1681 DRM_ERROR("Invalid VCO\n");
1682 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301683 }
1684
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001685 memset(&crtc_state->dpll_hw_state, 0,
1686 sizeof(crtc_state->dpll_hw_state));
1687
Vandana Kannane0681e32015-05-13 12:20:35 +05301688 if (clock > 270000)
1689 lanestagger = 0x18;
1690 else if (clock > 135000)
1691 lanestagger = 0x0d;
1692 else if (clock > 67000)
1693 lanestagger = 0x07;
1694 else if (clock > 33000)
1695 lanestagger = 0x04;
1696 else
1697 lanestagger = 0x02;
1698
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301699 crtc_state->dpll_hw_state.ebb0 =
1700 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1701 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1702 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1703 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1704
1705 if (clk_div.m2_frac_en)
1706 crtc_state->dpll_hw_state.pll3 =
1707 PORT_PLL_M2_FRAC_ENABLE;
1708
1709 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301710 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301711 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301712 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301713
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301714 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1715
Imre Deak05712c12015-06-18 17:25:54 +03001716 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1717
Vandana Kannane6292552015-07-01 17:02:57 +05301718 crtc_state->dpll_hw_state.pll10 =
1719 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1720 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301721
Imre Deak05712c12015-06-18 17:25:54 +03001722 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1723
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301724 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301725 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301726
1727 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1728 if (pll == NULL) {
1729 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1730 pipe_name(intel_crtc->pipe));
1731 return false;
1732 }
1733
1734 /* shared DPLL id 0 is DPLL A */
1735 crtc_state->ddi_pll_sel = pll->id;
1736
1737 return true;
1738}
1739
Damien Lespiau0220ab62014-07-29 18:06:22 +01001740/*
1741 * Tries to find a *shared* PLL for the CRTC and store it in
1742 * intel_crtc->ddi_pll_sel.
1743 *
1744 * For private DPLLs, compute_config() should do the selection for us. This
1745 * function should be folded into compute_config() eventually.
1746 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001747bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1748 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001749{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001750 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001751 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001752 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001753
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001754 if (IS_SKYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001755 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001756 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301757 else if (IS_BROXTON(dev))
1758 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001759 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001760 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001761 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001762 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001763}
1764
Paulo Zanonidae84792012-10-15 15:51:30 -03001765void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1766{
1767 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1768 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1769 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001770 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001771 int type = intel_encoder->type;
1772 uint32_t temp;
1773
Dave Airlie0e32b392014-05-02 14:02:48 +10001774 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001775 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001776 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001777 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001778 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001779 break;
1780 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001781 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001782 break;
1783 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001784 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001785 break;
1786 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001787 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001788 break;
1789 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001790 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001791 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001792 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001793 }
1794}
1795
Dave Airlie0e32b392014-05-02 14:02:48 +10001796void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1797{
1798 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1799 struct drm_device *dev = crtc->dev;
1800 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001801 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001802 uint32_t temp;
1803 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1804 if (state == true)
1805 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1806 else
1807 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1808 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1809}
1810
Damien Lespiau8228c252013-03-07 15:30:27 +00001811void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001812{
1813 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1814 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001815 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001816 struct drm_device *dev = crtc->dev;
1817 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001818 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001819 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001820 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001821 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001822 uint32_t temp;
1823
Paulo Zanoniad80a812012-10-24 16:06:19 -02001824 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1825 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001826 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001827
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001828 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001829 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001830 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001831 break;
1832 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001833 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001834 break;
1835 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001836 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001837 break;
1838 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001839 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001840 break;
1841 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001842 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001843 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001844
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001845 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001846 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001847 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001848 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001849
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001850 if (cpu_transcoder == TRANSCODER_EDP) {
1851 switch (pipe) {
1852 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001853 /* On Haswell, can only use the always-on power well for
1854 * eDP when not using the panel fitter, and when not
1855 * using motion blur mitigation (which we don't
1856 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001857 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001858 (intel_crtc->config->pch_pfit.enabled ||
1859 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001860 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1861 else
1862 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001863 break;
1864 case PIPE_B:
1865 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1866 break;
1867 case PIPE_C:
1868 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1869 break;
1870 default:
1871 BUG();
1872 break;
1873 }
1874 }
1875
Paulo Zanoni7739c332012-10-15 15:51:29 -03001876 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001877 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001878 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001879 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001880 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001881
Paulo Zanoni7739c332012-10-15 15:51:29 -03001882 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001883 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001884 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001885
1886 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1887 type == INTEL_OUTPUT_EDP) {
1888 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1889
Dave Airlie0e32b392014-05-02 14:02:48 +10001890 if (intel_dp->is_mst) {
1891 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1892 } else
1893 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1894
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001895 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001896 } else if (type == INTEL_OUTPUT_DP_MST) {
1897 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1898
1899 if (intel_dp->is_mst) {
1900 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1901 } else
1902 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001903
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001904 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001905 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001906 WARN(1, "Invalid encoder type %d for pipe %c\n",
1907 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001908 }
1909
Paulo Zanoniad80a812012-10-24 16:06:19 -02001910 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001911}
1912
Paulo Zanoniad80a812012-10-24 16:06:19 -02001913void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1914 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001915{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001916 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001917 uint32_t val = I915_READ(reg);
1918
Dave Airlie0e32b392014-05-02 14:02:48 +10001919 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001920 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001921 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001922}
1923
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001924bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1925{
1926 struct drm_device *dev = intel_connector->base.dev;
1927 struct drm_i915_private *dev_priv = dev->dev_private;
1928 struct intel_encoder *intel_encoder = intel_connector->encoder;
1929 int type = intel_connector->base.connector_type;
1930 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1931 enum pipe pipe = 0;
1932 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001933 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001934 uint32_t tmp;
1935
Paulo Zanoni882244a2014-04-01 14:55:12 -03001936 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001937 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001938 return false;
1939
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001940 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1941 return false;
1942
1943 if (port == PORT_A)
1944 cpu_transcoder = TRANSCODER_EDP;
1945 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001946 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001947
1948 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1949
1950 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1951 case TRANS_DDI_MODE_SELECT_HDMI:
1952 case TRANS_DDI_MODE_SELECT_DVI:
1953 return (type == DRM_MODE_CONNECTOR_HDMIA);
1954
1955 case TRANS_DDI_MODE_SELECT_DP_SST:
1956 if (type == DRM_MODE_CONNECTOR_eDP)
1957 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001958 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001959 case TRANS_DDI_MODE_SELECT_DP_MST:
1960 /* if the transcoder is in MST state then
1961 * connector isn't connected */
1962 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001963
1964 case TRANS_DDI_MODE_SELECT_FDI:
1965 return (type == DRM_MODE_CONNECTOR_VGA);
1966
1967 default:
1968 return false;
1969 }
1970}
1971
Daniel Vetter85234cd2012-07-02 13:27:29 +02001972bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1973 enum pipe *pipe)
1974{
1975 struct drm_device *dev = encoder->base.dev;
1976 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001977 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001978 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001979 u32 tmp;
1980 int i;
1981
Imre Deak6d129be2014-03-05 16:20:54 +02001982 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001983 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02001984 return false;
1985
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001986 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001987
1988 if (!(tmp & DDI_BUF_CTL_ENABLE))
1989 return false;
1990
Paulo Zanoniad80a812012-10-24 16:06:19 -02001991 if (port == PORT_A) {
1992 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001993
Paulo Zanoniad80a812012-10-24 16:06:19 -02001994 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
1995 case TRANS_DDI_EDP_INPUT_A_ON:
1996 case TRANS_DDI_EDP_INPUT_A_ONOFF:
1997 *pipe = PIPE_A;
1998 break;
1999 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2000 *pipe = PIPE_B;
2001 break;
2002 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2003 *pipe = PIPE_C;
2004 break;
2005 }
2006
2007 return true;
2008 } else {
2009 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2010 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2011
2012 if ((tmp & TRANS_DDI_PORT_MASK)
2013 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002014 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2015 return false;
2016
Paulo Zanoniad80a812012-10-24 16:06:19 -02002017 *pipe = i;
2018 return true;
2019 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002020 }
2021 }
2022
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002023 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002024
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002025 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002026}
2027
Paulo Zanonifc914632012-10-05 12:05:54 -03002028void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2029{
2030 struct drm_crtc *crtc = &intel_crtc->base;
2031 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2032 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2033 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002034 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002035
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002036 if (cpu_transcoder != TRANSCODER_EDP)
2037 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2038 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002039}
2040
2041void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2042{
2043 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002044 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002045
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002046 if (cpu_transcoder != TRANSCODER_EDP)
2047 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2048 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002049}
2050
David Weinehallf8896f52015-06-25 11:11:03 +03002051static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2052 enum port port, int type)
2053{
2054 struct drm_i915_private *dev_priv = dev->dev_private;
2055 const struct ddi_buf_trans *ddi_translations;
2056 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002057 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002058 int n_entries;
2059 u32 reg;
2060
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002061 /* VBT may override standard boost values */
2062 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2063 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2064
David Weinehallf8896f52015-06-25 11:11:03 +03002065 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002066 if (dp_iboost) {
2067 iboost = dp_iboost;
2068 } else {
2069 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2070 iboost = ddi_translations[port].i_boost;
2071 }
David Weinehallf8896f52015-06-25 11:11:03 +03002072 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002073 if (dp_iboost) {
2074 iboost = dp_iboost;
2075 } else {
2076 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2077 iboost = ddi_translations[port].i_boost;
2078 }
David Weinehallf8896f52015-06-25 11:11:03 +03002079 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002080 if (hdmi_iboost) {
2081 iboost = hdmi_iboost;
2082 } else {
2083 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2084 iboost = ddi_translations[port].i_boost;
2085 }
David Weinehallf8896f52015-06-25 11:11:03 +03002086 } else {
2087 return;
2088 }
2089
2090 /* Make sure that the requested I_boost is valid */
2091 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2092 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2093 return;
2094 }
2095
2096 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2097 reg &= ~BALANCE_LEG_MASK(port);
2098 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2099
2100 if (iboost)
2101 reg |= iboost << BALANCE_LEG_SHIFT(port);
2102 else
2103 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2104
2105 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2106}
2107
2108static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2109 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302110{
2111 struct drm_i915_private *dev_priv = dev->dev_private;
2112 const struct bxt_ddi_buf_trans *ddi_translations;
2113 u32 n_entries, i;
2114 uint32_t val;
2115
2116 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
2117 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2118 ddi_translations = bxt_ddi_translations_dp;
2119 } else if (type == INTEL_OUTPUT_HDMI) {
2120 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2121 ddi_translations = bxt_ddi_translations_hdmi;
2122 } else {
2123 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2124 type);
2125 return;
2126 }
2127
2128 /* Check if default value has to be used */
2129 if (level >= n_entries ||
2130 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2131 for (i = 0; i < n_entries; i++) {
2132 if (ddi_translations[i].default_index) {
2133 level = i;
2134 break;
2135 }
2136 }
2137 }
2138
2139 /*
2140 * While we write to the group register to program all lanes at once we
2141 * can read only lane registers and we pick lanes 0/1 for that.
2142 */
2143 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2144 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2145 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2146
2147 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2148 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2149 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2150 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2151 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2152
2153 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
2154 val &= ~UNIQE_TRANGE_EN_METHOD;
2155 if (ddi_translations[level].enable)
2156 val |= UNIQE_TRANGE_EN_METHOD;
2157 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2158
2159 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2160 val &= ~DE_EMPHASIS;
2161 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2162 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2163
2164 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2165 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2166 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2167}
2168
David Weinehallf8896f52015-06-25 11:11:03 +03002169static uint32_t translate_signal_level(int signal_levels)
2170{
2171 uint32_t level;
2172
2173 switch (signal_levels) {
2174 default:
2175 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2176 signal_levels);
2177 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2178 level = 0;
2179 break;
2180 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2181 level = 1;
2182 break;
2183 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2184 level = 2;
2185 break;
2186 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2187 level = 3;
2188 break;
2189
2190 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2191 level = 4;
2192 break;
2193 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2194 level = 5;
2195 break;
2196 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2197 level = 6;
2198 break;
2199
2200 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2201 level = 7;
2202 break;
2203 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2204 level = 8;
2205 break;
2206
2207 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2208 level = 9;
2209 break;
2210 }
2211
2212 return level;
2213}
2214
2215uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2216{
2217 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2218 struct drm_device *dev = dport->base.base.dev;
2219 struct intel_encoder *encoder = &dport->base;
2220 uint8_t train_set = intel_dp->train_set[0];
2221 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2222 DP_TRAIN_PRE_EMPHASIS_MASK);
2223 enum port port = dport->port;
2224 uint32_t level;
2225
2226 level = translate_signal_level(signal_levels);
2227
2228 if (IS_SKYLAKE(dev))
2229 skl_ddi_set_iboost(dev, level, port, encoder->type);
2230 else if (IS_BROXTON(dev))
2231 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2232
2233 return DDI_BUF_TRANS_SELECT(level);
2234}
2235
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002236static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002237{
Paulo Zanonic19b0662012-10-15 15:51:41 -03002238 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002239 struct drm_device *dev = encoder->dev;
2240 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002241 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002242 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002243 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302244 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002245
2246 if (type == INTEL_OUTPUT_EDP) {
2247 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01002248 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002249 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002250
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002251 if (IS_SKYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002252 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002253 uint32_t val;
2254
Damien Lespiau5416d872014-11-14 17:24:33 +00002255 /*
2256 * DPLL0 is used for eDP and is the only "private" DPLL (as
2257 * opposed to shared) on SKL
2258 */
2259 if (type == INTEL_OUTPUT_EDP) {
2260 WARN_ON(dpll != SKL_DPLL0);
2261
2262 val = I915_READ(DPLL_CTRL1);
2263
2264 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2265 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002266 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002267 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002268
2269 I915_WRITE(DPLL_CTRL1, val);
2270 POSTING_READ(DPLL_CTRL1);
2271 }
2272
2273 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002274 val = I915_READ(DPLL_CTRL2);
2275
2276 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2277 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2278 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2279 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2280
2281 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002282
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302283 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002284 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2285 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002286 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002287
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002288 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002289 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002290
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002291 intel_dp_set_link_params(intel_dp, crtc->config);
2292
Dave Airlie44905a272014-05-02 13:36:43 +10002293 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002294
2295 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2296 intel_dp_start_link_train(intel_dp);
2297 intel_dp_complete_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002298 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002299 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002300 } else if (type == INTEL_OUTPUT_HDMI) {
2301 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2302
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302303 if (IS_BROXTON(dev)) {
2304 hdmi_level = dev_priv->vbt.
2305 ddi_port_info[port].hdmi_level_shift;
2306 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2307 INTEL_OUTPUT_HDMI);
2308 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002309 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002310 crtc->config->has_hdmi_sink,
2311 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002312 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002313}
2314
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002315static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002316{
2317 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002318 struct drm_device *dev = encoder->dev;
2319 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002320 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002321 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002322 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002323 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002324
2325 val = I915_READ(DDI_BUF_CTL(port));
2326 if (val & DDI_BUF_CTL_ENABLE) {
2327 val &= ~DDI_BUF_CTL_ENABLE;
2328 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002329 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002330 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002331
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002332 val = I915_READ(DP_TP_CTL(port));
2333 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2334 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2335 I915_WRITE(DP_TP_CTL(port), val);
2336
2337 if (wait)
2338 intel_wait_ddi_buf_idle(dev_priv, port);
2339
Jani Nikula76bb80e2013-11-15 15:29:57 +02002340 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002341 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002342 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002343 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002344 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002345 }
2346
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002347 if (IS_SKYLAKE(dev))
2348 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2349 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302350 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002351 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002352}
2353
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002354static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002355{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002356 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002357 struct drm_crtc *crtc = encoder->crtc;
2358 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002359 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002360 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002361 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2362 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002363
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002364 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002365 struct intel_digital_port *intel_dig_port =
2366 enc_to_dig_port(encoder);
2367
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002368 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2369 * are ignored so nothing special needs to be done besides
2370 * enabling the port.
2371 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002372 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de42013-07-12 13:54:41 -07002373 intel_dig_port->saved_port_bits |
2374 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002375 } else if (type == INTEL_OUTPUT_EDP) {
2376 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2377
Vandana Kannan23f08d82014-11-13 14:55:22 +00002378 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002379 intel_dp_stop_link_train(intel_dp);
2380
Daniel Vetter4be73782014-01-17 14:39:48 +01002381 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002382 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302383 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002384 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002385
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002386 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002387 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002388 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002389 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002390}
2391
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002392static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002393{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002394 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002395 struct drm_crtc *crtc = encoder->crtc;
2396 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002397 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002398 struct drm_device *dev = encoder->dev;
2399 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002400
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002401 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002402 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002403 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2404 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002405
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002406 if (type == INTEL_OUTPUT_EDP) {
2407 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2408
Vandana Kannanc3955782015-01-22 15:17:40 +05302409 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002410 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002411 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002412 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002413}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002414
Daniel Vettere0b01be2014-06-25 22:02:01 +03002415static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2416 struct intel_shared_dpll *pll)
2417{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002418 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002419 POSTING_READ(WRPLL_CTL(pll->id));
2420 udelay(20);
2421}
2422
Daniel Vetter12030432014-06-25 22:02:00 +03002423static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2424 struct intel_shared_dpll *pll)
2425{
2426 uint32_t val;
2427
2428 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002429 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2430 POSTING_READ(WRPLL_CTL(pll->id));
2431}
2432
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002433static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2434 struct intel_shared_dpll *pll,
2435 struct intel_dpll_hw_state *hw_state)
2436{
2437 uint32_t val;
2438
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002439 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002440 return false;
2441
2442 val = I915_READ(WRPLL_CTL(pll->id));
2443 hw_state->wrpll = val;
2444
2445 return val & WRPLL_PLL_ENABLE;
2446}
2447
Damien Lespiauca1381b2014-07-15 15:05:33 +01002448static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002449 "WRPLL 1",
2450 "WRPLL 2",
2451};
2452
Damien Lespiau143b3072014-07-29 18:06:19 +01002453static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002454{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002455 int i;
2456
Daniel Vetter716c2e52014-06-25 22:02:02 +03002457 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002458
Daniel Vetter716c2e52014-06-25 22:02:02 +03002459 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002460 dev_priv->shared_dplls[i].id = i;
2461 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002462 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002463 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002464 dev_priv->shared_dplls[i].get_hw_state =
2465 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002466 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002467}
2468
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002469static const char * const skl_ddi_pll_names[] = {
2470 "DPLL 1",
2471 "DPLL 2",
2472 "DPLL 3",
2473};
2474
2475struct skl_dpll_regs {
2476 u32 ctl, cfgcr1, cfgcr2;
2477};
2478
2479/* this array is indexed by the *shared* pll id */
2480static const struct skl_dpll_regs skl_dpll_regs[3] = {
2481 {
2482 /* DPLL 1 */
2483 .ctl = LCPLL2_CTL,
2484 .cfgcr1 = DPLL1_CFGCR1,
2485 .cfgcr2 = DPLL1_CFGCR2,
2486 },
2487 {
2488 /* DPLL 2 */
2489 .ctl = WRPLL_CTL1,
2490 .cfgcr1 = DPLL2_CFGCR1,
2491 .cfgcr2 = DPLL2_CFGCR2,
2492 },
2493 {
2494 /* DPLL 3 */
2495 .ctl = WRPLL_CTL2,
2496 .cfgcr1 = DPLL3_CFGCR1,
2497 .cfgcr2 = DPLL3_CFGCR2,
2498 },
2499};
2500
2501static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2502 struct intel_shared_dpll *pll)
2503{
2504 uint32_t val;
2505 unsigned int dpll;
2506 const struct skl_dpll_regs *regs = skl_dpll_regs;
2507
2508 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2509 dpll = pll->id + 1;
2510
2511 val = I915_READ(DPLL_CTRL1);
2512
2513 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002514 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002515 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2516
2517 I915_WRITE(DPLL_CTRL1, val);
2518 POSTING_READ(DPLL_CTRL1);
2519
2520 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2521 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2522 POSTING_READ(regs[pll->id].cfgcr1);
2523 POSTING_READ(regs[pll->id].cfgcr2);
2524
2525 /* the enable bit is always bit 31 */
2526 I915_WRITE(regs[pll->id].ctl,
2527 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2528
2529 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2530 DRM_ERROR("DPLL %d not locked\n", dpll);
2531}
2532
2533static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2534 struct intel_shared_dpll *pll)
2535{
2536 const struct skl_dpll_regs *regs = skl_dpll_regs;
2537
2538 /* the enable bit is always bit 31 */
2539 I915_WRITE(regs[pll->id].ctl,
2540 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2541 POSTING_READ(regs[pll->id].ctl);
2542}
2543
2544static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2545 struct intel_shared_dpll *pll,
2546 struct intel_dpll_hw_state *hw_state)
2547{
2548 uint32_t val;
2549 unsigned int dpll;
2550 const struct skl_dpll_regs *regs = skl_dpll_regs;
2551
2552 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2553 return false;
2554
2555 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2556 dpll = pll->id + 1;
2557
2558 val = I915_READ(regs[pll->id].ctl);
2559 if (!(val & LCPLL_PLL_ENABLE))
2560 return false;
2561
2562 val = I915_READ(DPLL_CTRL1);
2563 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2564
2565 /* avoid reading back stale values if HDMI mode is not enabled */
2566 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2567 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2568 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2569 }
2570
2571 return true;
2572}
2573
2574static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2575{
2576 int i;
2577
2578 dev_priv->num_shared_dpll = 3;
2579
2580 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2581 dev_priv->shared_dplls[i].id = i;
2582 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2583 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2584 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2585 dev_priv->shared_dplls[i].get_hw_state =
2586 skl_ddi_pll_get_hw_state;
2587 }
2588}
2589
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302590static void broxton_phy_init(struct drm_i915_private *dev_priv,
2591 enum dpio_phy phy)
2592{
2593 enum port port;
2594 uint32_t val;
2595
2596 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2597 val |= GT_DISPLAY_POWER_ON(phy);
2598 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2599
2600 /* Considering 10ms timeout until BSpec is updated */
2601 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2602 DRM_ERROR("timeout during PHY%d power on\n", phy);
2603
2604 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2605 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2606 int lane;
2607
2608 for (lane = 0; lane < 4; lane++) {
2609 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2610 /*
2611 * Note that on CHV this flag is called UPAR, but has
2612 * the same function.
2613 */
2614 val &= ~LATENCY_OPTIM;
2615 if (lane != 1)
2616 val |= LATENCY_OPTIM;
2617
2618 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2619 }
2620 }
2621
2622 /* Program PLL Rcomp code offset */
2623 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2624 val &= ~IREF0RC_OFFSET_MASK;
2625 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2626 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2627
2628 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2629 val &= ~IREF1RC_OFFSET_MASK;
2630 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2631 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2632
2633 /* Program power gating */
2634 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2635 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2636 SUS_CLK_CONFIG;
2637 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2638
2639 if (phy == DPIO_PHY0) {
2640 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2641 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2642 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2643 }
2644
2645 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2646 val &= ~OCL2_LDOFUSE_PWR_DIS;
2647 /*
2648 * On PHY1 disable power on the second channel, since no port is
2649 * connected there. On PHY0 both channels have a port, so leave it
2650 * enabled.
2651 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2652 * power down the second channel on PHY0 as well.
2653 */
2654 if (phy == DPIO_PHY1)
2655 val |= OCL2_LDOFUSE_PWR_DIS;
2656 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2657
2658 if (phy == DPIO_PHY0) {
2659 uint32_t grc_code;
2660 /*
2661 * PHY0 isn't connected to an RCOMP resistor so copy over
2662 * the corresponding calibrated value from PHY1, and disable
2663 * the automatic calibration on PHY0.
2664 */
2665 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2666 10))
2667 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2668
2669 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2670 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2671 grc_code = val << GRC_CODE_FAST_SHIFT |
2672 val << GRC_CODE_SLOW_SHIFT |
2673 val;
2674 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2675
2676 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2677 val |= GRC_DIS | GRC_RDY_OVRD;
2678 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2679 }
2680
2681 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2682 val |= COMMON_RESET_DIS;
2683 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2684}
2685
2686void broxton_ddi_phy_init(struct drm_device *dev)
2687{
2688 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2689 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2690 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2691}
2692
2693static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2694 enum dpio_phy phy)
2695{
2696 uint32_t val;
2697
2698 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2699 val &= ~COMMON_RESET_DIS;
2700 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2701}
2702
2703void broxton_ddi_phy_uninit(struct drm_device *dev)
2704{
2705 struct drm_i915_private *dev_priv = dev->dev_private;
2706
2707 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2708 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2709
2710 /* FIXME: do this in broxton_phy_uninit per phy */
2711 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2712}
2713
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302714static const char * const bxt_ddi_pll_names[] = {
2715 "PORT PLL A",
2716 "PORT PLL B",
2717 "PORT PLL C",
2718};
2719
2720static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2721 struct intel_shared_dpll *pll)
2722{
2723 uint32_t temp;
2724 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2725
2726 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2727 temp &= ~PORT_PLL_REF_SEL;
2728 /* Non-SSC reference */
2729 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2730
2731 /* Disable 10 bit clock */
2732 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2733 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2734 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2735
2736 /* Write P1 & P2 */
2737 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2738 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2739 temp |= pll->config.hw_state.ebb0;
2740 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2741
2742 /* Write M2 integer */
2743 temp = I915_READ(BXT_PORT_PLL(port, 0));
2744 temp &= ~PORT_PLL_M2_MASK;
2745 temp |= pll->config.hw_state.pll0;
2746 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2747
2748 /* Write N */
2749 temp = I915_READ(BXT_PORT_PLL(port, 1));
2750 temp &= ~PORT_PLL_N_MASK;
2751 temp |= pll->config.hw_state.pll1;
2752 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2753
2754 /* Write M2 fraction */
2755 temp = I915_READ(BXT_PORT_PLL(port, 2));
2756 temp &= ~PORT_PLL_M2_FRAC_MASK;
2757 temp |= pll->config.hw_state.pll2;
2758 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2759
2760 /* Write M2 fraction enable */
2761 temp = I915_READ(BXT_PORT_PLL(port, 3));
2762 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2763 temp |= pll->config.hw_state.pll3;
2764 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2765
2766 /* Write coeff */
2767 temp = I915_READ(BXT_PORT_PLL(port, 6));
2768 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2769 temp &= ~PORT_PLL_INT_COEFF_MASK;
2770 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2771 temp |= pll->config.hw_state.pll6;
2772 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2773
2774 /* Write calibration val */
2775 temp = I915_READ(BXT_PORT_PLL(port, 8));
2776 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2777 temp |= pll->config.hw_state.pll8;
2778 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2779
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302780 temp = I915_READ(BXT_PORT_PLL(port, 9));
2781 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002782 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302783 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2784
2785 temp = I915_READ(BXT_PORT_PLL(port, 10));
2786 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2787 temp &= ~PORT_PLL_DCO_AMP_MASK;
2788 temp |= pll->config.hw_state.pll10;
2789 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302790
2791 /* Recalibrate with new settings */
2792 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2793 temp |= PORT_PLL_RECALIBRATE;
2794 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002795 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2796 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302797 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2798
2799 /* Enable PLL */
2800 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2801 temp |= PORT_PLL_ENABLE;
2802 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2803 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2804
2805 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2806 PORT_PLL_LOCK), 200))
2807 DRM_ERROR("PLL %d not locked\n", port);
2808
2809 /*
2810 * While we write to the group register to program all lanes at once we
2811 * can read only lane registers and we pick lanes 0/1 for that.
2812 */
2813 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2814 temp &= ~LANE_STAGGER_MASK;
2815 temp &= ~LANESTAGGER_STRAP_OVRD;
2816 temp |= pll->config.hw_state.pcsdw12;
2817 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2818}
2819
2820static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2821 struct intel_shared_dpll *pll)
2822{
2823 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2824 uint32_t temp;
2825
2826 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2827 temp &= ~PORT_PLL_ENABLE;
2828 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2829 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2830}
2831
2832static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2833 struct intel_shared_dpll *pll,
2834 struct intel_dpll_hw_state *hw_state)
2835{
2836 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2837 uint32_t val;
2838
2839 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2840 return false;
2841
2842 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2843 if (!(val & PORT_PLL_ENABLE))
2844 return false;
2845
2846 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002847 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2848
Imre Deak05712c12015-06-18 17:25:54 +03002849 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2850 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2851
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302852 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002853 hw_state->pll0 &= PORT_PLL_M2_MASK;
2854
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302855 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002856 hw_state->pll1 &= PORT_PLL_N_MASK;
2857
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302858 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002859 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2860
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302861 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002862 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2863
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302864 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002865 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2866 PORT_PLL_INT_COEFF_MASK |
2867 PORT_PLL_GAIN_CTL_MASK;
2868
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302869 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002870 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2871
Imre Deak05712c12015-06-18 17:25:54 +03002872 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2873 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2874
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302875 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002876 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2877 PORT_PLL_DCO_AMP_MASK;
2878
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302879 /*
2880 * While we write to the group register to program all lanes at once we
2881 * can read only lane registers. We configure all lanes the same way, so
2882 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2883 */
2884 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2885 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port) != hw_state->pcsdw12))
2886 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2887 hw_state->pcsdw12,
2888 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002889 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302890
2891 return true;
2892}
2893
2894static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2895{
2896 int i;
2897
2898 dev_priv->num_shared_dpll = 3;
2899
2900 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2901 dev_priv->shared_dplls[i].id = i;
2902 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2903 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2904 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2905 dev_priv->shared_dplls[i].get_hw_state =
2906 bxt_ddi_pll_get_hw_state;
2907 }
2908}
2909
Damien Lespiau143b3072014-07-29 18:06:19 +01002910void intel_ddi_pll_init(struct drm_device *dev)
2911{
2912 struct drm_i915_private *dev_priv = dev->dev_private;
2913 uint32_t val = I915_READ(LCPLL_CTL);
2914
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002915 if (IS_SKYLAKE(dev))
2916 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302917 else if (IS_BROXTON(dev))
2918 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002919 else
2920 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002921
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002922 if (IS_SKYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002923 int cdclk_freq;
2924
2925 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002926 dev_priv->skl_boot_cdclk = cdclk_freq;
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002927 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2928 DRM_ERROR("LCPLL1 is disabled\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002929 else
2930 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302931 } else if (IS_BROXTON(dev)) {
2932 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302933 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002934 } else {
2935 /*
2936 * The LCPLL register should be turned on by the BIOS. For now
2937 * let's just check its state and print errors in case
2938 * something is wrong. Don't even try to turn it on.
2939 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002940
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002941 if (val & LCPLL_CD_SOURCE_FCLK)
2942 DRM_ERROR("CDCLK source is not LCPLL\n");
2943
2944 if (val & LCPLL_PLL_DISABLE)
2945 DRM_ERROR("LCPLL is disabled\n");
2946 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002947}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002948
2949void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
2950{
Paulo Zanoni174edf12012-10-26 19:05:50 -02002951 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
2952 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002953 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02002954 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002955 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302956 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002957
2958 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2959 val = I915_READ(DDI_BUF_CTL(port));
2960 if (val & DDI_BUF_CTL_ENABLE) {
2961 val &= ~DDI_BUF_CTL_ENABLE;
2962 I915_WRITE(DDI_BUF_CTL(port), val);
2963 wait = true;
2964 }
2965
2966 val = I915_READ(DP_TP_CTL(port));
2967 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2968 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2969 I915_WRITE(DP_TP_CTL(port), val);
2970 POSTING_READ(DP_TP_CTL(port));
2971
2972 if (wait)
2973 intel_wait_ddi_buf_idle(dev_priv, port);
2974 }
2975
Dave Airlie0e32b392014-05-02 14:02:48 +10002976 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03002977 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10002978 if (intel_dp->is_mst)
2979 val |= DP_TP_CTL_MODE_MST;
2980 else {
2981 val |= DP_TP_CTL_MODE_SST;
2982 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
2983 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
2984 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002985 I915_WRITE(DP_TP_CTL(port), val);
2986 POSTING_READ(DP_TP_CTL(port));
2987
2988 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
2989 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
2990 POSTING_READ(DDI_BUF_CTL(port));
2991
2992 udelay(600);
2993}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002994
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02002995void intel_ddi_fdi_disable(struct drm_crtc *crtc)
2996{
2997 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2998 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2999 uint32_t val;
3000
3001 intel_ddi_post_disable(intel_encoder);
3002
3003 val = I915_READ(_FDI_RXA_CTL);
3004 val &= ~FDI_RX_ENABLE;
3005 I915_WRITE(_FDI_RXA_CTL, val);
3006
3007 val = I915_READ(_FDI_RXA_MISC);
3008 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3009 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
3010 I915_WRITE(_FDI_RXA_MISC, val);
3011
3012 val = I915_READ(_FDI_RXA_CTL);
3013 val &= ~FDI_PCDCLK;
3014 I915_WRITE(_FDI_RXA_CTL, val);
3015
3016 val = I915_READ(_FDI_RXA_CTL);
3017 val &= ~FDI_RX_PLL_ENABLE;
3018 I915_WRITE(_FDI_RXA_CTL, val);
3019}
3020
Ville Syrjälä6801c182013-09-24 14:24:05 +03003021void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003022 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003023{
3024 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3025 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003026 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003027 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003028 u32 temp, flags = 0;
3029
3030 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3031 if (temp & TRANS_DDI_PHSYNC)
3032 flags |= DRM_MODE_FLAG_PHSYNC;
3033 else
3034 flags |= DRM_MODE_FLAG_NHSYNC;
3035 if (temp & TRANS_DDI_PVSYNC)
3036 flags |= DRM_MODE_FLAG_PVSYNC;
3037 else
3038 flags |= DRM_MODE_FLAG_NVSYNC;
3039
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003040 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003041
3042 switch (temp & TRANS_DDI_BPC_MASK) {
3043 case TRANS_DDI_BPC_6:
3044 pipe_config->pipe_bpp = 18;
3045 break;
3046 case TRANS_DDI_BPC_8:
3047 pipe_config->pipe_bpp = 24;
3048 break;
3049 case TRANS_DDI_BPC_10:
3050 pipe_config->pipe_bpp = 30;
3051 break;
3052 case TRANS_DDI_BPC_12:
3053 pipe_config->pipe_bpp = 36;
3054 break;
3055 default:
3056 break;
3057 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003058
3059 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3060 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003061 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003062 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3063
3064 if (intel_hdmi->infoframe_enabled(&encoder->base))
3065 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003066 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003067 case TRANS_DDI_MODE_SELECT_DVI:
3068 case TRANS_DDI_MODE_SELECT_FDI:
3069 break;
3070 case TRANS_DDI_MODE_SELECT_DP_SST:
3071 case TRANS_DDI_MODE_SELECT_DP_MST:
3072 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003073 pipe_config->lane_count =
3074 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003075 intel_dp_get_m_n(intel_crtc, pipe_config);
3076 break;
3077 default:
3078 break;
3079 }
Daniel Vetter10214422013-11-18 07:38:16 +01003080
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003081 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003082 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003083 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003084 pipe_config->has_audio = true;
3085 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003086
Daniel Vetter10214422013-11-18 07:38:16 +01003087 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3088 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3089 /*
3090 * This is a big fat ugly hack.
3091 *
3092 * Some machines in UEFI boot mode provide us a VBT that has 18
3093 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3094 * unknown we fail to light up. Yet the same BIOS boots up with
3095 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3096 * max, not what it tells us to use.
3097 *
3098 * Note: This will still be broken if the eDP panel is not lit
3099 * up by the BIOS, and thus we can't get the mode at module
3100 * load.
3101 */
3102 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3103 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3104 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3105 }
Jesse Barnes11578552014-01-21 12:42:10 -08003106
Damien Lespiau22606a12014-12-12 14:26:57 +00003107 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003108}
3109
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003110static void intel_ddi_destroy(struct drm_encoder *encoder)
3111{
3112 /* HDMI has nothing special to destroy, so we can go with this. */
3113 intel_dp_encoder_destroy(encoder);
3114}
3115
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003116static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003117 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003118{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003119 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003120 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003121
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003122 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003123
Daniel Vettereccb1402013-05-22 00:50:22 +02003124 if (port == PORT_A)
3125 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3126
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003127 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003128 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003129 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003130 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003131}
3132
3133static const struct drm_encoder_funcs intel_ddi_funcs = {
3134 .destroy = intel_ddi_destroy,
3135};
3136
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003137static struct intel_connector *
3138intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3139{
3140 struct intel_connector *connector;
3141 enum port port = intel_dig_port->port;
3142
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003143 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003144 if (!connector)
3145 return NULL;
3146
3147 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3148 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3149 kfree(connector);
3150 return NULL;
3151 }
3152
3153 return connector;
3154}
3155
3156static struct intel_connector *
3157intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3158{
3159 struct intel_connector *connector;
3160 enum port port = intel_dig_port->port;
3161
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003162 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003163 if (!connector)
3164 return NULL;
3165
3166 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3167 intel_hdmi_init_connector(intel_dig_port, connector);
3168
3169 return connector;
3170}
3171
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003172void intel_ddi_init(struct drm_device *dev, enum port port)
3173{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003174 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003175 struct intel_digital_port *intel_dig_port;
3176 struct intel_encoder *intel_encoder;
3177 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003178 bool init_hdmi, init_dp;
3179
3180 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3181 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3182 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3183 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003184 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003185 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003186 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003187 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003188
Daniel Vetterb14c5672013-09-19 12:18:32 +02003189 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003190 if (!intel_dig_port)
3191 return;
3192
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003193 intel_encoder = &intel_dig_port->base;
3194 encoder = &intel_encoder->base;
3195
3196 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3197 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003198
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003199 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003200 intel_encoder->enable = intel_enable_ddi;
3201 intel_encoder->pre_enable = intel_ddi_pre_enable;
3202 intel_encoder->disable = intel_disable_ddi;
3203 intel_encoder->post_disable = intel_ddi_post_disable;
3204 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003205 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003206
3207 intel_dig_port->port = port;
Stéphane Marchesinbcf53de42013-07-12 13:54:41 -07003208 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3209 (DDI_BUF_PORT_REVERSAL |
3210 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003211
3212 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003213 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003214 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003215
Chris Wilsonf68d6972014-08-04 07:15:09 +01003216 if (init_dp) {
3217 if (!intel_ddi_init_dp_connector(intel_dig_port))
3218 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003219
Chris Wilsonf68d6972014-08-04 07:15:09 +01003220 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303221 /*
3222 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3223 * interrupts to check the external panel connection.
3224 */
3225 if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)
3226 && port == PORT_B)
3227 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3228 else
3229 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003230 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003231
Paulo Zanoni311a2092013-09-12 17:12:18 -03003232 /* In theory we don't need the encoder->type check, but leave it just in
3233 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003234 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3235 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3236 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003237 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003238
3239 return;
3240
3241err:
3242 drm_encoder_cleanup(encoder);
3243 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003244}