blob: 2ed64725470adbe5f5ece353a1d826152f2f6c7f [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 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800136 { 0x80009010, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300137 { 0x00002016, 0x0000009B, 0x0 },
138 { 0x00005012, 0x00000088, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800139 { 0x80007011, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300140 { 0x00002016, 0x000000DF, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800141 { 0x80005012, 0x000000C0, 0x1 },
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 },
Rodrigo Vivi63ebce12016-01-05 07:58:31 -0800148 { 0x80007011, 0x000000CD, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800149 { 0x80009010, 0x000000C0, 0x1 },
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700150 { 0x0000201B, 0x0000009D, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800151 { 0x80005012, 0x000000C0, 0x1 },
152 { 0x80007011, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300153 { 0x00002016, 0x00000088, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800154 { 0x80005012, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300155};
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 },
Rodrigo Vivi63ebce12016-01-05 07:58:31 -0800161 { 0x80007011, 0x000000CD, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800162 { 0x80009010, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300163 { 0x00000018, 0x0000009D, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800164 { 0x80005012, 0x000000C0, 0x3 },
165 { 0x80007011, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300166 { 0x00000018, 0x00000088, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800167 { 0x80005012, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300168};
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 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800229 { 0x80006012, 0x000000CD, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300230 { 0x00000018, 0x000000DF, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800231 { 0x80003015, 0x000000CD, 0x1 }, /* Default */
232 { 0x80003015, 0x000000C0, 0x1 },
233 { 0x80000018, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300234};
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 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800240 { 0x80007011, 0x000000CB, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300241 { 0x00000018, 0x000000A4, 0x0 },
242 { 0x00000018, 0x0000009D, 0x0 },
243 { 0x00004013, 0x00000080, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800244 { 0x80006013, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300245 { 0x00000018, 0x0000008A, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800246 { 0x80003015, 0x000000C0, 0x3 }, /* Default */
247 { 0x80003015, 0x000000C0, 0x3 },
248 { 0x80000018, 0x000000C0, 0x3 },
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
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200304static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
305 u32 level, enum port port, int type);
David Weinehallf8896f52015-06-25 11:11:03 +0300306
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
Ville Syrjäläacee2992015-12-08 19:59:39 +0200345static const struct ddi_buf_trans *
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200346skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
David Weinehallf8896f52015-06-25 11:11:03 +0300347{
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200348 if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700349 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200350 return skl_y_ddi_translations_dp;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200351 } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300352 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200353 return skl_u_ddi_translations_dp;
David Weinehallf8896f52015-06-25 11:11:03 +0300354 } else {
David Weinehallf8896f52015-06-25 11:11:03 +0300355 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200356 return skl_ddi_translations_dp;
David Weinehallf8896f52015-06-25 11:11:03 +0300357 }
David Weinehallf8896f52015-06-25 11:11:03 +0300358}
359
360static const struct ddi_buf_trans *
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200361skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
David Weinehallf8896f52015-06-25 11:11:03 +0300362{
Ville Syrjäläcd1101c2015-12-08 19:59:40 +0200363 if (dev_priv->edp_low_vswing) {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200364 if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200365 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
366 return skl_y_ddi_translations_edp;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200367 } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200368 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
369 return skl_u_ddi_translations_edp;
370 } else {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200371 *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
372 return skl_ddi_translations_edp;
Ville Syrjäläacee2992015-12-08 19:59:39 +0200373 }
David Weinehallf8896f52015-06-25 11:11:03 +0300374 }
Ville Syrjäläcd1101c2015-12-08 19:59:40 +0200375
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200376 return skl_get_buf_trans_dp(dev_priv, n_entries);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200377}
David Weinehallf8896f52015-06-25 11:11:03 +0300378
Ville Syrjäläacee2992015-12-08 19:59:39 +0200379static const struct ddi_buf_trans *
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200380skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
Ville Syrjäläacee2992015-12-08 19:59:39 +0200381{
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200382 if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200383 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
384 return skl_y_ddi_translations_hdmi;
385 } else {
386 *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
387 return skl_ddi_translations_hdmi;
388 }
David Weinehallf8896f52015-06-25 11:11:03 +0300389}
390
Art Runyane58623c2013-11-02 21:07:41 -0700391/*
392 * Starting with Haswell, DDI port buffers must be programmed with correct
393 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300394 * but the HDMI/DVI fields are shared among those. So we program the DDI
395 * in either FDI or DP modes only, as HDMI connections will work with both
396 * of those
397 */
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200398void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300399{
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200400 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300401 u32 iboost_bit = 0;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000402 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530403 size;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200404 int hdmi_level;
405 enum port port;
Jani Nikula10122052014-08-27 16:27:30 +0300406 const struct ddi_buf_trans *ddi_translations_fdi;
407 const struct ddi_buf_trans *ddi_translations_dp;
408 const struct ddi_buf_trans *ddi_translations_edp;
409 const struct ddi_buf_trans *ddi_translations_hdmi;
410 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700411
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200412 port = intel_ddi_get_encoder_port(encoder);
413 hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
414
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200415 if (IS_BROXTON(dev_priv)) {
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200416 if (encoder->type != INTEL_OUTPUT_HDMI)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530417 return;
418
419 /* Vswing programming for HDMI */
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200420 bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530421 INTEL_OUTPUT_HDMI);
422 return;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200423 }
424
425 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300426 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300427 ddi_translations_dp =
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200428 skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
David Weinehallf8896f52015-06-25 11:11:03 +0300429 ddi_translations_edp =
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200430 skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
David Weinehallf8896f52015-06-25 11:11:03 +0300431 ddi_translations_hdmi =
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200432 skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
David Weinehallf8896f52015-06-25 11:11:03 +0300433 hdmi_default_entry = 8;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300434 /* If we're boosting the current, set bit 31 of trans1 */
435 if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
436 dev_priv->vbt.ddi_port_info[port].dp_boost_level)
437 iboost_bit = 1<<31;
Ville Syrjälä10afa0b2015-12-08 19:59:43 +0200438
439 if (WARN_ON(port != PORT_A &&
440 port != PORT_E && n_edp_entries > 9))
441 n_edp_entries = 9;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200442 } else if (IS_BROADWELL(dev_priv)) {
Art Runyane58623c2013-11-02 21:07:41 -0700443 ddi_translations_fdi = bdw_ddi_translations_fdi;
444 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700445 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100446 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530447 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
448 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300449 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000450 hdmi_default_entry = 7;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200451 } else if (IS_HASWELL(dev_priv)) {
Art Runyane58623c2013-11-02 21:07:41 -0700452 ddi_translations_fdi = hsw_ddi_translations_fdi;
453 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700454 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100455 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530456 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300457 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000458 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700459 } else {
460 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700461 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700462 ddi_translations_fdi = bdw_ddi_translations_fdi;
463 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100464 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530465 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
466 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300467 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000468 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700469 }
470
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200471 switch (encoder->type) {
472 case INTEL_OUTPUT_EDP:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700473 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530474 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700475 break;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200476 case INTEL_OUTPUT_DISPLAYPORT:
477 case INTEL_OUTPUT_HDMI:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700478 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530479 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700480 break;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200481 case INTEL_OUTPUT_ANALOG:
482 ddi_translations = ddi_translations_fdi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530483 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700484 break;
485 default:
486 BUG();
487 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300488
Ville Syrjälä9712e682015-09-18 20:03:22 +0300489 for (i = 0; i < size; i++) {
490 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
491 ddi_translations[i].trans1 | iboost_bit);
492 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
493 ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300494 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100495
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200496 if (encoder->type != INTEL_OUTPUT_HDMI)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100497 return;
498
Damien Lespiauce4dd492014-08-01 11:07:54 +0100499 /* Choose a good default if VBT is badly populated */
500 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
501 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000502 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100503
Paulo Zanoni6acab152013-09-12 17:06:24 -0300504 /* Entry 9 is for HDMI: */
Ville Syrjälä9712e682015-09-18 20:03:22 +0300505 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
506 ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
507 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
508 ddi_translations_hdmi[hdmi_level].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300509}
510
Paulo Zanoni248138b2012-11-29 11:29:31 -0200511static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
512 enum port port)
513{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200514 i915_reg_t reg = DDI_BUF_CTL(port);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200515 int i;
516
Vandana Kannan3449ca82015-03-27 14:19:09 +0200517 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200518 udelay(1);
519 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
520 return;
521 }
522 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
523}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300524
525/* Starting with Haswell, different DDI ports can work in FDI mode for
526 * connection to the PCH-located connectors. For this, it is necessary to train
527 * both the DDI port and PCH receiver for the desired DDI buffer settings.
528 *
529 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
530 * please note that when FDI mode is active on DDI E, it shares 2 lines with
531 * DDI A (which is used for eDP)
532 */
533
534void hsw_fdi_link_train(struct drm_crtc *crtc)
535{
536 struct drm_device *dev = crtc->dev;
537 struct drm_i915_private *dev_priv = dev->dev_private;
538 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200539 struct intel_encoder *encoder;
Paulo Zanoni04945642012-11-01 21:00:59 -0200540 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300541
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200542 for_each_encoder_on_crtc(dev, crtc, encoder) {
543 WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
544 intel_prepare_ddi_buffer(encoder);
545 }
546
Paulo Zanoni04945642012-11-01 21:00:59 -0200547 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
548 * mode set "sequence for CRT port" document:
549 * - TP1 to TP2 time with the default value
550 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100551 *
552 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200553 */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300554 I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) |
Paulo Zanoni04945642012-11-01 21:00:59 -0200555 FDI_RX_PWRDN_LANE0_VAL(2) |
556 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
557
558 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000559 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100560 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200561 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300562 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
563 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200564 udelay(220);
565
566 /* Switch from Rawclk to PCDclk */
567 rx_ctl_val |= FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300568 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
Paulo Zanoni04945642012-11-01 21:00:59 -0200569
570 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200571 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
572 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200573
574 /* Start the training iterating through available voltages and emphasis,
575 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300576 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300577 /* Configure DP_TP_CTL with auto-training */
578 I915_WRITE(DP_TP_CTL(PORT_E),
579 DP_TP_CTL_FDI_AUTOTRAIN |
580 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
581 DP_TP_CTL_LINK_TRAIN_PAT1 |
582 DP_TP_CTL_ENABLE);
583
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000584 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
585 * DDI E does not support port reversal, the functionality is
586 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
587 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300588 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200589 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200590 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530591 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200592 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300593
594 udelay(600);
595
Paulo Zanoni04945642012-11-01 21:00:59 -0200596 /* Program PCH FDI Receiver TU */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300597 I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300598
Paulo Zanoni04945642012-11-01 21:00:59 -0200599 /* Enable PCH FDI Receiver with auto-training */
600 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300601 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
602 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200603
604 /* Wait for FDI receiver lane calibration */
605 udelay(30);
606
607 /* Unset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300608 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200609 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300610 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
611 POSTING_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200612
613 /* Wait for FDI auto training time */
614 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300615
616 temp = I915_READ(DP_TP_STATUS(PORT_E));
617 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200618 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200619 break;
620 }
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300621
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200622 /*
623 * Leave things enabled even if we failed to train FDI.
624 * Results in less fireworks from the state checker.
625 */
626 if (i == ARRAY_SIZE(hsw_ddi_translations_fdi) * 2 - 1) {
627 DRM_ERROR("FDI link training failed!\n");
628 break;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300629 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200630
Paulo Zanoni248138b2012-11-29 11:29:31 -0200631 temp = I915_READ(DDI_BUF_CTL(PORT_E));
632 temp &= ~DDI_BUF_CTL_ENABLE;
633 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
634 POSTING_READ(DDI_BUF_CTL(PORT_E));
635
Paulo Zanoni04945642012-11-01 21:00:59 -0200636 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200637 temp = I915_READ(DP_TP_CTL(PORT_E));
638 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
639 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
640 I915_WRITE(DP_TP_CTL(PORT_E), temp);
641 POSTING_READ(DP_TP_CTL(PORT_E));
642
643 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200644
645 rx_ctl_val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300646 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
647 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200648
649 /* Reset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300650 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200651 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
652 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300653 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
654 POSTING_READ(FDI_RX_MISC(PIPE_A));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300655 }
656
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200657 /* Enable normal pixel sending for FDI */
658 I915_WRITE(DP_TP_CTL(PORT_E),
659 DP_TP_CTL_FDI_AUTOTRAIN |
660 DP_TP_CTL_LINK_TRAIN_NORMAL |
661 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
662 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300663}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300664
Dave Airlie44905a272014-05-02 13:36:43 +1000665void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
666{
667 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
668 struct intel_digital_port *intel_dig_port =
669 enc_to_dig_port(&encoder->base);
670
671 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530672 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300673 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a272014-05-02 13:36:43 +1000674}
675
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300676static struct intel_encoder *
677intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
678{
679 struct drm_device *dev = crtc->dev;
680 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
681 struct intel_encoder *intel_encoder, *ret = NULL;
682 int num_encoders = 0;
683
684 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
685 ret = intel_encoder;
686 num_encoders++;
687 }
688
689 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300690 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
691 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300692
693 BUG_ON(ret == NULL);
694 return ret;
695}
696
Satheeshakrishna Mbcddf6102014-08-22 09:49:10 +0530697struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200698intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200699{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200700 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
701 struct intel_encoder *ret = NULL;
702 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300703 struct drm_connector *connector;
704 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200705 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200706 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200707
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200708 state = crtc_state->base.state;
709
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300710 for_each_connector_in_state(state, connector, connector_state, i) {
711 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200712 continue;
713
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300714 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200715 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200716 }
717
718 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
719 pipe_name(crtc->pipe));
720
721 BUG_ON(ret == NULL);
722 return ret;
723}
724
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100725#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100726#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100727
728#define P_MIN 2
729#define P_MAX 64
730#define P_INC 2
731
732/* Constraints for PLL good behavior */
733#define REF_MIN 48
734#define REF_MAX 400
735#define VCO_MIN 2400
736#define VCO_MAX 4800
737
Damien Lespiau27893392014-09-04 12:27:23 +0100738#define abs_diff(a, b) ({ \
739 typeof(a) __a = (a); \
740 typeof(b) __b = (b); \
741 (void) (&__a == &__b); \
742 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100743
Damien Lespiau63582982015-05-07 18:38:46 +0100744struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100745 unsigned p, n2, r2;
746};
747
Damien Lespiau63582982015-05-07 18:38:46 +0100748static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300749{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100750 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300751
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100752 switch (clock) {
753 case 25175000:
754 case 25200000:
755 case 27000000:
756 case 27027000:
757 case 37762500:
758 case 37800000:
759 case 40500000:
760 case 40541000:
761 case 54000000:
762 case 54054000:
763 case 59341000:
764 case 59400000:
765 case 72000000:
766 case 74176000:
767 case 74250000:
768 case 81000000:
769 case 81081000:
770 case 89012000:
771 case 89100000:
772 case 108000000:
773 case 108108000:
774 case 111264000:
775 case 111375000:
776 case 148352000:
777 case 148500000:
778 case 162000000:
779 case 162162000:
780 case 222525000:
781 case 222750000:
782 case 296703000:
783 case 297000000:
784 budget = 0;
785 break;
786 case 233500000:
787 case 245250000:
788 case 247750000:
789 case 253250000:
790 case 298000000:
791 budget = 1500;
792 break;
793 case 169128000:
794 case 169500000:
795 case 179500000:
796 case 202000000:
797 budget = 2000;
798 break;
799 case 256250000:
800 case 262500000:
801 case 270000000:
802 case 272500000:
803 case 273750000:
804 case 280750000:
805 case 281250000:
806 case 286000000:
807 case 291750000:
808 budget = 4000;
809 break;
810 case 267250000:
811 case 268500000:
812 budget = 5000;
813 break;
814 default:
815 budget = 1000;
816 break;
817 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300818
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100819 return budget;
820}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300821
Damien Lespiau63582982015-05-07 18:38:46 +0100822static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
823 unsigned r2, unsigned n2, unsigned p,
824 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100825{
826 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300827
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100828 /* No best (r,n,p) yet */
829 if (best->p == 0) {
830 best->p = p;
831 best->n2 = n2;
832 best->r2 = r2;
833 return;
834 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300835
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100836 /*
837 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
838 * freq2k.
839 *
840 * delta = 1e6 *
841 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
842 * freq2k;
843 *
844 * and we would like delta <= budget.
845 *
846 * If the discrepancy is above the PPM-based budget, always prefer to
847 * improve upon the previous solution. However, if you're within the
848 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
849 */
850 a = freq2k * budget * p * r2;
851 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100852 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
853 diff_best = abs_diff(freq2k * best->p * best->r2,
854 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100855 c = 1000000 * diff;
856 d = 1000000 * diff_best;
857
858 if (a < c && b < d) {
859 /* If both are above the budget, pick the closer */
860 if (best->p * best->r2 * diff < p * r2 * diff_best) {
861 best->p = p;
862 best->n2 = n2;
863 best->r2 = r2;
864 }
865 } else if (a >= c && b < d) {
866 /* If A is below the threshold but B is above it? Update. */
867 best->p = p;
868 best->n2 = n2;
869 best->r2 = r2;
870 } else if (a >= c && b >= d) {
871 /* Both are below the limit, so pick the higher n2/(r2*r2) */
872 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
873 best->p = p;
874 best->n2 = n2;
875 best->r2 = r2;
876 }
877 }
878 /* Otherwise a < c && b >= d, do nothing */
879}
880
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200881static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
882 i915_reg_t reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800883{
884 int refclk = LC_FREQ;
885 int n, p, r;
886 u32 wrpll;
887
888 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300889 switch (wrpll & WRPLL_PLL_REF_MASK) {
890 case WRPLL_PLL_SSC:
891 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800892 /*
893 * We could calculate spread here, but our checking
894 * code only cares about 5% accuracy, and spread is a max of
895 * 0.5% downspread.
896 */
897 refclk = 135;
898 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300899 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800900 refclk = LC_FREQ;
901 break;
902 default:
903 WARN(1, "bad wrpll refclk\n");
904 return 0;
905 }
906
907 r = wrpll & WRPLL_DIVIDER_REF_MASK;
908 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
909 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
910
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800911 /* Convert to KHz, p & r have a fixed point portion */
912 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800913}
914
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000915static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
916 uint32_t dpll)
917{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200918 i915_reg_t cfgcr1_reg, cfgcr2_reg;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000919 uint32_t cfgcr1_val, cfgcr2_val;
920 uint32_t p0, p1, p2, dco_freq;
921
Ville Syrjälä923c12412015-09-30 17:06:43 +0300922 cfgcr1_reg = DPLL_CFGCR1(dpll);
923 cfgcr2_reg = DPLL_CFGCR2(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000924
925 cfgcr1_val = I915_READ(cfgcr1_reg);
926 cfgcr2_val = I915_READ(cfgcr2_reg);
927
928 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
929 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
930
931 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
932 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
933 else
934 p1 = 1;
935
936
937 switch (p0) {
938 case DPLL_CFGCR2_PDIV_1:
939 p0 = 1;
940 break;
941 case DPLL_CFGCR2_PDIV_2:
942 p0 = 2;
943 break;
944 case DPLL_CFGCR2_PDIV_3:
945 p0 = 3;
946 break;
947 case DPLL_CFGCR2_PDIV_7:
948 p0 = 7;
949 break;
950 }
951
952 switch (p2) {
953 case DPLL_CFGCR2_KDIV_5:
954 p2 = 5;
955 break;
956 case DPLL_CFGCR2_KDIV_2:
957 p2 = 2;
958 break;
959 case DPLL_CFGCR2_KDIV_3:
960 p2 = 3;
961 break;
962 case DPLL_CFGCR2_KDIV_1:
963 p2 = 1;
964 break;
965 }
966
967 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
968
969 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
970 1000) / 0x8000;
971
972 return dco_freq / (p0 * p1 * p2 * 5);
973}
974
Ville Syrjälä398a0172015-06-30 15:33:51 +0300975static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
976{
977 int dotclock;
978
979 if (pipe_config->has_pch_encoder)
980 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
981 &pipe_config->fdi_m_n);
982 else if (pipe_config->has_dp_encoder)
983 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
984 &pipe_config->dp_m_n);
985 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
986 dotclock = pipe_config->port_clock * 2 / 3;
987 else
988 dotclock = pipe_config->port_clock;
989
990 if (pipe_config->pixel_multiplier)
991 dotclock /= pipe_config->pixel_multiplier;
992
993 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
994}
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000995
996static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +0200997 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000998{
999 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001000 int link_clock = 0;
1001 uint32_t dpll_ctl1, dpll;
1002
Damien Lespiau134ffa42014-11-14 17:24:34 +00001003 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001004
1005 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1006
1007 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1008 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1009 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001010 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1011 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001012
1013 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001014 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001015 link_clock = 81000;
1016 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001017 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301018 link_clock = 108000;
1019 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001020 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001021 link_clock = 135000;
1022 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001023 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301024 link_clock = 162000;
1025 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001026 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301027 link_clock = 216000;
1028 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001029 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001030 link_clock = 270000;
1031 break;
1032 default:
1033 WARN(1, "Unsupported link rate\n");
1034 break;
1035 }
1036 link_clock *= 2;
1037 }
1038
1039 pipe_config->port_clock = link_clock;
1040
Ville Syrjälä398a0172015-06-30 15:33:51 +03001041 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001042}
1043
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001044static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001045 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001046{
1047 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001048 int link_clock = 0;
1049 u32 val, pll;
1050
Daniel Vetter26804af2014-06-25 22:01:55 +03001051 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001052 switch (val & PORT_CLK_SEL_MASK) {
1053 case PORT_CLK_SEL_LCPLL_810:
1054 link_clock = 81000;
1055 break;
1056 case PORT_CLK_SEL_LCPLL_1350:
1057 link_clock = 135000;
1058 break;
1059 case PORT_CLK_SEL_LCPLL_2700:
1060 link_clock = 270000;
1061 break;
1062 case PORT_CLK_SEL_WRPLL1:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001063 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
Jesse Barnes11578552014-01-21 12:42:10 -08001064 break;
1065 case PORT_CLK_SEL_WRPLL2:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001066 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
Jesse Barnes11578552014-01-21 12:42:10 -08001067 break;
1068 case PORT_CLK_SEL_SPLL:
1069 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1070 if (pll == SPLL_PLL_FREQ_810MHz)
1071 link_clock = 81000;
1072 else if (pll == SPLL_PLL_FREQ_1350MHz)
1073 link_clock = 135000;
1074 else if (pll == SPLL_PLL_FREQ_2700MHz)
1075 link_clock = 270000;
1076 else {
1077 WARN(1, "bad spll freq\n");
1078 return;
1079 }
1080 break;
1081 default:
1082 WARN(1, "bad port clock sel\n");
1083 return;
1084 }
1085
1086 pipe_config->port_clock = link_clock * 2;
1087
Ville Syrjälä398a0172015-06-30 15:33:51 +03001088 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001089}
1090
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301091static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1092 enum intel_dpll_id dpll)
1093{
Imre Deakaa610dc2015-06-22 23:35:52 +03001094 struct intel_shared_dpll *pll;
1095 struct intel_dpll_hw_state *state;
1096 intel_clock_t clock;
1097
1098 /* For DDI ports we always use a shared PLL. */
1099 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1100 return 0;
1101
1102 pll = &dev_priv->shared_dplls[dpll];
1103 state = &pll->config.hw_state;
1104
1105 clock.m1 = 2;
1106 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1107 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1108 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1109 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1110 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1111 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1112
1113 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301114}
1115
1116static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1117 struct intel_crtc_state *pipe_config)
1118{
1119 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1120 enum port port = intel_ddi_get_encoder_port(encoder);
1121 uint32_t dpll = port;
1122
Ville Syrjälä398a0172015-06-30 15:33:51 +03001123 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301124
Ville Syrjälä398a0172015-06-30 15:33:51 +03001125 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301126}
1127
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001128void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001129 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001130{
Damien Lespiau22606a12014-12-12 14:26:57 +00001131 struct drm_device *dev = encoder->base.dev;
1132
1133 if (INTEL_INFO(dev)->gen <= 8)
1134 hsw_ddi_clock_get(encoder, pipe_config);
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001135 else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001136 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301137 else if (IS_BROXTON(dev))
1138 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001139}
1140
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001141static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001142hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1143 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001144{
1145 uint64_t freq2k;
1146 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001147 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001148 unsigned budget;
1149
1150 freq2k = clock / 100;
1151
Damien Lespiau63582982015-05-07 18:38:46 +01001152 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001153
1154 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1155 * and directly pass the LC PLL to it. */
1156 if (freq2k == 5400000) {
1157 *n2_out = 2;
1158 *p_out = 1;
1159 *r2_out = 2;
1160 return;
1161 }
1162
1163 /*
1164 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1165 * the WR PLL.
1166 *
1167 * We want R so that REF_MIN <= Ref <= REF_MAX.
1168 * Injecting R2 = 2 * R gives:
1169 * REF_MAX * r2 > LC_FREQ * 2 and
1170 * REF_MIN * r2 < LC_FREQ * 2
1171 *
1172 * Which means the desired boundaries for r2 are:
1173 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1174 *
1175 */
1176 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1177 r2 <= LC_FREQ * 2 / REF_MIN;
1178 r2++) {
1179
1180 /*
1181 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1182 *
1183 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1184 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1185 * VCO_MAX * r2 > n2 * LC_FREQ and
1186 * VCO_MIN * r2 < n2 * LC_FREQ)
1187 *
1188 * Which means the desired boundaries for n2 are:
1189 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1190 */
1191 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1192 n2 <= VCO_MAX * r2 / LC_FREQ;
1193 n2++) {
1194
1195 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001196 hsw_wrpll_update_rnp(freq2k, budget,
1197 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001198 }
1199 }
1200
1201 *n2_out = best.n2;
1202 *p_out = best.p;
1203 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001204}
1205
Damien Lespiau0220ab62014-07-29 18:06:22 +01001206static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001207hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001208 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001209 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001210{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001211 int clock = crtc_state->port_clock;
1212
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001213 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001214 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001215 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001216 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001217
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001218 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001219
Daniel Vetter114fe482014-06-25 22:01:48 +03001220 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001221 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1222 WRPLL_DIVIDER_POST(p);
1223
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001224 memset(&crtc_state->dpll_hw_state, 0,
1225 sizeof(crtc_state->dpll_hw_state));
1226
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001227 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001228
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001229 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001230 if (pll == NULL) {
1231 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1232 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001233 return false;
1234 }
1235
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001236 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Maarten Lankhorst00490c22015-11-16 14:42:12 +01001237 } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
1238 struct drm_atomic_state *state = crtc_state->base.state;
1239 struct intel_shared_dpll_config *spll =
1240 &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
1241
1242 if (spll->crtc_mask &&
1243 WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
1244 return false;
1245
1246 crtc_state->shared_dpll = DPLL_ID_SPLL;
1247 spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
1248 spll->crtc_mask |= 1 << intel_crtc->pipe;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001249 }
1250
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001251 return true;
1252}
1253
Damien Lespiaudc253812015-06-25 16:15:06 +01001254struct skl_wrpll_context {
1255 uint64_t min_deviation; /* current minimal deviation */
1256 uint64_t central_freq; /* chosen central freq */
1257 uint64_t dco_freq; /* chosen dco freq */
1258 unsigned int p; /* chosen divider */
1259};
1260
1261static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1262{
1263 memset(ctx, 0, sizeof(*ctx));
1264
1265 ctx->min_deviation = U64_MAX;
1266}
1267
1268/* DCO freq must be within +1%/-6% of the DCO central freq */
1269#define SKL_DCO_MAX_PDEVIATION 100
1270#define SKL_DCO_MAX_NDEVIATION 600
1271
1272static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1273 uint64_t central_freq,
1274 uint64_t dco_freq,
1275 unsigned int divider)
1276{
1277 uint64_t deviation;
1278
1279 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1280 central_freq);
1281
1282 /* positive deviation */
1283 if (dco_freq >= central_freq) {
1284 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1285 deviation < ctx->min_deviation) {
1286 ctx->min_deviation = deviation;
1287 ctx->central_freq = central_freq;
1288 ctx->dco_freq = dco_freq;
1289 ctx->p = divider;
1290 }
1291 /* negative deviation */
1292 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1293 deviation < ctx->min_deviation) {
1294 ctx->min_deviation = deviation;
1295 ctx->central_freq = central_freq;
1296 ctx->dco_freq = dco_freq;
1297 ctx->p = divider;
1298 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001299}
1300
1301static void skl_wrpll_get_multipliers(unsigned int p,
1302 unsigned int *p0 /* out */,
1303 unsigned int *p1 /* out */,
1304 unsigned int *p2 /* out */)
1305{
1306 /* even dividers */
1307 if (p % 2 == 0) {
1308 unsigned int half = p / 2;
1309
1310 if (half == 1 || half == 2 || half == 3 || half == 5) {
1311 *p0 = 2;
1312 *p1 = 1;
1313 *p2 = half;
1314 } else if (half % 2 == 0) {
1315 *p0 = 2;
1316 *p1 = half / 2;
1317 *p2 = 2;
1318 } else if (half % 3 == 0) {
1319 *p0 = 3;
1320 *p1 = half / 3;
1321 *p2 = 2;
1322 } else if (half % 7 == 0) {
1323 *p0 = 7;
1324 *p1 = half / 7;
1325 *p2 = 2;
1326 }
1327 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1328 *p0 = 3;
1329 *p1 = 1;
1330 *p2 = p / 3;
1331 } else if (p == 5 || p == 7) {
1332 *p0 = p;
1333 *p1 = 1;
1334 *p2 = 1;
1335 } else if (p == 15) {
1336 *p0 = 3;
1337 *p1 = 1;
1338 *p2 = 5;
1339 } else if (p == 21) {
1340 *p0 = 7;
1341 *p1 = 1;
1342 *p2 = 3;
1343 } else if (p == 35) {
1344 *p0 = 7;
1345 *p1 = 1;
1346 *p2 = 5;
1347 }
1348}
1349
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001350struct skl_wrpll_params {
1351 uint32_t dco_fraction;
1352 uint32_t dco_integer;
1353 uint32_t qdiv_ratio;
1354 uint32_t qdiv_mode;
1355 uint32_t kdiv;
1356 uint32_t pdiv;
1357 uint32_t central_freq;
1358};
1359
Damien Lespiau76516fb2015-05-07 18:38:42 +01001360static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1361 uint64_t afe_clock,
1362 uint64_t central_freq,
1363 uint32_t p0, uint32_t p1, uint32_t p2)
1364{
1365 uint64_t dco_freq;
1366
Damien Lespiau76516fb2015-05-07 18:38:42 +01001367 switch (central_freq) {
1368 case 9600000000ULL:
1369 params->central_freq = 0;
1370 break;
1371 case 9000000000ULL:
1372 params->central_freq = 1;
1373 break;
1374 case 8400000000ULL:
1375 params->central_freq = 3;
1376 }
1377
1378 switch (p0) {
1379 case 1:
1380 params->pdiv = 0;
1381 break;
1382 case 2:
1383 params->pdiv = 1;
1384 break;
1385 case 3:
1386 params->pdiv = 2;
1387 break;
1388 case 7:
1389 params->pdiv = 4;
1390 break;
1391 default:
1392 WARN(1, "Incorrect PDiv\n");
1393 }
1394
1395 switch (p2) {
1396 case 5:
1397 params->kdiv = 0;
1398 break;
1399 case 2:
1400 params->kdiv = 1;
1401 break;
1402 case 3:
1403 params->kdiv = 2;
1404 break;
1405 case 1:
1406 params->kdiv = 3;
1407 break;
1408 default:
1409 WARN(1, "Incorrect KDiv\n");
1410 }
1411
1412 params->qdiv_ratio = p1;
1413 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1414
1415 dco_freq = p0 * p1 * p2 * afe_clock;
1416
1417 /*
1418 * Intermediate values are in Hz.
1419 * Divide by MHz to match bsepc
1420 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001421 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001422 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001423 div_u64((div_u64(dco_freq, 24) -
1424 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001425}
1426
Damien Lespiau318bd822015-05-07 18:38:40 +01001427static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001428skl_ddi_calculate_wrpll(int clock /* in Hz */,
1429 struct skl_wrpll_params *wrpll_params)
1430{
1431 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001432 uint64_t dco_central_freq[3] = {8400000000ULL,
1433 9000000000ULL,
1434 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001435 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1436 24, 28, 30, 32, 36, 40, 42, 44,
1437 48, 52, 54, 56, 60, 64, 66, 68,
1438 70, 72, 76, 78, 80, 84, 88, 90,
1439 92, 96, 98 };
1440 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1441 static const struct {
1442 const int *list;
1443 int n_dividers;
1444 } dividers[] = {
1445 { even_dividers, ARRAY_SIZE(even_dividers) },
1446 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1447 };
1448 struct skl_wrpll_context ctx;
1449 unsigned int dco, d, i;
1450 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001451
Damien Lespiaudc253812015-06-25 16:15:06 +01001452 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001453
Damien Lespiaudc253812015-06-25 16:15:06 +01001454 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1455 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1456 for (i = 0; i < dividers[d].n_dividers; i++) {
1457 unsigned int p = dividers[d].list[i];
1458 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001459
Damien Lespiaudc253812015-06-25 16:15:06 +01001460 skl_wrpll_try_divider(&ctx,
1461 dco_central_freq[dco],
1462 dco_freq,
1463 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001464 /*
1465 * Skip the remaining dividers if we're sure to
1466 * have found the definitive divider, we can't
1467 * improve a 0 deviation.
1468 */
1469 if (ctx.min_deviation == 0)
1470 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001471 }
1472 }
Damien Lespiau267db662015-06-25 16:19:24 +01001473
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001474skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001475 /*
1476 * If a solution is found with an even divider, prefer
1477 * this one.
1478 */
1479 if (d == 0 && ctx.p)
1480 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001481 }
1482
Damien Lespiaudc253812015-06-25 16:15:06 +01001483 if (!ctx.p) {
1484 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001485 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001486 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001487
Damien Lespiaudc253812015-06-25 16:15:06 +01001488 /*
1489 * gcc incorrectly analyses that these can be used without being
1490 * initialized. To be fair, it's hard to guess.
1491 */
1492 p0 = p1 = p2 = 0;
1493 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1494 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1495 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001496
Damien Lespiau318bd822015-05-07 18:38:40 +01001497 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001498}
1499
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001500static bool
1501skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001502 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001503 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001504{
1505 struct intel_shared_dpll *pll;
1506 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001507 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001508
1509 /*
1510 * See comment in intel_dpll_hw_state to understand why we always use 0
1511 * as the DPLL id in this function.
1512 */
1513
1514 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1515
1516 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1517 struct skl_wrpll_params wrpll_params = { 0, };
1518
1519 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1520
Damien Lespiau318bd822015-05-07 18:38:40 +01001521 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1522 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001523
1524 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1525 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1526 wrpll_params.dco_integer;
1527
1528 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1529 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1530 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1531 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1532 wrpll_params.central_freq;
1533 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001534 switch (crtc_state->port_clock / 2) {
1535 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001536 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001537 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001538 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001539 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001540 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001541 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001542 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001543 break;
1544 }
1545
1546 cfgcr1 = cfgcr2 = 0;
1547 } else /* eDP */
1548 return true;
1549
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001550 memset(&crtc_state->dpll_hw_state, 0,
1551 sizeof(crtc_state->dpll_hw_state));
1552
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001553 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1554 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1555 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001556
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001557 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001558 if (pll == NULL) {
1559 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1560 pipe_name(intel_crtc->pipe));
1561 return false;
1562 }
1563
1564 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001565 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001566
1567 return true;
1568}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001569
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301570/* bxt clock parameters */
1571struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301572 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301573 uint32_t p1;
1574 uint32_t p2;
1575 uint32_t m2_int;
1576 uint32_t m2_frac;
1577 bool m2_frac_en;
1578 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301579};
1580
1581/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301582static const struct bxt_clk_div bxt_dp_clk_val[] = {
1583 {162000, 4, 2, 32, 1677722, 1, 1},
1584 {270000, 4, 1, 27, 0, 0, 1},
1585 {540000, 2, 1, 27, 0, 0, 1},
1586 {216000, 3, 2, 32, 1677722, 1, 1},
1587 {243000, 4, 1, 24, 1258291, 1, 1},
1588 {324000, 4, 1, 32, 1677722, 1, 1},
1589 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301590};
1591
1592static bool
1593bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1594 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001595 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301596{
1597 struct intel_shared_dpll *pll;
1598 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301599 int vco = 0;
1600 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301601 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001602 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301603
1604 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1605 intel_clock_t best_clock;
1606
1607 /* Calculate HDMI div */
1608 /*
1609 * FIXME: tie the following calculation into
1610 * i9xx_crtc_compute_clock
1611 */
1612 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1613 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1614 clock, pipe_name(intel_crtc->pipe));
1615 return false;
1616 }
1617
1618 clk_div.p1 = best_clock.p1;
1619 clk_div.p2 = best_clock.p2;
1620 WARN_ON(best_clock.m1 != 2);
1621 clk_div.n = best_clock.n;
1622 clk_div.m2_int = best_clock.m2 >> 22;
1623 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1624 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1625
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301626 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301627 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1628 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301629 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301630
Sonika Jindal64987fc2015-05-26 17:50:13 +05301631 clk_div = bxt_dp_clk_val[0];
1632 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1633 if (bxt_dp_clk_val[i].clock == clock) {
1634 clk_div = bxt_dp_clk_val[i];
1635 break;
1636 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301637 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301638 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1639 }
1640
Vandana Kannane6292552015-07-01 17:02:57 +05301641 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301642 prop_coef = 4;
1643 int_coef = 9;
1644 gain_ctl = 3;
1645 targ_cnt = 8;
1646 } else if ((vco > 5400000 && vco < 6200000) ||
1647 (vco >= 4800000 && vco < 5400000)) {
1648 prop_coef = 5;
1649 int_coef = 11;
1650 gain_ctl = 3;
1651 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301652 } else if (vco == 5400000) {
1653 prop_coef = 3;
1654 int_coef = 8;
1655 gain_ctl = 1;
1656 targ_cnt = 9;
1657 } else {
1658 DRM_ERROR("Invalid VCO\n");
1659 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301660 }
1661
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001662 memset(&crtc_state->dpll_hw_state, 0,
1663 sizeof(crtc_state->dpll_hw_state));
1664
Vandana Kannane0681e32015-05-13 12:20:35 +05301665 if (clock > 270000)
1666 lanestagger = 0x18;
1667 else if (clock > 135000)
1668 lanestagger = 0x0d;
1669 else if (clock > 67000)
1670 lanestagger = 0x07;
1671 else if (clock > 33000)
1672 lanestagger = 0x04;
1673 else
1674 lanestagger = 0x02;
1675
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301676 crtc_state->dpll_hw_state.ebb0 =
1677 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1678 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1679 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1680 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1681
1682 if (clk_div.m2_frac_en)
1683 crtc_state->dpll_hw_state.pll3 =
1684 PORT_PLL_M2_FRAC_ENABLE;
1685
1686 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301687 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301688 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301689 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301690
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301691 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1692
Imre Deak05712c12015-06-18 17:25:54 +03001693 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1694
Vandana Kannane6292552015-07-01 17:02:57 +05301695 crtc_state->dpll_hw_state.pll10 =
1696 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1697 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301698
Imre Deak05712c12015-06-18 17:25:54 +03001699 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1700
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301701 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301702 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301703
1704 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1705 if (pll == NULL) {
1706 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1707 pipe_name(intel_crtc->pipe));
1708 return false;
1709 }
1710
1711 /* shared DPLL id 0 is DPLL A */
1712 crtc_state->ddi_pll_sel = pll->id;
1713
1714 return true;
1715}
1716
Damien Lespiau0220ab62014-07-29 18:06:22 +01001717/*
1718 * Tries to find a *shared* PLL for the CRTC and store it in
1719 * intel_crtc->ddi_pll_sel.
1720 *
1721 * For private DPLLs, compute_config() should do the selection for us. This
1722 * function should be folded into compute_config() eventually.
1723 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001724bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1725 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001726{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001727 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001728 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001729 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001730
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001731 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001732 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001733 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301734 else if (IS_BROXTON(dev))
1735 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001736 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001737 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001738 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001739 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001740}
1741
Paulo Zanonidae84792012-10-15 15:51:30 -03001742void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1743{
1744 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1745 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1746 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001747 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001748 int type = intel_encoder->type;
1749 uint32_t temp;
1750
Dave Airlie0e32b392014-05-02 14:02:48 +10001751 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001752 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001753 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001754 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001755 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001756 break;
1757 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001758 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001759 break;
1760 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001761 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001762 break;
1763 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001764 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001765 break;
1766 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001767 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001768 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001769 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001770 }
1771}
1772
Dave Airlie0e32b392014-05-02 14:02:48 +10001773void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1774{
1775 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1776 struct drm_device *dev = crtc->dev;
1777 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001778 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001779 uint32_t temp;
1780 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1781 if (state == true)
1782 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1783 else
1784 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1785 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1786}
1787
Damien Lespiau8228c252013-03-07 15:30:27 +00001788void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001789{
1790 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1791 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001792 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001793 struct drm_device *dev = crtc->dev;
1794 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001795 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001796 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001797 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001798 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001799 uint32_t temp;
1800
Paulo Zanoniad80a812012-10-24 16:06:19 -02001801 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1802 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001803 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001804
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001805 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001806 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001807 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001808 break;
1809 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001810 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001811 break;
1812 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001813 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001814 break;
1815 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001816 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001817 break;
1818 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001819 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001820 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001821
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001822 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001823 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001824 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001825 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001826
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001827 if (cpu_transcoder == TRANSCODER_EDP) {
1828 switch (pipe) {
1829 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001830 /* On Haswell, can only use the always-on power well for
1831 * eDP when not using the panel fitter, and when not
1832 * using motion blur mitigation (which we don't
1833 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001834 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001835 (intel_crtc->config->pch_pfit.enabled ||
1836 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001837 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1838 else
1839 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001840 break;
1841 case PIPE_B:
1842 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1843 break;
1844 case PIPE_C:
1845 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1846 break;
1847 default:
1848 BUG();
1849 break;
1850 }
1851 }
1852
Paulo Zanoni7739c332012-10-15 15:51:29 -03001853 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001854 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001855 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001856 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001857 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001858
Paulo Zanoni7739c332012-10-15 15:51:29 -03001859 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001860 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001861 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001862
1863 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1864 type == INTEL_OUTPUT_EDP) {
1865 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1866
Dave Airlie0e32b392014-05-02 14:02:48 +10001867 if (intel_dp->is_mst) {
1868 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1869 } else
1870 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1871
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001872 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001873 } else if (type == INTEL_OUTPUT_DP_MST) {
1874 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1875
1876 if (intel_dp->is_mst) {
1877 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1878 } else
1879 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001880
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001881 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001882 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001883 WARN(1, "Invalid encoder type %d for pipe %c\n",
1884 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001885 }
1886
Paulo Zanoniad80a812012-10-24 16:06:19 -02001887 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001888}
1889
Paulo Zanoniad80a812012-10-24 16:06:19 -02001890void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1891 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001892{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02001893 i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001894 uint32_t val = I915_READ(reg);
1895
Dave Airlie0e32b392014-05-02 14:02:48 +10001896 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001897 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001898 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001899}
1900
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001901bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1902{
1903 struct drm_device *dev = intel_connector->base.dev;
1904 struct drm_i915_private *dev_priv = dev->dev_private;
1905 struct intel_encoder *intel_encoder = intel_connector->encoder;
1906 int type = intel_connector->base.connector_type;
1907 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1908 enum pipe pipe = 0;
1909 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001910 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001911 uint32_t tmp;
1912
Paulo Zanoni882244a2014-04-01 14:55:12 -03001913 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001914 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001915 return false;
1916
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001917 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1918 return false;
1919
1920 if (port == PORT_A)
1921 cpu_transcoder = TRANSCODER_EDP;
1922 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001923 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001924
1925 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1926
1927 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1928 case TRANS_DDI_MODE_SELECT_HDMI:
1929 case TRANS_DDI_MODE_SELECT_DVI:
1930 return (type == DRM_MODE_CONNECTOR_HDMIA);
1931
1932 case TRANS_DDI_MODE_SELECT_DP_SST:
1933 if (type == DRM_MODE_CONNECTOR_eDP)
1934 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001935 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001936 case TRANS_DDI_MODE_SELECT_DP_MST:
1937 /* if the transcoder is in MST state then
1938 * connector isn't connected */
1939 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001940
1941 case TRANS_DDI_MODE_SELECT_FDI:
1942 return (type == DRM_MODE_CONNECTOR_VGA);
1943
1944 default:
1945 return false;
1946 }
1947}
1948
Daniel Vetter85234cd2012-07-02 13:27:29 +02001949bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1950 enum pipe *pipe)
1951{
1952 struct drm_device *dev = encoder->base.dev;
1953 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001954 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001955 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001956 u32 tmp;
1957 int i;
1958
Imre Deak6d129be2014-03-05 16:20:54 +02001959 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001960 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02001961 return false;
1962
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001963 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001964
1965 if (!(tmp & DDI_BUF_CTL_ENABLE))
1966 return false;
1967
Paulo Zanoniad80a812012-10-24 16:06:19 -02001968 if (port == PORT_A) {
1969 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001970
Paulo Zanoniad80a812012-10-24 16:06:19 -02001971 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
1972 case TRANS_DDI_EDP_INPUT_A_ON:
1973 case TRANS_DDI_EDP_INPUT_A_ONOFF:
1974 *pipe = PIPE_A;
1975 break;
1976 case TRANS_DDI_EDP_INPUT_B_ONOFF:
1977 *pipe = PIPE_B;
1978 break;
1979 case TRANS_DDI_EDP_INPUT_C_ONOFF:
1980 *pipe = PIPE_C;
1981 break;
1982 }
1983
1984 return true;
1985 } else {
1986 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
1987 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
1988
1989 if ((tmp & TRANS_DDI_PORT_MASK)
1990 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10001991 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
1992 return false;
1993
Paulo Zanoniad80a812012-10-24 16:06:19 -02001994 *pipe = i;
1995 return true;
1996 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02001997 }
1998 }
1999
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002000 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002001
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002002 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002003}
2004
Paulo Zanonifc914632012-10-05 12:05:54 -03002005void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2006{
2007 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302008 struct drm_device *dev = crtc->dev;
2009 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002010 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2011 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002012 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002013
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002014 if (cpu_transcoder != TRANSCODER_EDP)
2015 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2016 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002017}
2018
2019void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2020{
2021 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002022 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002023
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002024 if (cpu_transcoder != TRANSCODER_EDP)
2025 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2026 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002027}
2028
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002029static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
2030 u32 level, enum port port, int type)
David Weinehallf8896f52015-06-25 11:11:03 +03002031{
David Weinehallf8896f52015-06-25 11:11:03 +03002032 const struct ddi_buf_trans *ddi_translations;
2033 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002034 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002035 int n_entries;
2036 u32 reg;
2037
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002038 /* VBT may override standard boost values */
2039 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2040 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2041
David Weinehallf8896f52015-06-25 11:11:03 +03002042 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002043 if (dp_iboost) {
2044 iboost = dp_iboost;
2045 } else {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002046 ddi_translations = skl_get_buf_trans_dp(dev_priv, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002047 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002048 }
David Weinehallf8896f52015-06-25 11:11:03 +03002049 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002050 if (dp_iboost) {
2051 iboost = dp_iboost;
2052 } else {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002053 ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
Ville Syrjälä10afa0b2015-12-08 19:59:43 +02002054
2055 if (WARN_ON(port != PORT_A &&
2056 port != PORT_E && n_entries > 9))
2057 n_entries = 9;
2058
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002059 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002060 }
David Weinehallf8896f52015-06-25 11:11:03 +03002061 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002062 if (hdmi_iboost) {
2063 iboost = hdmi_iboost;
2064 } else {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002065 ddi_translations = skl_get_buf_trans_hdmi(dev_priv, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002066 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002067 }
David Weinehallf8896f52015-06-25 11:11:03 +03002068 } else {
2069 return;
2070 }
2071
2072 /* Make sure that the requested I_boost is valid */
2073 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2074 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2075 return;
2076 }
2077
2078 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2079 reg &= ~BALANCE_LEG_MASK(port);
2080 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2081
2082 if (iboost)
2083 reg |= iboost << BALANCE_LEG_SHIFT(port);
2084 else
2085 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2086
2087 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2088}
2089
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002090static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
2091 u32 level, enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302092{
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302093 const struct bxt_ddi_buf_trans *ddi_translations;
2094 u32 n_entries, i;
2095 uint32_t val;
2096
Sonika Jindald9d70002015-09-24 10:24:56 +05302097 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2098 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2099 ddi_translations = bxt_ddi_translations_edp;
2100 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2101 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302102 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2103 ddi_translations = bxt_ddi_translations_dp;
2104 } else if (type == INTEL_OUTPUT_HDMI) {
2105 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2106 ddi_translations = bxt_ddi_translations_hdmi;
2107 } else {
2108 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2109 type);
2110 return;
2111 }
2112
2113 /* Check if default value has to be used */
2114 if (level >= n_entries ||
2115 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2116 for (i = 0; i < n_entries; i++) {
2117 if (ddi_translations[i].default_index) {
2118 level = i;
2119 break;
2120 }
2121 }
2122 }
2123
2124 /*
2125 * While we write to the group register to program all lanes at once we
2126 * can read only lane registers and we pick lanes 0/1 for that.
2127 */
2128 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2129 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2130 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2131
2132 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2133 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2134 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2135 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2136 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2137
2138 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302139 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302140 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302141 val |= SCALE_DCOMP_METHOD;
2142
2143 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2144 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2145
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302146 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2147
2148 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2149 val &= ~DE_EMPHASIS;
2150 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2151 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2152
2153 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2154 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2155 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2156}
2157
David Weinehallf8896f52015-06-25 11:11:03 +03002158static uint32_t translate_signal_level(int signal_levels)
2159{
2160 uint32_t level;
2161
2162 switch (signal_levels) {
2163 default:
2164 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2165 signal_levels);
2166 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2167 level = 0;
2168 break;
2169 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2170 level = 1;
2171 break;
2172 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2173 level = 2;
2174 break;
2175 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2176 level = 3;
2177 break;
2178
2179 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2180 level = 4;
2181 break;
2182 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2183 level = 5;
2184 break;
2185 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2186 level = 6;
2187 break;
2188
2189 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2190 level = 7;
2191 break;
2192 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2193 level = 8;
2194 break;
2195
2196 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2197 level = 9;
2198 break;
2199 }
2200
2201 return level;
2202}
2203
2204uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2205{
2206 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002207 struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
David Weinehallf8896f52015-06-25 11:11:03 +03002208 struct intel_encoder *encoder = &dport->base;
2209 uint8_t train_set = intel_dp->train_set[0];
2210 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2211 DP_TRAIN_PRE_EMPHASIS_MASK);
2212 enum port port = dport->port;
2213 uint32_t level;
2214
2215 level = translate_signal_level(signal_levels);
2216
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002217 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
2218 skl_ddi_set_iboost(dev_priv, level, port, encoder->type);
2219 else if (IS_BROXTON(dev_priv))
2220 bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type);
David Weinehallf8896f52015-06-25 11:11:03 +03002221
2222 return DDI_BUF_TRANS_SELECT(level);
2223}
2224
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002225void intel_ddi_clk_select(struct intel_encoder *encoder,
2226 const struct intel_crtc_state *pipe_config)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002227{
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002228 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2229 enum port port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002230
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002231 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
2232 uint32_t dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002233 uint32_t val;
2234
Damien Lespiau5416d872014-11-14 17:24:33 +00002235 /*
2236 * DPLL0 is used for eDP and is the only "private" DPLL (as
2237 * opposed to shared) on SKL
2238 */
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002239 if (encoder->type == INTEL_OUTPUT_EDP) {
Damien Lespiau5416d872014-11-14 17:24:33 +00002240 WARN_ON(dpll != SKL_DPLL0);
2241
2242 val = I915_READ(DPLL_CTRL1);
2243
2244 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2245 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002246 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002247 val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002248
2249 I915_WRITE(DPLL_CTRL1, val);
2250 POSTING_READ(DPLL_CTRL1);
2251 }
2252
2253 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002254 val = I915_READ(DPLL_CTRL2);
2255
2256 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2257 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2258 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2259 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2260
2261 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002262
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002263 } else if (INTEL_INFO(dev_priv)->gen < 9) {
2264 WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2265 I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002266 }
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002267}
2268
2269static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
2270{
2271 struct drm_encoder *encoder = &intel_encoder->base;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +02002272 struct drm_i915_private *dev_priv = to_i915(encoder->dev);
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002273 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
2274 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2275 int type = intel_encoder->type;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +02002276
2277 intel_prepare_ddi_buffer(intel_encoder);
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002278
2279 if (type == INTEL_OUTPUT_EDP) {
2280 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2281 intel_edp_panel_on(intel_dp);
2282 }
2283
2284 intel_ddi_clk_select(intel_encoder, crtc->config);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002285
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002286 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002287 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002288
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002289 intel_dp_set_link_params(intel_dp, crtc->config);
2290
Dave Airlie44905a272014-05-02 13:36:43 +10002291 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002292
2293 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2294 intel_dp_start_link_train(intel_dp);
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +02002295 if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002296 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002297 } else if (type == INTEL_OUTPUT_HDMI) {
2298 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2299
2300 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002301 crtc->config->has_hdmi_sink,
2302 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002303 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002304}
2305
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002306static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002307{
2308 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002309 struct drm_device *dev = encoder->dev;
2310 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002311 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002312 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002313 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002314 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002315
2316 val = I915_READ(DDI_BUF_CTL(port));
2317 if (val & DDI_BUF_CTL_ENABLE) {
2318 val &= ~DDI_BUF_CTL_ENABLE;
2319 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002320 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002321 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002322
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002323 val = I915_READ(DP_TP_CTL(port));
2324 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2325 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2326 I915_WRITE(DP_TP_CTL(port), val);
2327
2328 if (wait)
2329 intel_wait_ddi_buf_idle(dev_priv, port);
2330
Jani Nikula76bb80e2013-11-15 15:29:57 +02002331 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002332 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002333 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002334 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002335 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002336 }
2337
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002338 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002339 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2340 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302341 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002342 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002343}
2344
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002345static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002346{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002347 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002348 struct drm_crtc *crtc = encoder->crtc;
2349 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002350 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002351 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002352 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2353 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002354
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002355 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002356 struct intel_digital_port *intel_dig_port =
2357 enc_to_dig_port(encoder);
2358
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002359 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2360 * are ignored so nothing special needs to be done besides
2361 * enabling the port.
2362 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002363 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002364 intel_dig_port->saved_port_bits |
2365 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002366 } else if (type == INTEL_OUTPUT_EDP) {
2367 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2368
Vandana Kannan23f08d82014-11-13 14:55:22 +00002369 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002370 intel_dp_stop_link_train(intel_dp);
2371
Daniel Vetter4be73782014-01-17 14:39:48 +01002372 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002373 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302374 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002375 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002376
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002377 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002378 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002379 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002380 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002381}
2382
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002383static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002384{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002385 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002386 struct drm_crtc *crtc = encoder->crtc;
2387 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002388 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002389 struct drm_device *dev = encoder->dev;
2390 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002391
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002392 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002393 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002394 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2395 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002396
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002397 if (type == INTEL_OUTPUT_EDP) {
2398 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2399
Vandana Kannanc3955782015-01-22 15:17:40 +05302400 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002401 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002402 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002403 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002404}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002405
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002406static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
Daniel Vettere0b01be2014-06-25 22:02:01 +03002407 struct intel_shared_dpll *pll)
2408{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002409 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002410 POSTING_READ(WRPLL_CTL(pll->id));
2411 udelay(20);
2412}
2413
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002414static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
Daniel Vetter12030432014-06-25 22:02:00 +03002415 struct intel_shared_dpll *pll)
2416{
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002417 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
2418 POSTING_READ(SPLL_CTL);
2419 udelay(20);
2420}
2421
2422static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
2423 struct intel_shared_dpll *pll)
2424{
Daniel Vetter12030432014-06-25 22:02:00 +03002425 uint32_t val;
2426
2427 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002428 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2429 POSTING_READ(WRPLL_CTL(pll->id));
2430}
2431
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002432static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
2433 struct intel_shared_dpll *pll)
2434{
2435 uint32_t val;
2436
2437 val = I915_READ(SPLL_CTL);
2438 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
2439 POSTING_READ(SPLL_CTL);
2440}
2441
2442static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
2443 struct intel_shared_dpll *pll,
2444 struct intel_dpll_hw_state *hw_state)
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002445{
2446 uint32_t val;
2447
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002448 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002449 return false;
2450
2451 val = I915_READ(WRPLL_CTL(pll->id));
2452 hw_state->wrpll = val;
2453
2454 return val & WRPLL_PLL_ENABLE;
2455}
2456
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002457static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
2458 struct intel_shared_dpll *pll,
2459 struct intel_dpll_hw_state *hw_state)
2460{
2461 uint32_t val;
2462
2463 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2464 return false;
2465
2466 val = I915_READ(SPLL_CTL);
2467 hw_state->spll = val;
2468
2469 return val & SPLL_PLL_ENABLE;
2470}
2471
2472
Damien Lespiauca1381b2014-07-15 15:05:33 +01002473static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002474 "WRPLL 1",
2475 "WRPLL 2",
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002476 "SPLL"
Daniel Vetter9cd86932014-06-25 22:01:57 +03002477};
2478
Damien Lespiau143b3072014-07-29 18:06:19 +01002479static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002480{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002481 int i;
2482
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002483 dev_priv->num_shared_dpll = 3;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002484
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002485 for (i = 0; i < 2; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002486 dev_priv->shared_dplls[i].id = i;
2487 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002488 dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
2489 dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002490 dev_priv->shared_dplls[i].get_hw_state =
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002491 hsw_ddi_wrpll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002492 }
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002493
2494 /* SPLL is special, but needs to be initialized anyway.. */
2495 dev_priv->shared_dplls[i].id = i;
2496 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
2497 dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
2498 dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
2499 dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
2500
Damien Lespiau143b3072014-07-29 18:06:19 +01002501}
2502
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002503static const char * const skl_ddi_pll_names[] = {
2504 "DPLL 1",
2505 "DPLL 2",
2506 "DPLL 3",
2507};
2508
2509struct skl_dpll_regs {
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02002510 i915_reg_t ctl, cfgcr1, cfgcr2;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002511};
2512
2513/* this array is indexed by the *shared* pll id */
2514static const struct skl_dpll_regs skl_dpll_regs[3] = {
2515 {
2516 /* DPLL 1 */
2517 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002518 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2519 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002520 },
2521 {
2522 /* DPLL 2 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002523 .ctl = WRPLL_CTL(0),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002524 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2525 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002526 },
2527 {
2528 /* DPLL 3 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002529 .ctl = WRPLL_CTL(1),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002530 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2531 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002532 },
2533};
2534
2535static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2536 struct intel_shared_dpll *pll)
2537{
2538 uint32_t val;
2539 unsigned int dpll;
2540 const struct skl_dpll_regs *regs = skl_dpll_regs;
2541
2542 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2543 dpll = pll->id + 1;
2544
2545 val = I915_READ(DPLL_CTRL1);
2546
2547 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002548 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002549 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2550
2551 I915_WRITE(DPLL_CTRL1, val);
2552 POSTING_READ(DPLL_CTRL1);
2553
2554 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2555 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2556 POSTING_READ(regs[pll->id].cfgcr1);
2557 POSTING_READ(regs[pll->id].cfgcr2);
2558
2559 /* the enable bit is always bit 31 */
2560 I915_WRITE(regs[pll->id].ctl,
2561 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2562
2563 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2564 DRM_ERROR("DPLL %d not locked\n", dpll);
2565}
2566
2567static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2568 struct intel_shared_dpll *pll)
2569{
2570 const struct skl_dpll_regs *regs = skl_dpll_regs;
2571
2572 /* the enable bit is always bit 31 */
2573 I915_WRITE(regs[pll->id].ctl,
2574 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2575 POSTING_READ(regs[pll->id].ctl);
2576}
2577
2578static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2579 struct intel_shared_dpll *pll,
2580 struct intel_dpll_hw_state *hw_state)
2581{
2582 uint32_t val;
2583 unsigned int dpll;
2584 const struct skl_dpll_regs *regs = skl_dpll_regs;
2585
2586 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2587 return false;
2588
2589 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2590 dpll = pll->id + 1;
2591
2592 val = I915_READ(regs[pll->id].ctl);
2593 if (!(val & LCPLL_PLL_ENABLE))
2594 return false;
2595
2596 val = I915_READ(DPLL_CTRL1);
2597 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2598
2599 /* avoid reading back stale values if HDMI mode is not enabled */
2600 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2601 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2602 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2603 }
2604
2605 return true;
2606}
2607
2608static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2609{
2610 int i;
2611
2612 dev_priv->num_shared_dpll = 3;
2613
2614 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2615 dev_priv->shared_dplls[i].id = i;
2616 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2617 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2618 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2619 dev_priv->shared_dplls[i].get_hw_state =
2620 skl_ddi_pll_get_hw_state;
2621 }
2622}
2623
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302624static void broxton_phy_init(struct drm_i915_private *dev_priv,
2625 enum dpio_phy phy)
2626{
2627 enum port port;
2628 uint32_t val;
2629
2630 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2631 val |= GT_DISPLAY_POWER_ON(phy);
2632 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2633
2634 /* Considering 10ms timeout until BSpec is updated */
2635 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2636 DRM_ERROR("timeout during PHY%d power on\n", phy);
2637
2638 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2639 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2640 int lane;
2641
2642 for (lane = 0; lane < 4; lane++) {
2643 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2644 /*
2645 * Note that on CHV this flag is called UPAR, but has
2646 * the same function.
2647 */
2648 val &= ~LATENCY_OPTIM;
2649 if (lane != 1)
2650 val |= LATENCY_OPTIM;
2651
2652 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2653 }
2654 }
2655
2656 /* Program PLL Rcomp code offset */
2657 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2658 val &= ~IREF0RC_OFFSET_MASK;
2659 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2660 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2661
2662 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2663 val &= ~IREF1RC_OFFSET_MASK;
2664 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2665 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2666
2667 /* Program power gating */
2668 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2669 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2670 SUS_CLK_CONFIG;
2671 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2672
2673 if (phy == DPIO_PHY0) {
2674 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2675 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2676 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2677 }
2678
2679 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2680 val &= ~OCL2_LDOFUSE_PWR_DIS;
2681 /*
2682 * On PHY1 disable power on the second channel, since no port is
2683 * connected there. On PHY0 both channels have a port, so leave it
2684 * enabled.
2685 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2686 * power down the second channel on PHY0 as well.
2687 */
2688 if (phy == DPIO_PHY1)
2689 val |= OCL2_LDOFUSE_PWR_DIS;
2690 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2691
2692 if (phy == DPIO_PHY0) {
2693 uint32_t grc_code;
2694 /*
2695 * PHY0 isn't connected to an RCOMP resistor so copy over
2696 * the corresponding calibrated value from PHY1, and disable
2697 * the automatic calibration on PHY0.
2698 */
2699 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2700 10))
2701 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2702
2703 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2704 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2705 grc_code = val << GRC_CODE_FAST_SHIFT |
2706 val << GRC_CODE_SLOW_SHIFT |
2707 val;
2708 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2709
2710 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2711 val |= GRC_DIS | GRC_RDY_OVRD;
2712 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2713 }
2714
2715 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2716 val |= COMMON_RESET_DIS;
2717 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2718}
2719
2720void broxton_ddi_phy_init(struct drm_device *dev)
2721{
2722 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2723 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2724 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2725}
2726
2727static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2728 enum dpio_phy phy)
2729{
2730 uint32_t val;
2731
2732 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2733 val &= ~COMMON_RESET_DIS;
2734 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2735}
2736
2737void broxton_ddi_phy_uninit(struct drm_device *dev)
2738{
2739 struct drm_i915_private *dev_priv = dev->dev_private;
2740
2741 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2742 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2743
2744 /* FIXME: do this in broxton_phy_uninit per phy */
2745 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2746}
2747
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302748static const char * const bxt_ddi_pll_names[] = {
2749 "PORT PLL A",
2750 "PORT PLL B",
2751 "PORT PLL C",
2752};
2753
2754static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2755 struct intel_shared_dpll *pll)
2756{
2757 uint32_t temp;
2758 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2759
2760 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2761 temp &= ~PORT_PLL_REF_SEL;
2762 /* Non-SSC reference */
2763 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2764
2765 /* Disable 10 bit clock */
2766 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2767 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2768 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2769
2770 /* Write P1 & P2 */
2771 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2772 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2773 temp |= pll->config.hw_state.ebb0;
2774 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2775
2776 /* Write M2 integer */
2777 temp = I915_READ(BXT_PORT_PLL(port, 0));
2778 temp &= ~PORT_PLL_M2_MASK;
2779 temp |= pll->config.hw_state.pll0;
2780 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2781
2782 /* Write N */
2783 temp = I915_READ(BXT_PORT_PLL(port, 1));
2784 temp &= ~PORT_PLL_N_MASK;
2785 temp |= pll->config.hw_state.pll1;
2786 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2787
2788 /* Write M2 fraction */
2789 temp = I915_READ(BXT_PORT_PLL(port, 2));
2790 temp &= ~PORT_PLL_M2_FRAC_MASK;
2791 temp |= pll->config.hw_state.pll2;
2792 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2793
2794 /* Write M2 fraction enable */
2795 temp = I915_READ(BXT_PORT_PLL(port, 3));
2796 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2797 temp |= pll->config.hw_state.pll3;
2798 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2799
2800 /* Write coeff */
2801 temp = I915_READ(BXT_PORT_PLL(port, 6));
2802 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2803 temp &= ~PORT_PLL_INT_COEFF_MASK;
2804 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2805 temp |= pll->config.hw_state.pll6;
2806 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2807
2808 /* Write calibration val */
2809 temp = I915_READ(BXT_PORT_PLL(port, 8));
2810 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2811 temp |= pll->config.hw_state.pll8;
2812 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2813
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302814 temp = I915_READ(BXT_PORT_PLL(port, 9));
2815 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002816 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302817 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2818
2819 temp = I915_READ(BXT_PORT_PLL(port, 10));
2820 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2821 temp &= ~PORT_PLL_DCO_AMP_MASK;
2822 temp |= pll->config.hw_state.pll10;
2823 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302824
2825 /* Recalibrate with new settings */
2826 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2827 temp |= PORT_PLL_RECALIBRATE;
2828 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002829 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2830 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302831 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2832
2833 /* Enable PLL */
2834 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2835 temp |= PORT_PLL_ENABLE;
2836 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2837 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2838
2839 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2840 PORT_PLL_LOCK), 200))
2841 DRM_ERROR("PLL %d not locked\n", port);
2842
2843 /*
2844 * While we write to the group register to program all lanes at once we
2845 * can read only lane registers and we pick lanes 0/1 for that.
2846 */
2847 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2848 temp &= ~LANE_STAGGER_MASK;
2849 temp &= ~LANESTAGGER_STRAP_OVRD;
2850 temp |= pll->config.hw_state.pcsdw12;
2851 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2852}
2853
2854static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2855 struct intel_shared_dpll *pll)
2856{
2857 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2858 uint32_t temp;
2859
2860 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2861 temp &= ~PORT_PLL_ENABLE;
2862 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2863 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2864}
2865
2866static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2867 struct intel_shared_dpll *pll,
2868 struct intel_dpll_hw_state *hw_state)
2869{
2870 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2871 uint32_t val;
2872
2873 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2874 return false;
2875
2876 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2877 if (!(val & PORT_PLL_ENABLE))
2878 return false;
2879
2880 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002881 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2882
Imre Deak05712c12015-06-18 17:25:54 +03002883 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2884 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2885
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302886 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002887 hw_state->pll0 &= PORT_PLL_M2_MASK;
2888
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302889 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002890 hw_state->pll1 &= PORT_PLL_N_MASK;
2891
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302892 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002893 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2894
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302895 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002896 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2897
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302898 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002899 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2900 PORT_PLL_INT_COEFF_MASK |
2901 PORT_PLL_GAIN_CTL_MASK;
2902
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302903 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002904 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2905
Imre Deak05712c12015-06-18 17:25:54 +03002906 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2907 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2908
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302909 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002910 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2911 PORT_PLL_DCO_AMP_MASK;
2912
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302913 /*
2914 * While we write to the group register to program all lanes at once we
2915 * can read only lane registers. We configure all lanes the same way, so
2916 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2917 */
2918 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002919 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302920 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2921 hw_state->pcsdw12,
2922 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002923 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302924
2925 return true;
2926}
2927
2928static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2929{
2930 int i;
2931
2932 dev_priv->num_shared_dpll = 3;
2933
2934 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2935 dev_priv->shared_dplls[i].id = i;
2936 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2937 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2938 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2939 dev_priv->shared_dplls[i].get_hw_state =
2940 bxt_ddi_pll_get_hw_state;
2941 }
2942}
2943
Damien Lespiau143b3072014-07-29 18:06:19 +01002944void intel_ddi_pll_init(struct drm_device *dev)
2945{
2946 struct drm_i915_private *dev_priv = dev->dev_private;
2947 uint32_t val = I915_READ(LCPLL_CTL);
2948
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002949 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002950 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302951 else if (IS_BROXTON(dev))
2952 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002953 else
2954 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002955
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002956 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002957 int cdclk_freq;
2958
2959 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002960 dev_priv->skl_boot_cdclk = cdclk_freq;
Shobhit Kumarc73666f2015-10-20 18:13:12 +05302961 if (skl_sanitize_cdclk(dev_priv))
2962 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
Damien Lespiau2f693e22015-11-04 19:24:12 +02002963 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2964 DRM_ERROR("LCPLL1 is disabled\n");
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302965 } else if (IS_BROXTON(dev)) {
2966 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302967 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002968 } else {
2969 /*
2970 * The LCPLL register should be turned on by the BIOS. For now
2971 * let's just check its state and print errors in case
2972 * something is wrong. Don't even try to turn it on.
2973 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002974
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002975 if (val & LCPLL_CD_SOURCE_FCLK)
2976 DRM_ERROR("CDCLK source is not LCPLL\n");
2977
2978 if (val & LCPLL_PLL_DISABLE)
2979 DRM_ERROR("LCPLL is disabled\n");
2980 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002981}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002982
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03002983void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
Paulo Zanonic19b0662012-10-15 15:51:41 -03002984{
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03002985 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
2986 struct drm_i915_private *dev_priv =
2987 to_i915(intel_dig_port->base.base.dev);
Paulo Zanoni174edf12012-10-26 19:05:50 -02002988 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002989 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302990 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002991
2992 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2993 val = I915_READ(DDI_BUF_CTL(port));
2994 if (val & DDI_BUF_CTL_ENABLE) {
2995 val &= ~DDI_BUF_CTL_ENABLE;
2996 I915_WRITE(DDI_BUF_CTL(port), val);
2997 wait = true;
2998 }
2999
3000 val = I915_READ(DP_TP_CTL(port));
3001 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3002 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3003 I915_WRITE(DP_TP_CTL(port), val);
3004 POSTING_READ(DP_TP_CTL(port));
3005
3006 if (wait)
3007 intel_wait_ddi_buf_idle(dev_priv, port);
3008 }
3009
Dave Airlie0e32b392014-05-02 14:02:48 +10003010 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003011 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003012 if (intel_dp->is_mst)
3013 val |= DP_TP_CTL_MODE_MST;
3014 else {
3015 val |= DP_TP_CTL_MODE_SST;
3016 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3017 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3018 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003019 I915_WRITE(DP_TP_CTL(port), val);
3020 POSTING_READ(DP_TP_CTL(port));
3021
3022 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3023 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3024 POSTING_READ(DDI_BUF_CTL(port));
3025
3026 udelay(600);
3027}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003028
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003029void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3030{
3031 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3032 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3033 uint32_t val;
3034
3035 intel_ddi_post_disable(intel_encoder);
3036
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003037 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003038 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003039 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003040
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003041 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003042 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3043 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003044 I915_WRITE(FDI_RX_MISC(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003045
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003046 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003047 val &= ~FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003048 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003049
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003050 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003051 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003052 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003053}
3054
Libin Yang3d52ccf2015-12-02 14:09:44 +08003055bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
3056 struct intel_crtc *intel_crtc)
3057{
3058 u32 temp;
3059
3060 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
3061 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
3062 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
3063 return true;
3064 }
3065 return false;
3066}
3067
Ville Syrjälä6801c182013-09-24 14:24:05 +03003068void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003069 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003070{
3071 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3072 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003073 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003074 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003075 u32 temp, flags = 0;
3076
3077 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3078 if (temp & TRANS_DDI_PHSYNC)
3079 flags |= DRM_MODE_FLAG_PHSYNC;
3080 else
3081 flags |= DRM_MODE_FLAG_NHSYNC;
3082 if (temp & TRANS_DDI_PVSYNC)
3083 flags |= DRM_MODE_FLAG_PVSYNC;
3084 else
3085 flags |= DRM_MODE_FLAG_NVSYNC;
3086
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003087 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003088
3089 switch (temp & TRANS_DDI_BPC_MASK) {
3090 case TRANS_DDI_BPC_6:
3091 pipe_config->pipe_bpp = 18;
3092 break;
3093 case TRANS_DDI_BPC_8:
3094 pipe_config->pipe_bpp = 24;
3095 break;
3096 case TRANS_DDI_BPC_10:
3097 pipe_config->pipe_bpp = 30;
3098 break;
3099 case TRANS_DDI_BPC_12:
3100 pipe_config->pipe_bpp = 36;
3101 break;
3102 default:
3103 break;
3104 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003105
3106 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3107 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b52014-04-24 23:54:47 +02003108 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003109 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3110
Ville Syrjäläcda0aaa2015-11-26 18:27:07 +02003111 if (intel_hdmi->infoframe_enabled(&encoder->base, pipe_config))
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003112 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003113 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003114 case TRANS_DDI_MODE_SELECT_DVI:
3115 case TRANS_DDI_MODE_SELECT_FDI:
3116 break;
3117 case TRANS_DDI_MODE_SELECT_DP_SST:
3118 case TRANS_DDI_MODE_SELECT_DP_MST:
3119 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003120 pipe_config->lane_count =
3121 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003122 intel_dp_get_m_n(intel_crtc, pipe_config);
3123 break;
3124 default:
3125 break;
3126 }
Daniel Vetter10214422013-11-18 07:38:16 +01003127
Libin Yang3d52ccf2015-12-02 14:09:44 +08003128 pipe_config->has_audio =
3129 intel_ddi_is_audio_enabled(dev_priv, intel_crtc);
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003130
Daniel Vetter10214422013-11-18 07:38:16 +01003131 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3132 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3133 /*
3134 * This is a big fat ugly hack.
3135 *
3136 * Some machines in UEFI boot mode provide us a VBT that has 18
3137 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3138 * unknown we fail to light up. Yet the same BIOS boots up with
3139 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3140 * max, not what it tells us to use.
3141 *
3142 * Note: This will still be broken if the eDP panel is not lit
3143 * up by the BIOS, and thus we can't get the mode at module
3144 * load.
3145 */
3146 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3147 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3148 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3149 }
Jesse Barnes11578552014-01-21 12:42:10 -08003150
Damien Lespiau22606a12014-12-12 14:26:57 +00003151 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003152}
3153
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003154static void intel_ddi_destroy(struct drm_encoder *encoder)
3155{
3156 /* HDMI has nothing special to destroy, so we can go with this. */
3157 intel_dp_encoder_destroy(encoder);
3158}
3159
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003160static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003161 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003162{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003163 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003164 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003165
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003166 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003167
Daniel Vettereccb1402013-05-22 00:50:22 +02003168 if (port == PORT_A)
3169 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3170
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003171 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003172 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003173 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003174 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003175}
3176
3177static const struct drm_encoder_funcs intel_ddi_funcs = {
3178 .destroy = intel_ddi_destroy,
3179};
3180
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003181static struct intel_connector *
3182intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3183{
3184 struct intel_connector *connector;
3185 enum port port = intel_dig_port->port;
3186
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003187 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003188 if (!connector)
3189 return NULL;
3190
3191 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3192 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3193 kfree(connector);
3194 return NULL;
3195 }
3196
3197 return connector;
3198}
3199
3200static struct intel_connector *
3201intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3202{
3203 struct intel_connector *connector;
3204 enum port port = intel_dig_port->port;
3205
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003206 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003207 if (!connector)
3208 return NULL;
3209
3210 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3211 intel_hdmi_init_connector(intel_dig_port, connector);
3212
3213 return connector;
3214}
3215
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003216void intel_ddi_init(struct drm_device *dev, enum port port)
3217{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003218 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003219 struct intel_digital_port *intel_dig_port;
3220 struct intel_encoder *intel_encoder;
3221 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003222 bool init_hdmi, init_dp;
Ville Syrjälä10e7bec2015-12-08 19:59:37 +02003223 int max_lanes;
3224
3225 if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
3226 switch (port) {
3227 case PORT_A:
3228 max_lanes = 4;
3229 break;
3230 case PORT_E:
3231 max_lanes = 0;
3232 break;
3233 default:
3234 max_lanes = 4;
3235 break;
3236 }
3237 } else {
3238 switch (port) {
3239 case PORT_A:
3240 max_lanes = 2;
3241 break;
3242 case PORT_E:
3243 max_lanes = 2;
3244 break;
3245 default:
3246 max_lanes = 4;
3247 break;
3248 }
3249 }
Paulo Zanoni311a2092013-09-12 17:12:18 -03003250
3251 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3252 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3253 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3254 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003255 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003256 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003257 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003258 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003259
Daniel Vetterb14c5672013-09-19 12:18:32 +02003260 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003261 if (!intel_dig_port)
3262 return;
3263
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003264 intel_encoder = &intel_dig_port->base;
3265 encoder = &intel_encoder->base;
3266
3267 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3268 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003269
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003270 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003271 intel_encoder->enable = intel_enable_ddi;
3272 intel_encoder->pre_enable = intel_ddi_pre_enable;
3273 intel_encoder->disable = intel_disable_ddi;
3274 intel_encoder->post_disable = intel_ddi_post_disable;
3275 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003276 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003277
3278 intel_dig_port->port = port;
Takashi Iwai0bdf5a02015-11-30 18:19:39 +01003279 dev_priv->dig_port_map[port] = intel_encoder;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003280 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3281 (DDI_BUF_PORT_REVERSAL |
3282 DDI_A_4_LANES);
Ville Syrjäläccb1a832015-12-08 19:59:38 +02003283 intel_dig_port->max_lanes = max_lanes;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003284
Matt Roper6c566dc2015-11-05 14:53:32 -08003285 /*
3286 * Bspec says that DDI_A_4_LANES is the only supported configuration
3287 * for Broxton. Yet some BIOS fail to set this bit on port A if eDP
3288 * wasn't lit up at boot. Force this bit on in our internal
3289 * configuration so that we use the proper lane count for our
3290 * calculations.
3291 */
3292 if (IS_BROXTON(dev) && port == PORT_A) {
3293 if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) {
3294 DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
3295 intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
3296 }
3297 }
3298
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003299 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003300 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003301 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003302
Chris Wilsonf68d6972014-08-04 07:15:09 +01003303 if (init_dp) {
3304 if (!intel_ddi_init_dp_connector(intel_dig_port))
3305 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003306
Chris Wilsonf68d6972014-08-04 07:15:09 +01003307 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303308 /*
3309 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3310 * interrupts to check the external panel connection.
3311 */
Jani Nikulae87a0052015-10-20 15:22:02 +03003312 if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303313 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3314 else
3315 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003316 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003317
Paulo Zanoni311a2092013-09-12 17:12:18 -03003318 /* In theory we don't need the encoder->type check, but leave it just in
3319 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003320 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3321 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3322 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003323 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003324
3325 return;
3326
3327err:
3328 drm_encoder_cleanup(encoder);
3329 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003330}