blob: 9e640eafc50d2e52f7fe2c2ded012e7dab01d4bc [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;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300417 u32 iboost_bit = 0;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000418 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530419 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300420 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300421 const struct ddi_buf_trans *ddi_translations_fdi;
422 const struct ddi_buf_trans *ddi_translations_dp;
423 const struct ddi_buf_trans *ddi_translations_edp;
424 const struct ddi_buf_trans *ddi_translations_hdmi;
425 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700426
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530427 if (IS_BROXTON(dev)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300428 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530429 return;
430
431 /* Vswing programming for HDMI */
432 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
433 INTEL_OUTPUT_HDMI);
434 return;
435 } else if (IS_SKYLAKE(dev)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300436 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300437 ddi_translations_dp =
438 skl_get_buf_trans_dp(dev, &n_dp_entries);
439 ddi_translations_edp =
440 skl_get_buf_trans_edp(dev, &n_edp_entries);
441 ddi_translations_hdmi =
442 skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
443 hdmi_default_entry = 8;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300444 /* If we're boosting the current, set bit 31 of trans1 */
445 if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
446 dev_priv->vbt.ddi_port_info[port].dp_boost_level)
447 iboost_bit = 1<<31;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000448 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700449 ddi_translations_fdi = bdw_ddi_translations_fdi;
450 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700451 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100452 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530453 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
454 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300455 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000456 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700457 } else if (IS_HASWELL(dev)) {
458 ddi_translations_fdi = hsw_ddi_translations_fdi;
459 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700460 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100461 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530462 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300463 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000464 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700465 } else {
466 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700467 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700468 ddi_translations_fdi = bdw_ddi_translations_fdi;
469 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100470 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530471 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
472 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300473 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000474 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700475 }
476
Paulo Zanoni300644c2013-11-02 21:07:42 -0700477 switch (port) {
478 case PORT_A:
479 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530480 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700481 break;
482 case PORT_B:
483 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700484 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530485 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700486 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700487 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530488 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700489 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530490 size = n_edp_entries;
491 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700492 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530493 size = n_dp_entries;
494 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700495 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700496 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000497 if (ddi_translations_fdi)
498 ddi_translations = ddi_translations_fdi;
499 else
500 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530501 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700502 break;
503 default:
504 BUG();
505 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300506
Ville Syrjälä9712e682015-09-18 20:03:22 +0300507 for (i = 0; i < size; i++) {
508 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
509 ddi_translations[i].trans1 | iboost_bit);
510 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
511 ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300512 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100513
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300514 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100515 return;
516
Damien Lespiauce4dd492014-08-01 11:07:54 +0100517 /* Choose a good default if VBT is badly populated */
518 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
519 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000520 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100521
Paulo Zanoni6acab152013-09-12 17:06:24 -0300522 /* Entry 9 is for HDMI: */
Ville Syrjälä9712e682015-09-18 20:03:22 +0300523 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
524 ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
525 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
526 ddi_translations_hdmi[hdmi_level].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300527}
528
529/* Program DDI buffers translations for DP. By default, program ports A-D in DP
530 * mode and port E for FDI.
531 */
532void intel_prepare_ddi(struct drm_device *dev)
533{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300534 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100535 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300536
Paulo Zanoni0d536cb42012-11-23 16:46:41 -0200537 if (!HAS_DDI(dev))
538 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300539
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300540 for_each_intel_encoder(dev, intel_encoder) {
541 struct intel_digital_port *intel_dig_port;
542 enum port port;
543 bool supports_hdmi;
544
545 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
546
547 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100548 continue;
549
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300550 supports_hdmi = intel_dig_port &&
551 intel_dig_port_supports_hdmi(intel_dig_port);
552
553 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
554 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100555 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300556}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300557
Paulo Zanoni248138b2012-11-29 11:29:31 -0200558static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
559 enum port port)
560{
561 uint32_t reg = DDI_BUF_CTL(port);
562 int i;
563
Vandana Kannan3449ca82015-03-27 14:19:09 +0200564 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200565 udelay(1);
566 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
567 return;
568 }
569 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
570}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300571
572/* Starting with Haswell, different DDI ports can work in FDI mode for
573 * connection to the PCH-located connectors. For this, it is necessary to train
574 * both the DDI port and PCH receiver for the desired DDI buffer settings.
575 *
576 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
577 * please note that when FDI mode is active on DDI E, it shares 2 lines with
578 * DDI A (which is used for eDP)
579 */
580
581void hsw_fdi_link_train(struct drm_crtc *crtc)
582{
583 struct drm_device *dev = crtc->dev;
584 struct drm_i915_private *dev_priv = dev->dev_private;
585 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200586 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300587
Paulo Zanoni04945642012-11-01 21:00:59 -0200588 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
589 * mode set "sequence for CRT port" document:
590 * - TP1 to TP2 time with the default value
591 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100592 *
593 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200594 */
595 I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
596 FDI_RX_PWRDN_LANE0_VAL(2) |
597 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
598
599 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000600 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100601 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200602 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Paulo Zanoni04945642012-11-01 21:00:59 -0200603 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
604 POSTING_READ(_FDI_RXA_CTL);
605 udelay(220);
606
607 /* Switch from Rawclk to PCDclk */
608 rx_ctl_val |= FDI_PCDCLK;
609 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
610
611 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200612 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
613 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200614
615 /* Start the training iterating through available voltages and emphasis,
616 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300617 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300618 /* Configure DP_TP_CTL with auto-training */
619 I915_WRITE(DP_TP_CTL(PORT_E),
620 DP_TP_CTL_FDI_AUTOTRAIN |
621 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
622 DP_TP_CTL_LINK_TRAIN_PAT1 |
623 DP_TP_CTL_ENABLE);
624
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000625 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
626 * DDI E does not support port reversal, the functionality is
627 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
628 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300629 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200630 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200631 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530632 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200633 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300634
635 udelay(600);
636
Paulo Zanoni04945642012-11-01 21:00:59 -0200637 /* Program PCH FDI Receiver TU */
638 I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300639
Paulo Zanoni04945642012-11-01 21:00:59 -0200640 /* Enable PCH FDI Receiver with auto-training */
641 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
642 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
643 POSTING_READ(_FDI_RXA_CTL);
644
645 /* Wait for FDI receiver lane calibration */
646 udelay(30);
647
648 /* Unset FDI_RX_MISC pwrdn lanes */
649 temp = I915_READ(_FDI_RXA_MISC);
650 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
651 I915_WRITE(_FDI_RXA_MISC, temp);
652 POSTING_READ(_FDI_RXA_MISC);
653
654 /* Wait for FDI auto training time */
655 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300656
657 temp = I915_READ(DP_TP_STATUS(PORT_E));
658 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200659 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300660
661 /* Enable normal pixel sending for FDI */
662 I915_WRITE(DP_TP_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200663 DP_TP_CTL_FDI_AUTOTRAIN |
664 DP_TP_CTL_LINK_TRAIN_NORMAL |
665 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
666 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300667
Paulo Zanoni04945642012-11-01 21:00:59 -0200668 return;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300669 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200670
Paulo Zanoni248138b2012-11-29 11:29:31 -0200671 temp = I915_READ(DDI_BUF_CTL(PORT_E));
672 temp &= ~DDI_BUF_CTL_ENABLE;
673 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
674 POSTING_READ(DDI_BUF_CTL(PORT_E));
675
Paulo Zanoni04945642012-11-01 21:00:59 -0200676 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200677 temp = I915_READ(DP_TP_CTL(PORT_E));
678 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
679 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
680 I915_WRITE(DP_TP_CTL(PORT_E), temp);
681 POSTING_READ(DP_TP_CTL(PORT_E));
682
683 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200684
685 rx_ctl_val &= ~FDI_RX_ENABLE;
686 I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200687 POSTING_READ(_FDI_RXA_CTL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200688
689 /* Reset FDI_RX_MISC pwrdn lanes */
690 temp = I915_READ(_FDI_RXA_MISC);
691 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
692 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
693 I915_WRITE(_FDI_RXA_MISC, temp);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200694 POSTING_READ(_FDI_RXA_MISC);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300695 }
696
Paulo Zanoni04945642012-11-01 21:00:59 -0200697 DRM_ERROR("FDI link training failed!\n");
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300698}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300699
Dave Airlie44905a272014-05-02 13:36:43 +1000700void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
701{
702 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
703 struct intel_digital_port *intel_dig_port =
704 enc_to_dig_port(&encoder->base);
705
706 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530707 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300708 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a272014-05-02 13:36:43 +1000709}
710
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300711static struct intel_encoder *
712intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
713{
714 struct drm_device *dev = crtc->dev;
715 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
716 struct intel_encoder *intel_encoder, *ret = NULL;
717 int num_encoders = 0;
718
719 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
720 ret = intel_encoder;
721 num_encoders++;
722 }
723
724 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300725 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
726 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300727
728 BUG_ON(ret == NULL);
729 return ret;
730}
731
Satheeshakrishna Mbcddf6102014-08-22 09:49:10 +0530732struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200733intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200734{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200735 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
736 struct intel_encoder *ret = NULL;
737 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300738 struct drm_connector *connector;
739 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200740 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200741 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200742
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200743 state = crtc_state->base.state;
744
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300745 for_each_connector_in_state(state, connector, connector_state, i) {
746 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200747 continue;
748
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300749 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200750 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200751 }
752
753 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
754 pipe_name(crtc->pipe));
755
756 BUG_ON(ret == NULL);
757 return ret;
758}
759
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100760#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100761#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100762
763#define P_MIN 2
764#define P_MAX 64
765#define P_INC 2
766
767/* Constraints for PLL good behavior */
768#define REF_MIN 48
769#define REF_MAX 400
770#define VCO_MIN 2400
771#define VCO_MAX 4800
772
Damien Lespiau27893392014-09-04 12:27:23 +0100773#define abs_diff(a, b) ({ \
774 typeof(a) __a = (a); \
775 typeof(b) __b = (b); \
776 (void) (&__a == &__b); \
777 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100778
Damien Lespiau63582982015-05-07 18:38:46 +0100779struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100780 unsigned p, n2, r2;
781};
782
Damien Lespiau63582982015-05-07 18:38:46 +0100783static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300784{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100785 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300786
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100787 switch (clock) {
788 case 25175000:
789 case 25200000:
790 case 27000000:
791 case 27027000:
792 case 37762500:
793 case 37800000:
794 case 40500000:
795 case 40541000:
796 case 54000000:
797 case 54054000:
798 case 59341000:
799 case 59400000:
800 case 72000000:
801 case 74176000:
802 case 74250000:
803 case 81000000:
804 case 81081000:
805 case 89012000:
806 case 89100000:
807 case 108000000:
808 case 108108000:
809 case 111264000:
810 case 111375000:
811 case 148352000:
812 case 148500000:
813 case 162000000:
814 case 162162000:
815 case 222525000:
816 case 222750000:
817 case 296703000:
818 case 297000000:
819 budget = 0;
820 break;
821 case 233500000:
822 case 245250000:
823 case 247750000:
824 case 253250000:
825 case 298000000:
826 budget = 1500;
827 break;
828 case 169128000:
829 case 169500000:
830 case 179500000:
831 case 202000000:
832 budget = 2000;
833 break;
834 case 256250000:
835 case 262500000:
836 case 270000000:
837 case 272500000:
838 case 273750000:
839 case 280750000:
840 case 281250000:
841 case 286000000:
842 case 291750000:
843 budget = 4000;
844 break;
845 case 267250000:
846 case 268500000:
847 budget = 5000;
848 break;
849 default:
850 budget = 1000;
851 break;
852 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300853
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100854 return budget;
855}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300856
Damien Lespiau63582982015-05-07 18:38:46 +0100857static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
858 unsigned r2, unsigned n2, unsigned p,
859 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100860{
861 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300862
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100863 /* No best (r,n,p) yet */
864 if (best->p == 0) {
865 best->p = p;
866 best->n2 = n2;
867 best->r2 = r2;
868 return;
869 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300870
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100871 /*
872 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
873 * freq2k.
874 *
875 * delta = 1e6 *
876 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
877 * freq2k;
878 *
879 * and we would like delta <= budget.
880 *
881 * If the discrepancy is above the PPM-based budget, always prefer to
882 * improve upon the previous solution. However, if you're within the
883 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
884 */
885 a = freq2k * budget * p * r2;
886 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100887 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
888 diff_best = abs_diff(freq2k * best->p * best->r2,
889 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100890 c = 1000000 * diff;
891 d = 1000000 * diff_best;
892
893 if (a < c && b < d) {
894 /* If both are above the budget, pick the closer */
895 if (best->p * best->r2 * diff < p * r2 * diff_best) {
896 best->p = p;
897 best->n2 = n2;
898 best->r2 = r2;
899 }
900 } else if (a >= c && b < d) {
901 /* If A is below the threshold but B is above it? Update. */
902 best->p = p;
903 best->n2 = n2;
904 best->r2 = r2;
905 } else if (a >= c && b >= d) {
906 /* Both are below the limit, so pick the higher n2/(r2*r2) */
907 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
908 best->p = p;
909 best->n2 = n2;
910 best->r2 = r2;
911 }
912 }
913 /* Otherwise a < c && b >= d, do nothing */
914}
915
Damien Lespiau63582982015-05-07 18:38:46 +0100916static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, int reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800917{
918 int refclk = LC_FREQ;
919 int n, p, r;
920 u32 wrpll;
921
922 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300923 switch (wrpll & WRPLL_PLL_REF_MASK) {
924 case WRPLL_PLL_SSC:
925 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800926 /*
927 * We could calculate spread here, but our checking
928 * code only cares about 5% accuracy, and spread is a max of
929 * 0.5% downspread.
930 */
931 refclk = 135;
932 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300933 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800934 refclk = LC_FREQ;
935 break;
936 default:
937 WARN(1, "bad wrpll refclk\n");
938 return 0;
939 }
940
941 r = wrpll & WRPLL_DIVIDER_REF_MASK;
942 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
943 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
944
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800945 /* Convert to KHz, p & r have a fixed point portion */
946 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800947}
948
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000949static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
950 uint32_t dpll)
951{
952 uint32_t cfgcr1_reg, cfgcr2_reg;
953 uint32_t cfgcr1_val, cfgcr2_val;
954 uint32_t p0, p1, p2, dco_freq;
955
956 cfgcr1_reg = GET_CFG_CR1_REG(dpll);
957 cfgcr2_reg = GET_CFG_CR2_REG(dpll);
958
959 cfgcr1_val = I915_READ(cfgcr1_reg);
960 cfgcr2_val = I915_READ(cfgcr2_reg);
961
962 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
963 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
964
965 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
966 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
967 else
968 p1 = 1;
969
970
971 switch (p0) {
972 case DPLL_CFGCR2_PDIV_1:
973 p0 = 1;
974 break;
975 case DPLL_CFGCR2_PDIV_2:
976 p0 = 2;
977 break;
978 case DPLL_CFGCR2_PDIV_3:
979 p0 = 3;
980 break;
981 case DPLL_CFGCR2_PDIV_7:
982 p0 = 7;
983 break;
984 }
985
986 switch (p2) {
987 case DPLL_CFGCR2_KDIV_5:
988 p2 = 5;
989 break;
990 case DPLL_CFGCR2_KDIV_2:
991 p2 = 2;
992 break;
993 case DPLL_CFGCR2_KDIV_3:
994 p2 = 3;
995 break;
996 case DPLL_CFGCR2_KDIV_1:
997 p2 = 1;
998 break;
999 }
1000
1001 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1002
1003 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1004 1000) / 0x8000;
1005
1006 return dco_freq / (p0 * p1 * p2 * 5);
1007}
1008
Ville Syrjälä398a0172015-06-30 15:33:51 +03001009static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1010{
1011 int dotclock;
1012
1013 if (pipe_config->has_pch_encoder)
1014 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1015 &pipe_config->fdi_m_n);
1016 else if (pipe_config->has_dp_encoder)
1017 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1018 &pipe_config->dp_m_n);
1019 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1020 dotclock = pipe_config->port_clock * 2 / 3;
1021 else
1022 dotclock = pipe_config->port_clock;
1023
1024 if (pipe_config->pixel_multiplier)
1025 dotclock /= pipe_config->pixel_multiplier;
1026
1027 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1028}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001029
1030static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001031 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001032{
1033 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001034 int link_clock = 0;
1035 uint32_t dpll_ctl1, dpll;
1036
Damien Lespiau134ffa42014-11-14 17:24:34 +00001037 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001038
1039 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1040
1041 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1042 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1043 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001044 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1045 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001046
1047 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001048 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001049 link_clock = 81000;
1050 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001051 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301052 link_clock = 108000;
1053 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001054 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001055 link_clock = 135000;
1056 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001057 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301058 link_clock = 162000;
1059 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001060 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301061 link_clock = 216000;
1062 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001063 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001064 link_clock = 270000;
1065 break;
1066 default:
1067 WARN(1, "Unsupported link rate\n");
1068 break;
1069 }
1070 link_clock *= 2;
1071 }
1072
1073 pipe_config->port_clock = link_clock;
1074
Ville Syrjälä398a0172015-06-30 15:33:51 +03001075 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001076}
1077
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001078static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001079 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001080{
1081 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001082 int link_clock = 0;
1083 u32 val, pll;
1084
Daniel Vetter26804af2014-06-25 22:01:55 +03001085 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001086 switch (val & PORT_CLK_SEL_MASK) {
1087 case PORT_CLK_SEL_LCPLL_810:
1088 link_clock = 81000;
1089 break;
1090 case PORT_CLK_SEL_LCPLL_1350:
1091 link_clock = 135000;
1092 break;
1093 case PORT_CLK_SEL_LCPLL_2700:
1094 link_clock = 270000;
1095 break;
1096 case PORT_CLK_SEL_WRPLL1:
Damien Lespiau63582982015-05-07 18:38:46 +01001097 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL1);
Jesse Barnes11578552014-01-21 12:42:10 -08001098 break;
1099 case PORT_CLK_SEL_WRPLL2:
Damien Lespiau63582982015-05-07 18:38:46 +01001100 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL2);
Jesse Barnes11578552014-01-21 12:42:10 -08001101 break;
1102 case PORT_CLK_SEL_SPLL:
1103 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1104 if (pll == SPLL_PLL_FREQ_810MHz)
1105 link_clock = 81000;
1106 else if (pll == SPLL_PLL_FREQ_1350MHz)
1107 link_clock = 135000;
1108 else if (pll == SPLL_PLL_FREQ_2700MHz)
1109 link_clock = 270000;
1110 else {
1111 WARN(1, "bad spll freq\n");
1112 return;
1113 }
1114 break;
1115 default:
1116 WARN(1, "bad port clock sel\n");
1117 return;
1118 }
1119
1120 pipe_config->port_clock = link_clock * 2;
1121
Ville Syrjälä398a0172015-06-30 15:33:51 +03001122 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001123}
1124
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301125static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1126 enum intel_dpll_id dpll)
1127{
Imre Deakaa610dc2015-06-22 23:35:52 +03001128 struct intel_shared_dpll *pll;
1129 struct intel_dpll_hw_state *state;
1130 intel_clock_t clock;
1131
1132 /* For DDI ports we always use a shared PLL. */
1133 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1134 return 0;
1135
1136 pll = &dev_priv->shared_dplls[dpll];
1137 state = &pll->config.hw_state;
1138
1139 clock.m1 = 2;
1140 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1141 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1142 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1143 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1144 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1145 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1146
1147 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301148}
1149
1150static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1151 struct intel_crtc_state *pipe_config)
1152{
1153 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1154 enum port port = intel_ddi_get_encoder_port(encoder);
1155 uint32_t dpll = port;
1156
Ville Syrjälä398a0172015-06-30 15:33:51 +03001157 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301158
Ville Syrjälä398a0172015-06-30 15:33:51 +03001159 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301160}
1161
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001162void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001163 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001164{
Damien Lespiau22606a12014-12-12 14:26:57 +00001165 struct drm_device *dev = encoder->base.dev;
1166
1167 if (INTEL_INFO(dev)->gen <= 8)
1168 hsw_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301169 else if (IS_SKYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001170 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301171 else if (IS_BROXTON(dev))
1172 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001173}
1174
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001175static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001176hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1177 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001178{
1179 uint64_t freq2k;
1180 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001181 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001182 unsigned budget;
1183
1184 freq2k = clock / 100;
1185
Damien Lespiau63582982015-05-07 18:38:46 +01001186 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001187
1188 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1189 * and directly pass the LC PLL to it. */
1190 if (freq2k == 5400000) {
1191 *n2_out = 2;
1192 *p_out = 1;
1193 *r2_out = 2;
1194 return;
1195 }
1196
1197 /*
1198 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1199 * the WR PLL.
1200 *
1201 * We want R so that REF_MIN <= Ref <= REF_MAX.
1202 * Injecting R2 = 2 * R gives:
1203 * REF_MAX * r2 > LC_FREQ * 2 and
1204 * REF_MIN * r2 < LC_FREQ * 2
1205 *
1206 * Which means the desired boundaries for r2 are:
1207 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1208 *
1209 */
1210 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1211 r2 <= LC_FREQ * 2 / REF_MIN;
1212 r2++) {
1213
1214 /*
1215 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1216 *
1217 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1218 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1219 * VCO_MAX * r2 > n2 * LC_FREQ and
1220 * VCO_MIN * r2 < n2 * LC_FREQ)
1221 *
1222 * Which means the desired boundaries for n2 are:
1223 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1224 */
1225 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1226 n2 <= VCO_MAX * r2 / LC_FREQ;
1227 n2++) {
1228
1229 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001230 hsw_wrpll_update_rnp(freq2k, budget,
1231 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001232 }
1233 }
1234
1235 *n2_out = best.n2;
1236 *p_out = best.p;
1237 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001238}
1239
Damien Lespiau0220ab62014-07-29 18:06:22 +01001240static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001241hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001242 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001243 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001244{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001245 int clock = crtc_state->port_clock;
1246
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001247 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001248 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001249 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001250 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001251
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001252 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001253
Daniel Vetter114fe482014-06-25 22:01:48 +03001254 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001255 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1256 WRPLL_DIVIDER_POST(p);
1257
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001258 memset(&crtc_state->dpll_hw_state, 0,
1259 sizeof(crtc_state->dpll_hw_state));
1260
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001261 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001262
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001263 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001264 if (pll == NULL) {
1265 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1266 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001267 return false;
1268 }
1269
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001270 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001271 }
1272
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001273 return true;
1274}
1275
Damien Lespiaudc253812015-06-25 16:15:06 +01001276struct skl_wrpll_context {
1277 uint64_t min_deviation; /* current minimal deviation */
1278 uint64_t central_freq; /* chosen central freq */
1279 uint64_t dco_freq; /* chosen dco freq */
1280 unsigned int p; /* chosen divider */
1281};
1282
1283static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1284{
1285 memset(ctx, 0, sizeof(*ctx));
1286
1287 ctx->min_deviation = U64_MAX;
1288}
1289
1290/* DCO freq must be within +1%/-6% of the DCO central freq */
1291#define SKL_DCO_MAX_PDEVIATION 100
1292#define SKL_DCO_MAX_NDEVIATION 600
1293
1294static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1295 uint64_t central_freq,
1296 uint64_t dco_freq,
1297 unsigned int divider)
1298{
1299 uint64_t deviation;
1300
1301 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1302 central_freq);
1303
1304 /* positive deviation */
1305 if (dco_freq >= central_freq) {
1306 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1307 deviation < ctx->min_deviation) {
1308 ctx->min_deviation = deviation;
1309 ctx->central_freq = central_freq;
1310 ctx->dco_freq = dco_freq;
1311 ctx->p = divider;
1312 }
1313 /* negative deviation */
1314 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1315 deviation < ctx->min_deviation) {
1316 ctx->min_deviation = deviation;
1317 ctx->central_freq = central_freq;
1318 ctx->dco_freq = dco_freq;
1319 ctx->p = divider;
1320 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001321}
1322
1323static void skl_wrpll_get_multipliers(unsigned int p,
1324 unsigned int *p0 /* out */,
1325 unsigned int *p1 /* out */,
1326 unsigned int *p2 /* out */)
1327{
1328 /* even dividers */
1329 if (p % 2 == 0) {
1330 unsigned int half = p / 2;
1331
1332 if (half == 1 || half == 2 || half == 3 || half == 5) {
1333 *p0 = 2;
1334 *p1 = 1;
1335 *p2 = half;
1336 } else if (half % 2 == 0) {
1337 *p0 = 2;
1338 *p1 = half / 2;
1339 *p2 = 2;
1340 } else if (half % 3 == 0) {
1341 *p0 = 3;
1342 *p1 = half / 3;
1343 *p2 = 2;
1344 } else if (half % 7 == 0) {
1345 *p0 = 7;
1346 *p1 = half / 7;
1347 *p2 = 2;
1348 }
1349 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1350 *p0 = 3;
1351 *p1 = 1;
1352 *p2 = p / 3;
1353 } else if (p == 5 || p == 7) {
1354 *p0 = p;
1355 *p1 = 1;
1356 *p2 = 1;
1357 } else if (p == 15) {
1358 *p0 = 3;
1359 *p1 = 1;
1360 *p2 = 5;
1361 } else if (p == 21) {
1362 *p0 = 7;
1363 *p1 = 1;
1364 *p2 = 3;
1365 } else if (p == 35) {
1366 *p0 = 7;
1367 *p1 = 1;
1368 *p2 = 5;
1369 }
1370}
1371
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001372struct skl_wrpll_params {
1373 uint32_t dco_fraction;
1374 uint32_t dco_integer;
1375 uint32_t qdiv_ratio;
1376 uint32_t qdiv_mode;
1377 uint32_t kdiv;
1378 uint32_t pdiv;
1379 uint32_t central_freq;
1380};
1381
Damien Lespiau76516fb2015-05-07 18:38:42 +01001382static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1383 uint64_t afe_clock,
1384 uint64_t central_freq,
1385 uint32_t p0, uint32_t p1, uint32_t p2)
1386{
1387 uint64_t dco_freq;
1388
Damien Lespiau76516fb2015-05-07 18:38:42 +01001389 switch (central_freq) {
1390 case 9600000000ULL:
1391 params->central_freq = 0;
1392 break;
1393 case 9000000000ULL:
1394 params->central_freq = 1;
1395 break;
1396 case 8400000000ULL:
1397 params->central_freq = 3;
1398 }
1399
1400 switch (p0) {
1401 case 1:
1402 params->pdiv = 0;
1403 break;
1404 case 2:
1405 params->pdiv = 1;
1406 break;
1407 case 3:
1408 params->pdiv = 2;
1409 break;
1410 case 7:
1411 params->pdiv = 4;
1412 break;
1413 default:
1414 WARN(1, "Incorrect PDiv\n");
1415 }
1416
1417 switch (p2) {
1418 case 5:
1419 params->kdiv = 0;
1420 break;
1421 case 2:
1422 params->kdiv = 1;
1423 break;
1424 case 3:
1425 params->kdiv = 2;
1426 break;
1427 case 1:
1428 params->kdiv = 3;
1429 break;
1430 default:
1431 WARN(1, "Incorrect KDiv\n");
1432 }
1433
1434 params->qdiv_ratio = p1;
1435 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1436
1437 dco_freq = p0 * p1 * p2 * afe_clock;
1438
1439 /*
1440 * Intermediate values are in Hz.
1441 * Divide by MHz to match bsepc
1442 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001443 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001444 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001445 div_u64((div_u64(dco_freq, 24) -
1446 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001447}
1448
Damien Lespiau318bd822015-05-07 18:38:40 +01001449static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001450skl_ddi_calculate_wrpll(int clock /* in Hz */,
1451 struct skl_wrpll_params *wrpll_params)
1452{
1453 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001454 uint64_t dco_central_freq[3] = {8400000000ULL,
1455 9000000000ULL,
1456 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001457 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1458 24, 28, 30, 32, 36, 40, 42, 44,
1459 48, 52, 54, 56, 60, 64, 66, 68,
1460 70, 72, 76, 78, 80, 84, 88, 90,
1461 92, 96, 98 };
1462 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1463 static const struct {
1464 const int *list;
1465 int n_dividers;
1466 } dividers[] = {
1467 { even_dividers, ARRAY_SIZE(even_dividers) },
1468 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1469 };
1470 struct skl_wrpll_context ctx;
1471 unsigned int dco, d, i;
1472 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001473
Damien Lespiaudc253812015-06-25 16:15:06 +01001474 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001475
Damien Lespiaudc253812015-06-25 16:15:06 +01001476 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1477 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1478 for (i = 0; i < dividers[d].n_dividers; i++) {
1479 unsigned int p = dividers[d].list[i];
1480 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001481
Damien Lespiaudc253812015-06-25 16:15:06 +01001482 skl_wrpll_try_divider(&ctx,
1483 dco_central_freq[dco],
1484 dco_freq,
1485 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001486 /*
1487 * Skip the remaining dividers if we're sure to
1488 * have found the definitive divider, we can't
1489 * improve a 0 deviation.
1490 */
1491 if (ctx.min_deviation == 0)
1492 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001493 }
1494 }
Damien Lespiau267db662015-06-25 16:19:24 +01001495
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001496skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001497 /*
1498 * If a solution is found with an even divider, prefer
1499 * this one.
1500 */
1501 if (d == 0 && ctx.p)
1502 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001503 }
1504
Damien Lespiaudc253812015-06-25 16:15:06 +01001505 if (!ctx.p) {
1506 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001507 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001508 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001509
Damien Lespiaudc253812015-06-25 16:15:06 +01001510 /*
1511 * gcc incorrectly analyses that these can be used without being
1512 * initialized. To be fair, it's hard to guess.
1513 */
1514 p0 = p1 = p2 = 0;
1515 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1516 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1517 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001518
Damien Lespiau318bd822015-05-07 18:38:40 +01001519 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001520}
1521
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001522static bool
1523skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001524 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001525 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001526{
1527 struct intel_shared_dpll *pll;
1528 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001529 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001530
1531 /*
1532 * See comment in intel_dpll_hw_state to understand why we always use 0
1533 * as the DPLL id in this function.
1534 */
1535
1536 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1537
1538 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1539 struct skl_wrpll_params wrpll_params = { 0, };
1540
1541 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1542
Damien Lespiau318bd822015-05-07 18:38:40 +01001543 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1544 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001545
1546 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1547 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1548 wrpll_params.dco_integer;
1549
1550 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1551 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1552 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1553 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1554 wrpll_params.central_freq;
1555 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001556 switch (crtc_state->port_clock / 2) {
1557 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001558 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001559 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001560 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001561 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001562 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001563 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001564 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001565 break;
1566 }
1567
1568 cfgcr1 = cfgcr2 = 0;
1569 } else /* eDP */
1570 return true;
1571
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001572 memset(&crtc_state->dpll_hw_state, 0,
1573 sizeof(crtc_state->dpll_hw_state));
1574
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001575 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1576 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1577 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001578
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001579 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001580 if (pll == NULL) {
1581 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1582 pipe_name(intel_crtc->pipe));
1583 return false;
1584 }
1585
1586 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001587 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001588
1589 return true;
1590}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001591
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301592/* bxt clock parameters */
1593struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301594 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301595 uint32_t p1;
1596 uint32_t p2;
1597 uint32_t m2_int;
1598 uint32_t m2_frac;
1599 bool m2_frac_en;
1600 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301601};
1602
1603/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301604static const struct bxt_clk_div bxt_dp_clk_val[] = {
1605 {162000, 4, 2, 32, 1677722, 1, 1},
1606 {270000, 4, 1, 27, 0, 0, 1},
1607 {540000, 2, 1, 27, 0, 0, 1},
1608 {216000, 3, 2, 32, 1677722, 1, 1},
1609 {243000, 4, 1, 24, 1258291, 1, 1},
1610 {324000, 4, 1, 32, 1677722, 1, 1},
1611 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301612};
1613
1614static bool
1615bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1616 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001617 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301618{
1619 struct intel_shared_dpll *pll;
1620 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301621 int vco = 0;
1622 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301623 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001624 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301625
1626 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1627 intel_clock_t best_clock;
1628
1629 /* Calculate HDMI div */
1630 /*
1631 * FIXME: tie the following calculation into
1632 * i9xx_crtc_compute_clock
1633 */
1634 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1635 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1636 clock, pipe_name(intel_crtc->pipe));
1637 return false;
1638 }
1639
1640 clk_div.p1 = best_clock.p1;
1641 clk_div.p2 = best_clock.p2;
1642 WARN_ON(best_clock.m1 != 2);
1643 clk_div.n = best_clock.n;
1644 clk_div.m2_int = best_clock.m2 >> 22;
1645 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1646 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1647
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301648 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301649 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1650 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301651 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301652
Sonika Jindal64987fc2015-05-26 17:50:13 +05301653 clk_div = bxt_dp_clk_val[0];
1654 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1655 if (bxt_dp_clk_val[i].clock == clock) {
1656 clk_div = bxt_dp_clk_val[i];
1657 break;
1658 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301659 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301660 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1661 }
1662
Vandana Kannane6292552015-07-01 17:02:57 +05301663 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301664 prop_coef = 4;
1665 int_coef = 9;
1666 gain_ctl = 3;
1667 targ_cnt = 8;
1668 } else if ((vco > 5400000 && vco < 6200000) ||
1669 (vco >= 4800000 && vco < 5400000)) {
1670 prop_coef = 5;
1671 int_coef = 11;
1672 gain_ctl = 3;
1673 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301674 } else if (vco == 5400000) {
1675 prop_coef = 3;
1676 int_coef = 8;
1677 gain_ctl = 1;
1678 targ_cnt = 9;
1679 } else {
1680 DRM_ERROR("Invalid VCO\n");
1681 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301682 }
1683
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001684 memset(&crtc_state->dpll_hw_state, 0,
1685 sizeof(crtc_state->dpll_hw_state));
1686
Vandana Kannane0681e32015-05-13 12:20:35 +05301687 if (clock > 270000)
1688 lanestagger = 0x18;
1689 else if (clock > 135000)
1690 lanestagger = 0x0d;
1691 else if (clock > 67000)
1692 lanestagger = 0x07;
1693 else if (clock > 33000)
1694 lanestagger = 0x04;
1695 else
1696 lanestagger = 0x02;
1697
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301698 crtc_state->dpll_hw_state.ebb0 =
1699 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1700 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1701 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1702 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1703
1704 if (clk_div.m2_frac_en)
1705 crtc_state->dpll_hw_state.pll3 =
1706 PORT_PLL_M2_FRAC_ENABLE;
1707
1708 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301709 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301710 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301711 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301712
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301713 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1714
Imre Deak05712c12015-06-18 17:25:54 +03001715 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1716
Vandana Kannane6292552015-07-01 17:02:57 +05301717 crtc_state->dpll_hw_state.pll10 =
1718 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1719 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301720
Imre Deak05712c12015-06-18 17:25:54 +03001721 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1722
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301723 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301724 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301725
1726 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1727 if (pll == NULL) {
1728 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1729 pipe_name(intel_crtc->pipe));
1730 return false;
1731 }
1732
1733 /* shared DPLL id 0 is DPLL A */
1734 crtc_state->ddi_pll_sel = pll->id;
1735
1736 return true;
1737}
1738
Damien Lespiau0220ab62014-07-29 18:06:22 +01001739/*
1740 * Tries to find a *shared* PLL for the CRTC and store it in
1741 * intel_crtc->ddi_pll_sel.
1742 *
1743 * For private DPLLs, compute_config() should do the selection for us. This
1744 * function should be folded into compute_config() eventually.
1745 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001746bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1747 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001748{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001749 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001750 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001751 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001752
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001753 if (IS_SKYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001754 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001755 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301756 else if (IS_BROXTON(dev))
1757 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001758 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001759 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001760 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001761 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001762}
1763
Paulo Zanonidae84792012-10-15 15:51:30 -03001764void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1765{
1766 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1767 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1768 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001769 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001770 int type = intel_encoder->type;
1771 uint32_t temp;
1772
Dave Airlie0e32b392014-05-02 14:02:48 +10001773 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001774 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001775 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001776 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001777 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001778 break;
1779 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001780 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001781 break;
1782 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001783 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001784 break;
1785 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001786 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001787 break;
1788 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001789 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001790 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001791 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001792 }
1793}
1794
Dave Airlie0e32b392014-05-02 14:02:48 +10001795void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1796{
1797 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1798 struct drm_device *dev = crtc->dev;
1799 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001800 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001801 uint32_t temp;
1802 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1803 if (state == true)
1804 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1805 else
1806 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1807 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1808}
1809
Damien Lespiau8228c252013-03-07 15:30:27 +00001810void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001811{
1812 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1813 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001814 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001815 struct drm_device *dev = crtc->dev;
1816 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001817 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001818 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001819 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001820 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001821 uint32_t temp;
1822
Paulo Zanoniad80a812012-10-24 16:06:19 -02001823 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1824 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001825 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001826
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001827 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001828 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001829 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001830 break;
1831 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001832 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001833 break;
1834 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001835 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001836 break;
1837 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001838 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001839 break;
1840 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001841 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001842 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001843
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001844 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001845 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001846 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001847 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001848
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001849 if (cpu_transcoder == TRANSCODER_EDP) {
1850 switch (pipe) {
1851 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001852 /* On Haswell, can only use the always-on power well for
1853 * eDP when not using the panel fitter, and when not
1854 * using motion blur mitigation (which we don't
1855 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001856 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001857 (intel_crtc->config->pch_pfit.enabled ||
1858 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001859 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1860 else
1861 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001862 break;
1863 case PIPE_B:
1864 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1865 break;
1866 case PIPE_C:
1867 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1868 break;
1869 default:
1870 BUG();
1871 break;
1872 }
1873 }
1874
Paulo Zanoni7739c332012-10-15 15:51:29 -03001875 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001876 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001877 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001878 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001879 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001880
Paulo Zanoni7739c332012-10-15 15:51:29 -03001881 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001882 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001883 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001884
1885 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1886 type == INTEL_OUTPUT_EDP) {
1887 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1888
Dave Airlie0e32b392014-05-02 14:02:48 +10001889 if (intel_dp->is_mst) {
1890 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1891 } else
1892 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1893
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001894 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001895 } else if (type == INTEL_OUTPUT_DP_MST) {
1896 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1897
1898 if (intel_dp->is_mst) {
1899 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1900 } else
1901 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001902
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001903 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001904 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001905 WARN(1, "Invalid encoder type %d for pipe %c\n",
1906 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001907 }
1908
Paulo Zanoniad80a812012-10-24 16:06:19 -02001909 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001910}
1911
Paulo Zanoniad80a812012-10-24 16:06:19 -02001912void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1913 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001914{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001915 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001916 uint32_t val = I915_READ(reg);
1917
Dave Airlie0e32b392014-05-02 14:02:48 +10001918 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001919 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001920 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001921}
1922
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001923bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1924{
1925 struct drm_device *dev = intel_connector->base.dev;
1926 struct drm_i915_private *dev_priv = dev->dev_private;
1927 struct intel_encoder *intel_encoder = intel_connector->encoder;
1928 int type = intel_connector->base.connector_type;
1929 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1930 enum pipe pipe = 0;
1931 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001932 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001933 uint32_t tmp;
1934
Paulo Zanoni882244a2014-04-01 14:55:12 -03001935 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001936 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001937 return false;
1938
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001939 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1940 return false;
1941
1942 if (port == PORT_A)
1943 cpu_transcoder = TRANSCODER_EDP;
1944 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001945 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001946
1947 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1948
1949 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1950 case TRANS_DDI_MODE_SELECT_HDMI:
1951 case TRANS_DDI_MODE_SELECT_DVI:
1952 return (type == DRM_MODE_CONNECTOR_HDMIA);
1953
1954 case TRANS_DDI_MODE_SELECT_DP_SST:
1955 if (type == DRM_MODE_CONNECTOR_eDP)
1956 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001957 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001958 case TRANS_DDI_MODE_SELECT_DP_MST:
1959 /* if the transcoder is in MST state then
1960 * connector isn't connected */
1961 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001962
1963 case TRANS_DDI_MODE_SELECT_FDI:
1964 return (type == DRM_MODE_CONNECTOR_VGA);
1965
1966 default:
1967 return false;
1968 }
1969}
1970
Daniel Vetter85234cd2012-07-02 13:27:29 +02001971bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1972 enum pipe *pipe)
1973{
1974 struct drm_device *dev = encoder->base.dev;
1975 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001976 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001977 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001978 u32 tmp;
1979 int i;
1980
Imre Deak6d129be2014-03-05 16:20:54 +02001981 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001982 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02001983 return false;
1984
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001985 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001986
1987 if (!(tmp & DDI_BUF_CTL_ENABLE))
1988 return false;
1989
Paulo Zanoniad80a812012-10-24 16:06:19 -02001990 if (port == PORT_A) {
1991 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001992
Paulo Zanoniad80a812012-10-24 16:06:19 -02001993 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
1994 case TRANS_DDI_EDP_INPUT_A_ON:
1995 case TRANS_DDI_EDP_INPUT_A_ONOFF:
1996 *pipe = PIPE_A;
1997 break;
1998 case TRANS_DDI_EDP_INPUT_B_ONOFF:
1999 *pipe = PIPE_B;
2000 break;
2001 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2002 *pipe = PIPE_C;
2003 break;
2004 }
2005
2006 return true;
2007 } else {
2008 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2009 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2010
2011 if ((tmp & TRANS_DDI_PORT_MASK)
2012 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002013 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2014 return false;
2015
Paulo Zanoniad80a812012-10-24 16:06:19 -02002016 *pipe = i;
2017 return true;
2018 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002019 }
2020 }
2021
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002022 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002023
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002024 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002025}
2026
Paulo Zanonifc914632012-10-05 12:05:54 -03002027void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2028{
2029 struct drm_crtc *crtc = &intel_crtc->base;
2030 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2031 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2032 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002033 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002034
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002035 if (cpu_transcoder != TRANSCODER_EDP)
2036 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2037 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002038}
2039
2040void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2041{
2042 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002043 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002044
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002045 if (cpu_transcoder != TRANSCODER_EDP)
2046 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2047 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002048}
2049
David Weinehallf8896f52015-06-25 11:11:03 +03002050static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2051 enum port port, int type)
2052{
2053 struct drm_i915_private *dev_priv = dev->dev_private;
2054 const struct ddi_buf_trans *ddi_translations;
2055 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002056 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002057 int n_entries;
2058 u32 reg;
2059
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002060 /* VBT may override standard boost values */
2061 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2062 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2063
David Weinehallf8896f52015-06-25 11:11:03 +03002064 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002065 if (dp_iboost) {
2066 iboost = dp_iboost;
2067 } else {
2068 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2069 iboost = ddi_translations[port].i_boost;
2070 }
David Weinehallf8896f52015-06-25 11:11:03 +03002071 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002072 if (dp_iboost) {
2073 iboost = dp_iboost;
2074 } else {
2075 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2076 iboost = ddi_translations[port].i_boost;
2077 }
David Weinehallf8896f52015-06-25 11:11:03 +03002078 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002079 if (hdmi_iboost) {
2080 iboost = hdmi_iboost;
2081 } else {
2082 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2083 iboost = ddi_translations[port].i_boost;
2084 }
David Weinehallf8896f52015-06-25 11:11:03 +03002085 } else {
2086 return;
2087 }
2088
2089 /* Make sure that the requested I_boost is valid */
2090 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2091 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2092 return;
2093 }
2094
2095 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2096 reg &= ~BALANCE_LEG_MASK(port);
2097 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2098
2099 if (iboost)
2100 reg |= iboost << BALANCE_LEG_SHIFT(port);
2101 else
2102 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2103
2104 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2105}
2106
2107static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2108 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302109{
2110 struct drm_i915_private *dev_priv = dev->dev_private;
2111 const struct bxt_ddi_buf_trans *ddi_translations;
2112 u32 n_entries, i;
2113 uint32_t val;
2114
2115 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
2116 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2117 ddi_translations = bxt_ddi_translations_dp;
2118 } else if (type == INTEL_OUTPUT_HDMI) {
2119 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2120 ddi_translations = bxt_ddi_translations_hdmi;
2121 } else {
2122 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2123 type);
2124 return;
2125 }
2126
2127 /* Check if default value has to be used */
2128 if (level >= n_entries ||
2129 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2130 for (i = 0; i < n_entries; i++) {
2131 if (ddi_translations[i].default_index) {
2132 level = i;
2133 break;
2134 }
2135 }
2136 }
2137
2138 /*
2139 * While we write to the group register to program all lanes at once we
2140 * can read only lane registers and we pick lanes 0/1 for that.
2141 */
2142 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2143 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2144 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2145
2146 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2147 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2148 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2149 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2150 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2151
2152 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
2153 val &= ~UNIQE_TRANGE_EN_METHOD;
2154 if (ddi_translations[level].enable)
2155 val |= UNIQE_TRANGE_EN_METHOD;
2156 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2157
2158 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2159 val &= ~DE_EMPHASIS;
2160 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2161 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2162
2163 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2164 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2165 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2166}
2167
David Weinehallf8896f52015-06-25 11:11:03 +03002168static uint32_t translate_signal_level(int signal_levels)
2169{
2170 uint32_t level;
2171
2172 switch (signal_levels) {
2173 default:
2174 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2175 signal_levels);
2176 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2177 level = 0;
2178 break;
2179 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2180 level = 1;
2181 break;
2182 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2183 level = 2;
2184 break;
2185 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2186 level = 3;
2187 break;
2188
2189 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2190 level = 4;
2191 break;
2192 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2193 level = 5;
2194 break;
2195 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2196 level = 6;
2197 break;
2198
2199 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2200 level = 7;
2201 break;
2202 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2203 level = 8;
2204 break;
2205
2206 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2207 level = 9;
2208 break;
2209 }
2210
2211 return level;
2212}
2213
2214uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2215{
2216 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2217 struct drm_device *dev = dport->base.base.dev;
2218 struct intel_encoder *encoder = &dport->base;
2219 uint8_t train_set = intel_dp->train_set[0];
2220 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2221 DP_TRAIN_PRE_EMPHASIS_MASK);
2222 enum port port = dport->port;
2223 uint32_t level;
2224
2225 level = translate_signal_level(signal_levels);
2226
2227 if (IS_SKYLAKE(dev))
2228 skl_ddi_set_iboost(dev, level, port, encoder->type);
2229 else if (IS_BROXTON(dev))
2230 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2231
2232 return DDI_BUF_TRANS_SELECT(level);
2233}
2234
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002235static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002236{
Paulo Zanonic19b0662012-10-15 15:51:41 -03002237 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002238 struct drm_device *dev = encoder->dev;
2239 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002240 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002241 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002242 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302243 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002244
2245 if (type == INTEL_OUTPUT_EDP) {
2246 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01002247 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002248 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002249
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002250 if (IS_SKYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002251 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002252 uint32_t val;
2253
Damien Lespiau5416d872014-11-14 17:24:33 +00002254 /*
2255 * DPLL0 is used for eDP and is the only "private" DPLL (as
2256 * opposed to shared) on SKL
2257 */
2258 if (type == INTEL_OUTPUT_EDP) {
2259 WARN_ON(dpll != SKL_DPLL0);
2260
2261 val = I915_READ(DPLL_CTRL1);
2262
2263 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2264 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002265 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002266 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002267
2268 I915_WRITE(DPLL_CTRL1, val);
2269 POSTING_READ(DPLL_CTRL1);
2270 }
2271
2272 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002273 val = I915_READ(DPLL_CTRL2);
2274
2275 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2276 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2277 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2278 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2279
2280 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002281
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302282 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002283 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2284 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002285 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002286
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002287 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002288 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002289
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002290 intel_dp_set_link_params(intel_dp, crtc->config);
2291
Dave Airlie44905a272014-05-02 13:36:43 +10002292 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002293
2294 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2295 intel_dp_start_link_train(intel_dp);
2296 intel_dp_complete_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002297 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002298 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002299 } else if (type == INTEL_OUTPUT_HDMI) {
2300 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2301
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302302 if (IS_BROXTON(dev)) {
2303 hdmi_level = dev_priv->vbt.
2304 ddi_port_info[port].hdmi_level_shift;
2305 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2306 INTEL_OUTPUT_HDMI);
2307 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002308 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002309 crtc->config->has_hdmi_sink,
2310 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002311 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002312}
2313
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002314static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002315{
2316 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002317 struct drm_device *dev = encoder->dev;
2318 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002319 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002320 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002321 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002322 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002323
2324 val = I915_READ(DDI_BUF_CTL(port));
2325 if (val & DDI_BUF_CTL_ENABLE) {
2326 val &= ~DDI_BUF_CTL_ENABLE;
2327 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002328 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002329 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002330
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002331 val = I915_READ(DP_TP_CTL(port));
2332 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2333 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2334 I915_WRITE(DP_TP_CTL(port), val);
2335
2336 if (wait)
2337 intel_wait_ddi_buf_idle(dev_priv, port);
2338
Jani Nikula76bb80e2013-11-15 15:29:57 +02002339 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002340 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002341 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002342 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002343 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002344 }
2345
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002346 if (IS_SKYLAKE(dev))
2347 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2348 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302349 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002350 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002351}
2352
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002353static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002354{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002355 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002356 struct drm_crtc *crtc = encoder->crtc;
2357 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002358 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002359 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002360 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2361 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002362
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002363 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002364 struct intel_digital_port *intel_dig_port =
2365 enc_to_dig_port(encoder);
2366
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002367 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2368 * are ignored so nothing special needs to be done besides
2369 * enabling the port.
2370 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002371 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002372 intel_dig_port->saved_port_bits |
2373 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002374 } else if (type == INTEL_OUTPUT_EDP) {
2375 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2376
Vandana Kannan23f08d82014-11-13 14:55:22 +00002377 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002378 intel_dp_stop_link_train(intel_dp);
2379
Daniel Vetter4be73782014-01-17 14:39:48 +01002380 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002381 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302382 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002383 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002384
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002385 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002386 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002387 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002388 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002389}
2390
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002391static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002392{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002393 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002394 struct drm_crtc *crtc = encoder->crtc;
2395 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002396 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002397 struct drm_device *dev = encoder->dev;
2398 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002399
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002400 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002401 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002402 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2403 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002404
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002405 if (type == INTEL_OUTPUT_EDP) {
2406 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2407
Vandana Kannanc3955782015-01-22 15:17:40 +05302408 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002409 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002410 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002411 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002412}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002413
Daniel Vettere0b01be2014-06-25 22:02:01 +03002414static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2415 struct intel_shared_dpll *pll)
2416{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002417 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002418 POSTING_READ(WRPLL_CTL(pll->id));
2419 udelay(20);
2420}
2421
Daniel Vetter12030432014-06-25 22:02:00 +03002422static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2423 struct intel_shared_dpll *pll)
2424{
2425 uint32_t val;
2426
2427 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002428 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2429 POSTING_READ(WRPLL_CTL(pll->id));
2430}
2431
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002432static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2433 struct intel_shared_dpll *pll,
2434 struct intel_dpll_hw_state *hw_state)
2435{
2436 uint32_t val;
2437
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002438 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002439 return false;
2440
2441 val = I915_READ(WRPLL_CTL(pll->id));
2442 hw_state->wrpll = val;
2443
2444 return val & WRPLL_PLL_ENABLE;
2445}
2446
Damien Lespiauca1381b2014-07-15 15:05:33 +01002447static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002448 "WRPLL 1",
2449 "WRPLL 2",
2450};
2451
Damien Lespiau143b3072014-07-29 18:06:19 +01002452static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002453{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002454 int i;
2455
Daniel Vetter716c2e52014-06-25 22:02:02 +03002456 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002457
Daniel Vetter716c2e52014-06-25 22:02:02 +03002458 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002459 dev_priv->shared_dplls[i].id = i;
2460 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002461 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002462 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002463 dev_priv->shared_dplls[i].get_hw_state =
2464 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002465 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002466}
2467
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002468static const char * const skl_ddi_pll_names[] = {
2469 "DPLL 1",
2470 "DPLL 2",
2471 "DPLL 3",
2472};
2473
2474struct skl_dpll_regs {
2475 u32 ctl, cfgcr1, cfgcr2;
2476};
2477
2478/* this array is indexed by the *shared* pll id */
2479static const struct skl_dpll_regs skl_dpll_regs[3] = {
2480 {
2481 /* DPLL 1 */
2482 .ctl = LCPLL2_CTL,
2483 .cfgcr1 = DPLL1_CFGCR1,
2484 .cfgcr2 = DPLL1_CFGCR2,
2485 },
2486 {
2487 /* DPLL 2 */
2488 .ctl = WRPLL_CTL1,
2489 .cfgcr1 = DPLL2_CFGCR1,
2490 .cfgcr2 = DPLL2_CFGCR2,
2491 },
2492 {
2493 /* DPLL 3 */
2494 .ctl = WRPLL_CTL2,
2495 .cfgcr1 = DPLL3_CFGCR1,
2496 .cfgcr2 = DPLL3_CFGCR2,
2497 },
2498};
2499
2500static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2501 struct intel_shared_dpll *pll)
2502{
2503 uint32_t val;
2504 unsigned int dpll;
2505 const struct skl_dpll_regs *regs = skl_dpll_regs;
2506
2507 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2508 dpll = pll->id + 1;
2509
2510 val = I915_READ(DPLL_CTRL1);
2511
2512 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002513 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002514 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2515
2516 I915_WRITE(DPLL_CTRL1, val);
2517 POSTING_READ(DPLL_CTRL1);
2518
2519 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2520 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2521 POSTING_READ(regs[pll->id].cfgcr1);
2522 POSTING_READ(regs[pll->id].cfgcr2);
2523
2524 /* the enable bit is always bit 31 */
2525 I915_WRITE(regs[pll->id].ctl,
2526 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2527
2528 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2529 DRM_ERROR("DPLL %d not locked\n", dpll);
2530}
2531
2532static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2533 struct intel_shared_dpll *pll)
2534{
2535 const struct skl_dpll_regs *regs = skl_dpll_regs;
2536
2537 /* the enable bit is always bit 31 */
2538 I915_WRITE(regs[pll->id].ctl,
2539 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2540 POSTING_READ(regs[pll->id].ctl);
2541}
2542
2543static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2544 struct intel_shared_dpll *pll,
2545 struct intel_dpll_hw_state *hw_state)
2546{
2547 uint32_t val;
2548 unsigned int dpll;
2549 const struct skl_dpll_regs *regs = skl_dpll_regs;
2550
2551 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2552 return false;
2553
2554 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2555 dpll = pll->id + 1;
2556
2557 val = I915_READ(regs[pll->id].ctl);
2558 if (!(val & LCPLL_PLL_ENABLE))
2559 return false;
2560
2561 val = I915_READ(DPLL_CTRL1);
2562 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2563
2564 /* avoid reading back stale values if HDMI mode is not enabled */
2565 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2566 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2567 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2568 }
2569
2570 return true;
2571}
2572
2573static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2574{
2575 int i;
2576
2577 dev_priv->num_shared_dpll = 3;
2578
2579 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2580 dev_priv->shared_dplls[i].id = i;
2581 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2582 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2583 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2584 dev_priv->shared_dplls[i].get_hw_state =
2585 skl_ddi_pll_get_hw_state;
2586 }
2587}
2588
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302589static void broxton_phy_init(struct drm_i915_private *dev_priv,
2590 enum dpio_phy phy)
2591{
2592 enum port port;
2593 uint32_t val;
2594
2595 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2596 val |= GT_DISPLAY_POWER_ON(phy);
2597 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2598
2599 /* Considering 10ms timeout until BSpec is updated */
2600 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2601 DRM_ERROR("timeout during PHY%d power on\n", phy);
2602
2603 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2604 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2605 int lane;
2606
2607 for (lane = 0; lane < 4; lane++) {
2608 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2609 /*
2610 * Note that on CHV this flag is called UPAR, but has
2611 * the same function.
2612 */
2613 val &= ~LATENCY_OPTIM;
2614 if (lane != 1)
2615 val |= LATENCY_OPTIM;
2616
2617 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2618 }
2619 }
2620
2621 /* Program PLL Rcomp code offset */
2622 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2623 val &= ~IREF0RC_OFFSET_MASK;
2624 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2625 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2626
2627 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2628 val &= ~IREF1RC_OFFSET_MASK;
2629 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2630 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2631
2632 /* Program power gating */
2633 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2634 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2635 SUS_CLK_CONFIG;
2636 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2637
2638 if (phy == DPIO_PHY0) {
2639 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2640 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2641 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2642 }
2643
2644 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2645 val &= ~OCL2_LDOFUSE_PWR_DIS;
2646 /*
2647 * On PHY1 disable power on the second channel, since no port is
2648 * connected there. On PHY0 both channels have a port, so leave it
2649 * enabled.
2650 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2651 * power down the second channel on PHY0 as well.
2652 */
2653 if (phy == DPIO_PHY1)
2654 val |= OCL2_LDOFUSE_PWR_DIS;
2655 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2656
2657 if (phy == DPIO_PHY0) {
2658 uint32_t grc_code;
2659 /*
2660 * PHY0 isn't connected to an RCOMP resistor so copy over
2661 * the corresponding calibrated value from PHY1, and disable
2662 * the automatic calibration on PHY0.
2663 */
2664 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2665 10))
2666 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2667
2668 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2669 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2670 grc_code = val << GRC_CODE_FAST_SHIFT |
2671 val << GRC_CODE_SLOW_SHIFT |
2672 val;
2673 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2674
2675 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2676 val |= GRC_DIS | GRC_RDY_OVRD;
2677 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2678 }
2679
2680 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2681 val |= COMMON_RESET_DIS;
2682 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2683}
2684
2685void broxton_ddi_phy_init(struct drm_device *dev)
2686{
2687 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2688 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2689 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2690}
2691
2692static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2693 enum dpio_phy phy)
2694{
2695 uint32_t val;
2696
2697 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2698 val &= ~COMMON_RESET_DIS;
2699 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2700}
2701
2702void broxton_ddi_phy_uninit(struct drm_device *dev)
2703{
2704 struct drm_i915_private *dev_priv = dev->dev_private;
2705
2706 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2707 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2708
2709 /* FIXME: do this in broxton_phy_uninit per phy */
2710 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2711}
2712
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302713static const char * const bxt_ddi_pll_names[] = {
2714 "PORT PLL A",
2715 "PORT PLL B",
2716 "PORT PLL C",
2717};
2718
2719static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2720 struct intel_shared_dpll *pll)
2721{
2722 uint32_t temp;
2723 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2724
2725 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2726 temp &= ~PORT_PLL_REF_SEL;
2727 /* Non-SSC reference */
2728 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2729
2730 /* Disable 10 bit clock */
2731 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2732 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2733 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2734
2735 /* Write P1 & P2 */
2736 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2737 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2738 temp |= pll->config.hw_state.ebb0;
2739 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2740
2741 /* Write M2 integer */
2742 temp = I915_READ(BXT_PORT_PLL(port, 0));
2743 temp &= ~PORT_PLL_M2_MASK;
2744 temp |= pll->config.hw_state.pll0;
2745 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2746
2747 /* Write N */
2748 temp = I915_READ(BXT_PORT_PLL(port, 1));
2749 temp &= ~PORT_PLL_N_MASK;
2750 temp |= pll->config.hw_state.pll1;
2751 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2752
2753 /* Write M2 fraction */
2754 temp = I915_READ(BXT_PORT_PLL(port, 2));
2755 temp &= ~PORT_PLL_M2_FRAC_MASK;
2756 temp |= pll->config.hw_state.pll2;
2757 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2758
2759 /* Write M2 fraction enable */
2760 temp = I915_READ(BXT_PORT_PLL(port, 3));
2761 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2762 temp |= pll->config.hw_state.pll3;
2763 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2764
2765 /* Write coeff */
2766 temp = I915_READ(BXT_PORT_PLL(port, 6));
2767 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2768 temp &= ~PORT_PLL_INT_COEFF_MASK;
2769 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2770 temp |= pll->config.hw_state.pll6;
2771 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2772
2773 /* Write calibration val */
2774 temp = I915_READ(BXT_PORT_PLL(port, 8));
2775 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2776 temp |= pll->config.hw_state.pll8;
2777 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2778
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302779 temp = I915_READ(BXT_PORT_PLL(port, 9));
2780 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002781 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302782 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2783
2784 temp = I915_READ(BXT_PORT_PLL(port, 10));
2785 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2786 temp &= ~PORT_PLL_DCO_AMP_MASK;
2787 temp |= pll->config.hw_state.pll10;
2788 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302789
2790 /* Recalibrate with new settings */
2791 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2792 temp |= PORT_PLL_RECALIBRATE;
2793 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002794 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2795 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302796 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2797
2798 /* Enable PLL */
2799 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2800 temp |= PORT_PLL_ENABLE;
2801 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2802 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2803
2804 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2805 PORT_PLL_LOCK), 200))
2806 DRM_ERROR("PLL %d not locked\n", port);
2807
2808 /*
2809 * While we write to the group register to program all lanes at once we
2810 * can read only lane registers and we pick lanes 0/1 for that.
2811 */
2812 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2813 temp &= ~LANE_STAGGER_MASK;
2814 temp &= ~LANESTAGGER_STRAP_OVRD;
2815 temp |= pll->config.hw_state.pcsdw12;
2816 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2817}
2818
2819static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2820 struct intel_shared_dpll *pll)
2821{
2822 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2823 uint32_t temp;
2824
2825 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2826 temp &= ~PORT_PLL_ENABLE;
2827 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2828 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2829}
2830
2831static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2832 struct intel_shared_dpll *pll,
2833 struct intel_dpll_hw_state *hw_state)
2834{
2835 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2836 uint32_t val;
2837
2838 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2839 return false;
2840
2841 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2842 if (!(val & PORT_PLL_ENABLE))
2843 return false;
2844
2845 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002846 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2847
Imre Deak05712c12015-06-18 17:25:54 +03002848 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2849 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2850
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302851 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002852 hw_state->pll0 &= PORT_PLL_M2_MASK;
2853
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302854 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002855 hw_state->pll1 &= PORT_PLL_N_MASK;
2856
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302857 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002858 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2859
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302860 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002861 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2862
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302863 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002864 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2865 PORT_PLL_INT_COEFF_MASK |
2866 PORT_PLL_GAIN_CTL_MASK;
2867
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302868 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002869 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2870
Imre Deak05712c12015-06-18 17:25:54 +03002871 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2872 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2873
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302874 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002875 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2876 PORT_PLL_DCO_AMP_MASK;
2877
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302878 /*
2879 * While we write to the group register to program all lanes at once we
2880 * can read only lane registers. We configure all lanes the same way, so
2881 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2882 */
2883 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002884 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302885 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2886 hw_state->pcsdw12,
2887 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002888 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302889
2890 return true;
2891}
2892
2893static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2894{
2895 int i;
2896
2897 dev_priv->num_shared_dpll = 3;
2898
2899 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2900 dev_priv->shared_dplls[i].id = i;
2901 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2902 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2903 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2904 dev_priv->shared_dplls[i].get_hw_state =
2905 bxt_ddi_pll_get_hw_state;
2906 }
2907}
2908
Damien Lespiau143b3072014-07-29 18:06:19 +01002909void intel_ddi_pll_init(struct drm_device *dev)
2910{
2911 struct drm_i915_private *dev_priv = dev->dev_private;
2912 uint32_t val = I915_READ(LCPLL_CTL);
2913
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002914 if (IS_SKYLAKE(dev))
2915 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302916 else if (IS_BROXTON(dev))
2917 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002918 else
2919 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002920
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002921 if (IS_SKYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002922 int cdclk_freq;
2923
2924 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002925 dev_priv->skl_boot_cdclk = cdclk_freq;
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002926 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2927 DRM_ERROR("LCPLL1 is disabled\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002928 else
2929 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302930 } else if (IS_BROXTON(dev)) {
2931 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302932 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002933 } else {
2934 /*
2935 * The LCPLL register should be turned on by the BIOS. For now
2936 * let's just check its state and print errors in case
2937 * something is wrong. Don't even try to turn it on.
2938 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002939
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002940 if (val & LCPLL_CD_SOURCE_FCLK)
2941 DRM_ERROR("CDCLK source is not LCPLL\n");
2942
2943 if (val & LCPLL_PLL_DISABLE)
2944 DRM_ERROR("LCPLL is disabled\n");
2945 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002946}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002947
2948void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
2949{
Paulo Zanoni174edf12012-10-26 19:05:50 -02002950 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
2951 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002952 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02002953 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002954 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302955 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002956
2957 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2958 val = I915_READ(DDI_BUF_CTL(port));
2959 if (val & DDI_BUF_CTL_ENABLE) {
2960 val &= ~DDI_BUF_CTL_ENABLE;
2961 I915_WRITE(DDI_BUF_CTL(port), val);
2962 wait = true;
2963 }
2964
2965 val = I915_READ(DP_TP_CTL(port));
2966 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2967 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2968 I915_WRITE(DP_TP_CTL(port), val);
2969 POSTING_READ(DP_TP_CTL(port));
2970
2971 if (wait)
2972 intel_wait_ddi_buf_idle(dev_priv, port);
2973 }
2974
Dave Airlie0e32b392014-05-02 14:02:48 +10002975 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03002976 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10002977 if (intel_dp->is_mst)
2978 val |= DP_TP_CTL_MODE_MST;
2979 else {
2980 val |= DP_TP_CTL_MODE_SST;
2981 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
2982 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
2983 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002984 I915_WRITE(DP_TP_CTL(port), val);
2985 POSTING_READ(DP_TP_CTL(port));
2986
2987 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
2988 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
2989 POSTING_READ(DDI_BUF_CTL(port));
2990
2991 udelay(600);
2992}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002993
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02002994void intel_ddi_fdi_disable(struct drm_crtc *crtc)
2995{
2996 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
2997 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2998 uint32_t val;
2999
3000 intel_ddi_post_disable(intel_encoder);
3001
3002 val = I915_READ(_FDI_RXA_CTL);
3003 val &= ~FDI_RX_ENABLE;
3004 I915_WRITE(_FDI_RXA_CTL, val);
3005
3006 val = I915_READ(_FDI_RXA_MISC);
3007 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3008 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
3009 I915_WRITE(_FDI_RXA_MISC, val);
3010
3011 val = I915_READ(_FDI_RXA_CTL);
3012 val &= ~FDI_PCDCLK;
3013 I915_WRITE(_FDI_RXA_CTL, val);
3014
3015 val = I915_READ(_FDI_RXA_CTL);
3016 val &= ~FDI_RX_PLL_ENABLE;
3017 I915_WRITE(_FDI_RXA_CTL, val);
3018}
3019
Ville Syrjälä6801c182013-09-24 14:24:05 +03003020void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003021 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003022{
3023 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3024 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003025 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003026 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003027 u32 temp, flags = 0;
3028
3029 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3030 if (temp & TRANS_DDI_PHSYNC)
3031 flags |= DRM_MODE_FLAG_PHSYNC;
3032 else
3033 flags |= DRM_MODE_FLAG_NHSYNC;
3034 if (temp & TRANS_DDI_PVSYNC)
3035 flags |= DRM_MODE_FLAG_PVSYNC;
3036 else
3037 flags |= DRM_MODE_FLAG_NVSYNC;
3038
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003039 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003040
3041 switch (temp & TRANS_DDI_BPC_MASK) {
3042 case TRANS_DDI_BPC_6:
3043 pipe_config->pipe_bpp = 18;
3044 break;
3045 case TRANS_DDI_BPC_8:
3046 pipe_config->pipe_bpp = 24;
3047 break;
3048 case TRANS_DDI_BPC_10:
3049 pipe_config->pipe_bpp = 30;
3050 break;
3051 case TRANS_DDI_BPC_12:
3052 pipe_config->pipe_bpp = 36;
3053 break;
3054 default:
3055 break;
3056 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003057
3058 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3059 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b52014-04-24 23:54:47 +02003060 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003061 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3062
3063 if (intel_hdmi->infoframe_enabled(&encoder->base))
3064 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003065 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003066 case TRANS_DDI_MODE_SELECT_DVI:
3067 case TRANS_DDI_MODE_SELECT_FDI:
3068 break;
3069 case TRANS_DDI_MODE_SELECT_DP_SST:
3070 case TRANS_DDI_MODE_SELECT_DP_MST:
3071 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003072 pipe_config->lane_count =
3073 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003074 intel_dp_get_m_n(intel_crtc, pipe_config);
3075 break;
3076 default:
3077 break;
3078 }
Daniel Vetter10214422013-11-18 07:38:16 +01003079
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003080 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003081 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003082 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003083 pipe_config->has_audio = true;
3084 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003085
Daniel Vetter10214422013-11-18 07:38:16 +01003086 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3087 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3088 /*
3089 * This is a big fat ugly hack.
3090 *
3091 * Some machines in UEFI boot mode provide us a VBT that has 18
3092 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3093 * unknown we fail to light up. Yet the same BIOS boots up with
3094 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3095 * max, not what it tells us to use.
3096 *
3097 * Note: This will still be broken if the eDP panel is not lit
3098 * up by the BIOS, and thus we can't get the mode at module
3099 * load.
3100 */
3101 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3102 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3103 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3104 }
Jesse Barnes11578552014-01-21 12:42:10 -08003105
Damien Lespiau22606a12014-12-12 14:26:57 +00003106 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003107}
3108
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003109static void intel_ddi_destroy(struct drm_encoder *encoder)
3110{
3111 /* HDMI has nothing special to destroy, so we can go with this. */
3112 intel_dp_encoder_destroy(encoder);
3113}
3114
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003115static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003116 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003117{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003118 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003119 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003120
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003121 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003122
Daniel Vettereccb1402013-05-22 00:50:22 +02003123 if (port == PORT_A)
3124 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3125
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003126 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003127 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003128 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003129 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003130}
3131
3132static const struct drm_encoder_funcs intel_ddi_funcs = {
3133 .destroy = intel_ddi_destroy,
3134};
3135
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003136static struct intel_connector *
3137intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3138{
3139 struct intel_connector *connector;
3140 enum port port = intel_dig_port->port;
3141
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003142 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003143 if (!connector)
3144 return NULL;
3145
3146 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3147 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3148 kfree(connector);
3149 return NULL;
3150 }
3151
3152 return connector;
3153}
3154
3155static struct intel_connector *
3156intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3157{
3158 struct intel_connector *connector;
3159 enum port port = intel_dig_port->port;
3160
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003161 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003162 if (!connector)
3163 return NULL;
3164
3165 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3166 intel_hdmi_init_connector(intel_dig_port, connector);
3167
3168 return connector;
3169}
3170
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003171void intel_ddi_init(struct drm_device *dev, enum port port)
3172{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003173 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003174 struct intel_digital_port *intel_dig_port;
3175 struct intel_encoder *intel_encoder;
3176 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003177 bool init_hdmi, init_dp;
3178
3179 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3180 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3181 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3182 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003183 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003184 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003185 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003186 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003187
Daniel Vetterb14c5672013-09-19 12:18:32 +02003188 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003189 if (!intel_dig_port)
3190 return;
3191
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003192 intel_encoder = &intel_dig_port->base;
3193 encoder = &intel_encoder->base;
3194
3195 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3196 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003197
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003198 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003199 intel_encoder->enable = intel_enable_ddi;
3200 intel_encoder->pre_enable = intel_ddi_pre_enable;
3201 intel_encoder->disable = intel_disable_ddi;
3202 intel_encoder->post_disable = intel_ddi_post_disable;
3203 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003204 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003205
3206 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003207 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3208 (DDI_BUF_PORT_REVERSAL |
3209 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003210
3211 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003212 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003213 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003214
Chris Wilsonf68d6972014-08-04 07:15:09 +01003215 if (init_dp) {
3216 if (!intel_ddi_init_dp_connector(intel_dig_port))
3217 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003218
Chris Wilsonf68d6972014-08-04 07:15:09 +01003219 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303220 /*
3221 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3222 * interrupts to check the external panel connection.
3223 */
3224 if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)
3225 && port == PORT_B)
3226 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3227 else
3228 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003229 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003230
Paulo Zanoni311a2092013-09-12 17:12:18 -03003231 /* In theory we don't need the encoder->type check, but leave it just in
3232 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003233 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3234 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3235 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003236 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003237
3238 return;
3239
3240err:
3241 drm_encoder_cleanup(encoder);
3242 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003243}