blob: da46eddd80f4b45063fb298850e2031f94f74ce0 [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
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530259static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
260 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300261 { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */
262 { 78, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
263 { 104, 0x9A, 0, 64, false }, /* 2: 400 6 */
264 { 154, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
265 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
266 { 116, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
267 { 154, 0x9A, 0, 64, false }, /* 6: 600 6 */
268 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
269 { 154, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
David Weinehallf8896f52015-06-25 11:11:03 +0300270 { 154, 0x9A, 1, 128, false }, /* 9: 1200 0 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530271};
272
Sonika Jindald9d70002015-09-24 10:24:56 +0530273static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = {
274 /* Idx NT mV diff db */
275 { 26, 0, 0, 128, false }, /* 0: 200 0 */
276 { 38, 0, 0, 112, false }, /* 1: 200 1.5 */
277 { 48, 0, 0, 96, false }, /* 2: 200 4 */
278 { 54, 0, 0, 69, false }, /* 3: 200 6 */
279 { 32, 0, 0, 128, false }, /* 4: 250 0 */
280 { 48, 0, 0, 104, false }, /* 5: 250 1.5 */
281 { 54, 0, 0, 85, false }, /* 6: 250 4 */
282 { 43, 0, 0, 128, false }, /* 7: 300 0 */
283 { 54, 0, 0, 101, false }, /* 8: 300 1.5 */
284 { 48, 0, 0, 128, false }, /* 9: 300 0 */
285};
286
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530287/* BSpec has 2 recommended values - entries 0 and 8.
288 * Using the entry with higher vswing.
289 */
290static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
291 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300292 { 52, 0x9A, 0, 128, false }, /* 0: 400 0 */
293 { 52, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
294 { 52, 0x9A, 0, 64, false }, /* 2: 400 6 */
295 { 42, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
296 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
297 { 77, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
298 { 77, 0x9A, 0, 64, false }, /* 6: 600 6 */
299 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
300 { 102, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530301 { 154, 0x9A, 1, 128, true }, /* 9: 1200 0 */
302};
303
David Weinehallf8896f52015-06-25 11:11:03 +0300304static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
305 enum port port, int type);
306
Imre Deaka1e6ad62015-04-17 19:31:21 +0300307static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
308 struct intel_digital_port **dig_port,
309 enum port *port)
Paulo Zanonifc914632012-10-05 12:05:54 -0300310{
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300311 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonifc914632012-10-05 12:05:54 -0300312
Jani Nikula8cd21b72015-09-29 10:24:26 +0300313 switch (intel_encoder->type) {
314 case INTEL_OUTPUT_DP_MST:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300315 *dig_port = enc_to_mst(encoder)->primary;
316 *port = (*dig_port)->port;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300317 break;
318 case INTEL_OUTPUT_DISPLAYPORT:
319 case INTEL_OUTPUT_EDP:
320 case INTEL_OUTPUT_HDMI:
321 case INTEL_OUTPUT_UNKNOWN:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300322 *dig_port = enc_to_dig_port(encoder);
323 *port = (*dig_port)->port;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300324 break;
325 case INTEL_OUTPUT_ANALOG:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300326 *dig_port = NULL;
327 *port = PORT_E;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300328 break;
329 default:
330 WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
331 break;
Paulo Zanonifc914632012-10-05 12:05:54 -0300332 }
333}
334
Imre Deaka1e6ad62015-04-17 19:31:21 +0300335enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
336{
337 struct intel_digital_port *dig_port;
338 enum port port;
339
340 ddi_get_encoder_port(intel_encoder, &dig_port, &port);
341
342 return port;
343}
344
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100345static bool
346intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
347{
348 return intel_dig_port->hdmi.hdmi_reg;
349}
350
David Weinehallf8896f52015-06-25 11:11:03 +0300351static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,
352 int *n_entries)
353{
David Weinehallf8896f52015-06-25 11:11:03 +0300354 const struct ddi_buf_trans *ddi_translations;
David Weinehallf8896f52015-06-25 11:11:03 +0300355
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700356 if (IS_SKL_ULX(dev)) {
357 ddi_translations = skl_y_ddi_translations_dp;
358 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
David Weinehallf8896f52015-06-25 11:11:03 +0300359 } else if (IS_SKL_ULT(dev)) {
360 ddi_translations = skl_u_ddi_translations_dp;
361 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
362 } else {
363 ddi_translations = skl_ddi_translations_dp;
364 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
365 }
366
367 return ddi_translations;
368}
369
370static const struct ddi_buf_trans *skl_get_buf_trans_edp(struct drm_device *dev,
371 int *n_entries)
372{
373 struct drm_i915_private *dev_priv = dev->dev_private;
374 const struct ddi_buf_trans *ddi_translations;
David Weinehallf8896f52015-06-25 11:11:03 +0300375
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700376 if (IS_SKL_ULX(dev)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300377 if (dev_priv->edp_low_vswing) {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700378 ddi_translations = skl_y_ddi_translations_edp;
379 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
David Weinehallf8896f52015-06-25 11:11:03 +0300380 } else {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700381 ddi_translations = skl_y_ddi_translations_dp;
382 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
David Weinehallf8896f52015-06-25 11:11:03 +0300383 }
384 } else if (IS_SKL_ULT(dev)) {
385 if (dev_priv->edp_low_vswing) {
386 ddi_translations = skl_u_ddi_translations_edp;
387 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
388 } else {
389 ddi_translations = skl_u_ddi_translations_dp;
390 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
391 }
392 } else {
393 if (dev_priv->edp_low_vswing) {
394 ddi_translations = skl_ddi_translations_edp;
395 *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
396 } else {
397 ddi_translations = skl_ddi_translations_dp;
398 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
399 }
400 }
401
402 return ddi_translations;
403}
404
405static const struct ddi_buf_trans *
406skl_get_buf_trans_hdmi(struct drm_device *dev,
407 int *n_entries)
408{
David Weinehallf8896f52015-06-25 11:11:03 +0300409 const struct ddi_buf_trans *ddi_translations;
David Weinehallf8896f52015-06-25 11:11:03 +0300410
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700411 if (IS_SKL_ULX(dev)) {
412 ddi_translations = skl_y_ddi_translations_hdmi;
413 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
David Weinehallf8896f52015-06-25 11:11:03 +0300414 } else {
415 ddi_translations = skl_ddi_translations_hdmi;
416 *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
417 }
418
419 return ddi_translations;
420}
421
Art Runyane58623c2013-11-02 21:07:41 -0700422/*
423 * Starting with Haswell, DDI port buffers must be programmed with correct
424 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300425 * but the HDMI/DVI fields are shared among those. So we program the DDI
426 * in either FDI or DP modes only, as HDMI connections will work with both
427 * of those
428 */
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300429static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
430 bool supports_hdmi)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300431{
432 struct drm_i915_private *dev_priv = dev->dev_private;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300433 u32 iboost_bit = 0;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000434 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530435 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300436 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300437 const struct ddi_buf_trans *ddi_translations_fdi;
438 const struct ddi_buf_trans *ddi_translations_dp;
439 const struct ddi_buf_trans *ddi_translations_edp;
440 const struct ddi_buf_trans *ddi_translations_hdmi;
441 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700442
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530443 if (IS_BROXTON(dev)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300444 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530445 return;
446
447 /* Vswing programming for HDMI */
448 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
449 INTEL_OUTPUT_HDMI);
450 return;
Rodrigo Vivief11bdb2015-10-28 04:16:45 -0700451 } else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300452 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300453 ddi_translations_dp =
454 skl_get_buf_trans_dp(dev, &n_dp_entries);
455 ddi_translations_edp =
456 skl_get_buf_trans_edp(dev, &n_edp_entries);
457 ddi_translations_hdmi =
458 skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
459 hdmi_default_entry = 8;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300460 /* If we're boosting the current, set bit 31 of trans1 */
461 if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
462 dev_priv->vbt.ddi_port_info[port].dp_boost_level)
463 iboost_bit = 1<<31;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000464 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700465 ddi_translations_fdi = bdw_ddi_translations_fdi;
466 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700467 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100468 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530469 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
470 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300471 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000472 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700473 } else if (IS_HASWELL(dev)) {
474 ddi_translations_fdi = hsw_ddi_translations_fdi;
475 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700476 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100477 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530478 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300479 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000480 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700481 } else {
482 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700483 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700484 ddi_translations_fdi = bdw_ddi_translations_fdi;
485 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100486 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530487 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
488 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300489 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000490 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700491 }
492
Paulo Zanoni300644c2013-11-02 21:07:42 -0700493 switch (port) {
494 case PORT_A:
495 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530496 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700497 break;
498 case PORT_B:
499 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700500 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;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700503 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530504 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700505 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530506 size = n_edp_entries;
507 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700508 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530509 size = n_dp_entries;
510 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700511 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700512 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000513 if (ddi_translations_fdi)
514 ddi_translations = ddi_translations_fdi;
515 else
516 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530517 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700518 break;
519 default:
520 BUG();
521 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300522
Ville Syrjälä9712e682015-09-18 20:03:22 +0300523 for (i = 0; i < size; i++) {
524 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
525 ddi_translations[i].trans1 | iboost_bit);
526 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
527 ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300528 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100529
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300530 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100531 return;
532
Damien Lespiauce4dd492014-08-01 11:07:54 +0100533 /* Choose a good default if VBT is badly populated */
534 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
535 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000536 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100537
Paulo Zanoni6acab152013-09-12 17:06:24 -0300538 /* Entry 9 is for HDMI: */
Ville Syrjälä9712e682015-09-18 20:03:22 +0300539 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
540 ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
541 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
542 ddi_translations_hdmi[hdmi_level].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300543}
544
545/* Program DDI buffers translations for DP. By default, program ports A-D in DP
546 * mode and port E for FDI.
547 */
548void intel_prepare_ddi(struct drm_device *dev)
549{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300550 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100551 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300552
Paulo Zanoni0d536cb2012-11-23 16:46:41 -0200553 if (!HAS_DDI(dev))
554 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300555
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300556 for_each_intel_encoder(dev, intel_encoder) {
557 struct intel_digital_port *intel_dig_port;
558 enum port port;
559 bool supports_hdmi;
560
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530561 if (intel_encoder->type == INTEL_OUTPUT_DSI)
562 continue;
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300563
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530564 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300565 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100566 continue;
567
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300568 supports_hdmi = intel_dig_port &&
569 intel_dig_port_supports_hdmi(intel_dig_port);
570
571 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
572 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100573 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300574}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300575
Paulo Zanoni248138b2012-11-29 11:29:31 -0200576static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
577 enum port port)
578{
579 uint32_t reg = DDI_BUF_CTL(port);
580 int i;
581
Vandana Kannan3449ca82015-03-27 14:19:09 +0200582 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200583 udelay(1);
584 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
585 return;
586 }
587 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
588}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300589
590/* Starting with Haswell, different DDI ports can work in FDI mode for
591 * connection to the PCH-located connectors. For this, it is necessary to train
592 * both the DDI port and PCH receiver for the desired DDI buffer settings.
593 *
594 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
595 * please note that when FDI mode is active on DDI E, it shares 2 lines with
596 * DDI A (which is used for eDP)
597 */
598
599void hsw_fdi_link_train(struct drm_crtc *crtc)
600{
601 struct drm_device *dev = crtc->dev;
602 struct drm_i915_private *dev_priv = dev->dev_private;
603 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200604 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300605
Paulo Zanoni04945642012-11-01 21:00:59 -0200606 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
607 * mode set "sequence for CRT port" document:
608 * - TP1 to TP2 time with the default value
609 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100610 *
611 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200612 */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300613 I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) |
Paulo Zanoni04945642012-11-01 21:00:59 -0200614 FDI_RX_PWRDN_LANE0_VAL(2) |
615 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
616
617 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000618 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100619 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200620 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300621 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
622 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200623 udelay(220);
624
625 /* Switch from Rawclk to PCDclk */
626 rx_ctl_val |= FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300627 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
Paulo Zanoni04945642012-11-01 21:00:59 -0200628
629 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200630 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
631 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200632
633 /* Start the training iterating through available voltages and emphasis,
634 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300635 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300636 /* Configure DP_TP_CTL with auto-training */
637 I915_WRITE(DP_TP_CTL(PORT_E),
638 DP_TP_CTL_FDI_AUTOTRAIN |
639 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
640 DP_TP_CTL_LINK_TRAIN_PAT1 |
641 DP_TP_CTL_ENABLE);
642
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000643 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
644 * DDI E does not support port reversal, the functionality is
645 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
646 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300647 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200648 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200649 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530650 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200651 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300652
653 udelay(600);
654
Paulo Zanoni04945642012-11-01 21:00:59 -0200655 /* Program PCH FDI Receiver TU */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300656 I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300657
Paulo Zanoni04945642012-11-01 21:00:59 -0200658 /* Enable PCH FDI Receiver with auto-training */
659 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300660 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
661 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200662
663 /* Wait for FDI receiver lane calibration */
664 udelay(30);
665
666 /* Unset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300667 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200668 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300669 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
670 POSTING_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200671
672 /* Wait for FDI auto training time */
673 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300674
675 temp = I915_READ(DP_TP_STATUS(PORT_E));
676 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200677 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300678
679 /* Enable normal pixel sending for FDI */
680 I915_WRITE(DP_TP_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200681 DP_TP_CTL_FDI_AUTOTRAIN |
682 DP_TP_CTL_LINK_TRAIN_NORMAL |
683 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
684 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300685
Paulo Zanoni04945642012-11-01 21:00:59 -0200686 return;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300687 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200688
Paulo Zanoni248138b2012-11-29 11:29:31 -0200689 temp = I915_READ(DDI_BUF_CTL(PORT_E));
690 temp &= ~DDI_BUF_CTL_ENABLE;
691 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
692 POSTING_READ(DDI_BUF_CTL(PORT_E));
693
Paulo Zanoni04945642012-11-01 21:00:59 -0200694 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200695 temp = I915_READ(DP_TP_CTL(PORT_E));
696 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
697 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
698 I915_WRITE(DP_TP_CTL(PORT_E), temp);
699 POSTING_READ(DP_TP_CTL(PORT_E));
700
701 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200702
703 rx_ctl_val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300704 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
705 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200706
707 /* Reset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300708 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200709 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
710 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300711 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
712 POSTING_READ(FDI_RX_MISC(PIPE_A));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300713 }
714
Paulo Zanoni04945642012-11-01 21:00:59 -0200715 DRM_ERROR("FDI link training failed!\n");
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300716}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300717
Dave Airlie44905a22014-05-02 13:36:43 +1000718void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
719{
720 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
721 struct intel_digital_port *intel_dig_port =
722 enc_to_dig_port(&encoder->base);
723
724 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530725 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300726 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a22014-05-02 13:36:43 +1000727}
728
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300729static struct intel_encoder *
730intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
731{
732 struct drm_device *dev = crtc->dev;
733 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
734 struct intel_encoder *intel_encoder, *ret = NULL;
735 int num_encoders = 0;
736
737 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
738 ret = intel_encoder;
739 num_encoders++;
740 }
741
742 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300743 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
744 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300745
746 BUG_ON(ret == NULL);
747 return ret;
748}
749
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530750struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200751intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200752{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200753 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
754 struct intel_encoder *ret = NULL;
755 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300756 struct drm_connector *connector;
757 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200758 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200759 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200760
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200761 state = crtc_state->base.state;
762
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300763 for_each_connector_in_state(state, connector, connector_state, i) {
764 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200765 continue;
766
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300767 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200768 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200769 }
770
771 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
772 pipe_name(crtc->pipe));
773
774 BUG_ON(ret == NULL);
775 return ret;
776}
777
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100778#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100779#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100780
781#define P_MIN 2
782#define P_MAX 64
783#define P_INC 2
784
785/* Constraints for PLL good behavior */
786#define REF_MIN 48
787#define REF_MAX 400
788#define VCO_MIN 2400
789#define VCO_MAX 4800
790
Damien Lespiau27893392014-09-04 12:27:23 +0100791#define abs_diff(a, b) ({ \
792 typeof(a) __a = (a); \
793 typeof(b) __b = (b); \
794 (void) (&__a == &__b); \
795 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100796
Damien Lespiau63582982015-05-07 18:38:46 +0100797struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100798 unsigned p, n2, r2;
799};
800
Damien Lespiau63582982015-05-07 18:38:46 +0100801static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300802{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100803 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300804
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100805 switch (clock) {
806 case 25175000:
807 case 25200000:
808 case 27000000:
809 case 27027000:
810 case 37762500:
811 case 37800000:
812 case 40500000:
813 case 40541000:
814 case 54000000:
815 case 54054000:
816 case 59341000:
817 case 59400000:
818 case 72000000:
819 case 74176000:
820 case 74250000:
821 case 81000000:
822 case 81081000:
823 case 89012000:
824 case 89100000:
825 case 108000000:
826 case 108108000:
827 case 111264000:
828 case 111375000:
829 case 148352000:
830 case 148500000:
831 case 162000000:
832 case 162162000:
833 case 222525000:
834 case 222750000:
835 case 296703000:
836 case 297000000:
837 budget = 0;
838 break;
839 case 233500000:
840 case 245250000:
841 case 247750000:
842 case 253250000:
843 case 298000000:
844 budget = 1500;
845 break;
846 case 169128000:
847 case 169500000:
848 case 179500000:
849 case 202000000:
850 budget = 2000;
851 break;
852 case 256250000:
853 case 262500000:
854 case 270000000:
855 case 272500000:
856 case 273750000:
857 case 280750000:
858 case 281250000:
859 case 286000000:
860 case 291750000:
861 budget = 4000;
862 break;
863 case 267250000:
864 case 268500000:
865 budget = 5000;
866 break;
867 default:
868 budget = 1000;
869 break;
870 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300871
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100872 return budget;
873}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300874
Damien Lespiau63582982015-05-07 18:38:46 +0100875static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
876 unsigned r2, unsigned n2, unsigned p,
877 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100878{
879 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300880
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100881 /* No best (r,n,p) yet */
882 if (best->p == 0) {
883 best->p = p;
884 best->n2 = n2;
885 best->r2 = r2;
886 return;
887 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300888
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100889 /*
890 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
891 * freq2k.
892 *
893 * delta = 1e6 *
894 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
895 * freq2k;
896 *
897 * and we would like delta <= budget.
898 *
899 * If the discrepancy is above the PPM-based budget, always prefer to
900 * improve upon the previous solution. However, if you're within the
901 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
902 */
903 a = freq2k * budget * p * r2;
904 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100905 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
906 diff_best = abs_diff(freq2k * best->p * best->r2,
907 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100908 c = 1000000 * diff;
909 d = 1000000 * diff_best;
910
911 if (a < c && b < d) {
912 /* If both are above the budget, pick the closer */
913 if (best->p * best->r2 * diff < p * r2 * diff_best) {
914 best->p = p;
915 best->n2 = n2;
916 best->r2 = r2;
917 }
918 } else if (a >= c && b < d) {
919 /* If A is below the threshold but B is above it? Update. */
920 best->p = p;
921 best->n2 = n2;
922 best->r2 = r2;
923 } else if (a >= c && b >= d) {
924 /* Both are below the limit, so pick the higher n2/(r2*r2) */
925 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
926 best->p = p;
927 best->n2 = n2;
928 best->r2 = r2;
929 }
930 }
931 /* Otherwise a < c && b >= d, do nothing */
932}
933
Damien Lespiau63582982015-05-07 18:38:46 +0100934static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, int reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800935{
936 int refclk = LC_FREQ;
937 int n, p, r;
938 u32 wrpll;
939
940 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300941 switch (wrpll & WRPLL_PLL_REF_MASK) {
942 case WRPLL_PLL_SSC:
943 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800944 /*
945 * We could calculate spread here, but our checking
946 * code only cares about 5% accuracy, and spread is a max of
947 * 0.5% downspread.
948 */
949 refclk = 135;
950 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300951 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800952 refclk = LC_FREQ;
953 break;
954 default:
955 WARN(1, "bad wrpll refclk\n");
956 return 0;
957 }
958
959 r = wrpll & WRPLL_DIVIDER_REF_MASK;
960 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
961 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
962
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800963 /* Convert to KHz, p & r have a fixed point portion */
964 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800965}
966
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000967static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
968 uint32_t dpll)
969{
970 uint32_t cfgcr1_reg, cfgcr2_reg;
971 uint32_t cfgcr1_val, cfgcr2_val;
972 uint32_t p0, p1, p2, dco_freq;
973
Ville Syrjälä923c12412015-09-30 17:06:43 +0300974 cfgcr1_reg = DPLL_CFGCR1(dpll);
975 cfgcr2_reg = DPLL_CFGCR2(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000976
977 cfgcr1_val = I915_READ(cfgcr1_reg);
978 cfgcr2_val = I915_READ(cfgcr2_reg);
979
980 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
981 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
982
983 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
984 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
985 else
986 p1 = 1;
987
988
989 switch (p0) {
990 case DPLL_CFGCR2_PDIV_1:
991 p0 = 1;
992 break;
993 case DPLL_CFGCR2_PDIV_2:
994 p0 = 2;
995 break;
996 case DPLL_CFGCR2_PDIV_3:
997 p0 = 3;
998 break;
999 case DPLL_CFGCR2_PDIV_7:
1000 p0 = 7;
1001 break;
1002 }
1003
1004 switch (p2) {
1005 case DPLL_CFGCR2_KDIV_5:
1006 p2 = 5;
1007 break;
1008 case DPLL_CFGCR2_KDIV_2:
1009 p2 = 2;
1010 break;
1011 case DPLL_CFGCR2_KDIV_3:
1012 p2 = 3;
1013 break;
1014 case DPLL_CFGCR2_KDIV_1:
1015 p2 = 1;
1016 break;
1017 }
1018
1019 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1020
1021 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1022 1000) / 0x8000;
1023
1024 return dco_freq / (p0 * p1 * p2 * 5);
1025}
1026
Ville Syrjälä398a0172015-06-30 15:33:51 +03001027static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1028{
1029 int dotclock;
1030
1031 if (pipe_config->has_pch_encoder)
1032 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1033 &pipe_config->fdi_m_n);
1034 else if (pipe_config->has_dp_encoder)
1035 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1036 &pipe_config->dp_m_n);
1037 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1038 dotclock = pipe_config->port_clock * 2 / 3;
1039 else
1040 dotclock = pipe_config->port_clock;
1041
1042 if (pipe_config->pixel_multiplier)
1043 dotclock /= pipe_config->pixel_multiplier;
1044
1045 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1046}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001047
1048static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001049 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001050{
1051 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001052 int link_clock = 0;
1053 uint32_t dpll_ctl1, dpll;
1054
Damien Lespiau134ffa42014-11-14 17:24:34 +00001055 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001056
1057 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1058
1059 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1060 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1061 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001062 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1063 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001064
1065 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001066 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001067 link_clock = 81000;
1068 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001069 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301070 link_clock = 108000;
1071 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001072 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001073 link_clock = 135000;
1074 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001075 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301076 link_clock = 162000;
1077 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001078 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301079 link_clock = 216000;
1080 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001081 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001082 link_clock = 270000;
1083 break;
1084 default:
1085 WARN(1, "Unsupported link rate\n");
1086 break;
1087 }
1088 link_clock *= 2;
1089 }
1090
1091 pipe_config->port_clock = link_clock;
1092
Ville Syrjälä398a0172015-06-30 15:33:51 +03001093 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001094}
1095
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001096static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001097 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001098{
1099 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001100 int link_clock = 0;
1101 u32 val, pll;
1102
Daniel Vetter26804af2014-06-25 22:01:55 +03001103 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001104 switch (val & PORT_CLK_SEL_MASK) {
1105 case PORT_CLK_SEL_LCPLL_810:
1106 link_clock = 81000;
1107 break;
1108 case PORT_CLK_SEL_LCPLL_1350:
1109 link_clock = 135000;
1110 break;
1111 case PORT_CLK_SEL_LCPLL_2700:
1112 link_clock = 270000;
1113 break;
1114 case PORT_CLK_SEL_WRPLL1:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001115 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
Jesse Barnes11578552014-01-21 12:42:10 -08001116 break;
1117 case PORT_CLK_SEL_WRPLL2:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001118 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
Jesse Barnes11578552014-01-21 12:42:10 -08001119 break;
1120 case PORT_CLK_SEL_SPLL:
1121 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1122 if (pll == SPLL_PLL_FREQ_810MHz)
1123 link_clock = 81000;
1124 else if (pll == SPLL_PLL_FREQ_1350MHz)
1125 link_clock = 135000;
1126 else if (pll == SPLL_PLL_FREQ_2700MHz)
1127 link_clock = 270000;
1128 else {
1129 WARN(1, "bad spll freq\n");
1130 return;
1131 }
1132 break;
1133 default:
1134 WARN(1, "bad port clock sel\n");
1135 return;
1136 }
1137
1138 pipe_config->port_clock = link_clock * 2;
1139
Ville Syrjälä398a0172015-06-30 15:33:51 +03001140 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001141}
1142
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301143static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1144 enum intel_dpll_id dpll)
1145{
Imre Deakaa610dc2015-06-22 23:35:52 +03001146 struct intel_shared_dpll *pll;
1147 struct intel_dpll_hw_state *state;
1148 intel_clock_t clock;
1149
1150 /* For DDI ports we always use a shared PLL. */
1151 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1152 return 0;
1153
1154 pll = &dev_priv->shared_dplls[dpll];
1155 state = &pll->config.hw_state;
1156
1157 clock.m1 = 2;
1158 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1159 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1160 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1161 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1162 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1163 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1164
1165 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301166}
1167
1168static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1169 struct intel_crtc_state *pipe_config)
1170{
1171 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1172 enum port port = intel_ddi_get_encoder_port(encoder);
1173 uint32_t dpll = port;
1174
Ville Syrjälä398a0172015-06-30 15:33:51 +03001175 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301176
Ville Syrjälä398a0172015-06-30 15:33:51 +03001177 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301178}
1179
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001180void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001181 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001182{
Damien Lespiau22606a12014-12-12 14:26:57 +00001183 struct drm_device *dev = encoder->base.dev;
1184
1185 if (INTEL_INFO(dev)->gen <= 8)
1186 hsw_ddi_clock_get(encoder, pipe_config);
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001187 else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001188 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301189 else if (IS_BROXTON(dev))
1190 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001191}
1192
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001193static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001194hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1195 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001196{
1197 uint64_t freq2k;
1198 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001199 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001200 unsigned budget;
1201
1202 freq2k = clock / 100;
1203
Damien Lespiau63582982015-05-07 18:38:46 +01001204 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001205
1206 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1207 * and directly pass the LC PLL to it. */
1208 if (freq2k == 5400000) {
1209 *n2_out = 2;
1210 *p_out = 1;
1211 *r2_out = 2;
1212 return;
1213 }
1214
1215 /*
1216 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1217 * the WR PLL.
1218 *
1219 * We want R so that REF_MIN <= Ref <= REF_MAX.
1220 * Injecting R2 = 2 * R gives:
1221 * REF_MAX * r2 > LC_FREQ * 2 and
1222 * REF_MIN * r2 < LC_FREQ * 2
1223 *
1224 * Which means the desired boundaries for r2 are:
1225 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1226 *
1227 */
1228 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1229 r2 <= LC_FREQ * 2 / REF_MIN;
1230 r2++) {
1231
1232 /*
1233 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1234 *
1235 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1236 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1237 * VCO_MAX * r2 > n2 * LC_FREQ and
1238 * VCO_MIN * r2 < n2 * LC_FREQ)
1239 *
1240 * Which means the desired boundaries for n2 are:
1241 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1242 */
1243 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1244 n2 <= VCO_MAX * r2 / LC_FREQ;
1245 n2++) {
1246
1247 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001248 hsw_wrpll_update_rnp(freq2k, budget,
1249 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001250 }
1251 }
1252
1253 *n2_out = best.n2;
1254 *p_out = best.p;
1255 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001256}
1257
Damien Lespiau0220ab62014-07-29 18:06:22 +01001258static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001259hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001260 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001261 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001262{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001263 int clock = crtc_state->port_clock;
1264
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001265 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001266 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001267 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001268 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001269
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001270 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001271
Daniel Vetter114fe482014-06-25 22:01:48 +03001272 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001273 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1274 WRPLL_DIVIDER_POST(p);
1275
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001276 memset(&crtc_state->dpll_hw_state, 0,
1277 sizeof(crtc_state->dpll_hw_state));
1278
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001279 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001280
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001281 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001282 if (pll == NULL) {
1283 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1284 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001285 return false;
1286 }
1287
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001288 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001289 }
1290
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001291 return true;
1292}
1293
Damien Lespiaudc253812015-06-25 16:15:06 +01001294struct skl_wrpll_context {
1295 uint64_t min_deviation; /* current minimal deviation */
1296 uint64_t central_freq; /* chosen central freq */
1297 uint64_t dco_freq; /* chosen dco freq */
1298 unsigned int p; /* chosen divider */
1299};
1300
1301static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1302{
1303 memset(ctx, 0, sizeof(*ctx));
1304
1305 ctx->min_deviation = U64_MAX;
1306}
1307
1308/* DCO freq must be within +1%/-6% of the DCO central freq */
1309#define SKL_DCO_MAX_PDEVIATION 100
1310#define SKL_DCO_MAX_NDEVIATION 600
1311
1312static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1313 uint64_t central_freq,
1314 uint64_t dco_freq,
1315 unsigned int divider)
1316{
1317 uint64_t deviation;
1318
1319 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1320 central_freq);
1321
1322 /* positive deviation */
1323 if (dco_freq >= central_freq) {
1324 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1325 deviation < ctx->min_deviation) {
1326 ctx->min_deviation = deviation;
1327 ctx->central_freq = central_freq;
1328 ctx->dco_freq = dco_freq;
1329 ctx->p = divider;
1330 }
1331 /* negative deviation */
1332 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1333 deviation < ctx->min_deviation) {
1334 ctx->min_deviation = deviation;
1335 ctx->central_freq = central_freq;
1336 ctx->dco_freq = dco_freq;
1337 ctx->p = divider;
1338 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001339}
1340
1341static void skl_wrpll_get_multipliers(unsigned int p,
1342 unsigned int *p0 /* out */,
1343 unsigned int *p1 /* out */,
1344 unsigned int *p2 /* out */)
1345{
1346 /* even dividers */
1347 if (p % 2 == 0) {
1348 unsigned int half = p / 2;
1349
1350 if (half == 1 || half == 2 || half == 3 || half == 5) {
1351 *p0 = 2;
1352 *p1 = 1;
1353 *p2 = half;
1354 } else if (half % 2 == 0) {
1355 *p0 = 2;
1356 *p1 = half / 2;
1357 *p2 = 2;
1358 } else if (half % 3 == 0) {
1359 *p0 = 3;
1360 *p1 = half / 3;
1361 *p2 = 2;
1362 } else if (half % 7 == 0) {
1363 *p0 = 7;
1364 *p1 = half / 7;
1365 *p2 = 2;
1366 }
1367 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1368 *p0 = 3;
1369 *p1 = 1;
1370 *p2 = p / 3;
1371 } else if (p == 5 || p == 7) {
1372 *p0 = p;
1373 *p1 = 1;
1374 *p2 = 1;
1375 } else if (p == 15) {
1376 *p0 = 3;
1377 *p1 = 1;
1378 *p2 = 5;
1379 } else if (p == 21) {
1380 *p0 = 7;
1381 *p1 = 1;
1382 *p2 = 3;
1383 } else if (p == 35) {
1384 *p0 = 7;
1385 *p1 = 1;
1386 *p2 = 5;
1387 }
1388}
1389
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001390struct skl_wrpll_params {
1391 uint32_t dco_fraction;
1392 uint32_t dco_integer;
1393 uint32_t qdiv_ratio;
1394 uint32_t qdiv_mode;
1395 uint32_t kdiv;
1396 uint32_t pdiv;
1397 uint32_t central_freq;
1398};
1399
Damien Lespiau76516fb2015-05-07 18:38:42 +01001400static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1401 uint64_t afe_clock,
1402 uint64_t central_freq,
1403 uint32_t p0, uint32_t p1, uint32_t p2)
1404{
1405 uint64_t dco_freq;
1406
Damien Lespiau76516fb2015-05-07 18:38:42 +01001407 switch (central_freq) {
1408 case 9600000000ULL:
1409 params->central_freq = 0;
1410 break;
1411 case 9000000000ULL:
1412 params->central_freq = 1;
1413 break;
1414 case 8400000000ULL:
1415 params->central_freq = 3;
1416 }
1417
1418 switch (p0) {
1419 case 1:
1420 params->pdiv = 0;
1421 break;
1422 case 2:
1423 params->pdiv = 1;
1424 break;
1425 case 3:
1426 params->pdiv = 2;
1427 break;
1428 case 7:
1429 params->pdiv = 4;
1430 break;
1431 default:
1432 WARN(1, "Incorrect PDiv\n");
1433 }
1434
1435 switch (p2) {
1436 case 5:
1437 params->kdiv = 0;
1438 break;
1439 case 2:
1440 params->kdiv = 1;
1441 break;
1442 case 3:
1443 params->kdiv = 2;
1444 break;
1445 case 1:
1446 params->kdiv = 3;
1447 break;
1448 default:
1449 WARN(1, "Incorrect KDiv\n");
1450 }
1451
1452 params->qdiv_ratio = p1;
1453 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1454
1455 dco_freq = p0 * p1 * p2 * afe_clock;
1456
1457 /*
1458 * Intermediate values are in Hz.
1459 * Divide by MHz to match bsepc
1460 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001461 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001462 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001463 div_u64((div_u64(dco_freq, 24) -
1464 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001465}
1466
Damien Lespiau318bd822015-05-07 18:38:40 +01001467static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001468skl_ddi_calculate_wrpll(int clock /* in Hz */,
1469 struct skl_wrpll_params *wrpll_params)
1470{
1471 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001472 uint64_t dco_central_freq[3] = {8400000000ULL,
1473 9000000000ULL,
1474 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001475 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1476 24, 28, 30, 32, 36, 40, 42, 44,
1477 48, 52, 54, 56, 60, 64, 66, 68,
1478 70, 72, 76, 78, 80, 84, 88, 90,
1479 92, 96, 98 };
1480 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1481 static const struct {
1482 const int *list;
1483 int n_dividers;
1484 } dividers[] = {
1485 { even_dividers, ARRAY_SIZE(even_dividers) },
1486 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1487 };
1488 struct skl_wrpll_context ctx;
1489 unsigned int dco, d, i;
1490 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001491
Damien Lespiaudc253812015-06-25 16:15:06 +01001492 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001493
Damien Lespiaudc253812015-06-25 16:15:06 +01001494 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1495 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1496 for (i = 0; i < dividers[d].n_dividers; i++) {
1497 unsigned int p = dividers[d].list[i];
1498 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001499
Damien Lespiaudc253812015-06-25 16:15:06 +01001500 skl_wrpll_try_divider(&ctx,
1501 dco_central_freq[dco],
1502 dco_freq,
1503 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001504 /*
1505 * Skip the remaining dividers if we're sure to
1506 * have found the definitive divider, we can't
1507 * improve a 0 deviation.
1508 */
1509 if (ctx.min_deviation == 0)
1510 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001511 }
1512 }
Damien Lespiau267db662015-06-25 16:19:24 +01001513
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001514skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001515 /*
1516 * If a solution is found with an even divider, prefer
1517 * this one.
1518 */
1519 if (d == 0 && ctx.p)
1520 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001521 }
1522
Damien Lespiaudc253812015-06-25 16:15:06 +01001523 if (!ctx.p) {
1524 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001525 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001526 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001527
Damien Lespiaudc253812015-06-25 16:15:06 +01001528 /*
1529 * gcc incorrectly analyses that these can be used without being
1530 * initialized. To be fair, it's hard to guess.
1531 */
1532 p0 = p1 = p2 = 0;
1533 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1534 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1535 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001536
Damien Lespiau318bd822015-05-07 18:38:40 +01001537 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001538}
1539
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001540static bool
1541skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001542 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001543 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001544{
1545 struct intel_shared_dpll *pll;
1546 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001547 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001548
1549 /*
1550 * See comment in intel_dpll_hw_state to understand why we always use 0
1551 * as the DPLL id in this function.
1552 */
1553
1554 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1555
1556 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1557 struct skl_wrpll_params wrpll_params = { 0, };
1558
1559 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1560
Damien Lespiau318bd822015-05-07 18:38:40 +01001561 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1562 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001563
1564 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1565 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1566 wrpll_params.dco_integer;
1567
1568 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1569 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1570 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1571 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1572 wrpll_params.central_freq;
1573 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001574 switch (crtc_state->port_clock / 2) {
1575 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001576 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001577 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001578 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001579 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001580 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001581 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001582 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001583 break;
1584 }
1585
1586 cfgcr1 = cfgcr2 = 0;
1587 } else /* eDP */
1588 return true;
1589
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001590 memset(&crtc_state->dpll_hw_state, 0,
1591 sizeof(crtc_state->dpll_hw_state));
1592
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001593 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1594 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1595 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001596
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001597 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001598 if (pll == NULL) {
1599 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1600 pipe_name(intel_crtc->pipe));
1601 return false;
1602 }
1603
1604 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001605 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001606
1607 return true;
1608}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001609
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301610/* bxt clock parameters */
1611struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301612 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301613 uint32_t p1;
1614 uint32_t p2;
1615 uint32_t m2_int;
1616 uint32_t m2_frac;
1617 bool m2_frac_en;
1618 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301619};
1620
1621/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301622static const struct bxt_clk_div bxt_dp_clk_val[] = {
1623 {162000, 4, 2, 32, 1677722, 1, 1},
1624 {270000, 4, 1, 27, 0, 0, 1},
1625 {540000, 2, 1, 27, 0, 0, 1},
1626 {216000, 3, 2, 32, 1677722, 1, 1},
1627 {243000, 4, 1, 24, 1258291, 1, 1},
1628 {324000, 4, 1, 32, 1677722, 1, 1},
1629 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301630};
1631
1632static bool
1633bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1634 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001635 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301636{
1637 struct intel_shared_dpll *pll;
1638 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301639 int vco = 0;
1640 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301641 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001642 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301643
1644 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1645 intel_clock_t best_clock;
1646
1647 /* Calculate HDMI div */
1648 /*
1649 * FIXME: tie the following calculation into
1650 * i9xx_crtc_compute_clock
1651 */
1652 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1653 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1654 clock, pipe_name(intel_crtc->pipe));
1655 return false;
1656 }
1657
1658 clk_div.p1 = best_clock.p1;
1659 clk_div.p2 = best_clock.p2;
1660 WARN_ON(best_clock.m1 != 2);
1661 clk_div.n = best_clock.n;
1662 clk_div.m2_int = best_clock.m2 >> 22;
1663 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1664 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1665
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301666 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301667 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1668 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301669 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301670
Sonika Jindal64987fc2015-05-26 17:50:13 +05301671 clk_div = bxt_dp_clk_val[0];
1672 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1673 if (bxt_dp_clk_val[i].clock == clock) {
1674 clk_div = bxt_dp_clk_val[i];
1675 break;
1676 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301677 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301678 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1679 }
1680
Vandana Kannane6292552015-07-01 17:02:57 +05301681 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301682 prop_coef = 4;
1683 int_coef = 9;
1684 gain_ctl = 3;
1685 targ_cnt = 8;
1686 } else if ((vco > 5400000 && vco < 6200000) ||
1687 (vco >= 4800000 && vco < 5400000)) {
1688 prop_coef = 5;
1689 int_coef = 11;
1690 gain_ctl = 3;
1691 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301692 } else if (vco == 5400000) {
1693 prop_coef = 3;
1694 int_coef = 8;
1695 gain_ctl = 1;
1696 targ_cnt = 9;
1697 } else {
1698 DRM_ERROR("Invalid VCO\n");
1699 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301700 }
1701
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001702 memset(&crtc_state->dpll_hw_state, 0,
1703 sizeof(crtc_state->dpll_hw_state));
1704
Vandana Kannane0681e32015-05-13 12:20:35 +05301705 if (clock > 270000)
1706 lanestagger = 0x18;
1707 else if (clock > 135000)
1708 lanestagger = 0x0d;
1709 else if (clock > 67000)
1710 lanestagger = 0x07;
1711 else if (clock > 33000)
1712 lanestagger = 0x04;
1713 else
1714 lanestagger = 0x02;
1715
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301716 crtc_state->dpll_hw_state.ebb0 =
1717 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1718 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1719 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1720 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1721
1722 if (clk_div.m2_frac_en)
1723 crtc_state->dpll_hw_state.pll3 =
1724 PORT_PLL_M2_FRAC_ENABLE;
1725
1726 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301727 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301728 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301729 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301730
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301731 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1732
Imre Deak05712c12015-06-18 17:25:54 +03001733 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1734
Vandana Kannane6292552015-07-01 17:02:57 +05301735 crtc_state->dpll_hw_state.pll10 =
1736 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1737 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301738
Imre Deak05712c12015-06-18 17:25:54 +03001739 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1740
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301741 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301742 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301743
1744 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1745 if (pll == NULL) {
1746 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1747 pipe_name(intel_crtc->pipe));
1748 return false;
1749 }
1750
1751 /* shared DPLL id 0 is DPLL A */
1752 crtc_state->ddi_pll_sel = pll->id;
1753
1754 return true;
1755}
1756
Damien Lespiau0220ab62014-07-29 18:06:22 +01001757/*
1758 * Tries to find a *shared* PLL for the CRTC and store it in
1759 * intel_crtc->ddi_pll_sel.
1760 *
1761 * For private DPLLs, compute_config() should do the selection for us. This
1762 * function should be folded into compute_config() eventually.
1763 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001764bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1765 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001766{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001767 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001768 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001769 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001770
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001771 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001772 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001773 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301774 else if (IS_BROXTON(dev))
1775 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001776 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001777 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001778 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001779 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001780}
1781
Paulo Zanonidae84792012-10-15 15:51:30 -03001782void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1783{
1784 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1785 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1786 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001787 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001788 int type = intel_encoder->type;
1789 uint32_t temp;
1790
Dave Airlie0e32b392014-05-02 14:02:48 +10001791 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001792 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001793 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001794 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001795 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001796 break;
1797 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001798 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001799 break;
1800 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001801 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001802 break;
1803 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001804 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001805 break;
1806 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001807 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001808 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001809 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001810 }
1811}
1812
Dave Airlie0e32b392014-05-02 14:02:48 +10001813void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1814{
1815 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1816 struct drm_device *dev = crtc->dev;
1817 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001818 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001819 uint32_t temp;
1820 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1821 if (state == true)
1822 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1823 else
1824 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1825 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1826}
1827
Damien Lespiau8228c252013-03-07 15:30:27 +00001828void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001829{
1830 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1831 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001832 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001833 struct drm_device *dev = crtc->dev;
1834 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001835 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001836 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001837 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001838 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001839 uint32_t temp;
1840
Paulo Zanoniad80a812012-10-24 16:06:19 -02001841 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1842 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001843 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001844
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001845 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001846 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001847 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001848 break;
1849 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001850 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001851 break;
1852 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001853 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001854 break;
1855 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001856 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001857 break;
1858 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001859 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001860 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001861
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001862 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001863 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001864 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001865 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c2012-08-08 14:15:28 -03001866
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001867 if (cpu_transcoder == TRANSCODER_EDP) {
1868 switch (pipe) {
1869 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001870 /* On Haswell, can only use the always-on power well for
1871 * eDP when not using the panel fitter, and when not
1872 * using motion blur mitigation (which we don't
1873 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001874 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001875 (intel_crtc->config->pch_pfit.enabled ||
1876 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001877 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1878 else
1879 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001880 break;
1881 case PIPE_B:
1882 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1883 break;
1884 case PIPE_C:
1885 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1886 break;
1887 default:
1888 BUG();
1889 break;
1890 }
1891 }
1892
Paulo Zanoni7739c332012-10-15 15:51:29 -03001893 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001894 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001895 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001896 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001897 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001898
Paulo Zanoni7739c332012-10-15 15:51:29 -03001899 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001900 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001901 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001902
1903 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1904 type == INTEL_OUTPUT_EDP) {
1905 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1906
Dave Airlie0e32b392014-05-02 14:02:48 +10001907 if (intel_dp->is_mst) {
1908 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1909 } else
1910 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1911
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001912 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001913 } else if (type == INTEL_OUTPUT_DP_MST) {
1914 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1915
1916 if (intel_dp->is_mst) {
1917 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1918 } else
1919 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001920
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001921 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001922 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001923 WARN(1, "Invalid encoder type %d for pipe %c\n",
1924 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001925 }
1926
Paulo Zanoniad80a812012-10-24 16:06:19 -02001927 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001928}
1929
Paulo Zanoniad80a812012-10-24 16:06:19 -02001930void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1931 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001932{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001933 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001934 uint32_t val = I915_READ(reg);
1935
Dave Airlie0e32b392014-05-02 14:02:48 +10001936 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001937 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001938 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001939}
1940
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001941bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1942{
1943 struct drm_device *dev = intel_connector->base.dev;
1944 struct drm_i915_private *dev_priv = dev->dev_private;
1945 struct intel_encoder *intel_encoder = intel_connector->encoder;
1946 int type = intel_connector->base.connector_type;
1947 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1948 enum pipe pipe = 0;
1949 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001950 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001951 uint32_t tmp;
1952
Paulo Zanoni882244a2014-04-01 14:55:12 -03001953 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001954 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001955 return false;
1956
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001957 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1958 return false;
1959
1960 if (port == PORT_A)
1961 cpu_transcoder = TRANSCODER_EDP;
1962 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001963 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001964
1965 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1966
1967 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1968 case TRANS_DDI_MODE_SELECT_HDMI:
1969 case TRANS_DDI_MODE_SELECT_DVI:
1970 return (type == DRM_MODE_CONNECTOR_HDMIA);
1971
1972 case TRANS_DDI_MODE_SELECT_DP_SST:
1973 if (type == DRM_MODE_CONNECTOR_eDP)
1974 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001975 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001976 case TRANS_DDI_MODE_SELECT_DP_MST:
1977 /* if the transcoder is in MST state then
1978 * connector isn't connected */
1979 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001980
1981 case TRANS_DDI_MODE_SELECT_FDI:
1982 return (type == DRM_MODE_CONNECTOR_VGA);
1983
1984 default:
1985 return false;
1986 }
1987}
1988
Daniel Vetter85234cd2012-07-02 13:27:29 +02001989bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1990 enum pipe *pipe)
1991{
1992 struct drm_device *dev = encoder->base.dev;
1993 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001994 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001995 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001996 u32 tmp;
1997 int i;
1998
Imre Deak6d129be2014-03-05 16:20:54 +02001999 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002000 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02002001 return false;
2002
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002003 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002004
2005 if (!(tmp & DDI_BUF_CTL_ENABLE))
2006 return false;
2007
Paulo Zanoniad80a812012-10-24 16:06:19 -02002008 if (port == PORT_A) {
2009 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002010
Paulo Zanoniad80a812012-10-24 16:06:19 -02002011 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2012 case TRANS_DDI_EDP_INPUT_A_ON:
2013 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2014 *pipe = PIPE_A;
2015 break;
2016 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2017 *pipe = PIPE_B;
2018 break;
2019 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2020 *pipe = PIPE_C;
2021 break;
2022 }
2023
2024 return true;
2025 } else {
2026 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2027 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2028
2029 if ((tmp & TRANS_DDI_PORT_MASK)
2030 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002031 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2032 return false;
2033
Paulo Zanoniad80a812012-10-24 16:06:19 -02002034 *pipe = i;
2035 return true;
2036 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002037 }
2038 }
2039
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002040 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002041
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002042 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002043}
2044
Paulo Zanonifc914632012-10-05 12:05:54 -03002045void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2046{
2047 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302048 struct drm_device *dev = crtc->dev;
2049 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002050 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2051 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002052 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002053
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002054 if (cpu_transcoder != TRANSCODER_EDP)
2055 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2056 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002057}
2058
2059void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2060{
2061 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002062 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002063
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002064 if (cpu_transcoder != TRANSCODER_EDP)
2065 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2066 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002067}
2068
David Weinehallf8896f52015-06-25 11:11:03 +03002069static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2070 enum port port, int type)
2071{
2072 struct drm_i915_private *dev_priv = dev->dev_private;
2073 const struct ddi_buf_trans *ddi_translations;
2074 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002075 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002076 int n_entries;
2077 u32 reg;
2078
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002079 /* VBT may override standard boost values */
2080 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2081 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2082
David Weinehallf8896f52015-06-25 11:11:03 +03002083 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002084 if (dp_iboost) {
2085 iboost = dp_iboost;
2086 } else {
2087 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2088 iboost = ddi_translations[port].i_boost;
2089 }
David Weinehallf8896f52015-06-25 11:11:03 +03002090 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002091 if (dp_iboost) {
2092 iboost = dp_iboost;
2093 } else {
2094 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2095 iboost = ddi_translations[port].i_boost;
2096 }
David Weinehallf8896f52015-06-25 11:11:03 +03002097 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002098 if (hdmi_iboost) {
2099 iboost = hdmi_iboost;
2100 } else {
2101 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2102 iboost = ddi_translations[port].i_boost;
2103 }
David Weinehallf8896f52015-06-25 11:11:03 +03002104 } else {
2105 return;
2106 }
2107
2108 /* Make sure that the requested I_boost is valid */
2109 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2110 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2111 return;
2112 }
2113
2114 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2115 reg &= ~BALANCE_LEG_MASK(port);
2116 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2117
2118 if (iboost)
2119 reg |= iboost << BALANCE_LEG_SHIFT(port);
2120 else
2121 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2122
2123 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2124}
2125
2126static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2127 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302128{
2129 struct drm_i915_private *dev_priv = dev->dev_private;
2130 const struct bxt_ddi_buf_trans *ddi_translations;
2131 u32 n_entries, i;
2132 uint32_t val;
2133
Sonika Jindald9d70002015-09-24 10:24:56 +05302134 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2135 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2136 ddi_translations = bxt_ddi_translations_edp;
2137 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2138 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302139 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2140 ddi_translations = bxt_ddi_translations_dp;
2141 } else if (type == INTEL_OUTPUT_HDMI) {
2142 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2143 ddi_translations = bxt_ddi_translations_hdmi;
2144 } else {
2145 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2146 type);
2147 return;
2148 }
2149
2150 /* Check if default value has to be used */
2151 if (level >= n_entries ||
2152 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2153 for (i = 0; i < n_entries; i++) {
2154 if (ddi_translations[i].default_index) {
2155 level = i;
2156 break;
2157 }
2158 }
2159 }
2160
2161 /*
2162 * While we write to the group register to program all lanes at once we
2163 * can read only lane registers and we pick lanes 0/1 for that.
2164 */
2165 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2166 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2167 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2168
2169 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2170 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2171 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2172 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2173 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2174
2175 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302176 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302177 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302178 val |= SCALE_DCOMP_METHOD;
2179
2180 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2181 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2182
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302183 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2184
2185 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2186 val &= ~DE_EMPHASIS;
2187 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2188 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2189
2190 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2191 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2192 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2193}
2194
David Weinehallf8896f52015-06-25 11:11:03 +03002195static uint32_t translate_signal_level(int signal_levels)
2196{
2197 uint32_t level;
2198
2199 switch (signal_levels) {
2200 default:
2201 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2202 signal_levels);
2203 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2204 level = 0;
2205 break;
2206 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2207 level = 1;
2208 break;
2209 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2210 level = 2;
2211 break;
2212 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2213 level = 3;
2214 break;
2215
2216 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2217 level = 4;
2218 break;
2219 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2220 level = 5;
2221 break;
2222 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2223 level = 6;
2224 break;
2225
2226 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2227 level = 7;
2228 break;
2229 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2230 level = 8;
2231 break;
2232
2233 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2234 level = 9;
2235 break;
2236 }
2237
2238 return level;
2239}
2240
2241uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2242{
2243 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2244 struct drm_device *dev = dport->base.base.dev;
2245 struct intel_encoder *encoder = &dport->base;
2246 uint8_t train_set = intel_dp->train_set[0];
2247 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2248 DP_TRAIN_PRE_EMPHASIS_MASK);
2249 enum port port = dport->port;
2250 uint32_t level;
2251
2252 level = translate_signal_level(signal_levels);
2253
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002254 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
David Weinehallf8896f52015-06-25 11:11:03 +03002255 skl_ddi_set_iboost(dev, level, port, encoder->type);
2256 else if (IS_BROXTON(dev))
2257 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2258
2259 return DDI_BUF_TRANS_SELECT(level);
2260}
2261
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002262void intel_ddi_clk_select(struct intel_encoder *encoder,
2263 const struct intel_crtc_state *pipe_config)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002264{
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002265 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2266 enum port port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002267
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002268 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
2269 uint32_t dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002270 uint32_t val;
2271
Damien Lespiau5416d872014-11-14 17:24:33 +00002272 /*
2273 * DPLL0 is used for eDP and is the only "private" DPLL (as
2274 * opposed to shared) on SKL
2275 */
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002276 if (encoder->type == INTEL_OUTPUT_EDP) {
Damien Lespiau5416d872014-11-14 17:24:33 +00002277 WARN_ON(dpll != SKL_DPLL0);
2278
2279 val = I915_READ(DPLL_CTRL1);
2280
2281 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2282 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002283 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002284 val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002285
2286 I915_WRITE(DPLL_CTRL1, val);
2287 POSTING_READ(DPLL_CTRL1);
2288 }
2289
2290 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002291 val = I915_READ(DPLL_CTRL2);
2292
2293 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2294 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2295 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2296 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2297
2298 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002299
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002300 } else if (INTEL_INFO(dev_priv)->gen < 9) {
2301 WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2302 I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002303 }
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002304}
2305
2306static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
2307{
2308 struct drm_encoder *encoder = &intel_encoder->base;
2309 struct drm_device *dev = encoder->dev;
2310 struct drm_i915_private *dev_priv = dev->dev_private;
2311 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
2312 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2313 int type = intel_encoder->type;
2314 int hdmi_level;
2315
2316 if (type == INTEL_OUTPUT_EDP) {
2317 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2318 intel_edp_panel_on(intel_dp);
2319 }
2320
2321 intel_ddi_clk_select(intel_encoder, crtc->config);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002322
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002323 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002324 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002325
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002326 intel_dp_set_link_params(intel_dp, crtc->config);
2327
Dave Airlie44905a22014-05-02 13:36:43 +10002328 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002329
2330 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2331 intel_dp_start_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002332 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002333 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002334 } else if (type == INTEL_OUTPUT_HDMI) {
2335 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2336
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302337 if (IS_BROXTON(dev)) {
2338 hdmi_level = dev_priv->vbt.
2339 ddi_port_info[port].hdmi_level_shift;
2340 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2341 INTEL_OUTPUT_HDMI);
2342 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002343 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002344 crtc->config->has_hdmi_sink,
2345 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002346 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002347}
2348
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002349static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002350{
2351 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002352 struct drm_device *dev = encoder->dev;
2353 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002354 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002355 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002356 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002357 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002358
2359 val = I915_READ(DDI_BUF_CTL(port));
2360 if (val & DDI_BUF_CTL_ENABLE) {
2361 val &= ~DDI_BUF_CTL_ENABLE;
2362 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002363 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002364 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002365
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002366 val = I915_READ(DP_TP_CTL(port));
2367 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2368 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2369 I915_WRITE(DP_TP_CTL(port), val);
2370
2371 if (wait)
2372 intel_wait_ddi_buf_idle(dev_priv, port);
2373
Jani Nikula76bb80e2013-11-15 15:29:57 +02002374 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002375 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002376 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002377 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002378 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002379 }
2380
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002381 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002382 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2383 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302384 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002385 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002386}
2387
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002388static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002389{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002390 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002391 struct drm_crtc *crtc = encoder->crtc;
2392 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002393 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002394 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002395 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2396 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002397
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002398 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002399 struct intel_digital_port *intel_dig_port =
2400 enc_to_dig_port(encoder);
2401
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002402 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2403 * are ignored so nothing special needs to be done besides
2404 * enabling the port.
2405 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002406 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002407 intel_dig_port->saved_port_bits |
2408 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002409 } else if (type == INTEL_OUTPUT_EDP) {
2410 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2411
Vandana Kannan23f08d82014-11-13 14:55:22 +00002412 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002413 intel_dp_stop_link_train(intel_dp);
2414
Daniel Vetter4be73782014-01-17 14:39:48 +01002415 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002416 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302417 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002418 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002419
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002420 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002421 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002422 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002423 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002424}
2425
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002426static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002427{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002428 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002429 struct drm_crtc *crtc = encoder->crtc;
2430 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002431 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002432 struct drm_device *dev = encoder->dev;
2433 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002434
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002435 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002436 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002437 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2438 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002439
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002440 if (type == INTEL_OUTPUT_EDP) {
2441 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2442
Vandana Kannanc3955782015-01-22 15:17:40 +05302443 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002444 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002445 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002446 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002447}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002448
Daniel Vettere0b01be2014-06-25 22:02:01 +03002449static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2450 struct intel_shared_dpll *pll)
2451{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002452 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002453 POSTING_READ(WRPLL_CTL(pll->id));
2454 udelay(20);
2455}
2456
Daniel Vetter12030432014-06-25 22:02:00 +03002457static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2458 struct intel_shared_dpll *pll)
2459{
2460 uint32_t val;
2461
2462 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002463 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2464 POSTING_READ(WRPLL_CTL(pll->id));
2465}
2466
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002467static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2468 struct intel_shared_dpll *pll,
2469 struct intel_dpll_hw_state *hw_state)
2470{
2471 uint32_t val;
2472
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002473 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002474 return false;
2475
2476 val = I915_READ(WRPLL_CTL(pll->id));
2477 hw_state->wrpll = val;
2478
2479 return val & WRPLL_PLL_ENABLE;
2480}
2481
Damien Lespiauca1381b2014-07-15 15:05:33 +01002482static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002483 "WRPLL 1",
2484 "WRPLL 2",
2485};
2486
Damien Lespiau143b3072014-07-29 18:06:19 +01002487static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002488{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002489 int i;
2490
Daniel Vetter716c2e52014-06-25 22:02:02 +03002491 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002492
Daniel Vetter716c2e52014-06-25 22:02:02 +03002493 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002494 dev_priv->shared_dplls[i].id = i;
2495 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002496 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002497 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002498 dev_priv->shared_dplls[i].get_hw_state =
2499 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002500 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002501}
2502
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002503static const char * const skl_ddi_pll_names[] = {
2504 "DPLL 1",
2505 "DPLL 2",
2506 "DPLL 3",
2507};
2508
2509struct skl_dpll_regs {
2510 u32 ctl, cfgcr1, cfgcr2;
2511};
2512
2513/* this array is indexed by the *shared* pll id */
2514static const struct skl_dpll_regs skl_dpll_regs[3] = {
2515 {
2516 /* DPLL 1 */
2517 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002518 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2519 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002520 },
2521 {
2522 /* DPLL 2 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002523 .ctl = WRPLL_CTL(0),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002524 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2525 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002526 },
2527 {
2528 /* DPLL 3 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002529 .ctl = WRPLL_CTL(1),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002530 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2531 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002532 },
2533};
2534
2535static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2536 struct intel_shared_dpll *pll)
2537{
2538 uint32_t val;
2539 unsigned int dpll;
2540 const struct skl_dpll_regs *regs = skl_dpll_regs;
2541
2542 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2543 dpll = pll->id + 1;
2544
2545 val = I915_READ(DPLL_CTRL1);
2546
2547 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002548 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002549 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2550
2551 I915_WRITE(DPLL_CTRL1, val);
2552 POSTING_READ(DPLL_CTRL1);
2553
2554 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2555 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2556 POSTING_READ(regs[pll->id].cfgcr1);
2557 POSTING_READ(regs[pll->id].cfgcr2);
2558
2559 /* the enable bit is always bit 31 */
2560 I915_WRITE(regs[pll->id].ctl,
2561 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2562
2563 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2564 DRM_ERROR("DPLL %d not locked\n", dpll);
2565}
2566
2567static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2568 struct intel_shared_dpll *pll)
2569{
2570 const struct skl_dpll_regs *regs = skl_dpll_regs;
2571
2572 /* the enable bit is always bit 31 */
2573 I915_WRITE(regs[pll->id].ctl,
2574 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2575 POSTING_READ(regs[pll->id].ctl);
2576}
2577
2578static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2579 struct intel_shared_dpll *pll,
2580 struct intel_dpll_hw_state *hw_state)
2581{
2582 uint32_t val;
2583 unsigned int dpll;
2584 const struct skl_dpll_regs *regs = skl_dpll_regs;
2585
2586 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2587 return false;
2588
2589 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2590 dpll = pll->id + 1;
2591
2592 val = I915_READ(regs[pll->id].ctl);
2593 if (!(val & LCPLL_PLL_ENABLE))
2594 return false;
2595
2596 val = I915_READ(DPLL_CTRL1);
2597 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2598
2599 /* avoid reading back stale values if HDMI mode is not enabled */
2600 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2601 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2602 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2603 }
2604
2605 return true;
2606}
2607
2608static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2609{
2610 int i;
2611
2612 dev_priv->num_shared_dpll = 3;
2613
2614 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2615 dev_priv->shared_dplls[i].id = i;
2616 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2617 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2618 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2619 dev_priv->shared_dplls[i].get_hw_state =
2620 skl_ddi_pll_get_hw_state;
2621 }
2622}
2623
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302624static void broxton_phy_init(struct drm_i915_private *dev_priv,
2625 enum dpio_phy phy)
2626{
2627 enum port port;
2628 uint32_t val;
2629
2630 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2631 val |= GT_DISPLAY_POWER_ON(phy);
2632 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2633
2634 /* Considering 10ms timeout until BSpec is updated */
2635 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2636 DRM_ERROR("timeout during PHY%d power on\n", phy);
2637
2638 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2639 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2640 int lane;
2641
2642 for (lane = 0; lane < 4; lane++) {
2643 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2644 /*
2645 * Note that on CHV this flag is called UPAR, but has
2646 * the same function.
2647 */
2648 val &= ~LATENCY_OPTIM;
2649 if (lane != 1)
2650 val |= LATENCY_OPTIM;
2651
2652 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2653 }
2654 }
2655
2656 /* Program PLL Rcomp code offset */
2657 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2658 val &= ~IREF0RC_OFFSET_MASK;
2659 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2660 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2661
2662 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2663 val &= ~IREF1RC_OFFSET_MASK;
2664 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2665 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2666
2667 /* Program power gating */
2668 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2669 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2670 SUS_CLK_CONFIG;
2671 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2672
2673 if (phy == DPIO_PHY0) {
2674 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2675 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2676 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2677 }
2678
2679 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2680 val &= ~OCL2_LDOFUSE_PWR_DIS;
2681 /*
2682 * On PHY1 disable power on the second channel, since no port is
2683 * connected there. On PHY0 both channels have a port, so leave it
2684 * enabled.
2685 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2686 * power down the second channel on PHY0 as well.
2687 */
2688 if (phy == DPIO_PHY1)
2689 val |= OCL2_LDOFUSE_PWR_DIS;
2690 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2691
2692 if (phy == DPIO_PHY0) {
2693 uint32_t grc_code;
2694 /*
2695 * PHY0 isn't connected to an RCOMP resistor so copy over
2696 * the corresponding calibrated value from PHY1, and disable
2697 * the automatic calibration on PHY0.
2698 */
2699 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2700 10))
2701 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2702
2703 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2704 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2705 grc_code = val << GRC_CODE_FAST_SHIFT |
2706 val << GRC_CODE_SLOW_SHIFT |
2707 val;
2708 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2709
2710 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2711 val |= GRC_DIS | GRC_RDY_OVRD;
2712 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2713 }
2714
2715 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2716 val |= COMMON_RESET_DIS;
2717 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2718}
2719
2720void broxton_ddi_phy_init(struct drm_device *dev)
2721{
2722 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2723 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2724 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2725}
2726
2727static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2728 enum dpio_phy phy)
2729{
2730 uint32_t val;
2731
2732 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2733 val &= ~COMMON_RESET_DIS;
2734 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2735}
2736
2737void broxton_ddi_phy_uninit(struct drm_device *dev)
2738{
2739 struct drm_i915_private *dev_priv = dev->dev_private;
2740
2741 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2742 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2743
2744 /* FIXME: do this in broxton_phy_uninit per phy */
2745 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2746}
2747
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302748static const char * const bxt_ddi_pll_names[] = {
2749 "PORT PLL A",
2750 "PORT PLL B",
2751 "PORT PLL C",
2752};
2753
2754static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2755 struct intel_shared_dpll *pll)
2756{
2757 uint32_t temp;
2758 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2759
2760 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2761 temp &= ~PORT_PLL_REF_SEL;
2762 /* Non-SSC reference */
2763 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2764
2765 /* Disable 10 bit clock */
2766 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2767 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2768 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2769
2770 /* Write P1 & P2 */
2771 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2772 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2773 temp |= pll->config.hw_state.ebb0;
2774 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2775
2776 /* Write M2 integer */
2777 temp = I915_READ(BXT_PORT_PLL(port, 0));
2778 temp &= ~PORT_PLL_M2_MASK;
2779 temp |= pll->config.hw_state.pll0;
2780 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2781
2782 /* Write N */
2783 temp = I915_READ(BXT_PORT_PLL(port, 1));
2784 temp &= ~PORT_PLL_N_MASK;
2785 temp |= pll->config.hw_state.pll1;
2786 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2787
2788 /* Write M2 fraction */
2789 temp = I915_READ(BXT_PORT_PLL(port, 2));
2790 temp &= ~PORT_PLL_M2_FRAC_MASK;
2791 temp |= pll->config.hw_state.pll2;
2792 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2793
2794 /* Write M2 fraction enable */
2795 temp = I915_READ(BXT_PORT_PLL(port, 3));
2796 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2797 temp |= pll->config.hw_state.pll3;
2798 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2799
2800 /* Write coeff */
2801 temp = I915_READ(BXT_PORT_PLL(port, 6));
2802 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2803 temp &= ~PORT_PLL_INT_COEFF_MASK;
2804 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2805 temp |= pll->config.hw_state.pll6;
2806 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2807
2808 /* Write calibration val */
2809 temp = I915_READ(BXT_PORT_PLL(port, 8));
2810 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2811 temp |= pll->config.hw_state.pll8;
2812 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2813
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302814 temp = I915_READ(BXT_PORT_PLL(port, 9));
2815 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002816 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302817 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2818
2819 temp = I915_READ(BXT_PORT_PLL(port, 10));
2820 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2821 temp &= ~PORT_PLL_DCO_AMP_MASK;
2822 temp |= pll->config.hw_state.pll10;
2823 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302824
2825 /* Recalibrate with new settings */
2826 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2827 temp |= PORT_PLL_RECALIBRATE;
2828 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002829 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2830 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302831 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2832
2833 /* Enable PLL */
2834 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2835 temp |= PORT_PLL_ENABLE;
2836 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2837 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2838
2839 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2840 PORT_PLL_LOCK), 200))
2841 DRM_ERROR("PLL %d not locked\n", port);
2842
2843 /*
2844 * While we write to the group register to program all lanes at once we
2845 * can read only lane registers and we pick lanes 0/1 for that.
2846 */
2847 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2848 temp &= ~LANE_STAGGER_MASK;
2849 temp &= ~LANESTAGGER_STRAP_OVRD;
2850 temp |= pll->config.hw_state.pcsdw12;
2851 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2852}
2853
2854static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2855 struct intel_shared_dpll *pll)
2856{
2857 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2858 uint32_t temp;
2859
2860 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2861 temp &= ~PORT_PLL_ENABLE;
2862 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2863 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2864}
2865
2866static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2867 struct intel_shared_dpll *pll,
2868 struct intel_dpll_hw_state *hw_state)
2869{
2870 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2871 uint32_t val;
2872
2873 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2874 return false;
2875
2876 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2877 if (!(val & PORT_PLL_ENABLE))
2878 return false;
2879
2880 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002881 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2882
Imre Deak05712c12015-06-18 17:25:54 +03002883 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2884 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2885
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302886 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002887 hw_state->pll0 &= PORT_PLL_M2_MASK;
2888
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302889 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002890 hw_state->pll1 &= PORT_PLL_N_MASK;
2891
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302892 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002893 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2894
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302895 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002896 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2897
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302898 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002899 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2900 PORT_PLL_INT_COEFF_MASK |
2901 PORT_PLL_GAIN_CTL_MASK;
2902
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302903 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002904 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2905
Imre Deak05712c12015-06-18 17:25:54 +03002906 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2907 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2908
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302909 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002910 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2911 PORT_PLL_DCO_AMP_MASK;
2912
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302913 /*
2914 * While we write to the group register to program all lanes at once we
2915 * can read only lane registers. We configure all lanes the same way, so
2916 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2917 */
2918 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002919 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302920 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2921 hw_state->pcsdw12,
2922 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002923 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302924
2925 return true;
2926}
2927
2928static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2929{
2930 int i;
2931
2932 dev_priv->num_shared_dpll = 3;
2933
2934 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2935 dev_priv->shared_dplls[i].id = i;
2936 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2937 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2938 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2939 dev_priv->shared_dplls[i].get_hw_state =
2940 bxt_ddi_pll_get_hw_state;
2941 }
2942}
2943
Damien Lespiau143b3072014-07-29 18:06:19 +01002944void intel_ddi_pll_init(struct drm_device *dev)
2945{
2946 struct drm_i915_private *dev_priv = dev->dev_private;
2947 uint32_t val = I915_READ(LCPLL_CTL);
2948
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002949 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002950 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302951 else if (IS_BROXTON(dev))
2952 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002953 else
2954 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002955
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002956 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002957 int cdclk_freq;
2958
2959 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002960 dev_priv->skl_boot_cdclk = cdclk_freq;
Shobhit Kumarc73666f2015-10-20 18:13:12 +05302961 if (skl_sanitize_cdclk(dev_priv))
2962 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002963 else
2964 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302965 } else if (IS_BROXTON(dev)) {
2966 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302967 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002968 } else {
2969 /*
2970 * The LCPLL register should be turned on by the BIOS. For now
2971 * let's just check its state and print errors in case
2972 * something is wrong. Don't even try to turn it on.
2973 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002974
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002975 if (val & LCPLL_CD_SOURCE_FCLK)
2976 DRM_ERROR("CDCLK source is not LCPLL\n");
2977
2978 if (val & LCPLL_PLL_DISABLE)
2979 DRM_ERROR("LCPLL is disabled\n");
2980 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002981}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002982
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03002983void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
Paulo Zanonic19b0662012-10-15 15:51:41 -03002984{
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03002985 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
2986 struct drm_i915_private *dev_priv =
2987 to_i915(intel_dig_port->base.base.dev);
Paulo Zanoni174edf12012-10-26 19:05:50 -02002988 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002989 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302990 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002991
2992 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2993 val = I915_READ(DDI_BUF_CTL(port));
2994 if (val & DDI_BUF_CTL_ENABLE) {
2995 val &= ~DDI_BUF_CTL_ENABLE;
2996 I915_WRITE(DDI_BUF_CTL(port), val);
2997 wait = true;
2998 }
2999
3000 val = I915_READ(DP_TP_CTL(port));
3001 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3002 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3003 I915_WRITE(DP_TP_CTL(port), val);
3004 POSTING_READ(DP_TP_CTL(port));
3005
3006 if (wait)
3007 intel_wait_ddi_buf_idle(dev_priv, port);
3008 }
3009
Dave Airlie0e32b392014-05-02 14:02:48 +10003010 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003011 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003012 if (intel_dp->is_mst)
3013 val |= DP_TP_CTL_MODE_MST;
3014 else {
3015 val |= DP_TP_CTL_MODE_SST;
3016 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3017 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3018 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003019 I915_WRITE(DP_TP_CTL(port), val);
3020 POSTING_READ(DP_TP_CTL(port));
3021
3022 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3023 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3024 POSTING_READ(DDI_BUF_CTL(port));
3025
3026 udelay(600);
3027}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003028
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003029void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3030{
3031 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3032 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3033 uint32_t val;
3034
3035 intel_ddi_post_disable(intel_encoder);
3036
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003037 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003038 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003039 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003040
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003041 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003042 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3043 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003044 I915_WRITE(FDI_RX_MISC(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003045
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003046 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003047 val &= ~FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003048 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003049
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003050 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003051 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003052 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003053}
3054
Ville Syrjälä6801c182013-09-24 14:24:05 +03003055void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003056 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003057{
3058 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3059 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003060 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003061 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003062 u32 temp, flags = 0;
3063
3064 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3065 if (temp & TRANS_DDI_PHSYNC)
3066 flags |= DRM_MODE_FLAG_PHSYNC;
3067 else
3068 flags |= DRM_MODE_FLAG_NHSYNC;
3069 if (temp & TRANS_DDI_PVSYNC)
3070 flags |= DRM_MODE_FLAG_PVSYNC;
3071 else
3072 flags |= DRM_MODE_FLAG_NVSYNC;
3073
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003074 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003075
3076 switch (temp & TRANS_DDI_BPC_MASK) {
3077 case TRANS_DDI_BPC_6:
3078 pipe_config->pipe_bpp = 18;
3079 break;
3080 case TRANS_DDI_BPC_8:
3081 pipe_config->pipe_bpp = 24;
3082 break;
3083 case TRANS_DDI_BPC_10:
3084 pipe_config->pipe_bpp = 30;
3085 break;
3086 case TRANS_DDI_BPC_12:
3087 pipe_config->pipe_bpp = 36;
3088 break;
3089 default:
3090 break;
3091 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003092
3093 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3094 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003095 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003096 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3097
3098 if (intel_hdmi->infoframe_enabled(&encoder->base))
3099 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003100 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003101 case TRANS_DDI_MODE_SELECT_DVI:
3102 case TRANS_DDI_MODE_SELECT_FDI:
3103 break;
3104 case TRANS_DDI_MODE_SELECT_DP_SST:
3105 case TRANS_DDI_MODE_SELECT_DP_MST:
3106 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003107 pipe_config->lane_count =
3108 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003109 intel_dp_get_m_n(intel_crtc, pipe_config);
3110 break;
3111 default:
3112 break;
3113 }
Daniel Vetter10214422013-11-18 07:38:16 +01003114
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003115 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003116 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003117 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003118 pipe_config->has_audio = true;
3119 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003120
Daniel Vetter10214422013-11-18 07:38:16 +01003121 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3122 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3123 /*
3124 * This is a big fat ugly hack.
3125 *
3126 * Some machines in UEFI boot mode provide us a VBT that has 18
3127 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3128 * unknown we fail to light up. Yet the same BIOS boots up with
3129 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3130 * max, not what it tells us to use.
3131 *
3132 * Note: This will still be broken if the eDP panel is not lit
3133 * up by the BIOS, and thus we can't get the mode at module
3134 * load.
3135 */
3136 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3137 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3138 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3139 }
Jesse Barnes11578552014-01-21 12:42:10 -08003140
Damien Lespiau22606a12014-12-12 14:26:57 +00003141 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003142}
3143
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003144static void intel_ddi_destroy(struct drm_encoder *encoder)
3145{
3146 /* HDMI has nothing special to destroy, so we can go with this. */
3147 intel_dp_encoder_destroy(encoder);
3148}
3149
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003150static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003151 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003152{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003153 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003154 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003155
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003156 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003157
Daniel Vettereccb1402013-05-22 00:50:22 +02003158 if (port == PORT_A)
3159 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3160
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003161 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003162 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003163 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003164 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003165}
3166
3167static const struct drm_encoder_funcs intel_ddi_funcs = {
3168 .destroy = intel_ddi_destroy,
3169};
3170
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003171static struct intel_connector *
3172intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3173{
3174 struct intel_connector *connector;
3175 enum port port = intel_dig_port->port;
3176
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003177 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003178 if (!connector)
3179 return NULL;
3180
3181 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3182 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3183 kfree(connector);
3184 return NULL;
3185 }
3186
3187 return connector;
3188}
3189
3190static struct intel_connector *
3191intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3192{
3193 struct intel_connector *connector;
3194 enum port port = intel_dig_port->port;
3195
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003196 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003197 if (!connector)
3198 return NULL;
3199
3200 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3201 intel_hdmi_init_connector(intel_dig_port, connector);
3202
3203 return connector;
3204}
3205
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003206void intel_ddi_init(struct drm_device *dev, enum port port)
3207{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003208 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003209 struct intel_digital_port *intel_dig_port;
3210 struct intel_encoder *intel_encoder;
3211 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003212 bool init_hdmi, init_dp;
3213
3214 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3215 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3216 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3217 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003218 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003219 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003220 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003221 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003222
Daniel Vetterb14c5672013-09-19 12:18:32 +02003223 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003224 if (!intel_dig_port)
3225 return;
3226
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003227 intel_encoder = &intel_dig_port->base;
3228 encoder = &intel_encoder->base;
3229
3230 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3231 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003232
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003233 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003234 intel_encoder->enable = intel_enable_ddi;
3235 intel_encoder->pre_enable = intel_ddi_pre_enable;
3236 intel_encoder->disable = intel_disable_ddi;
3237 intel_encoder->post_disable = intel_ddi_post_disable;
3238 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003239 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003240
3241 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003242 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3243 (DDI_BUF_PORT_REVERSAL |
3244 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003245
Matt Roper6c566dc2015-11-05 14:53:32 -08003246 /*
3247 * Bspec says that DDI_A_4_LANES is the only supported configuration
3248 * for Broxton. Yet some BIOS fail to set this bit on port A if eDP
3249 * wasn't lit up at boot. Force this bit on in our internal
3250 * configuration so that we use the proper lane count for our
3251 * calculations.
3252 */
3253 if (IS_BROXTON(dev) && port == PORT_A) {
3254 if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) {
3255 DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
3256 intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
3257 }
3258 }
3259
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003260 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003261 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003262 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003263
Chris Wilsonf68d6972014-08-04 07:15:09 +01003264 if (init_dp) {
3265 if (!intel_ddi_init_dp_connector(intel_dig_port))
3266 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003267
Chris Wilsonf68d6972014-08-04 07:15:09 +01003268 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303269 /*
3270 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3271 * interrupts to check the external panel connection.
3272 */
Jani Nikulae87a0052015-10-20 15:22:02 +03003273 if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303274 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3275 else
3276 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003277 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003278
Paulo Zanoni311a2092013-09-12 17:12:18 -03003279 /* In theory we don't need the encoder->type check, but leave it just in
3280 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003281 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3282 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3283 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003284 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003285
3286 return;
3287
3288err:
3289 drm_encoder_cleanup(encoder);
3290 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003291}