blob: 19004557c868afb419e3411748f066f7aff6101c [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 Zanoni0d536cb2012-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);
Dave Airlie44905a272014-05-02 13:36:43 +1000709 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
710
711}
712
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300713static struct intel_encoder *
714intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
715{
716 struct drm_device *dev = crtc->dev;
717 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
718 struct intel_encoder *intel_encoder, *ret = NULL;
719 int num_encoders = 0;
720
721 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
722 ret = intel_encoder;
723 num_encoders++;
724 }
725
726 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300727 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
728 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300729
730 BUG_ON(ret == NULL);
731 return ret;
732}
733
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530734struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200735intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200736{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200737 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
738 struct intel_encoder *ret = NULL;
739 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300740 struct drm_connector *connector;
741 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200742 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200743 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200744
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200745 state = crtc_state->base.state;
746
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300747 for_each_connector_in_state(state, connector, connector_state, i) {
748 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200749 continue;
750
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300751 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200752 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200753 }
754
755 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
756 pipe_name(crtc->pipe));
757
758 BUG_ON(ret == NULL);
759 return ret;
760}
761
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100762#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100763#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100764
765#define P_MIN 2
766#define P_MAX 64
767#define P_INC 2
768
769/* Constraints for PLL good behavior */
770#define REF_MIN 48
771#define REF_MAX 400
772#define VCO_MIN 2400
773#define VCO_MAX 4800
774
Damien Lespiau27893392014-09-04 12:27:23 +0100775#define abs_diff(a, b) ({ \
776 typeof(a) __a = (a); \
777 typeof(b) __b = (b); \
778 (void) (&__a == &__b); \
779 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100780
Damien Lespiau63582982015-05-07 18:38:46 +0100781struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100782 unsigned p, n2, r2;
783};
784
Damien Lespiau63582982015-05-07 18:38:46 +0100785static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300786{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100787 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300788
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100789 switch (clock) {
790 case 25175000:
791 case 25200000:
792 case 27000000:
793 case 27027000:
794 case 37762500:
795 case 37800000:
796 case 40500000:
797 case 40541000:
798 case 54000000:
799 case 54054000:
800 case 59341000:
801 case 59400000:
802 case 72000000:
803 case 74176000:
804 case 74250000:
805 case 81000000:
806 case 81081000:
807 case 89012000:
808 case 89100000:
809 case 108000000:
810 case 108108000:
811 case 111264000:
812 case 111375000:
813 case 148352000:
814 case 148500000:
815 case 162000000:
816 case 162162000:
817 case 222525000:
818 case 222750000:
819 case 296703000:
820 case 297000000:
821 budget = 0;
822 break;
823 case 233500000:
824 case 245250000:
825 case 247750000:
826 case 253250000:
827 case 298000000:
828 budget = 1500;
829 break;
830 case 169128000:
831 case 169500000:
832 case 179500000:
833 case 202000000:
834 budget = 2000;
835 break;
836 case 256250000:
837 case 262500000:
838 case 270000000:
839 case 272500000:
840 case 273750000:
841 case 280750000:
842 case 281250000:
843 case 286000000:
844 case 291750000:
845 budget = 4000;
846 break;
847 case 267250000:
848 case 268500000:
849 budget = 5000;
850 break;
851 default:
852 budget = 1000;
853 break;
854 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300855
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100856 return budget;
857}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300858
Damien Lespiau63582982015-05-07 18:38:46 +0100859static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
860 unsigned r2, unsigned n2, unsigned p,
861 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100862{
863 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300864
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100865 /* No best (r,n,p) yet */
866 if (best->p == 0) {
867 best->p = p;
868 best->n2 = n2;
869 best->r2 = r2;
870 return;
871 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300872
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100873 /*
874 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
875 * freq2k.
876 *
877 * delta = 1e6 *
878 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
879 * freq2k;
880 *
881 * and we would like delta <= budget.
882 *
883 * If the discrepancy is above the PPM-based budget, always prefer to
884 * improve upon the previous solution. However, if you're within the
885 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
886 */
887 a = freq2k * budget * p * r2;
888 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100889 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
890 diff_best = abs_diff(freq2k * best->p * best->r2,
891 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100892 c = 1000000 * diff;
893 d = 1000000 * diff_best;
894
895 if (a < c && b < d) {
896 /* If both are above the budget, pick the closer */
897 if (best->p * best->r2 * diff < p * r2 * diff_best) {
898 best->p = p;
899 best->n2 = n2;
900 best->r2 = r2;
901 }
902 } else if (a >= c && b < d) {
903 /* If A is below the threshold but B is above it? Update. */
904 best->p = p;
905 best->n2 = n2;
906 best->r2 = r2;
907 } else if (a >= c && b >= d) {
908 /* Both are below the limit, so pick the higher n2/(r2*r2) */
909 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
910 best->p = p;
911 best->n2 = n2;
912 best->r2 = r2;
913 }
914 }
915 /* Otherwise a < c && b >= d, do nothing */
916}
917
Damien Lespiau63582982015-05-07 18:38:46 +0100918static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, int reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800919{
920 int refclk = LC_FREQ;
921 int n, p, r;
922 u32 wrpll;
923
924 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300925 switch (wrpll & WRPLL_PLL_REF_MASK) {
926 case WRPLL_PLL_SSC:
927 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800928 /*
929 * We could calculate spread here, but our checking
930 * code only cares about 5% accuracy, and spread is a max of
931 * 0.5% downspread.
932 */
933 refclk = 135;
934 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300935 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800936 refclk = LC_FREQ;
937 break;
938 default:
939 WARN(1, "bad wrpll refclk\n");
940 return 0;
941 }
942
943 r = wrpll & WRPLL_DIVIDER_REF_MASK;
944 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
945 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
946
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800947 /* Convert to KHz, p & r have a fixed point portion */
948 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800949}
950
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000951static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
952 uint32_t dpll)
953{
954 uint32_t cfgcr1_reg, cfgcr2_reg;
955 uint32_t cfgcr1_val, cfgcr2_val;
956 uint32_t p0, p1, p2, dco_freq;
957
958 cfgcr1_reg = GET_CFG_CR1_REG(dpll);
959 cfgcr2_reg = GET_CFG_CR2_REG(dpll);
960
961 cfgcr1_val = I915_READ(cfgcr1_reg);
962 cfgcr2_val = I915_READ(cfgcr2_reg);
963
964 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
965 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
966
967 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
968 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
969 else
970 p1 = 1;
971
972
973 switch (p0) {
974 case DPLL_CFGCR2_PDIV_1:
975 p0 = 1;
976 break;
977 case DPLL_CFGCR2_PDIV_2:
978 p0 = 2;
979 break;
980 case DPLL_CFGCR2_PDIV_3:
981 p0 = 3;
982 break;
983 case DPLL_CFGCR2_PDIV_7:
984 p0 = 7;
985 break;
986 }
987
988 switch (p2) {
989 case DPLL_CFGCR2_KDIV_5:
990 p2 = 5;
991 break;
992 case DPLL_CFGCR2_KDIV_2:
993 p2 = 2;
994 break;
995 case DPLL_CFGCR2_KDIV_3:
996 p2 = 3;
997 break;
998 case DPLL_CFGCR2_KDIV_1:
999 p2 = 1;
1000 break;
1001 }
1002
1003 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1004
1005 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1006 1000) / 0x8000;
1007
1008 return dco_freq / (p0 * p1 * p2 * 5);
1009}
1010
Ville Syrjälä398a0172015-06-30 15:33:51 +03001011static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1012{
1013 int dotclock;
1014
1015 if (pipe_config->has_pch_encoder)
1016 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1017 &pipe_config->fdi_m_n);
1018 else if (pipe_config->has_dp_encoder)
1019 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1020 &pipe_config->dp_m_n);
1021 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1022 dotclock = pipe_config->port_clock * 2 / 3;
1023 else
1024 dotclock = pipe_config->port_clock;
1025
1026 if (pipe_config->pixel_multiplier)
1027 dotclock /= pipe_config->pixel_multiplier;
1028
1029 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1030}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001031
1032static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001033 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001034{
1035 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001036 int link_clock = 0;
1037 uint32_t dpll_ctl1, dpll;
1038
Damien Lespiau134ffa42014-11-14 17:24:34 +00001039 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001040
1041 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1042
1043 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1044 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1045 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001046 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1047 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001048
1049 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001050 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001051 link_clock = 81000;
1052 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001053 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301054 link_clock = 108000;
1055 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001056 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001057 link_clock = 135000;
1058 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001059 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301060 link_clock = 162000;
1061 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001062 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301063 link_clock = 216000;
1064 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001065 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001066 link_clock = 270000;
1067 break;
1068 default:
1069 WARN(1, "Unsupported link rate\n");
1070 break;
1071 }
1072 link_clock *= 2;
1073 }
1074
1075 pipe_config->port_clock = link_clock;
1076
Ville Syrjälä398a0172015-06-30 15:33:51 +03001077 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001078}
1079
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001080static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001081 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001082{
1083 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001084 int link_clock = 0;
1085 u32 val, pll;
1086
Daniel Vetter26804af2014-06-25 22:01:55 +03001087 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001088 switch (val & PORT_CLK_SEL_MASK) {
1089 case PORT_CLK_SEL_LCPLL_810:
1090 link_clock = 81000;
1091 break;
1092 case PORT_CLK_SEL_LCPLL_1350:
1093 link_clock = 135000;
1094 break;
1095 case PORT_CLK_SEL_LCPLL_2700:
1096 link_clock = 270000;
1097 break;
1098 case PORT_CLK_SEL_WRPLL1:
Damien Lespiau63582982015-05-07 18:38:46 +01001099 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL1);
Jesse Barnes11578552014-01-21 12:42:10 -08001100 break;
1101 case PORT_CLK_SEL_WRPLL2:
Damien Lespiau63582982015-05-07 18:38:46 +01001102 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL2);
Jesse Barnes11578552014-01-21 12:42:10 -08001103 break;
1104 case PORT_CLK_SEL_SPLL:
1105 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1106 if (pll == SPLL_PLL_FREQ_810MHz)
1107 link_clock = 81000;
1108 else if (pll == SPLL_PLL_FREQ_1350MHz)
1109 link_clock = 135000;
1110 else if (pll == SPLL_PLL_FREQ_2700MHz)
1111 link_clock = 270000;
1112 else {
1113 WARN(1, "bad spll freq\n");
1114 return;
1115 }
1116 break;
1117 default:
1118 WARN(1, "bad port clock sel\n");
1119 return;
1120 }
1121
1122 pipe_config->port_clock = link_clock * 2;
1123
Ville Syrjälä398a0172015-06-30 15:33:51 +03001124 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001125}
1126
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301127static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1128 enum intel_dpll_id dpll)
1129{
Imre Deakaa610dc2015-06-22 23:35:52 +03001130 struct intel_shared_dpll *pll;
1131 struct intel_dpll_hw_state *state;
1132 intel_clock_t clock;
1133
1134 /* For DDI ports we always use a shared PLL. */
1135 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1136 return 0;
1137
1138 pll = &dev_priv->shared_dplls[dpll];
1139 state = &pll->config.hw_state;
1140
1141 clock.m1 = 2;
1142 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1143 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1144 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1145 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1146 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1147 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1148
1149 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301150}
1151
1152static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1153 struct intel_crtc_state *pipe_config)
1154{
1155 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1156 enum port port = intel_ddi_get_encoder_port(encoder);
1157 uint32_t dpll = port;
1158
Ville Syrjälä398a0172015-06-30 15:33:51 +03001159 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301160
Ville Syrjälä398a0172015-06-30 15:33:51 +03001161 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301162}
1163
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001164void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001165 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001166{
Damien Lespiau22606a12014-12-12 14:26:57 +00001167 struct drm_device *dev = encoder->base.dev;
1168
1169 if (INTEL_INFO(dev)->gen <= 8)
1170 hsw_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301171 else if (IS_SKYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001172 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301173 else if (IS_BROXTON(dev))
1174 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001175}
1176
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001177static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001178hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1179 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001180{
1181 uint64_t freq2k;
1182 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001183 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001184 unsigned budget;
1185
1186 freq2k = clock / 100;
1187
Damien Lespiau63582982015-05-07 18:38:46 +01001188 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001189
1190 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1191 * and directly pass the LC PLL to it. */
1192 if (freq2k == 5400000) {
1193 *n2_out = 2;
1194 *p_out = 1;
1195 *r2_out = 2;
1196 return;
1197 }
1198
1199 /*
1200 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1201 * the WR PLL.
1202 *
1203 * We want R so that REF_MIN <= Ref <= REF_MAX.
1204 * Injecting R2 = 2 * R gives:
1205 * REF_MAX * r2 > LC_FREQ * 2 and
1206 * REF_MIN * r2 < LC_FREQ * 2
1207 *
1208 * Which means the desired boundaries for r2 are:
1209 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1210 *
1211 */
1212 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1213 r2 <= LC_FREQ * 2 / REF_MIN;
1214 r2++) {
1215
1216 /*
1217 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1218 *
1219 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1220 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1221 * VCO_MAX * r2 > n2 * LC_FREQ and
1222 * VCO_MIN * r2 < n2 * LC_FREQ)
1223 *
1224 * Which means the desired boundaries for n2 are:
1225 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1226 */
1227 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1228 n2 <= VCO_MAX * r2 / LC_FREQ;
1229 n2++) {
1230
1231 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001232 hsw_wrpll_update_rnp(freq2k, budget,
1233 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001234 }
1235 }
1236
1237 *n2_out = best.n2;
1238 *p_out = best.p;
1239 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001240}
1241
Damien Lespiau0220ab62014-07-29 18:06:22 +01001242static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001243hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001244 struct intel_crtc_state *crtc_state,
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001245 struct intel_encoder *intel_encoder,
1246 int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001247{
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,
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001526 struct intel_encoder *intel_encoder,
1527 int clock)
1528{
1529 struct intel_shared_dpll *pll;
1530 uint32_t ctrl1, cfgcr1, cfgcr2;
1531
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) {
1557 struct drm_encoder *encoder = &intel_encoder->base;
1558 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1559
1560 switch (intel_dp->link_bw) {
1561 case DP_LINK_BW_1_62:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001562 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001563 break;
1564 case DP_LINK_BW_2_7:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001565 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001566 break;
1567 case DP_LINK_BW_5_4:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001568 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001569 break;
1570 }
1571
1572 cfgcr1 = cfgcr2 = 0;
1573 } else /* eDP */
1574 return true;
1575
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001576 memset(&crtc_state->dpll_hw_state, 0,
1577 sizeof(crtc_state->dpll_hw_state));
1578
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001579 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1580 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1581 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001582
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001583 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001584 if (pll == NULL) {
1585 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1586 pipe_name(intel_crtc->pipe));
1587 return false;
1588 }
1589
1590 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001591 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001592
1593 return true;
1594}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001595
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301596/* bxt clock parameters */
1597struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301598 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301599 uint32_t p1;
1600 uint32_t p2;
1601 uint32_t m2_int;
1602 uint32_t m2_frac;
1603 bool m2_frac_en;
1604 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301605};
1606
1607/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301608static const struct bxt_clk_div bxt_dp_clk_val[] = {
1609 {162000, 4, 2, 32, 1677722, 1, 1},
1610 {270000, 4, 1, 27, 0, 0, 1},
1611 {540000, 2, 1, 27, 0, 0, 1},
1612 {216000, 3, 2, 32, 1677722, 1, 1},
1613 {243000, 4, 1, 24, 1258291, 1, 1},
1614 {324000, 4, 1, 32, 1677722, 1, 1},
1615 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301616};
1617
1618static bool
1619bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1620 struct intel_crtc_state *crtc_state,
1621 struct intel_encoder *intel_encoder,
1622 int clock)
1623{
1624 struct intel_shared_dpll *pll;
1625 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301626 int vco = 0;
1627 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301628 uint32_t lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301629
1630 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1631 intel_clock_t best_clock;
1632
1633 /* Calculate HDMI div */
1634 /*
1635 * FIXME: tie the following calculation into
1636 * i9xx_crtc_compute_clock
1637 */
1638 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1639 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1640 clock, pipe_name(intel_crtc->pipe));
1641 return false;
1642 }
1643
1644 clk_div.p1 = best_clock.p1;
1645 clk_div.p2 = best_clock.p2;
1646 WARN_ON(best_clock.m1 != 2);
1647 clk_div.n = best_clock.n;
1648 clk_div.m2_int = best_clock.m2 >> 22;
1649 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1650 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1651
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301652 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301653 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1654 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301655 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301656
Sonika Jindal64987fc2015-05-26 17:50:13 +05301657 clk_div = bxt_dp_clk_val[0];
1658 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1659 if (bxt_dp_clk_val[i].clock == clock) {
1660 clk_div = bxt_dp_clk_val[i];
1661 break;
1662 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301663 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301664 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1665 }
1666
Vandana Kannane6292552015-07-01 17:02:57 +05301667 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301668 prop_coef = 4;
1669 int_coef = 9;
1670 gain_ctl = 3;
1671 targ_cnt = 8;
1672 } else if ((vco > 5400000 && vco < 6200000) ||
1673 (vco >= 4800000 && vco < 5400000)) {
1674 prop_coef = 5;
1675 int_coef = 11;
1676 gain_ctl = 3;
1677 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301678 } else if (vco == 5400000) {
1679 prop_coef = 3;
1680 int_coef = 8;
1681 gain_ctl = 1;
1682 targ_cnt = 9;
1683 } else {
1684 DRM_ERROR("Invalid VCO\n");
1685 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301686 }
1687
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001688 memset(&crtc_state->dpll_hw_state, 0,
1689 sizeof(crtc_state->dpll_hw_state));
1690
Vandana Kannane0681e32015-05-13 12:20:35 +05301691 if (clock > 270000)
1692 lanestagger = 0x18;
1693 else if (clock > 135000)
1694 lanestagger = 0x0d;
1695 else if (clock > 67000)
1696 lanestagger = 0x07;
1697 else if (clock > 33000)
1698 lanestagger = 0x04;
1699 else
1700 lanestagger = 0x02;
1701
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301702 crtc_state->dpll_hw_state.ebb0 =
1703 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1704 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1705 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1706 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1707
1708 if (clk_div.m2_frac_en)
1709 crtc_state->dpll_hw_state.pll3 =
1710 PORT_PLL_M2_FRAC_ENABLE;
1711
1712 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301713 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301714 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301715 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301716
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301717 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1718
Imre Deak05712c12015-06-18 17:25:54 +03001719 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1720
Vandana Kannane6292552015-07-01 17:02:57 +05301721 crtc_state->dpll_hw_state.pll10 =
1722 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1723 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301724
Imre Deak05712c12015-06-18 17:25:54 +03001725 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1726
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301727 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301728 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301729
1730 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1731 if (pll == NULL) {
1732 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1733 pipe_name(intel_crtc->pipe));
1734 return false;
1735 }
1736
1737 /* shared DPLL id 0 is DPLL A */
1738 crtc_state->ddi_pll_sel = pll->id;
1739
1740 return true;
1741}
1742
Damien Lespiau0220ab62014-07-29 18:06:22 +01001743/*
1744 * Tries to find a *shared* PLL for the CRTC and store it in
1745 * intel_crtc->ddi_pll_sel.
1746 *
1747 * For private DPLLs, compute_config() should do the selection for us. This
1748 * function should be folded into compute_config() eventually.
1749 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001750bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1751 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001752{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001753 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001754 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001755 intel_ddi_get_crtc_new_encoder(crtc_state);
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001756 int clock = crtc_state->port_clock;
Damien Lespiau0220ab62014-07-29 18:06:22 +01001757
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001758 if (IS_SKYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001759 return skl_ddi_pll_select(intel_crtc, crtc_state,
1760 intel_encoder, clock);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301761 else if (IS_BROXTON(dev))
1762 return bxt_ddi_pll_select(intel_crtc, crtc_state,
1763 intel_encoder, clock);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001764 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001765 return hsw_ddi_pll_select(intel_crtc, crtc_state,
1766 intel_encoder, clock);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001767}
1768
Paulo Zanonidae84792012-10-15 15:51:30 -03001769void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1770{
1771 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1772 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1773 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001774 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001775 int type = intel_encoder->type;
1776 uint32_t temp;
1777
Dave Airlie0e32b392014-05-02 14:02:48 +10001778 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001779 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001780 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001781 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001782 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001783 break;
1784 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001785 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001786 break;
1787 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001788 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001789 break;
1790 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001791 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001792 break;
1793 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001794 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001795 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001796 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001797 }
1798}
1799
Dave Airlie0e32b392014-05-02 14:02:48 +10001800void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1801{
1802 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1803 struct drm_device *dev = crtc->dev;
1804 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001805 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001806 uint32_t temp;
1807 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1808 if (state == true)
1809 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1810 else
1811 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1812 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1813}
1814
Damien Lespiau8228c252013-03-07 15:30:27 +00001815void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001816{
1817 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1818 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001819 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001820 struct drm_device *dev = crtc->dev;
1821 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001822 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001823 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001824 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001825 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001826 uint32_t temp;
1827
Paulo Zanoniad80a812012-10-24 16:06:19 -02001828 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1829 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001830 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001831
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001832 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001833 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001834 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001835 break;
1836 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001837 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001838 break;
1839 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001840 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001841 break;
1842 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001843 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001844 break;
1845 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001846 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001847 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001848
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001849 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001850 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001851 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001852 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001853
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001854 if (cpu_transcoder == TRANSCODER_EDP) {
1855 switch (pipe) {
1856 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001857 /* On Haswell, can only use the always-on power well for
1858 * eDP when not using the panel fitter, and when not
1859 * using motion blur mitigation (which we don't
1860 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001861 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001862 (intel_crtc->config->pch_pfit.enabled ||
1863 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001864 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1865 else
1866 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001867 break;
1868 case PIPE_B:
1869 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1870 break;
1871 case PIPE_C:
1872 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1873 break;
1874 default:
1875 BUG();
1876 break;
1877 }
1878 }
1879
Paulo Zanoni7739c332012-10-15 15:51:29 -03001880 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001881 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001882 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001883 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001884 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001885
Paulo Zanoni7739c332012-10-15 15:51:29 -03001886 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001887 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001888 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001889
1890 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1891 type == INTEL_OUTPUT_EDP) {
1892 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1893
Dave Airlie0e32b392014-05-02 14:02:48 +10001894 if (intel_dp->is_mst) {
1895 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1896 } else
1897 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1898
1899 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
1900 } else if (type == INTEL_OUTPUT_DP_MST) {
1901 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1902
1903 if (intel_dp->is_mst) {
1904 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1905 } else
1906 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001907
Daniel Vetter17aa6be2013-04-30 14:01:40 +02001908 temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001909 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001910 WARN(1, "Invalid encoder type %d for pipe %c\n",
1911 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001912 }
1913
Paulo Zanoniad80a812012-10-24 16:06:19 -02001914 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001915}
1916
Paulo Zanoniad80a812012-10-24 16:06:19 -02001917void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1918 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001919{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001920 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001921 uint32_t val = I915_READ(reg);
1922
Dave Airlie0e32b392014-05-02 14:02:48 +10001923 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001924 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001925 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001926}
1927
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001928bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1929{
1930 struct drm_device *dev = intel_connector->base.dev;
1931 struct drm_i915_private *dev_priv = dev->dev_private;
1932 struct intel_encoder *intel_encoder = intel_connector->encoder;
1933 int type = intel_connector->base.connector_type;
1934 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1935 enum pipe pipe = 0;
1936 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001937 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001938 uint32_t tmp;
1939
Paulo Zanoni882244a2014-04-01 14:55:12 -03001940 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001941 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001942 return false;
1943
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001944 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1945 return false;
1946
1947 if (port == PORT_A)
1948 cpu_transcoder = TRANSCODER_EDP;
1949 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001950 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001951
1952 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1953
1954 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1955 case TRANS_DDI_MODE_SELECT_HDMI:
1956 case TRANS_DDI_MODE_SELECT_DVI:
1957 return (type == DRM_MODE_CONNECTOR_HDMIA);
1958
1959 case TRANS_DDI_MODE_SELECT_DP_SST:
1960 if (type == DRM_MODE_CONNECTOR_eDP)
1961 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001962 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001963 case TRANS_DDI_MODE_SELECT_DP_MST:
1964 /* if the transcoder is in MST state then
1965 * connector isn't connected */
1966 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001967
1968 case TRANS_DDI_MODE_SELECT_FDI:
1969 return (type == DRM_MODE_CONNECTOR_VGA);
1970
1971 default:
1972 return false;
1973 }
1974}
1975
Daniel Vetter85234cd2012-07-02 13:27:29 +02001976bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1977 enum pipe *pipe)
1978{
1979 struct drm_device *dev = encoder->base.dev;
1980 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001981 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001982 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001983 u32 tmp;
1984 int i;
1985
Imre Deak6d129be2014-03-05 16:20:54 +02001986 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001987 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02001988 return false;
1989
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001990 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001991
1992 if (!(tmp & DDI_BUF_CTL_ENABLE))
1993 return false;
1994
Paulo Zanoniad80a812012-10-24 16:06:19 -02001995 if (port == PORT_A) {
1996 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001997
Paulo Zanoniad80a812012-10-24 16:06:19 -02001998 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
1999 case TRANS_DDI_EDP_INPUT_A_ON:
2000 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2001 *pipe = PIPE_A;
2002 break;
2003 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2004 *pipe = PIPE_B;
2005 break;
2006 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2007 *pipe = PIPE_C;
2008 break;
2009 }
2010
2011 return true;
2012 } else {
2013 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2014 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2015
2016 if ((tmp & TRANS_DDI_PORT_MASK)
2017 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002018 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2019 return false;
2020
Paulo Zanoniad80a812012-10-24 16:06:19 -02002021 *pipe = i;
2022 return true;
2023 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002024 }
2025 }
2026
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002027 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002028
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002029 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002030}
2031
Paulo Zanonifc914632012-10-05 12:05:54 -03002032void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2033{
2034 struct drm_crtc *crtc = &intel_crtc->base;
2035 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2036 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2037 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002038 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002039
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002040 if (cpu_transcoder != TRANSCODER_EDP)
2041 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2042 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002043}
2044
2045void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2046{
2047 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002048 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002049
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002050 if (cpu_transcoder != TRANSCODER_EDP)
2051 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2052 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002053}
2054
David Weinehallf8896f52015-06-25 11:11:03 +03002055static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2056 enum port port, int type)
2057{
2058 struct drm_i915_private *dev_priv = dev->dev_private;
2059 const struct ddi_buf_trans *ddi_translations;
2060 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002061 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002062 int n_entries;
2063 u32 reg;
2064
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002065 /* VBT may override standard boost values */
2066 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2067 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2068
David Weinehallf8896f52015-06-25 11:11:03 +03002069 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002070 if (dp_iboost) {
2071 iboost = dp_iboost;
2072 } else {
2073 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2074 iboost = ddi_translations[port].i_boost;
2075 }
David Weinehallf8896f52015-06-25 11:11:03 +03002076 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002077 if (dp_iboost) {
2078 iboost = dp_iboost;
2079 } else {
2080 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2081 iboost = ddi_translations[port].i_boost;
2082 }
David Weinehallf8896f52015-06-25 11:11:03 +03002083 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002084 if (hdmi_iboost) {
2085 iboost = hdmi_iboost;
2086 } else {
2087 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2088 iboost = ddi_translations[port].i_boost;
2089 }
David Weinehallf8896f52015-06-25 11:11:03 +03002090 } else {
2091 return;
2092 }
2093
2094 /* Make sure that the requested I_boost is valid */
2095 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2096 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2097 return;
2098 }
2099
2100 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2101 reg &= ~BALANCE_LEG_MASK(port);
2102 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2103
2104 if (iboost)
2105 reg |= iboost << BALANCE_LEG_SHIFT(port);
2106 else
2107 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2108
2109 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2110}
2111
2112static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2113 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302114{
2115 struct drm_i915_private *dev_priv = dev->dev_private;
2116 const struct bxt_ddi_buf_trans *ddi_translations;
2117 u32 n_entries, i;
2118 uint32_t val;
2119
2120 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
2121 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2122 ddi_translations = bxt_ddi_translations_dp;
2123 } else if (type == INTEL_OUTPUT_HDMI) {
2124 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2125 ddi_translations = bxt_ddi_translations_hdmi;
2126 } else {
2127 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2128 type);
2129 return;
2130 }
2131
2132 /* Check if default value has to be used */
2133 if (level >= n_entries ||
2134 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2135 for (i = 0; i < n_entries; i++) {
2136 if (ddi_translations[i].default_index) {
2137 level = i;
2138 break;
2139 }
2140 }
2141 }
2142
2143 /*
2144 * While we write to the group register to program all lanes at once we
2145 * can read only lane registers and we pick lanes 0/1 for that.
2146 */
2147 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2148 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2149 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2150
2151 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2152 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2153 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2154 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2155 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2156
2157 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
2158 val &= ~UNIQE_TRANGE_EN_METHOD;
2159 if (ddi_translations[level].enable)
2160 val |= UNIQE_TRANGE_EN_METHOD;
2161 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2162
2163 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2164 val &= ~DE_EMPHASIS;
2165 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2166 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2167
2168 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2169 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2170 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2171}
2172
David Weinehallf8896f52015-06-25 11:11:03 +03002173static uint32_t translate_signal_level(int signal_levels)
2174{
2175 uint32_t level;
2176
2177 switch (signal_levels) {
2178 default:
2179 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2180 signal_levels);
2181 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2182 level = 0;
2183 break;
2184 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2185 level = 1;
2186 break;
2187 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2188 level = 2;
2189 break;
2190 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2191 level = 3;
2192 break;
2193
2194 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2195 level = 4;
2196 break;
2197 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2198 level = 5;
2199 break;
2200 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2201 level = 6;
2202 break;
2203
2204 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2205 level = 7;
2206 break;
2207 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2208 level = 8;
2209 break;
2210
2211 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2212 level = 9;
2213 break;
2214 }
2215
2216 return level;
2217}
2218
2219uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2220{
2221 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2222 struct drm_device *dev = dport->base.base.dev;
2223 struct intel_encoder *encoder = &dport->base;
2224 uint8_t train_set = intel_dp->train_set[0];
2225 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2226 DP_TRAIN_PRE_EMPHASIS_MASK);
2227 enum port port = dport->port;
2228 uint32_t level;
2229
2230 level = translate_signal_level(signal_levels);
2231
2232 if (IS_SKYLAKE(dev))
2233 skl_ddi_set_iboost(dev, level, port, encoder->type);
2234 else if (IS_BROXTON(dev))
2235 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2236
2237 return DDI_BUF_TRANS_SELECT(level);
2238}
2239
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002240static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002241{
Paulo Zanonic19b0662012-10-15 15:51:41 -03002242 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002243 struct drm_device *dev = encoder->dev;
2244 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002245 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002246 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002247 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302248 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002249
2250 if (type == INTEL_OUTPUT_EDP) {
2251 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01002252 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002253 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002254
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002255 if (IS_SKYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002256 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002257 uint32_t val;
2258
Damien Lespiau5416d872014-11-14 17:24:33 +00002259 /*
2260 * DPLL0 is used for eDP and is the only "private" DPLL (as
2261 * opposed to shared) on SKL
2262 */
2263 if (type == INTEL_OUTPUT_EDP) {
2264 WARN_ON(dpll != SKL_DPLL0);
2265
2266 val = I915_READ(DPLL_CTRL1);
2267
2268 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2269 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002270 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002271 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002272
2273 I915_WRITE(DPLL_CTRL1, val);
2274 POSTING_READ(DPLL_CTRL1);
2275 }
2276
2277 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002278 val = I915_READ(DPLL_CTRL2);
2279
2280 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2281 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2282 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2283 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2284
2285 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002286
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302287 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002288 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2289 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002290 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002291
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002292 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002293 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002294
Dave Airlie44905a272014-05-02 13:36:43 +10002295 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002296
2297 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2298 intel_dp_start_link_train(intel_dp);
2299 intel_dp_complete_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002300 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002301 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002302 } else if (type == INTEL_OUTPUT_HDMI) {
2303 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2304
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302305 if (IS_BROXTON(dev)) {
2306 hdmi_level = dev_priv->vbt.
2307 ddi_port_info[port].hdmi_level_shift;
2308 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2309 INTEL_OUTPUT_HDMI);
2310 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002311 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002312 crtc->config->has_hdmi_sink,
2313 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002314 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002315}
2316
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002317static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002318{
2319 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002320 struct drm_device *dev = encoder->dev;
2321 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002322 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002323 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002324 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002325 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002326
2327 val = I915_READ(DDI_BUF_CTL(port));
2328 if (val & DDI_BUF_CTL_ENABLE) {
2329 val &= ~DDI_BUF_CTL_ENABLE;
2330 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002331 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002332 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002333
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002334 val = I915_READ(DP_TP_CTL(port));
2335 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2336 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2337 I915_WRITE(DP_TP_CTL(port), val);
2338
2339 if (wait)
2340 intel_wait_ddi_buf_idle(dev_priv, port);
2341
Jani Nikula76bb80e2013-11-15 15:29:57 +02002342 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002343 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002344 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002345 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002346 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002347 }
2348
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002349 if (IS_SKYLAKE(dev))
2350 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2351 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302352 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002353 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002354}
2355
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002356static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002357{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002358 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002359 struct drm_crtc *crtc = encoder->crtc;
2360 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002361 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002362 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002363 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2364 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002365
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002366 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002367 struct intel_digital_port *intel_dig_port =
2368 enc_to_dig_port(encoder);
2369
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002370 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2371 * are ignored so nothing special needs to be done besides
2372 * enabling the port.
2373 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002374 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002375 intel_dig_port->saved_port_bits |
2376 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002377 } else if (type == INTEL_OUTPUT_EDP) {
2378 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2379
Vandana Kannan23f08d82014-11-13 14:55:22 +00002380 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002381 intel_dp_stop_link_train(intel_dp);
2382
Daniel Vetter4be73782014-01-17 14:39:48 +01002383 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002384 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302385 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002386 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002387
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002388 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002389 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002390 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002391 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002392}
2393
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002394static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002395{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002396 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002397 struct drm_crtc *crtc = encoder->crtc;
2398 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002399 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002400 struct drm_device *dev = encoder->dev;
2401 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002402
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002403 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002404 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002405 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2406 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002407
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002408 if (type == INTEL_OUTPUT_EDP) {
2409 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2410
Vandana Kannanc3955782015-01-22 15:17:40 +05302411 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002412 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002413 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002414 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002415}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002416
Daniel Vettere0b01be2014-06-25 22:02:01 +03002417static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2418 struct intel_shared_dpll *pll)
2419{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002420 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002421 POSTING_READ(WRPLL_CTL(pll->id));
2422 udelay(20);
2423}
2424
Daniel Vetter12030432014-06-25 22:02:00 +03002425static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2426 struct intel_shared_dpll *pll)
2427{
2428 uint32_t val;
2429
2430 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002431 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2432 POSTING_READ(WRPLL_CTL(pll->id));
2433}
2434
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002435static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2436 struct intel_shared_dpll *pll,
2437 struct intel_dpll_hw_state *hw_state)
2438{
2439 uint32_t val;
2440
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002441 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002442 return false;
2443
2444 val = I915_READ(WRPLL_CTL(pll->id));
2445 hw_state->wrpll = val;
2446
2447 return val & WRPLL_PLL_ENABLE;
2448}
2449
Damien Lespiauca1381b2014-07-15 15:05:33 +01002450static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002451 "WRPLL 1",
2452 "WRPLL 2",
2453};
2454
Damien Lespiau143b3072014-07-29 18:06:19 +01002455static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002456{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002457 int i;
2458
Daniel Vetter716c2e52014-06-25 22:02:02 +03002459 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002460
Daniel Vetter716c2e52014-06-25 22:02:02 +03002461 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002462 dev_priv->shared_dplls[i].id = i;
2463 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002464 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002465 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002466 dev_priv->shared_dplls[i].get_hw_state =
2467 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002468 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002469}
2470
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002471static const char * const skl_ddi_pll_names[] = {
2472 "DPLL 1",
2473 "DPLL 2",
2474 "DPLL 3",
2475};
2476
2477struct skl_dpll_regs {
2478 u32 ctl, cfgcr1, cfgcr2;
2479};
2480
2481/* this array is indexed by the *shared* pll id */
2482static const struct skl_dpll_regs skl_dpll_regs[3] = {
2483 {
2484 /* DPLL 1 */
2485 .ctl = LCPLL2_CTL,
2486 .cfgcr1 = DPLL1_CFGCR1,
2487 .cfgcr2 = DPLL1_CFGCR2,
2488 },
2489 {
2490 /* DPLL 2 */
2491 .ctl = WRPLL_CTL1,
2492 .cfgcr1 = DPLL2_CFGCR1,
2493 .cfgcr2 = DPLL2_CFGCR2,
2494 },
2495 {
2496 /* DPLL 3 */
2497 .ctl = WRPLL_CTL2,
2498 .cfgcr1 = DPLL3_CFGCR1,
2499 .cfgcr2 = DPLL3_CFGCR2,
2500 },
2501};
2502
2503static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2504 struct intel_shared_dpll *pll)
2505{
2506 uint32_t val;
2507 unsigned int dpll;
2508 const struct skl_dpll_regs *regs = skl_dpll_regs;
2509
2510 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2511 dpll = pll->id + 1;
2512
2513 val = I915_READ(DPLL_CTRL1);
2514
2515 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002516 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002517 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2518
2519 I915_WRITE(DPLL_CTRL1, val);
2520 POSTING_READ(DPLL_CTRL1);
2521
2522 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2523 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2524 POSTING_READ(regs[pll->id].cfgcr1);
2525 POSTING_READ(regs[pll->id].cfgcr2);
2526
2527 /* the enable bit is always bit 31 */
2528 I915_WRITE(regs[pll->id].ctl,
2529 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2530
2531 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2532 DRM_ERROR("DPLL %d not locked\n", dpll);
2533}
2534
2535static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2536 struct intel_shared_dpll *pll)
2537{
2538 const struct skl_dpll_regs *regs = skl_dpll_regs;
2539
2540 /* the enable bit is always bit 31 */
2541 I915_WRITE(regs[pll->id].ctl,
2542 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2543 POSTING_READ(regs[pll->id].ctl);
2544}
2545
2546static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2547 struct intel_shared_dpll *pll,
2548 struct intel_dpll_hw_state *hw_state)
2549{
2550 uint32_t val;
2551 unsigned int dpll;
2552 const struct skl_dpll_regs *regs = skl_dpll_regs;
2553
2554 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2555 return false;
2556
2557 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2558 dpll = pll->id + 1;
2559
2560 val = I915_READ(regs[pll->id].ctl);
2561 if (!(val & LCPLL_PLL_ENABLE))
2562 return false;
2563
2564 val = I915_READ(DPLL_CTRL1);
2565 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2566
2567 /* avoid reading back stale values if HDMI mode is not enabled */
2568 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2569 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2570 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2571 }
2572
2573 return true;
2574}
2575
2576static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2577{
2578 int i;
2579
2580 dev_priv->num_shared_dpll = 3;
2581
2582 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2583 dev_priv->shared_dplls[i].id = i;
2584 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2585 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2586 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2587 dev_priv->shared_dplls[i].get_hw_state =
2588 skl_ddi_pll_get_hw_state;
2589 }
2590}
2591
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302592static void broxton_phy_init(struct drm_i915_private *dev_priv,
2593 enum dpio_phy phy)
2594{
2595 enum port port;
2596 uint32_t val;
2597
2598 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2599 val |= GT_DISPLAY_POWER_ON(phy);
2600 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2601
2602 /* Considering 10ms timeout until BSpec is updated */
2603 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2604 DRM_ERROR("timeout during PHY%d power on\n", phy);
2605
2606 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2607 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2608 int lane;
2609
2610 for (lane = 0; lane < 4; lane++) {
2611 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2612 /*
2613 * Note that on CHV this flag is called UPAR, but has
2614 * the same function.
2615 */
2616 val &= ~LATENCY_OPTIM;
2617 if (lane != 1)
2618 val |= LATENCY_OPTIM;
2619
2620 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2621 }
2622 }
2623
2624 /* Program PLL Rcomp code offset */
2625 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2626 val &= ~IREF0RC_OFFSET_MASK;
2627 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2628 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2629
2630 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2631 val &= ~IREF1RC_OFFSET_MASK;
2632 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2633 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2634
2635 /* Program power gating */
2636 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2637 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2638 SUS_CLK_CONFIG;
2639 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2640
2641 if (phy == DPIO_PHY0) {
2642 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2643 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2644 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2645 }
2646
2647 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2648 val &= ~OCL2_LDOFUSE_PWR_DIS;
2649 /*
2650 * On PHY1 disable power on the second channel, since no port is
2651 * connected there. On PHY0 both channels have a port, so leave it
2652 * enabled.
2653 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2654 * power down the second channel on PHY0 as well.
2655 */
2656 if (phy == DPIO_PHY1)
2657 val |= OCL2_LDOFUSE_PWR_DIS;
2658 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2659
2660 if (phy == DPIO_PHY0) {
2661 uint32_t grc_code;
2662 /*
2663 * PHY0 isn't connected to an RCOMP resistor so copy over
2664 * the corresponding calibrated value from PHY1, and disable
2665 * the automatic calibration on PHY0.
2666 */
2667 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2668 10))
2669 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2670
2671 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2672 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2673 grc_code = val << GRC_CODE_FAST_SHIFT |
2674 val << GRC_CODE_SLOW_SHIFT |
2675 val;
2676 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2677
2678 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2679 val |= GRC_DIS | GRC_RDY_OVRD;
2680 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2681 }
2682
2683 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2684 val |= COMMON_RESET_DIS;
2685 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2686}
2687
2688void broxton_ddi_phy_init(struct drm_device *dev)
2689{
2690 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2691 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2692 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2693}
2694
2695static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2696 enum dpio_phy phy)
2697{
2698 uint32_t val;
2699
2700 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2701 val &= ~COMMON_RESET_DIS;
2702 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2703}
2704
2705void broxton_ddi_phy_uninit(struct drm_device *dev)
2706{
2707 struct drm_i915_private *dev_priv = dev->dev_private;
2708
2709 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2710 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2711
2712 /* FIXME: do this in broxton_phy_uninit per phy */
2713 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2714}
2715
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302716static const char * const bxt_ddi_pll_names[] = {
2717 "PORT PLL A",
2718 "PORT PLL B",
2719 "PORT PLL C",
2720};
2721
2722static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2723 struct intel_shared_dpll *pll)
2724{
2725 uint32_t temp;
2726 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2727
2728 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2729 temp &= ~PORT_PLL_REF_SEL;
2730 /* Non-SSC reference */
2731 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2732
2733 /* Disable 10 bit clock */
2734 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2735 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2736 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2737
2738 /* Write P1 & P2 */
2739 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2740 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2741 temp |= pll->config.hw_state.ebb0;
2742 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2743
2744 /* Write M2 integer */
2745 temp = I915_READ(BXT_PORT_PLL(port, 0));
2746 temp &= ~PORT_PLL_M2_MASK;
2747 temp |= pll->config.hw_state.pll0;
2748 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2749
2750 /* Write N */
2751 temp = I915_READ(BXT_PORT_PLL(port, 1));
2752 temp &= ~PORT_PLL_N_MASK;
2753 temp |= pll->config.hw_state.pll1;
2754 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2755
2756 /* Write M2 fraction */
2757 temp = I915_READ(BXT_PORT_PLL(port, 2));
2758 temp &= ~PORT_PLL_M2_FRAC_MASK;
2759 temp |= pll->config.hw_state.pll2;
2760 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2761
2762 /* Write M2 fraction enable */
2763 temp = I915_READ(BXT_PORT_PLL(port, 3));
2764 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2765 temp |= pll->config.hw_state.pll3;
2766 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2767
2768 /* Write coeff */
2769 temp = I915_READ(BXT_PORT_PLL(port, 6));
2770 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2771 temp &= ~PORT_PLL_INT_COEFF_MASK;
2772 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2773 temp |= pll->config.hw_state.pll6;
2774 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2775
2776 /* Write calibration val */
2777 temp = I915_READ(BXT_PORT_PLL(port, 8));
2778 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2779 temp |= pll->config.hw_state.pll8;
2780 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2781
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302782 temp = I915_READ(BXT_PORT_PLL(port, 9));
2783 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002784 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302785 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2786
2787 temp = I915_READ(BXT_PORT_PLL(port, 10));
2788 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2789 temp &= ~PORT_PLL_DCO_AMP_MASK;
2790 temp |= pll->config.hw_state.pll10;
2791 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302792
2793 /* Recalibrate with new settings */
2794 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2795 temp |= PORT_PLL_RECALIBRATE;
2796 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002797 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2798 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302799 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2800
2801 /* Enable PLL */
2802 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2803 temp |= PORT_PLL_ENABLE;
2804 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2805 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2806
2807 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2808 PORT_PLL_LOCK), 200))
2809 DRM_ERROR("PLL %d not locked\n", port);
2810
2811 /*
2812 * While we write to the group register to program all lanes at once we
2813 * can read only lane registers and we pick lanes 0/1 for that.
2814 */
2815 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2816 temp &= ~LANE_STAGGER_MASK;
2817 temp &= ~LANESTAGGER_STRAP_OVRD;
2818 temp |= pll->config.hw_state.pcsdw12;
2819 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2820}
2821
2822static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2823 struct intel_shared_dpll *pll)
2824{
2825 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2826 uint32_t temp;
2827
2828 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2829 temp &= ~PORT_PLL_ENABLE;
2830 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2831 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2832}
2833
2834static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2835 struct intel_shared_dpll *pll,
2836 struct intel_dpll_hw_state *hw_state)
2837{
2838 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2839 uint32_t val;
2840
2841 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2842 return false;
2843
2844 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2845 if (!(val & PORT_PLL_ENABLE))
2846 return false;
2847
2848 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002849 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2850
Imre Deak05712c12015-06-18 17:25:54 +03002851 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2852 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2853
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302854 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002855 hw_state->pll0 &= PORT_PLL_M2_MASK;
2856
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302857 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002858 hw_state->pll1 &= PORT_PLL_N_MASK;
2859
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302860 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002861 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2862
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302863 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002864 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2865
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302866 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002867 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2868 PORT_PLL_INT_COEFF_MASK |
2869 PORT_PLL_GAIN_CTL_MASK;
2870
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302871 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002872 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2873
Imre Deak05712c12015-06-18 17:25:54 +03002874 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2875 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2876
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302877 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002878 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2879 PORT_PLL_DCO_AMP_MASK;
2880
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302881 /*
2882 * While we write to the group register to program all lanes at once we
2883 * can read only lane registers. We configure all lanes the same way, so
2884 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2885 */
2886 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2887 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port) != hw_state->pcsdw12))
2888 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2889 hw_state->pcsdw12,
2890 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002891 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302892
2893 return true;
2894}
2895
2896static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2897{
2898 int i;
2899
2900 dev_priv->num_shared_dpll = 3;
2901
2902 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2903 dev_priv->shared_dplls[i].id = i;
2904 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2905 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2906 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2907 dev_priv->shared_dplls[i].get_hw_state =
2908 bxt_ddi_pll_get_hw_state;
2909 }
2910}
2911
Damien Lespiau143b3072014-07-29 18:06:19 +01002912void intel_ddi_pll_init(struct drm_device *dev)
2913{
2914 struct drm_i915_private *dev_priv = dev->dev_private;
2915 uint32_t val = I915_READ(LCPLL_CTL);
2916
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002917 if (IS_SKYLAKE(dev))
2918 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302919 else if (IS_BROXTON(dev))
2920 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002921 else
2922 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002923
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002924 if (IS_SKYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002925 int cdclk_freq;
2926
2927 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002928 dev_priv->skl_boot_cdclk = cdclk_freq;
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002929 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2930 DRM_ERROR("LCPLL1 is disabled\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002931 else
2932 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302933 } else if (IS_BROXTON(dev)) {
2934 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302935 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002936 } else {
2937 /*
2938 * The LCPLL register should be turned on by the BIOS. For now
2939 * let's just check its state and print errors in case
2940 * something is wrong. Don't even try to turn it on.
2941 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002942
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002943 if (val & LCPLL_CD_SOURCE_FCLK)
2944 DRM_ERROR("CDCLK source is not LCPLL\n");
2945
2946 if (val & LCPLL_PLL_DISABLE)
2947 DRM_ERROR("LCPLL is disabled\n");
2948 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002949}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002950
2951void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
2952{
Paulo Zanoni174edf12012-10-26 19:05:50 -02002953 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
2954 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002955 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02002956 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002957 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302958 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002959
2960 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2961 val = I915_READ(DDI_BUF_CTL(port));
2962 if (val & DDI_BUF_CTL_ENABLE) {
2963 val &= ~DDI_BUF_CTL_ENABLE;
2964 I915_WRITE(DDI_BUF_CTL(port), val);
2965 wait = true;
2966 }
2967
2968 val = I915_READ(DP_TP_CTL(port));
2969 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2970 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2971 I915_WRITE(DP_TP_CTL(port), val);
2972 POSTING_READ(DP_TP_CTL(port));
2973
2974 if (wait)
2975 intel_wait_ddi_buf_idle(dev_priv, port);
2976 }
2977
Dave Airlie0e32b392014-05-02 14:02:48 +10002978 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03002979 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10002980 if (intel_dp->is_mst)
2981 val |= DP_TP_CTL_MODE_MST;
2982 else {
2983 val |= DP_TP_CTL_MODE_SST;
2984 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
2985 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
2986 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002987 I915_WRITE(DP_TP_CTL(port), val);
2988 POSTING_READ(DP_TP_CTL(port));
2989
2990 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
2991 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
2992 POSTING_READ(DDI_BUF_CTL(port));
2993
2994 udelay(600);
2995}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002996
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02002997void intel_ddi_fdi_disable(struct drm_crtc *crtc)
2998{
2999 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3000 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3001 uint32_t val;
3002
3003 intel_ddi_post_disable(intel_encoder);
3004
3005 val = I915_READ(_FDI_RXA_CTL);
3006 val &= ~FDI_RX_ENABLE;
3007 I915_WRITE(_FDI_RXA_CTL, val);
3008
3009 val = I915_READ(_FDI_RXA_MISC);
3010 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3011 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
3012 I915_WRITE(_FDI_RXA_MISC, val);
3013
3014 val = I915_READ(_FDI_RXA_CTL);
3015 val &= ~FDI_PCDCLK;
3016 I915_WRITE(_FDI_RXA_CTL, val);
3017
3018 val = I915_READ(_FDI_RXA_CTL);
3019 val &= ~FDI_RX_PLL_ENABLE;
3020 I915_WRITE(_FDI_RXA_CTL, val);
3021}
3022
Ville Syrjälä6801c182013-09-24 14:24:05 +03003023void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003024 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003025{
3026 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3027 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003028 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003029 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003030 u32 temp, flags = 0;
3031
3032 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3033 if (temp & TRANS_DDI_PHSYNC)
3034 flags |= DRM_MODE_FLAG_PHSYNC;
3035 else
3036 flags |= DRM_MODE_FLAG_NHSYNC;
3037 if (temp & TRANS_DDI_PVSYNC)
3038 flags |= DRM_MODE_FLAG_PVSYNC;
3039 else
3040 flags |= DRM_MODE_FLAG_NVSYNC;
3041
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003042 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003043
3044 switch (temp & TRANS_DDI_BPC_MASK) {
3045 case TRANS_DDI_BPC_6:
3046 pipe_config->pipe_bpp = 18;
3047 break;
3048 case TRANS_DDI_BPC_8:
3049 pipe_config->pipe_bpp = 24;
3050 break;
3051 case TRANS_DDI_BPC_10:
3052 pipe_config->pipe_bpp = 30;
3053 break;
3054 case TRANS_DDI_BPC_12:
3055 pipe_config->pipe_bpp = 36;
3056 break;
3057 default:
3058 break;
3059 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003060
3061 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3062 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003063 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003064 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3065
3066 if (intel_hdmi->infoframe_enabled(&encoder->base))
3067 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003068 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003069 case TRANS_DDI_MODE_SELECT_DVI:
3070 case TRANS_DDI_MODE_SELECT_FDI:
3071 break;
3072 case TRANS_DDI_MODE_SELECT_DP_SST:
3073 case TRANS_DDI_MODE_SELECT_DP_MST:
3074 pipe_config->has_dp_encoder = true;
3075 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 Marchesinbcf53de2013-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;
Jani Nikula5fcece82015-05-27 15:03:42 +03003221 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003222 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003223
Paulo Zanoni311a2092013-09-12 17:12:18 -03003224 /* In theory we don't need the encoder->type check, but leave it just in
3225 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003226 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3227 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3228 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003229 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003230
3231 return;
3232
3233err:
3234 drm_encoder_cleanup(encoder);
3235 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003236}