blob: a6752a61d99f268217e7054a8531036d109be7ee [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;
451 } else if (IS_SKYLAKE(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 Zanoni0d536cb42012-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 Airlie44905a272014-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 Airlie44905a272014-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 Oliveirada3ced2982015-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 Oliveirada3ced2982015-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 Oliveirada3ced2982015-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:
Damien Lespiau63582982015-05-07 18:38:46 +01001115 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL1);
Jesse Barnes11578552014-01-21 12:42:10 -08001116 break;
1117 case PORT_CLK_SEL_WRPLL2:
Damien Lespiau63582982015-05-07 18:38:46 +01001118 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL2);
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);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301187 else if (IS_SKYLAKE(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);
Maarten Lankhorst00490c22015-11-16 14:42:12 +01001289 } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
1290 struct drm_atomic_state *state = crtc_state->base.state;
1291 struct intel_shared_dpll_config *spll =
1292 &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
1293
1294 if (spll->crtc_mask &&
1295 WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
1296 return false;
1297
1298 crtc_state->shared_dpll = DPLL_ID_SPLL;
1299 spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
1300 spll->crtc_mask |= 1 << intel_crtc->pipe;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001301 }
1302
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001303 return true;
1304}
1305
Damien Lespiaudc253812015-06-25 16:15:06 +01001306struct skl_wrpll_context {
1307 uint64_t min_deviation; /* current minimal deviation */
1308 uint64_t central_freq; /* chosen central freq */
1309 uint64_t dco_freq; /* chosen dco freq */
1310 unsigned int p; /* chosen divider */
1311};
1312
1313static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1314{
1315 memset(ctx, 0, sizeof(*ctx));
1316
1317 ctx->min_deviation = U64_MAX;
1318}
1319
1320/* DCO freq must be within +1%/-6% of the DCO central freq */
1321#define SKL_DCO_MAX_PDEVIATION 100
1322#define SKL_DCO_MAX_NDEVIATION 600
1323
1324static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1325 uint64_t central_freq,
1326 uint64_t dco_freq,
1327 unsigned int divider)
1328{
1329 uint64_t deviation;
1330
1331 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1332 central_freq);
1333
1334 /* positive deviation */
1335 if (dco_freq >= central_freq) {
1336 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1337 deviation < ctx->min_deviation) {
1338 ctx->min_deviation = deviation;
1339 ctx->central_freq = central_freq;
1340 ctx->dco_freq = dco_freq;
1341 ctx->p = divider;
1342 }
1343 /* negative deviation */
1344 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1345 deviation < ctx->min_deviation) {
1346 ctx->min_deviation = deviation;
1347 ctx->central_freq = central_freq;
1348 ctx->dco_freq = dco_freq;
1349 ctx->p = divider;
1350 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001351}
1352
1353static void skl_wrpll_get_multipliers(unsigned int p,
1354 unsigned int *p0 /* out */,
1355 unsigned int *p1 /* out */,
1356 unsigned int *p2 /* out */)
1357{
1358 /* even dividers */
1359 if (p % 2 == 0) {
1360 unsigned int half = p / 2;
1361
1362 if (half == 1 || half == 2 || half == 3 || half == 5) {
1363 *p0 = 2;
1364 *p1 = 1;
1365 *p2 = half;
1366 } else if (half % 2 == 0) {
1367 *p0 = 2;
1368 *p1 = half / 2;
1369 *p2 = 2;
1370 } else if (half % 3 == 0) {
1371 *p0 = 3;
1372 *p1 = half / 3;
1373 *p2 = 2;
1374 } else if (half % 7 == 0) {
1375 *p0 = 7;
1376 *p1 = half / 7;
1377 *p2 = 2;
1378 }
1379 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1380 *p0 = 3;
1381 *p1 = 1;
1382 *p2 = p / 3;
1383 } else if (p == 5 || p == 7) {
1384 *p0 = p;
1385 *p1 = 1;
1386 *p2 = 1;
1387 } else if (p == 15) {
1388 *p0 = 3;
1389 *p1 = 1;
1390 *p2 = 5;
1391 } else if (p == 21) {
1392 *p0 = 7;
1393 *p1 = 1;
1394 *p2 = 3;
1395 } else if (p == 35) {
1396 *p0 = 7;
1397 *p1 = 1;
1398 *p2 = 5;
1399 }
1400}
1401
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001402struct skl_wrpll_params {
1403 uint32_t dco_fraction;
1404 uint32_t dco_integer;
1405 uint32_t qdiv_ratio;
1406 uint32_t qdiv_mode;
1407 uint32_t kdiv;
1408 uint32_t pdiv;
1409 uint32_t central_freq;
1410};
1411
Damien Lespiau76516fb2015-05-07 18:38:42 +01001412static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1413 uint64_t afe_clock,
1414 uint64_t central_freq,
1415 uint32_t p0, uint32_t p1, uint32_t p2)
1416{
1417 uint64_t dco_freq;
1418
Damien Lespiau76516fb2015-05-07 18:38:42 +01001419 switch (central_freq) {
1420 case 9600000000ULL:
1421 params->central_freq = 0;
1422 break;
1423 case 9000000000ULL:
1424 params->central_freq = 1;
1425 break;
1426 case 8400000000ULL:
1427 params->central_freq = 3;
1428 }
1429
1430 switch (p0) {
1431 case 1:
1432 params->pdiv = 0;
1433 break;
1434 case 2:
1435 params->pdiv = 1;
1436 break;
1437 case 3:
1438 params->pdiv = 2;
1439 break;
1440 case 7:
1441 params->pdiv = 4;
1442 break;
1443 default:
1444 WARN(1, "Incorrect PDiv\n");
1445 }
1446
1447 switch (p2) {
1448 case 5:
1449 params->kdiv = 0;
1450 break;
1451 case 2:
1452 params->kdiv = 1;
1453 break;
1454 case 3:
1455 params->kdiv = 2;
1456 break;
1457 case 1:
1458 params->kdiv = 3;
1459 break;
1460 default:
1461 WARN(1, "Incorrect KDiv\n");
1462 }
1463
1464 params->qdiv_ratio = p1;
1465 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1466
1467 dco_freq = p0 * p1 * p2 * afe_clock;
1468
1469 /*
1470 * Intermediate values are in Hz.
1471 * Divide by MHz to match bsepc
1472 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001473 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001474 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001475 div_u64((div_u64(dco_freq, 24) -
1476 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001477}
1478
Damien Lespiau318bd822015-05-07 18:38:40 +01001479static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001480skl_ddi_calculate_wrpll(int clock /* in Hz */,
1481 struct skl_wrpll_params *wrpll_params)
1482{
1483 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001484 uint64_t dco_central_freq[3] = {8400000000ULL,
1485 9000000000ULL,
1486 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001487 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1488 24, 28, 30, 32, 36, 40, 42, 44,
1489 48, 52, 54, 56, 60, 64, 66, 68,
1490 70, 72, 76, 78, 80, 84, 88, 90,
1491 92, 96, 98 };
1492 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1493 static const struct {
1494 const int *list;
1495 int n_dividers;
1496 } dividers[] = {
1497 { even_dividers, ARRAY_SIZE(even_dividers) },
1498 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1499 };
1500 struct skl_wrpll_context ctx;
1501 unsigned int dco, d, i;
1502 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001503
Damien Lespiaudc253812015-06-25 16:15:06 +01001504 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001505
Damien Lespiaudc253812015-06-25 16:15:06 +01001506 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1507 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1508 for (i = 0; i < dividers[d].n_dividers; i++) {
1509 unsigned int p = dividers[d].list[i];
1510 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001511
Damien Lespiaudc253812015-06-25 16:15:06 +01001512 skl_wrpll_try_divider(&ctx,
1513 dco_central_freq[dco],
1514 dco_freq,
1515 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001516 /*
1517 * Skip the remaining dividers if we're sure to
1518 * have found the definitive divider, we can't
1519 * improve a 0 deviation.
1520 */
1521 if (ctx.min_deviation == 0)
1522 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001523 }
1524 }
Damien Lespiau267db662015-06-25 16:19:24 +01001525
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001526skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001527 /*
1528 * If a solution is found with an even divider, prefer
1529 * this one.
1530 */
1531 if (d == 0 && ctx.p)
1532 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001533 }
1534
Damien Lespiaudc253812015-06-25 16:15:06 +01001535 if (!ctx.p) {
1536 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001537 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001538 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001539
Damien Lespiaudc253812015-06-25 16:15:06 +01001540 /*
1541 * gcc incorrectly analyses that these can be used without being
1542 * initialized. To be fair, it's hard to guess.
1543 */
1544 p0 = p1 = p2 = 0;
1545 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1546 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1547 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001548
Damien Lespiau318bd822015-05-07 18:38:40 +01001549 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001550}
1551
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001552static bool
1553skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001554 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001555 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001556{
1557 struct intel_shared_dpll *pll;
1558 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001559 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001560
1561 /*
1562 * See comment in intel_dpll_hw_state to understand why we always use 0
1563 * as the DPLL id in this function.
1564 */
1565
1566 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1567
1568 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1569 struct skl_wrpll_params wrpll_params = { 0, };
1570
1571 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1572
Damien Lespiau318bd822015-05-07 18:38:40 +01001573 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1574 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001575
1576 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1577 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1578 wrpll_params.dco_integer;
1579
1580 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1581 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1582 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1583 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1584 wrpll_params.central_freq;
1585 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001586 switch (crtc_state->port_clock / 2) {
1587 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001588 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001589 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001590 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001591 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001592 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001593 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001594 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001595 break;
1596 }
1597
1598 cfgcr1 = cfgcr2 = 0;
1599 } else /* eDP */
1600 return true;
1601
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001602 memset(&crtc_state->dpll_hw_state, 0,
1603 sizeof(crtc_state->dpll_hw_state));
1604
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001605 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1606 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1607 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001608
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001609 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001610 if (pll == NULL) {
1611 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1612 pipe_name(intel_crtc->pipe));
1613 return false;
1614 }
1615
1616 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001617 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001618
1619 return true;
1620}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001621
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301622/* bxt clock parameters */
1623struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301624 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301625 uint32_t p1;
1626 uint32_t p2;
1627 uint32_t m2_int;
1628 uint32_t m2_frac;
1629 bool m2_frac_en;
1630 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301631};
1632
1633/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301634static const struct bxt_clk_div bxt_dp_clk_val[] = {
1635 {162000, 4, 2, 32, 1677722, 1, 1},
1636 {270000, 4, 1, 27, 0, 0, 1},
1637 {540000, 2, 1, 27, 0, 0, 1},
1638 {216000, 3, 2, 32, 1677722, 1, 1},
1639 {243000, 4, 1, 24, 1258291, 1, 1},
1640 {324000, 4, 1, 32, 1677722, 1, 1},
1641 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301642};
1643
1644static bool
1645bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1646 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001647 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301648{
1649 struct intel_shared_dpll *pll;
1650 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301651 int vco = 0;
1652 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301653 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001654 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301655
1656 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1657 intel_clock_t best_clock;
1658
1659 /* Calculate HDMI div */
1660 /*
1661 * FIXME: tie the following calculation into
1662 * i9xx_crtc_compute_clock
1663 */
1664 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1665 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1666 clock, pipe_name(intel_crtc->pipe));
1667 return false;
1668 }
1669
1670 clk_div.p1 = best_clock.p1;
1671 clk_div.p2 = best_clock.p2;
1672 WARN_ON(best_clock.m1 != 2);
1673 clk_div.n = best_clock.n;
1674 clk_div.m2_int = best_clock.m2 >> 22;
1675 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1676 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1677
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301678 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301679 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1680 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301681 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301682
Sonika Jindal64987fc2015-05-26 17:50:13 +05301683 clk_div = bxt_dp_clk_val[0];
1684 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1685 if (bxt_dp_clk_val[i].clock == clock) {
1686 clk_div = bxt_dp_clk_val[i];
1687 break;
1688 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301689 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301690 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1691 }
1692
Vandana Kannane6292552015-07-01 17:02:57 +05301693 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301694 prop_coef = 4;
1695 int_coef = 9;
1696 gain_ctl = 3;
1697 targ_cnt = 8;
1698 } else if ((vco > 5400000 && vco < 6200000) ||
1699 (vco >= 4800000 && vco < 5400000)) {
1700 prop_coef = 5;
1701 int_coef = 11;
1702 gain_ctl = 3;
1703 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301704 } else if (vco == 5400000) {
1705 prop_coef = 3;
1706 int_coef = 8;
1707 gain_ctl = 1;
1708 targ_cnt = 9;
1709 } else {
1710 DRM_ERROR("Invalid VCO\n");
1711 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301712 }
1713
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001714 memset(&crtc_state->dpll_hw_state, 0,
1715 sizeof(crtc_state->dpll_hw_state));
1716
Vandana Kannane0681e32015-05-13 12:20:35 +05301717 if (clock > 270000)
1718 lanestagger = 0x18;
1719 else if (clock > 135000)
1720 lanestagger = 0x0d;
1721 else if (clock > 67000)
1722 lanestagger = 0x07;
1723 else if (clock > 33000)
1724 lanestagger = 0x04;
1725 else
1726 lanestagger = 0x02;
1727
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301728 crtc_state->dpll_hw_state.ebb0 =
1729 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1730 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1731 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1732 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1733
1734 if (clk_div.m2_frac_en)
1735 crtc_state->dpll_hw_state.pll3 =
1736 PORT_PLL_M2_FRAC_ENABLE;
1737
1738 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301739 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301740 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301741 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301742
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301743 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1744
Imre Deak05712c12015-06-18 17:25:54 +03001745 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1746
Vandana Kannane6292552015-07-01 17:02:57 +05301747 crtc_state->dpll_hw_state.pll10 =
1748 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1749 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301750
Imre Deak05712c12015-06-18 17:25:54 +03001751 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1752
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301753 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301754 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301755
1756 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1757 if (pll == NULL) {
1758 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1759 pipe_name(intel_crtc->pipe));
1760 return false;
1761 }
1762
1763 /* shared DPLL id 0 is DPLL A */
1764 crtc_state->ddi_pll_sel = pll->id;
1765
1766 return true;
1767}
1768
Damien Lespiau0220ab62014-07-29 18:06:22 +01001769/*
1770 * Tries to find a *shared* PLL for the CRTC and store it in
1771 * intel_crtc->ddi_pll_sel.
1772 *
1773 * For private DPLLs, compute_config() should do the selection for us. This
1774 * function should be folded into compute_config() eventually.
1775 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001776bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1777 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001778{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001779 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001780 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001781 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001782
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001783 if (IS_SKYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001784 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001785 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301786 else if (IS_BROXTON(dev))
1787 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001788 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001789 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001790 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001791 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001792}
1793
Paulo Zanonidae84792012-10-15 15:51:30 -03001794void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1795{
1796 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1797 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1798 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001799 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001800 int type = intel_encoder->type;
1801 uint32_t temp;
1802
Dave Airlie0e32b392014-05-02 14:02:48 +10001803 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001804 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001805 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001806 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001807 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001808 break;
1809 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001810 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001811 break;
1812 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001813 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001814 break;
1815 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001816 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001817 break;
1818 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001819 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001820 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001821 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001822 }
1823}
1824
Dave Airlie0e32b392014-05-02 14:02:48 +10001825void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1826{
1827 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1828 struct drm_device *dev = crtc->dev;
1829 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001830 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001831 uint32_t temp;
1832 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1833 if (state == true)
1834 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1835 else
1836 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1837 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1838}
1839
Damien Lespiau8228c252013-03-07 15:30:27 +00001840void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001841{
1842 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1843 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001844 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001845 struct drm_device *dev = crtc->dev;
1846 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001847 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001848 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001849 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001850 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001851 uint32_t temp;
1852
Paulo Zanoniad80a812012-10-24 16:06:19 -02001853 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1854 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001855 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001856
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001857 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001858 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001859 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001860 break;
1861 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001862 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001863 break;
1864 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001865 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001866 break;
1867 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001868 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001869 break;
1870 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001871 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001872 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001873
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001874 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001875 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001876 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001877 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001878
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001879 if (cpu_transcoder == TRANSCODER_EDP) {
1880 switch (pipe) {
1881 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001882 /* On Haswell, can only use the always-on power well for
1883 * eDP when not using the panel fitter, and when not
1884 * using motion blur mitigation (which we don't
1885 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001886 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001887 (intel_crtc->config->pch_pfit.enabled ||
1888 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001889 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1890 else
1891 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001892 break;
1893 case PIPE_B:
1894 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1895 break;
1896 case PIPE_C:
1897 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1898 break;
1899 default:
1900 BUG();
1901 break;
1902 }
1903 }
1904
Paulo Zanoni7739c332012-10-15 15:51:29 -03001905 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001906 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001907 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001908 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001909 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001910
Paulo Zanoni7739c332012-10-15 15:51:29 -03001911 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001912 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001913 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001914
1915 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1916 type == INTEL_OUTPUT_EDP) {
1917 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1918
Dave Airlie0e32b392014-05-02 14:02:48 +10001919 if (intel_dp->is_mst) {
1920 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1921 } else
1922 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1923
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001924 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001925 } else if (type == INTEL_OUTPUT_DP_MST) {
1926 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1927
1928 if (intel_dp->is_mst) {
1929 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1930 } else
1931 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001932
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001933 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001934 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001935 WARN(1, "Invalid encoder type %d for pipe %c\n",
1936 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001937 }
1938
Paulo Zanoniad80a812012-10-24 16:06:19 -02001939 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001940}
1941
Paulo Zanoniad80a812012-10-24 16:06:19 -02001942void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1943 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001944{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001945 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001946 uint32_t val = I915_READ(reg);
1947
Dave Airlie0e32b392014-05-02 14:02:48 +10001948 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001949 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001950 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001951}
1952
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001953bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1954{
1955 struct drm_device *dev = intel_connector->base.dev;
1956 struct drm_i915_private *dev_priv = dev->dev_private;
1957 struct intel_encoder *intel_encoder = intel_connector->encoder;
1958 int type = intel_connector->base.connector_type;
1959 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1960 enum pipe pipe = 0;
1961 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001962 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001963 uint32_t tmp;
1964
Paulo Zanoni882244a2014-04-01 14:55:12 -03001965 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001966 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001967 return false;
1968
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001969 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1970 return false;
1971
1972 if (port == PORT_A)
1973 cpu_transcoder = TRANSCODER_EDP;
1974 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001975 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001976
1977 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1978
1979 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1980 case TRANS_DDI_MODE_SELECT_HDMI:
1981 case TRANS_DDI_MODE_SELECT_DVI:
1982 return (type == DRM_MODE_CONNECTOR_HDMIA);
1983
1984 case TRANS_DDI_MODE_SELECT_DP_SST:
1985 if (type == DRM_MODE_CONNECTOR_eDP)
1986 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001987 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001988 case TRANS_DDI_MODE_SELECT_DP_MST:
1989 /* if the transcoder is in MST state then
1990 * connector isn't connected */
1991 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001992
1993 case TRANS_DDI_MODE_SELECT_FDI:
1994 return (type == DRM_MODE_CONNECTOR_VGA);
1995
1996 default:
1997 return false;
1998 }
1999}
2000
Daniel Vetter85234cd2012-07-02 13:27:29 +02002001bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
2002 enum pipe *pipe)
2003{
2004 struct drm_device *dev = encoder->base.dev;
2005 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002006 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02002007 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002008 u32 tmp;
2009 int i;
2010
Imre Deak6d129be2014-03-05 16:20:54 +02002011 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002012 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02002013 return false;
2014
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002015 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002016
2017 if (!(tmp & DDI_BUF_CTL_ENABLE))
2018 return false;
2019
Paulo Zanoniad80a812012-10-24 16:06:19 -02002020 if (port == PORT_A) {
2021 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002022
Paulo Zanoniad80a812012-10-24 16:06:19 -02002023 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2024 case TRANS_DDI_EDP_INPUT_A_ON:
2025 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2026 *pipe = PIPE_A;
2027 break;
2028 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2029 *pipe = PIPE_B;
2030 break;
2031 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2032 *pipe = PIPE_C;
2033 break;
2034 }
2035
2036 return true;
2037 } else {
2038 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2039 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2040
2041 if ((tmp & TRANS_DDI_PORT_MASK)
2042 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002043 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2044 return false;
2045
Paulo Zanoniad80a812012-10-24 16:06:19 -02002046 *pipe = i;
2047 return true;
2048 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002049 }
2050 }
2051
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002052 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002053
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002054 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002055}
2056
Paulo Zanonifc914632012-10-05 12:05:54 -03002057void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2058{
2059 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302060 struct drm_device *dev = crtc->dev;
2061 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002062 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2063 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002064 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002065
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002066 if (cpu_transcoder != TRANSCODER_EDP)
2067 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2068 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002069}
2070
2071void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2072{
2073 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002074 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002075
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002076 if (cpu_transcoder != TRANSCODER_EDP)
2077 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2078 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002079}
2080
David Weinehallf8896f52015-06-25 11:11:03 +03002081static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2082 enum port port, int type)
2083{
2084 struct drm_i915_private *dev_priv = dev->dev_private;
2085 const struct ddi_buf_trans *ddi_translations;
2086 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002087 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002088 int n_entries;
2089 u32 reg;
2090
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002091 /* VBT may override standard boost values */
2092 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2093 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2094
David Weinehallf8896f52015-06-25 11:11:03 +03002095 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002096 if (dp_iboost) {
2097 iboost = dp_iboost;
2098 } else {
2099 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2100 iboost = ddi_translations[port].i_boost;
2101 }
David Weinehallf8896f52015-06-25 11:11:03 +03002102 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002103 if (dp_iboost) {
2104 iboost = dp_iboost;
2105 } else {
2106 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2107 iboost = ddi_translations[port].i_boost;
2108 }
David Weinehallf8896f52015-06-25 11:11:03 +03002109 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002110 if (hdmi_iboost) {
2111 iboost = hdmi_iboost;
2112 } else {
2113 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2114 iboost = ddi_translations[port].i_boost;
2115 }
David Weinehallf8896f52015-06-25 11:11:03 +03002116 } else {
2117 return;
2118 }
2119
2120 /* Make sure that the requested I_boost is valid */
2121 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2122 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2123 return;
2124 }
2125
2126 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2127 reg &= ~BALANCE_LEG_MASK(port);
2128 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2129
2130 if (iboost)
2131 reg |= iboost << BALANCE_LEG_SHIFT(port);
2132 else
2133 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2134
2135 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2136}
2137
2138static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2139 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302140{
2141 struct drm_i915_private *dev_priv = dev->dev_private;
2142 const struct bxt_ddi_buf_trans *ddi_translations;
2143 u32 n_entries, i;
2144 uint32_t val;
2145
Sonika Jindald9d70002015-09-24 10:24:56 +05302146 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2147 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2148 ddi_translations = bxt_ddi_translations_edp;
2149 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2150 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302151 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2152 ddi_translations = bxt_ddi_translations_dp;
2153 } else if (type == INTEL_OUTPUT_HDMI) {
2154 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2155 ddi_translations = bxt_ddi_translations_hdmi;
2156 } else {
2157 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2158 type);
2159 return;
2160 }
2161
2162 /* Check if default value has to be used */
2163 if (level >= n_entries ||
2164 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2165 for (i = 0; i < n_entries; i++) {
2166 if (ddi_translations[i].default_index) {
2167 level = i;
2168 break;
2169 }
2170 }
2171 }
2172
2173 /*
2174 * While we write to the group register to program all lanes at once we
2175 * can read only lane registers and we pick lanes 0/1 for that.
2176 */
2177 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2178 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2179 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2180
2181 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2182 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2183 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2184 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2185 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2186
2187 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302188 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302189 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302190 val |= SCALE_DCOMP_METHOD;
2191
2192 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2193 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2194
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302195 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2196
2197 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2198 val &= ~DE_EMPHASIS;
2199 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2200 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2201
2202 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2203 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2204 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2205}
2206
David Weinehallf8896f52015-06-25 11:11:03 +03002207static uint32_t translate_signal_level(int signal_levels)
2208{
2209 uint32_t level;
2210
2211 switch (signal_levels) {
2212 default:
2213 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2214 signal_levels);
2215 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2216 level = 0;
2217 break;
2218 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2219 level = 1;
2220 break;
2221 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2222 level = 2;
2223 break;
2224 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2225 level = 3;
2226 break;
2227
2228 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2229 level = 4;
2230 break;
2231 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2232 level = 5;
2233 break;
2234 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2235 level = 6;
2236 break;
2237
2238 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2239 level = 7;
2240 break;
2241 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2242 level = 8;
2243 break;
2244
2245 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2246 level = 9;
2247 break;
2248 }
2249
2250 return level;
2251}
2252
2253uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2254{
2255 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2256 struct drm_device *dev = dport->base.base.dev;
2257 struct intel_encoder *encoder = &dport->base;
2258 uint8_t train_set = intel_dp->train_set[0];
2259 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2260 DP_TRAIN_PRE_EMPHASIS_MASK);
2261 enum port port = dport->port;
2262 uint32_t level;
2263
2264 level = translate_signal_level(signal_levels);
2265
2266 if (IS_SKYLAKE(dev))
2267 skl_ddi_set_iboost(dev, level, port, encoder->type);
2268 else if (IS_BROXTON(dev))
2269 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2270
2271 return DDI_BUF_TRANS_SELECT(level);
2272}
2273
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002274static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002275{
Paulo Zanonic19b0662012-10-15 15:51:41 -03002276 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002277 struct drm_device *dev = encoder->dev;
2278 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002279 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002280 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002281 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302282 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002283
2284 if (type == INTEL_OUTPUT_EDP) {
2285 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01002286 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002287 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002288
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002289 if (IS_SKYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002290 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002291 uint32_t val;
2292
Damien Lespiau5416d872014-11-14 17:24:33 +00002293 /*
2294 * DPLL0 is used for eDP and is the only "private" DPLL (as
2295 * opposed to shared) on SKL
2296 */
2297 if (type == INTEL_OUTPUT_EDP) {
2298 WARN_ON(dpll != SKL_DPLL0);
2299
2300 val = I915_READ(DPLL_CTRL1);
2301
2302 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2303 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002304 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002305 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002306
2307 I915_WRITE(DPLL_CTRL1, val);
2308 POSTING_READ(DPLL_CTRL1);
2309 }
2310
2311 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002312 val = I915_READ(DPLL_CTRL2);
2313
2314 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2315 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2316 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2317 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2318
2319 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002320
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302321 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002322 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2323 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002324 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002325
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002326 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002327 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002328
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002329 intel_dp_set_link_params(intel_dp, crtc->config);
2330
Dave Airlie44905a272014-05-02 13:36:43 +10002331 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002332
2333 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2334 intel_dp_start_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002335 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002336 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002337 } else if (type == INTEL_OUTPUT_HDMI) {
2338 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2339
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302340 if (IS_BROXTON(dev)) {
2341 hdmi_level = dev_priv->vbt.
2342 ddi_port_info[port].hdmi_level_shift;
2343 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2344 INTEL_OUTPUT_HDMI);
2345 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002346 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002347 crtc->config->has_hdmi_sink,
2348 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002349 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002350}
2351
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002352static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002353{
2354 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002355 struct drm_device *dev = encoder->dev;
2356 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002357 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002358 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002359 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002360 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002361
2362 val = I915_READ(DDI_BUF_CTL(port));
2363 if (val & DDI_BUF_CTL_ENABLE) {
2364 val &= ~DDI_BUF_CTL_ENABLE;
2365 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002366 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002367 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002368
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002369 val = I915_READ(DP_TP_CTL(port));
2370 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2371 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2372 I915_WRITE(DP_TP_CTL(port), val);
2373
2374 if (wait)
2375 intel_wait_ddi_buf_idle(dev_priv, port);
2376
Jani Nikula76bb80e2013-11-15 15:29:57 +02002377 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002378 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002379 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002380 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002381 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002382 }
2383
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002384 if (IS_SKYLAKE(dev))
2385 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2386 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302387 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002388 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002389}
2390
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002391static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002392{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002393 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002394 struct drm_crtc *crtc = encoder->crtc;
2395 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002396 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002397 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002398 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2399 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002400
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002401 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002402 struct intel_digital_port *intel_dig_port =
2403 enc_to_dig_port(encoder);
2404
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002405 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2406 * are ignored so nothing special needs to be done besides
2407 * enabling the port.
2408 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002409 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de42013-07-12 13:54:41 -07002410 intel_dig_port->saved_port_bits |
2411 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002412 } else if (type == INTEL_OUTPUT_EDP) {
2413 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2414
Vandana Kannan23f08d82014-11-13 14:55:22 +00002415 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002416 intel_dp_stop_link_train(intel_dp);
2417
Daniel Vetter4be73782014-01-17 14:39:48 +01002418 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002419 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302420 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002421 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002422
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002423 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002424 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002425 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002426 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002427}
2428
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002429static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002430{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002431 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002432 struct drm_crtc *crtc = encoder->crtc;
2433 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002434 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002435 struct drm_device *dev = encoder->dev;
2436 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002437
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002438 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002439 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002440 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2441 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002442
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002443 if (type == INTEL_OUTPUT_EDP) {
2444 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2445
Vandana Kannanc3955782015-01-22 15:17:40 +05302446 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002447 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002448 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002449 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002450}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002451
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002452static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
Daniel Vettere0b01be2014-06-25 22:02:01 +03002453 struct intel_shared_dpll *pll)
2454{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002455 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002456 POSTING_READ(WRPLL_CTL(pll->id));
2457 udelay(20);
2458}
2459
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002460static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
Daniel Vetter12030432014-06-25 22:02:00 +03002461 struct intel_shared_dpll *pll)
2462{
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002463 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
2464 POSTING_READ(SPLL_CTL);
2465 udelay(20);
2466}
2467
2468static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
2469 struct intel_shared_dpll *pll)
2470{
Daniel Vetter12030432014-06-25 22:02:00 +03002471 uint32_t val;
2472
2473 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002474 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2475 POSTING_READ(WRPLL_CTL(pll->id));
2476}
2477
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002478static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
2479 struct intel_shared_dpll *pll)
2480{
2481 uint32_t val;
2482
2483 val = I915_READ(SPLL_CTL);
2484 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
2485 POSTING_READ(SPLL_CTL);
2486}
2487
2488static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
2489 struct intel_shared_dpll *pll,
2490 struct intel_dpll_hw_state *hw_state)
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002491{
2492 uint32_t val;
2493
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002494 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002495 return false;
2496
2497 val = I915_READ(WRPLL_CTL(pll->id));
2498 hw_state->wrpll = val;
2499
2500 return val & WRPLL_PLL_ENABLE;
2501}
2502
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002503static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
2504 struct intel_shared_dpll *pll,
2505 struct intel_dpll_hw_state *hw_state)
2506{
2507 uint32_t val;
2508
2509 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2510 return false;
2511
2512 val = I915_READ(SPLL_CTL);
2513 hw_state->spll = val;
2514
2515 return val & SPLL_PLL_ENABLE;
2516}
2517
2518
Damien Lespiauca1381b2014-07-15 15:05:33 +01002519static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002520 "WRPLL 1",
2521 "WRPLL 2",
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002522 "SPLL"
Daniel Vetter9cd86932014-06-25 22:01:57 +03002523};
2524
Damien Lespiau143b3072014-07-29 18:06:19 +01002525static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002526{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002527 int i;
2528
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002529 dev_priv->num_shared_dpll = 3;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002530
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002531 for (i = 0; i < 2; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002532 dev_priv->shared_dplls[i].id = i;
2533 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002534 dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
2535 dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002536 dev_priv->shared_dplls[i].get_hw_state =
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002537 hsw_ddi_wrpll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002538 }
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002539
2540 /* SPLL is special, but needs to be initialized anyway.. */
2541 dev_priv->shared_dplls[i].id = i;
2542 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
2543 dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
2544 dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
2545 dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
2546
Damien Lespiau143b3072014-07-29 18:06:19 +01002547}
2548
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002549static const char * const skl_ddi_pll_names[] = {
2550 "DPLL 1",
2551 "DPLL 2",
2552 "DPLL 3",
2553};
2554
2555struct skl_dpll_regs {
2556 u32 ctl, cfgcr1, cfgcr2;
2557};
2558
2559/* this array is indexed by the *shared* pll id */
2560static const struct skl_dpll_regs skl_dpll_regs[3] = {
2561 {
2562 /* DPLL 1 */
2563 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002564 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2565 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002566 },
2567 {
2568 /* DPLL 2 */
2569 .ctl = WRPLL_CTL1,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002570 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2571 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002572 },
2573 {
2574 /* DPLL 3 */
2575 .ctl = WRPLL_CTL2,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002576 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2577 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002578 },
2579};
2580
2581static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2582 struct intel_shared_dpll *pll)
2583{
2584 uint32_t val;
2585 unsigned int dpll;
2586 const struct skl_dpll_regs *regs = skl_dpll_regs;
2587
2588 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2589 dpll = pll->id + 1;
2590
2591 val = I915_READ(DPLL_CTRL1);
2592
2593 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002594 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002595 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2596
2597 I915_WRITE(DPLL_CTRL1, val);
2598 POSTING_READ(DPLL_CTRL1);
2599
2600 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2601 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2602 POSTING_READ(regs[pll->id].cfgcr1);
2603 POSTING_READ(regs[pll->id].cfgcr2);
2604
2605 /* the enable bit is always bit 31 */
2606 I915_WRITE(regs[pll->id].ctl,
2607 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2608
2609 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2610 DRM_ERROR("DPLL %d not locked\n", dpll);
2611}
2612
2613static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2614 struct intel_shared_dpll *pll)
2615{
2616 const struct skl_dpll_regs *regs = skl_dpll_regs;
2617
2618 /* the enable bit is always bit 31 */
2619 I915_WRITE(regs[pll->id].ctl,
2620 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2621 POSTING_READ(regs[pll->id].ctl);
2622}
2623
2624static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2625 struct intel_shared_dpll *pll,
2626 struct intel_dpll_hw_state *hw_state)
2627{
2628 uint32_t val;
2629 unsigned int dpll;
2630 const struct skl_dpll_regs *regs = skl_dpll_regs;
2631
2632 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2633 return false;
2634
2635 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2636 dpll = pll->id + 1;
2637
2638 val = I915_READ(regs[pll->id].ctl);
2639 if (!(val & LCPLL_PLL_ENABLE))
2640 return false;
2641
2642 val = I915_READ(DPLL_CTRL1);
2643 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2644
2645 /* avoid reading back stale values if HDMI mode is not enabled */
2646 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2647 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2648 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2649 }
2650
2651 return true;
2652}
2653
2654static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2655{
2656 int i;
2657
2658 dev_priv->num_shared_dpll = 3;
2659
2660 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2661 dev_priv->shared_dplls[i].id = i;
2662 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2663 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2664 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2665 dev_priv->shared_dplls[i].get_hw_state =
2666 skl_ddi_pll_get_hw_state;
2667 }
2668}
2669
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302670static void broxton_phy_init(struct drm_i915_private *dev_priv,
2671 enum dpio_phy phy)
2672{
2673 enum port port;
2674 uint32_t val;
2675
2676 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2677 val |= GT_DISPLAY_POWER_ON(phy);
2678 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2679
2680 /* Considering 10ms timeout until BSpec is updated */
2681 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2682 DRM_ERROR("timeout during PHY%d power on\n", phy);
2683
2684 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2685 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2686 int lane;
2687
2688 for (lane = 0; lane < 4; lane++) {
2689 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2690 /*
2691 * Note that on CHV this flag is called UPAR, but has
2692 * the same function.
2693 */
2694 val &= ~LATENCY_OPTIM;
2695 if (lane != 1)
2696 val |= LATENCY_OPTIM;
2697
2698 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2699 }
2700 }
2701
2702 /* Program PLL Rcomp code offset */
2703 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2704 val &= ~IREF0RC_OFFSET_MASK;
2705 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2706 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2707
2708 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2709 val &= ~IREF1RC_OFFSET_MASK;
2710 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2711 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2712
2713 /* Program power gating */
2714 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2715 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2716 SUS_CLK_CONFIG;
2717 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2718
2719 if (phy == DPIO_PHY0) {
2720 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2721 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2722 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2723 }
2724
2725 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2726 val &= ~OCL2_LDOFUSE_PWR_DIS;
2727 /*
2728 * On PHY1 disable power on the second channel, since no port is
2729 * connected there. On PHY0 both channels have a port, so leave it
2730 * enabled.
2731 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2732 * power down the second channel on PHY0 as well.
2733 */
2734 if (phy == DPIO_PHY1)
2735 val |= OCL2_LDOFUSE_PWR_DIS;
2736 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2737
2738 if (phy == DPIO_PHY0) {
2739 uint32_t grc_code;
2740 /*
2741 * PHY0 isn't connected to an RCOMP resistor so copy over
2742 * the corresponding calibrated value from PHY1, and disable
2743 * the automatic calibration on PHY0.
2744 */
2745 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2746 10))
2747 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2748
2749 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2750 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2751 grc_code = val << GRC_CODE_FAST_SHIFT |
2752 val << GRC_CODE_SLOW_SHIFT |
2753 val;
2754 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2755
2756 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2757 val |= GRC_DIS | GRC_RDY_OVRD;
2758 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2759 }
2760
2761 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2762 val |= COMMON_RESET_DIS;
2763 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2764}
2765
2766void broxton_ddi_phy_init(struct drm_device *dev)
2767{
2768 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2769 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2770 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2771}
2772
2773static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2774 enum dpio_phy phy)
2775{
2776 uint32_t val;
2777
2778 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2779 val &= ~COMMON_RESET_DIS;
2780 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2781}
2782
2783void broxton_ddi_phy_uninit(struct drm_device *dev)
2784{
2785 struct drm_i915_private *dev_priv = dev->dev_private;
2786
2787 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2788 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2789
2790 /* FIXME: do this in broxton_phy_uninit per phy */
2791 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2792}
2793
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302794static const char * const bxt_ddi_pll_names[] = {
2795 "PORT PLL A",
2796 "PORT PLL B",
2797 "PORT PLL C",
2798};
2799
2800static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2801 struct intel_shared_dpll *pll)
2802{
2803 uint32_t temp;
2804 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2805
2806 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2807 temp &= ~PORT_PLL_REF_SEL;
2808 /* Non-SSC reference */
2809 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2810
2811 /* Disable 10 bit clock */
2812 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2813 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2814 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2815
2816 /* Write P1 & P2 */
2817 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2818 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2819 temp |= pll->config.hw_state.ebb0;
2820 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2821
2822 /* Write M2 integer */
2823 temp = I915_READ(BXT_PORT_PLL(port, 0));
2824 temp &= ~PORT_PLL_M2_MASK;
2825 temp |= pll->config.hw_state.pll0;
2826 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2827
2828 /* Write N */
2829 temp = I915_READ(BXT_PORT_PLL(port, 1));
2830 temp &= ~PORT_PLL_N_MASK;
2831 temp |= pll->config.hw_state.pll1;
2832 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2833
2834 /* Write M2 fraction */
2835 temp = I915_READ(BXT_PORT_PLL(port, 2));
2836 temp &= ~PORT_PLL_M2_FRAC_MASK;
2837 temp |= pll->config.hw_state.pll2;
2838 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2839
2840 /* Write M2 fraction enable */
2841 temp = I915_READ(BXT_PORT_PLL(port, 3));
2842 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2843 temp |= pll->config.hw_state.pll3;
2844 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2845
2846 /* Write coeff */
2847 temp = I915_READ(BXT_PORT_PLL(port, 6));
2848 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2849 temp &= ~PORT_PLL_INT_COEFF_MASK;
2850 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2851 temp |= pll->config.hw_state.pll6;
2852 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2853
2854 /* Write calibration val */
2855 temp = I915_READ(BXT_PORT_PLL(port, 8));
2856 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2857 temp |= pll->config.hw_state.pll8;
2858 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2859
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302860 temp = I915_READ(BXT_PORT_PLL(port, 9));
2861 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002862 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302863 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2864
2865 temp = I915_READ(BXT_PORT_PLL(port, 10));
2866 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2867 temp &= ~PORT_PLL_DCO_AMP_MASK;
2868 temp |= pll->config.hw_state.pll10;
2869 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302870
2871 /* Recalibrate with new settings */
2872 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2873 temp |= PORT_PLL_RECALIBRATE;
2874 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002875 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2876 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302877 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2878
2879 /* Enable PLL */
2880 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2881 temp |= PORT_PLL_ENABLE;
2882 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2883 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2884
2885 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2886 PORT_PLL_LOCK), 200))
2887 DRM_ERROR("PLL %d not locked\n", port);
2888
2889 /*
2890 * While we write to the group register to program all lanes at once we
2891 * can read only lane registers and we pick lanes 0/1 for that.
2892 */
2893 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2894 temp &= ~LANE_STAGGER_MASK;
2895 temp &= ~LANESTAGGER_STRAP_OVRD;
2896 temp |= pll->config.hw_state.pcsdw12;
2897 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2898}
2899
2900static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2901 struct intel_shared_dpll *pll)
2902{
2903 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2904 uint32_t temp;
2905
2906 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2907 temp &= ~PORT_PLL_ENABLE;
2908 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2909 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2910}
2911
2912static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2913 struct intel_shared_dpll *pll,
2914 struct intel_dpll_hw_state *hw_state)
2915{
2916 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2917 uint32_t val;
2918
2919 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2920 return false;
2921
2922 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2923 if (!(val & PORT_PLL_ENABLE))
2924 return false;
2925
2926 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002927 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2928
Imre Deak05712c12015-06-18 17:25:54 +03002929 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2930 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2931
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302932 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002933 hw_state->pll0 &= PORT_PLL_M2_MASK;
2934
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302935 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002936 hw_state->pll1 &= PORT_PLL_N_MASK;
2937
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302938 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002939 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2940
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302941 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002942 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2943
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302944 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002945 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2946 PORT_PLL_INT_COEFF_MASK |
2947 PORT_PLL_GAIN_CTL_MASK;
2948
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302949 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002950 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2951
Imre Deak05712c12015-06-18 17:25:54 +03002952 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2953 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2954
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302955 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002956 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2957 PORT_PLL_DCO_AMP_MASK;
2958
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302959 /*
2960 * While we write to the group register to program all lanes at once we
2961 * can read only lane registers. We configure all lanes the same way, so
2962 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2963 */
2964 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002965 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302966 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2967 hw_state->pcsdw12,
2968 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002969 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302970
2971 return true;
2972}
2973
2974static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2975{
2976 int i;
2977
2978 dev_priv->num_shared_dpll = 3;
2979
2980 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2981 dev_priv->shared_dplls[i].id = i;
2982 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2983 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2984 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2985 dev_priv->shared_dplls[i].get_hw_state =
2986 bxt_ddi_pll_get_hw_state;
2987 }
2988}
2989
Damien Lespiau143b3072014-07-29 18:06:19 +01002990void intel_ddi_pll_init(struct drm_device *dev)
2991{
2992 struct drm_i915_private *dev_priv = dev->dev_private;
2993 uint32_t val = I915_READ(LCPLL_CTL);
2994
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002995 if (IS_SKYLAKE(dev))
2996 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302997 else if (IS_BROXTON(dev))
2998 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002999 else
3000 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003001
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003002 if (IS_SKYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01003003 int cdclk_freq;
3004
3005 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01003006 dev_priv->skl_boot_cdclk = cdclk_freq;
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003007 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
3008 DRM_ERROR("LCPLL1 is disabled\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01003009 else
3010 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05303011 } else if (IS_BROXTON(dev)) {
3012 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05303013 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003014 } else {
3015 /*
3016 * The LCPLL register should be turned on by the BIOS. For now
3017 * let's just check its state and print errors in case
3018 * something is wrong. Don't even try to turn it on.
3019 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003020
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003021 if (val & LCPLL_CD_SOURCE_FCLK)
3022 DRM_ERROR("CDCLK source is not LCPLL\n");
3023
3024 if (val & LCPLL_PLL_DISABLE)
3025 DRM_ERROR("LCPLL is disabled\n");
3026 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003027}
Paulo Zanonic19b0662012-10-15 15:51:41 -03003028
3029void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
3030{
Paulo Zanoni174edf12012-10-26 19:05:50 -02003031 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
3032 struct intel_dp *intel_dp = &intel_dig_port->dp;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003033 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
Paulo Zanoni174edf12012-10-26 19:05:50 -02003034 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003035 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05303036 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003037
3038 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
3039 val = I915_READ(DDI_BUF_CTL(port));
3040 if (val & DDI_BUF_CTL_ENABLE) {
3041 val &= ~DDI_BUF_CTL_ENABLE;
3042 I915_WRITE(DDI_BUF_CTL(port), val);
3043 wait = true;
3044 }
3045
3046 val = I915_READ(DP_TP_CTL(port));
3047 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3048 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3049 I915_WRITE(DP_TP_CTL(port), val);
3050 POSTING_READ(DP_TP_CTL(port));
3051
3052 if (wait)
3053 intel_wait_ddi_buf_idle(dev_priv, port);
3054 }
3055
Dave Airlie0e32b392014-05-02 14:02:48 +10003056 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003057 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003058 if (intel_dp->is_mst)
3059 val |= DP_TP_CTL_MODE_MST;
3060 else {
3061 val |= DP_TP_CTL_MODE_SST;
3062 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3063 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3064 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003065 I915_WRITE(DP_TP_CTL(port), val);
3066 POSTING_READ(DP_TP_CTL(port));
3067
3068 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3069 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3070 POSTING_READ(DDI_BUF_CTL(port));
3071
3072 udelay(600);
3073}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003074
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003075void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3076{
3077 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3078 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3079 uint32_t val;
3080
3081 intel_ddi_post_disable(intel_encoder);
3082
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003083 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003084 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003085 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003086
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003087 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003088 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3089 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003090 I915_WRITE(FDI_RX_MISC(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003091
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003092 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003093 val &= ~FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003094 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003095
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003096 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003097 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003098 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003099}
3100
Ville Syrjälä6801c182013-09-24 14:24:05 +03003101void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003102 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003103{
3104 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3105 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003106 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003107 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003108 u32 temp, flags = 0;
3109
3110 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3111 if (temp & TRANS_DDI_PHSYNC)
3112 flags |= DRM_MODE_FLAG_PHSYNC;
3113 else
3114 flags |= DRM_MODE_FLAG_NHSYNC;
3115 if (temp & TRANS_DDI_PVSYNC)
3116 flags |= DRM_MODE_FLAG_PVSYNC;
3117 else
3118 flags |= DRM_MODE_FLAG_NVSYNC;
3119
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003120 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003121
3122 switch (temp & TRANS_DDI_BPC_MASK) {
3123 case TRANS_DDI_BPC_6:
3124 pipe_config->pipe_bpp = 18;
3125 break;
3126 case TRANS_DDI_BPC_8:
3127 pipe_config->pipe_bpp = 24;
3128 break;
3129 case TRANS_DDI_BPC_10:
3130 pipe_config->pipe_bpp = 30;
3131 break;
3132 case TRANS_DDI_BPC_12:
3133 pipe_config->pipe_bpp = 36;
3134 break;
3135 default:
3136 break;
3137 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003138
3139 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3140 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003141 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003142 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3143
3144 if (intel_hdmi->infoframe_enabled(&encoder->base))
3145 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003146 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003147 case TRANS_DDI_MODE_SELECT_DVI:
3148 case TRANS_DDI_MODE_SELECT_FDI:
3149 break;
3150 case TRANS_DDI_MODE_SELECT_DP_SST:
3151 case TRANS_DDI_MODE_SELECT_DP_MST:
3152 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003153 pipe_config->lane_count =
3154 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003155 intel_dp_get_m_n(intel_crtc, pipe_config);
3156 break;
3157 default:
3158 break;
3159 }
Daniel Vetter10214422013-11-18 07:38:16 +01003160
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003161 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003162 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003163 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003164 pipe_config->has_audio = true;
3165 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003166
Daniel Vetter10214422013-11-18 07:38:16 +01003167 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3168 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3169 /*
3170 * This is a big fat ugly hack.
3171 *
3172 * Some machines in UEFI boot mode provide us a VBT that has 18
3173 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3174 * unknown we fail to light up. Yet the same BIOS boots up with
3175 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3176 * max, not what it tells us to use.
3177 *
3178 * Note: This will still be broken if the eDP panel is not lit
3179 * up by the BIOS, and thus we can't get the mode at module
3180 * load.
3181 */
3182 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3183 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3184 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3185 }
Jesse Barnes11578552014-01-21 12:42:10 -08003186
Damien Lespiau22606a12014-12-12 14:26:57 +00003187 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003188}
3189
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003190static void intel_ddi_destroy(struct drm_encoder *encoder)
3191{
3192 /* HDMI has nothing special to destroy, so we can go with this. */
3193 intel_dp_encoder_destroy(encoder);
3194}
3195
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003196static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003197 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003198{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003199 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003200 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003201
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003202 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003203
Daniel Vettereccb1402013-05-22 00:50:22 +02003204 if (port == PORT_A)
3205 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3206
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003207 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003208 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003209 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003210 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003211}
3212
3213static const struct drm_encoder_funcs intel_ddi_funcs = {
3214 .destroy = intel_ddi_destroy,
3215};
3216
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003217static struct intel_connector *
3218intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3219{
3220 struct intel_connector *connector;
3221 enum port port = intel_dig_port->port;
3222
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003223 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003224 if (!connector)
3225 return NULL;
3226
3227 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3228 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3229 kfree(connector);
3230 return NULL;
3231 }
3232
3233 return connector;
3234}
3235
3236static struct intel_connector *
3237intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3238{
3239 struct intel_connector *connector;
3240 enum port port = intel_dig_port->port;
3241
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003242 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003243 if (!connector)
3244 return NULL;
3245
3246 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3247 intel_hdmi_init_connector(intel_dig_port, connector);
3248
3249 return connector;
3250}
3251
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003252void intel_ddi_init(struct drm_device *dev, enum port port)
3253{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003254 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003255 struct intel_digital_port *intel_dig_port;
3256 struct intel_encoder *intel_encoder;
3257 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003258 bool init_hdmi, init_dp;
3259
3260 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3261 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3262 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3263 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003264 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003265 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003266 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003267 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003268
Daniel Vetterb14c5672013-09-19 12:18:32 +02003269 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003270 if (!intel_dig_port)
3271 return;
3272
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003273 intel_encoder = &intel_dig_port->base;
3274 encoder = &intel_encoder->base;
3275
3276 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3277 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003278
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003279 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003280 intel_encoder->enable = intel_enable_ddi;
3281 intel_encoder->pre_enable = intel_ddi_pre_enable;
3282 intel_encoder->disable = intel_disable_ddi;
3283 intel_encoder->post_disable = intel_ddi_post_disable;
3284 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003285 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003286
3287 intel_dig_port->port = port;
Stéphane Marchesinbcf53de42013-07-12 13:54:41 -07003288 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3289 (DDI_BUF_PORT_REVERSAL |
3290 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003291
3292 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003293 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003294 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003295
Chris Wilsonf68d6972014-08-04 07:15:09 +01003296 if (init_dp) {
3297 if (!intel_ddi_init_dp_connector(intel_dig_port))
3298 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003299
Chris Wilsonf68d6972014-08-04 07:15:09 +01003300 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303301 /*
3302 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3303 * interrupts to check the external panel connection.
3304 */
3305 if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)
3306 && port == PORT_B)
3307 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3308 else
3309 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003310 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003311
Paulo Zanoni311a2092013-09-12 17:12:18 -03003312 /* In theory we don't need the encoder->type check, but leave it just in
3313 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003314 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3315 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3316 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003317 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003318
3319 return;
3320
3321err:
3322 drm_encoder_cleanup(encoder);
3323 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003324}