blob: 9f8b28faa8e2cff692f2b7e691f8188caa1f8ca6 [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
David Weinehallf8896f52015-06-25 11:11:03 +0300304static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
305 enum port port, int type);
306
Imre Deaka1e6ad62015-04-17 19:31:21 +0300307static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
308 struct intel_digital_port **dig_port,
309 enum port *port)
Paulo Zanonifc914632012-10-05 12:05:54 -0300310{
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300311 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonifc914632012-10-05 12:05:54 -0300312
Jani Nikula8cd21b72015-09-29 10:24:26 +0300313 switch (intel_encoder->type) {
314 case INTEL_OUTPUT_DP_MST:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300315 *dig_port = enc_to_mst(encoder)->primary;
316 *port = (*dig_port)->port;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300317 break;
318 case INTEL_OUTPUT_DISPLAYPORT:
319 case INTEL_OUTPUT_EDP:
320 case INTEL_OUTPUT_HDMI:
321 case INTEL_OUTPUT_UNKNOWN:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300322 *dig_port = enc_to_dig_port(encoder);
323 *port = (*dig_port)->port;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300324 break;
325 case INTEL_OUTPUT_ANALOG:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300326 *dig_port = NULL;
327 *port = PORT_E;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300328 break;
329 default:
330 WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
331 break;
Paulo Zanonifc914632012-10-05 12:05:54 -0300332 }
333}
334
Imre Deaka1e6ad62015-04-17 19:31:21 +0300335enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
336{
337 struct intel_digital_port *dig_port;
338 enum port port;
339
340 ddi_get_encoder_port(intel_encoder, &dig_port, &port);
341
342 return port;
343}
344
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100345static bool
346intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
347{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200348 return i915_mmio_reg_valid(intel_dig_port->hdmi.hdmi_reg);
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100349}
350
Ville Syrjäläacee2992015-12-08 19:59:39 +0200351static const struct ddi_buf_trans *
352skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries)
David Weinehallf8896f52015-06-25 11:11:03 +0300353{
Rodrigo Vivia5b79912015-12-08 16:58:37 -0800354 if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700355 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200356 return skl_y_ddi_translations_dp;
Rodrigo Vivia5b79912015-12-08 16:58:37 -0800357 } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300358 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200359 return skl_u_ddi_translations_dp;
David Weinehallf8896f52015-06-25 11:11:03 +0300360 } else {
David Weinehallf8896f52015-06-25 11:11:03 +0300361 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200362 return skl_ddi_translations_dp;
David Weinehallf8896f52015-06-25 11:11:03 +0300363 }
David Weinehallf8896f52015-06-25 11:11:03 +0300364}
365
366static const struct ddi_buf_trans *
Ville Syrjäläacee2992015-12-08 19:59:39 +0200367skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries)
David Weinehallf8896f52015-06-25 11:11:03 +0300368{
Ville Syrjäläacee2992015-12-08 19:59:39 +0200369 struct drm_i915_private *dev_priv = dev->dev_private;
David Weinehallf8896f52015-06-25 11:11:03 +0300370
Ville Syrjäläcd1101c2015-12-08 19:59:40 +0200371 if (dev_priv->edp_low_vswing) {
372 if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200373 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
374 return skl_y_ddi_translations_edp;
Ville Syrjäläcd1101c2015-12-08 19:59:40 +0200375 } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200376 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
377 return skl_u_ddi_translations_edp;
378 } else {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200379 *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
380 return skl_ddi_translations_edp;
Ville Syrjäläacee2992015-12-08 19:59:39 +0200381 }
David Weinehallf8896f52015-06-25 11:11:03 +0300382 }
Ville Syrjäläcd1101c2015-12-08 19:59:40 +0200383
384 return skl_get_buf_trans_dp(dev, n_entries);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200385}
David Weinehallf8896f52015-06-25 11:11:03 +0300386
Ville Syrjäläacee2992015-12-08 19:59:39 +0200387static const struct ddi_buf_trans *
388skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries)
389{
390 if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) {
391 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
392 return skl_y_ddi_translations_hdmi;
393 } else {
394 *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
395 return skl_ddi_translations_hdmi;
396 }
David Weinehallf8896f52015-06-25 11:11:03 +0300397}
398
Art Runyane58623c2013-11-02 21:07:41 -0700399/*
400 * Starting with Haswell, DDI port buffers must be programmed with correct
401 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300402 * but the HDMI/DVI fields are shared among those. So we program the DDI
403 * in either FDI or DP modes only, as HDMI connections will work with both
404 * of those
405 */
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300406static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
407 bool supports_hdmi)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300408{
409 struct drm_i915_private *dev_priv = dev->dev_private;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300410 u32 iboost_bit = 0;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000411 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530412 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300413 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300414 const struct ddi_buf_trans *ddi_translations_fdi;
415 const struct ddi_buf_trans *ddi_translations_dp;
416 const struct ddi_buf_trans *ddi_translations_edp;
417 const struct ddi_buf_trans *ddi_translations_hdmi;
418 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700419
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530420 if (IS_BROXTON(dev)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300421 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530422 return;
423
424 /* Vswing programming for HDMI */
425 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
426 INTEL_OUTPUT_HDMI);
427 return;
Rodrigo Vivief11bdb2015-10-28 04:16:45 -0700428 } else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300429 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300430 ddi_translations_dp =
431 skl_get_buf_trans_dp(dev, &n_dp_entries);
432 ddi_translations_edp =
433 skl_get_buf_trans_edp(dev, &n_edp_entries);
434 ddi_translations_hdmi =
435 skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
436 hdmi_default_entry = 8;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300437 /* If we're boosting the current, set bit 31 of trans1 */
438 if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
439 dev_priv->vbt.ddi_port_info[port].dp_boost_level)
440 iboost_bit = 1<<31;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000441 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700442 ddi_translations_fdi = bdw_ddi_translations_fdi;
443 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700444 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100445 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530446 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
447 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300448 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000449 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700450 } else if (IS_HASWELL(dev)) {
451 ddi_translations_fdi = hsw_ddi_translations_fdi;
452 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700453 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100454 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530455 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300456 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000457 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700458 } else {
459 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700460 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700461 ddi_translations_fdi = bdw_ddi_translations_fdi;
462 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100463 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530464 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
465 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300466 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000467 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700468 }
469
Paulo Zanoni300644c2013-11-02 21:07:42 -0700470 switch (port) {
471 case PORT_A:
472 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530473 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700474 break;
475 case PORT_B:
476 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700477 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530478 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700479 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700480 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530481 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700482 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530483 size = n_edp_entries;
484 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700485 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530486 size = n_dp_entries;
487 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700488 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700489 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000490 if (ddi_translations_fdi)
491 ddi_translations = ddi_translations_fdi;
492 else
493 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530494 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700495 break;
496 default:
497 BUG();
498 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300499
Ville Syrjälä9712e682015-09-18 20:03:22 +0300500 for (i = 0; i < size; i++) {
501 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
502 ddi_translations[i].trans1 | iboost_bit);
503 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
504 ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300505 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100506
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300507 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100508 return;
509
Damien Lespiauce4dd492014-08-01 11:07:54 +0100510 /* Choose a good default if VBT is badly populated */
511 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
512 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000513 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100514
Paulo Zanoni6acab152013-09-12 17:06:24 -0300515 /* Entry 9 is for HDMI: */
Ville Syrjälä9712e682015-09-18 20:03:22 +0300516 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
517 ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
518 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
519 ddi_translations_hdmi[hdmi_level].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300520}
521
522/* Program DDI buffers translations for DP. By default, program ports A-D in DP
523 * mode and port E for FDI.
524 */
525void intel_prepare_ddi(struct drm_device *dev)
526{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300527 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100528 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300529
Paulo Zanoni0d536cb42012-11-23 16:46:41 -0200530 if (!HAS_DDI(dev))
531 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300532
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300533 for_each_intel_encoder(dev, intel_encoder) {
534 struct intel_digital_port *intel_dig_port;
535 enum port port;
536 bool supports_hdmi;
537
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530538 if (intel_encoder->type == INTEL_OUTPUT_DSI)
539 continue;
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300540
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530541 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300542 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100543 continue;
544
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300545 supports_hdmi = intel_dig_port &&
546 intel_dig_port_supports_hdmi(intel_dig_port);
547
548 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
549 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100550 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300551}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300552
Paulo Zanoni248138b2012-11-29 11:29:31 -0200553static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
554 enum port port)
555{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200556 i915_reg_t reg = DDI_BUF_CTL(port);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200557 int i;
558
Vandana Kannan3449ca82015-03-27 14:19:09 +0200559 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200560 udelay(1);
561 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
562 return;
563 }
564 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
565}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300566
567/* Starting with Haswell, different DDI ports can work in FDI mode for
568 * connection to the PCH-located connectors. For this, it is necessary to train
569 * both the DDI port and PCH receiver for the desired DDI buffer settings.
570 *
571 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
572 * please note that when FDI mode is active on DDI E, it shares 2 lines with
573 * DDI A (which is used for eDP)
574 */
575
576void hsw_fdi_link_train(struct drm_crtc *crtc)
577{
578 struct drm_device *dev = crtc->dev;
579 struct drm_i915_private *dev_priv = dev->dev_private;
580 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200581 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300582
Paulo Zanoni04945642012-11-01 21:00:59 -0200583 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
584 * mode set "sequence for CRT port" document:
585 * - TP1 to TP2 time with the default value
586 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100587 *
588 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200589 */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300590 I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) |
Paulo Zanoni04945642012-11-01 21:00:59 -0200591 FDI_RX_PWRDN_LANE0_VAL(2) |
592 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
593
594 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000595 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100596 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200597 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300598 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
599 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200600 udelay(220);
601
602 /* Switch from Rawclk to PCDclk */
603 rx_ctl_val |= FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300604 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
Paulo Zanoni04945642012-11-01 21:00:59 -0200605
606 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200607 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
608 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200609
610 /* Start the training iterating through available voltages and emphasis,
611 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300612 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300613 /* Configure DP_TP_CTL with auto-training */
614 I915_WRITE(DP_TP_CTL(PORT_E),
615 DP_TP_CTL_FDI_AUTOTRAIN |
616 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
617 DP_TP_CTL_LINK_TRAIN_PAT1 |
618 DP_TP_CTL_ENABLE);
619
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000620 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
621 * DDI E does not support port reversal, the functionality is
622 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
623 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300624 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200625 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200626 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530627 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200628 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300629
630 udelay(600);
631
Paulo Zanoni04945642012-11-01 21:00:59 -0200632 /* Program PCH FDI Receiver TU */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300633 I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300634
Paulo Zanoni04945642012-11-01 21:00:59 -0200635 /* Enable PCH FDI Receiver with auto-training */
636 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300637 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
638 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200639
640 /* Wait for FDI receiver lane calibration */
641 udelay(30);
642
643 /* Unset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300644 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200645 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300646 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
647 POSTING_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200648
649 /* Wait for FDI auto training time */
650 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300651
652 temp = I915_READ(DP_TP_STATUS(PORT_E));
653 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200654 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200655 break;
656 }
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300657
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200658 /*
659 * Leave things enabled even if we failed to train FDI.
660 * Results in less fireworks from the state checker.
661 */
662 if (i == ARRAY_SIZE(hsw_ddi_translations_fdi) * 2 - 1) {
663 DRM_ERROR("FDI link training failed!\n");
664 break;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300665 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200666
Paulo Zanoni248138b2012-11-29 11:29:31 -0200667 temp = I915_READ(DDI_BUF_CTL(PORT_E));
668 temp &= ~DDI_BUF_CTL_ENABLE;
669 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
670 POSTING_READ(DDI_BUF_CTL(PORT_E));
671
Paulo Zanoni04945642012-11-01 21:00:59 -0200672 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200673 temp = I915_READ(DP_TP_CTL(PORT_E));
674 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
675 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
676 I915_WRITE(DP_TP_CTL(PORT_E), temp);
677 POSTING_READ(DP_TP_CTL(PORT_E));
678
679 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200680
681 rx_ctl_val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300682 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
683 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200684
685 /* Reset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300686 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200687 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
688 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300689 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
690 POSTING_READ(FDI_RX_MISC(PIPE_A));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300691 }
692
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200693 /* Enable normal pixel sending for FDI */
694 I915_WRITE(DP_TP_CTL(PORT_E),
695 DP_TP_CTL_FDI_AUTOTRAIN |
696 DP_TP_CTL_LINK_TRAIN_NORMAL |
697 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
698 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300699}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300700
Dave Airlie44905a272014-05-02 13:36:43 +1000701void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
702{
703 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
704 struct intel_digital_port *intel_dig_port =
705 enc_to_dig_port(&encoder->base);
706
707 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530708 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300709 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a272014-05-02 13:36:43 +1000710}
711
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300712static struct intel_encoder *
713intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
714{
715 struct drm_device *dev = crtc->dev;
716 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
717 struct intel_encoder *intel_encoder, *ret = NULL;
718 int num_encoders = 0;
719
720 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
721 ret = intel_encoder;
722 num_encoders++;
723 }
724
725 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300726 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
727 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300728
729 BUG_ON(ret == NULL);
730 return ret;
731}
732
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530733struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200734intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200735{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200736 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
737 struct intel_encoder *ret = NULL;
738 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300739 struct drm_connector *connector;
740 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200741 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200742 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200743
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200744 state = crtc_state->base.state;
745
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300746 for_each_connector_in_state(state, connector, connector_state, i) {
747 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200748 continue;
749
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300750 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200751 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200752 }
753
754 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
755 pipe_name(crtc->pipe));
756
757 BUG_ON(ret == NULL);
758 return ret;
759}
760
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100761#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100762#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100763
764#define P_MIN 2
765#define P_MAX 64
766#define P_INC 2
767
768/* Constraints for PLL good behavior */
769#define REF_MIN 48
770#define REF_MAX 400
771#define VCO_MIN 2400
772#define VCO_MAX 4800
773
Damien Lespiau27893392014-09-04 12:27:23 +0100774#define abs_diff(a, b) ({ \
775 typeof(a) __a = (a); \
776 typeof(b) __b = (b); \
777 (void) (&__a == &__b); \
778 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100779
Damien Lespiau63582982015-05-07 18:38:46 +0100780struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100781 unsigned p, n2, r2;
782};
783
Damien Lespiau63582982015-05-07 18:38:46 +0100784static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300785{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100786 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300787
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100788 switch (clock) {
789 case 25175000:
790 case 25200000:
791 case 27000000:
792 case 27027000:
793 case 37762500:
794 case 37800000:
795 case 40500000:
796 case 40541000:
797 case 54000000:
798 case 54054000:
799 case 59341000:
800 case 59400000:
801 case 72000000:
802 case 74176000:
803 case 74250000:
804 case 81000000:
805 case 81081000:
806 case 89012000:
807 case 89100000:
808 case 108000000:
809 case 108108000:
810 case 111264000:
811 case 111375000:
812 case 148352000:
813 case 148500000:
814 case 162000000:
815 case 162162000:
816 case 222525000:
817 case 222750000:
818 case 296703000:
819 case 297000000:
820 budget = 0;
821 break;
822 case 233500000:
823 case 245250000:
824 case 247750000:
825 case 253250000:
826 case 298000000:
827 budget = 1500;
828 break;
829 case 169128000:
830 case 169500000:
831 case 179500000:
832 case 202000000:
833 budget = 2000;
834 break;
835 case 256250000:
836 case 262500000:
837 case 270000000:
838 case 272500000:
839 case 273750000:
840 case 280750000:
841 case 281250000:
842 case 286000000:
843 case 291750000:
844 budget = 4000;
845 break;
846 case 267250000:
847 case 268500000:
848 budget = 5000;
849 break;
850 default:
851 budget = 1000;
852 break;
853 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300854
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100855 return budget;
856}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300857
Damien Lespiau63582982015-05-07 18:38:46 +0100858static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
859 unsigned r2, unsigned n2, unsigned p,
860 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100861{
862 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300863
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100864 /* No best (r,n,p) yet */
865 if (best->p == 0) {
866 best->p = p;
867 best->n2 = n2;
868 best->r2 = r2;
869 return;
870 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300871
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100872 /*
873 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
874 * freq2k.
875 *
876 * delta = 1e6 *
877 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
878 * freq2k;
879 *
880 * and we would like delta <= budget.
881 *
882 * If the discrepancy is above the PPM-based budget, always prefer to
883 * improve upon the previous solution. However, if you're within the
884 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
885 */
886 a = freq2k * budget * p * r2;
887 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100888 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
889 diff_best = abs_diff(freq2k * best->p * best->r2,
890 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100891 c = 1000000 * diff;
892 d = 1000000 * diff_best;
893
894 if (a < c && b < d) {
895 /* If both are above the budget, pick the closer */
896 if (best->p * best->r2 * diff < p * r2 * diff_best) {
897 best->p = p;
898 best->n2 = n2;
899 best->r2 = r2;
900 }
901 } else if (a >= c && b < d) {
902 /* If A is below the threshold but B is above it? Update. */
903 best->p = p;
904 best->n2 = n2;
905 best->r2 = r2;
906 } else if (a >= c && b >= d) {
907 /* Both are below the limit, so pick the higher n2/(r2*r2) */
908 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
909 best->p = p;
910 best->n2 = n2;
911 best->r2 = r2;
912 }
913 }
914 /* Otherwise a < c && b >= d, do nothing */
915}
916
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200917static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
918 i915_reg_t reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800919{
920 int refclk = LC_FREQ;
921 int n, p, r;
922 u32 wrpll;
923
924 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300925 switch (wrpll & WRPLL_PLL_REF_MASK) {
926 case WRPLL_PLL_SSC:
927 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800928 /*
929 * We could calculate spread here, but our checking
930 * code only cares about 5% accuracy, and spread is a max of
931 * 0.5% downspread.
932 */
933 refclk = 135;
934 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300935 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800936 refclk = LC_FREQ;
937 break;
938 default:
939 WARN(1, "bad wrpll refclk\n");
940 return 0;
941 }
942
943 r = wrpll & WRPLL_DIVIDER_REF_MASK;
944 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
945 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
946
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800947 /* Convert to KHz, p & r have a fixed point portion */
948 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800949}
950
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000951static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
952 uint32_t dpll)
953{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200954 i915_reg_t cfgcr1_reg, cfgcr2_reg;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000955 uint32_t cfgcr1_val, cfgcr2_val;
956 uint32_t p0, p1, p2, dco_freq;
957
Ville Syrjälä923c12412015-09-30 17:06:43 +0300958 cfgcr1_reg = DPLL_CFGCR1(dpll);
959 cfgcr2_reg = DPLL_CFGCR2(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000960
961 cfgcr1_val = I915_READ(cfgcr1_reg);
962 cfgcr2_val = I915_READ(cfgcr2_reg);
963
964 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
965 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
966
967 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
968 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
969 else
970 p1 = 1;
971
972
973 switch (p0) {
974 case DPLL_CFGCR2_PDIV_1:
975 p0 = 1;
976 break;
977 case DPLL_CFGCR2_PDIV_2:
978 p0 = 2;
979 break;
980 case DPLL_CFGCR2_PDIV_3:
981 p0 = 3;
982 break;
983 case DPLL_CFGCR2_PDIV_7:
984 p0 = 7;
985 break;
986 }
987
988 switch (p2) {
989 case DPLL_CFGCR2_KDIV_5:
990 p2 = 5;
991 break;
992 case DPLL_CFGCR2_KDIV_2:
993 p2 = 2;
994 break;
995 case DPLL_CFGCR2_KDIV_3:
996 p2 = 3;
997 break;
998 case DPLL_CFGCR2_KDIV_1:
999 p2 = 1;
1000 break;
1001 }
1002
1003 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1004
1005 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1006 1000) / 0x8000;
1007
1008 return dco_freq / (p0 * p1 * p2 * 5);
1009}
1010
Ville Syrjälä398a0172015-06-30 15:33:51 +03001011static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1012{
1013 int dotclock;
1014
1015 if (pipe_config->has_pch_encoder)
1016 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1017 &pipe_config->fdi_m_n);
1018 else if (pipe_config->has_dp_encoder)
1019 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1020 &pipe_config->dp_m_n);
1021 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1022 dotclock = pipe_config->port_clock * 2 / 3;
1023 else
1024 dotclock = pipe_config->port_clock;
1025
1026 if (pipe_config->pixel_multiplier)
1027 dotclock /= pipe_config->pixel_multiplier;
1028
1029 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1030}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001031
1032static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001033 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001034{
1035 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001036 int link_clock = 0;
1037 uint32_t dpll_ctl1, dpll;
1038
Damien Lespiau134ffa42014-11-14 17:24:34 +00001039 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001040
1041 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1042
1043 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1044 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1045 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001046 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1047 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001048
1049 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001050 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001051 link_clock = 81000;
1052 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001053 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301054 link_clock = 108000;
1055 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001056 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001057 link_clock = 135000;
1058 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001059 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301060 link_clock = 162000;
1061 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001062 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301063 link_clock = 216000;
1064 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001065 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001066 link_clock = 270000;
1067 break;
1068 default:
1069 WARN(1, "Unsupported link rate\n");
1070 break;
1071 }
1072 link_clock *= 2;
1073 }
1074
1075 pipe_config->port_clock = link_clock;
1076
Ville Syrjälä398a0172015-06-30 15:33:51 +03001077 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001078}
1079
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001080static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001081 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001082{
1083 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001084 int link_clock = 0;
1085 u32 val, pll;
1086
Daniel Vetter26804af2014-06-25 22:01:55 +03001087 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001088 switch (val & PORT_CLK_SEL_MASK) {
1089 case PORT_CLK_SEL_LCPLL_810:
1090 link_clock = 81000;
1091 break;
1092 case PORT_CLK_SEL_LCPLL_1350:
1093 link_clock = 135000;
1094 break;
1095 case PORT_CLK_SEL_LCPLL_2700:
1096 link_clock = 270000;
1097 break;
1098 case PORT_CLK_SEL_WRPLL1:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001099 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
Jesse Barnes11578552014-01-21 12:42:10 -08001100 break;
1101 case PORT_CLK_SEL_WRPLL2:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001102 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
Jesse Barnes11578552014-01-21 12:42:10 -08001103 break;
1104 case PORT_CLK_SEL_SPLL:
1105 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1106 if (pll == SPLL_PLL_FREQ_810MHz)
1107 link_clock = 81000;
1108 else if (pll == SPLL_PLL_FREQ_1350MHz)
1109 link_clock = 135000;
1110 else if (pll == SPLL_PLL_FREQ_2700MHz)
1111 link_clock = 270000;
1112 else {
1113 WARN(1, "bad spll freq\n");
1114 return;
1115 }
1116 break;
1117 default:
1118 WARN(1, "bad port clock sel\n");
1119 return;
1120 }
1121
1122 pipe_config->port_clock = link_clock * 2;
1123
Ville Syrjälä398a0172015-06-30 15:33:51 +03001124 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001125}
1126
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301127static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1128 enum intel_dpll_id dpll)
1129{
Imre Deakaa610dc2015-06-22 23:35:52 +03001130 struct intel_shared_dpll *pll;
1131 struct intel_dpll_hw_state *state;
1132 intel_clock_t clock;
1133
1134 /* For DDI ports we always use a shared PLL. */
1135 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1136 return 0;
1137
1138 pll = &dev_priv->shared_dplls[dpll];
1139 state = &pll->config.hw_state;
1140
1141 clock.m1 = 2;
1142 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1143 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1144 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1145 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1146 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1147 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1148
1149 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301150}
1151
1152static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1153 struct intel_crtc_state *pipe_config)
1154{
1155 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1156 enum port port = intel_ddi_get_encoder_port(encoder);
1157 uint32_t dpll = port;
1158
Ville Syrjälä398a0172015-06-30 15:33:51 +03001159 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301160
Ville Syrjälä398a0172015-06-30 15:33:51 +03001161 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301162}
1163
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001164void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001165 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001166{
Damien Lespiau22606a12014-12-12 14:26:57 +00001167 struct drm_device *dev = encoder->base.dev;
1168
1169 if (INTEL_INFO(dev)->gen <= 8)
1170 hsw_ddi_clock_get(encoder, pipe_config);
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001171 else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001172 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301173 else if (IS_BROXTON(dev))
1174 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001175}
1176
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001177static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001178hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1179 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001180{
1181 uint64_t freq2k;
1182 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001183 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001184 unsigned budget;
1185
1186 freq2k = clock / 100;
1187
Damien Lespiau63582982015-05-07 18:38:46 +01001188 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001189
1190 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1191 * and directly pass the LC PLL to it. */
1192 if (freq2k == 5400000) {
1193 *n2_out = 2;
1194 *p_out = 1;
1195 *r2_out = 2;
1196 return;
1197 }
1198
1199 /*
1200 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1201 * the WR PLL.
1202 *
1203 * We want R so that REF_MIN <= Ref <= REF_MAX.
1204 * Injecting R2 = 2 * R gives:
1205 * REF_MAX * r2 > LC_FREQ * 2 and
1206 * REF_MIN * r2 < LC_FREQ * 2
1207 *
1208 * Which means the desired boundaries for r2 are:
1209 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1210 *
1211 */
1212 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1213 r2 <= LC_FREQ * 2 / REF_MIN;
1214 r2++) {
1215
1216 /*
1217 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1218 *
1219 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1220 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1221 * VCO_MAX * r2 > n2 * LC_FREQ and
1222 * VCO_MIN * r2 < n2 * LC_FREQ)
1223 *
1224 * Which means the desired boundaries for n2 are:
1225 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1226 */
1227 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1228 n2 <= VCO_MAX * r2 / LC_FREQ;
1229 n2++) {
1230
1231 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001232 hsw_wrpll_update_rnp(freq2k, budget,
1233 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001234 }
1235 }
1236
1237 *n2_out = best.n2;
1238 *p_out = best.p;
1239 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001240}
1241
Damien Lespiau0220ab62014-07-29 18:06:22 +01001242static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001243hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001244 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001245 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001246{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001247 int clock = crtc_state->port_clock;
1248
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001249 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001250 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001251 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001252 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001253
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001254 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001255
Daniel Vetter114fe482014-06-25 22:01:48 +03001256 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001257 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1258 WRPLL_DIVIDER_POST(p);
1259
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001260 memset(&crtc_state->dpll_hw_state, 0,
1261 sizeof(crtc_state->dpll_hw_state));
1262
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001263 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001264
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001265 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001266 if (pll == NULL) {
1267 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1268 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001269 return false;
1270 }
1271
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001272 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Maarten Lankhorst00490c22015-11-16 14:42:12 +01001273 } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
1274 struct drm_atomic_state *state = crtc_state->base.state;
1275 struct intel_shared_dpll_config *spll =
1276 &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
1277
1278 if (spll->crtc_mask &&
1279 WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
1280 return false;
1281
1282 crtc_state->shared_dpll = DPLL_ID_SPLL;
1283 spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
1284 spll->crtc_mask |= 1 << intel_crtc->pipe;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001285 }
1286
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001287 return true;
1288}
1289
Damien Lespiaudc253812015-06-25 16:15:06 +01001290struct skl_wrpll_context {
1291 uint64_t min_deviation; /* current minimal deviation */
1292 uint64_t central_freq; /* chosen central freq */
1293 uint64_t dco_freq; /* chosen dco freq */
1294 unsigned int p; /* chosen divider */
1295};
1296
1297static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1298{
1299 memset(ctx, 0, sizeof(*ctx));
1300
1301 ctx->min_deviation = U64_MAX;
1302}
1303
1304/* DCO freq must be within +1%/-6% of the DCO central freq */
1305#define SKL_DCO_MAX_PDEVIATION 100
1306#define SKL_DCO_MAX_NDEVIATION 600
1307
1308static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1309 uint64_t central_freq,
1310 uint64_t dco_freq,
1311 unsigned int divider)
1312{
1313 uint64_t deviation;
1314
1315 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1316 central_freq);
1317
1318 /* positive deviation */
1319 if (dco_freq >= central_freq) {
1320 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1321 deviation < ctx->min_deviation) {
1322 ctx->min_deviation = deviation;
1323 ctx->central_freq = central_freq;
1324 ctx->dco_freq = dco_freq;
1325 ctx->p = divider;
1326 }
1327 /* negative deviation */
1328 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1329 deviation < ctx->min_deviation) {
1330 ctx->min_deviation = deviation;
1331 ctx->central_freq = central_freq;
1332 ctx->dco_freq = dco_freq;
1333 ctx->p = divider;
1334 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001335}
1336
1337static void skl_wrpll_get_multipliers(unsigned int p,
1338 unsigned int *p0 /* out */,
1339 unsigned int *p1 /* out */,
1340 unsigned int *p2 /* out */)
1341{
1342 /* even dividers */
1343 if (p % 2 == 0) {
1344 unsigned int half = p / 2;
1345
1346 if (half == 1 || half == 2 || half == 3 || half == 5) {
1347 *p0 = 2;
1348 *p1 = 1;
1349 *p2 = half;
1350 } else if (half % 2 == 0) {
1351 *p0 = 2;
1352 *p1 = half / 2;
1353 *p2 = 2;
1354 } else if (half % 3 == 0) {
1355 *p0 = 3;
1356 *p1 = half / 3;
1357 *p2 = 2;
1358 } else if (half % 7 == 0) {
1359 *p0 = 7;
1360 *p1 = half / 7;
1361 *p2 = 2;
1362 }
1363 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1364 *p0 = 3;
1365 *p1 = 1;
1366 *p2 = p / 3;
1367 } else if (p == 5 || p == 7) {
1368 *p0 = p;
1369 *p1 = 1;
1370 *p2 = 1;
1371 } else if (p == 15) {
1372 *p0 = 3;
1373 *p1 = 1;
1374 *p2 = 5;
1375 } else if (p == 21) {
1376 *p0 = 7;
1377 *p1 = 1;
1378 *p2 = 3;
1379 } else if (p == 35) {
1380 *p0 = 7;
1381 *p1 = 1;
1382 *p2 = 5;
1383 }
1384}
1385
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001386struct skl_wrpll_params {
1387 uint32_t dco_fraction;
1388 uint32_t dco_integer;
1389 uint32_t qdiv_ratio;
1390 uint32_t qdiv_mode;
1391 uint32_t kdiv;
1392 uint32_t pdiv;
1393 uint32_t central_freq;
1394};
1395
Damien Lespiau76516fb2015-05-07 18:38:42 +01001396static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1397 uint64_t afe_clock,
1398 uint64_t central_freq,
1399 uint32_t p0, uint32_t p1, uint32_t p2)
1400{
1401 uint64_t dco_freq;
1402
Damien Lespiau76516fb2015-05-07 18:38:42 +01001403 switch (central_freq) {
1404 case 9600000000ULL:
1405 params->central_freq = 0;
1406 break;
1407 case 9000000000ULL:
1408 params->central_freq = 1;
1409 break;
1410 case 8400000000ULL:
1411 params->central_freq = 3;
1412 }
1413
1414 switch (p0) {
1415 case 1:
1416 params->pdiv = 0;
1417 break;
1418 case 2:
1419 params->pdiv = 1;
1420 break;
1421 case 3:
1422 params->pdiv = 2;
1423 break;
1424 case 7:
1425 params->pdiv = 4;
1426 break;
1427 default:
1428 WARN(1, "Incorrect PDiv\n");
1429 }
1430
1431 switch (p2) {
1432 case 5:
1433 params->kdiv = 0;
1434 break;
1435 case 2:
1436 params->kdiv = 1;
1437 break;
1438 case 3:
1439 params->kdiv = 2;
1440 break;
1441 case 1:
1442 params->kdiv = 3;
1443 break;
1444 default:
1445 WARN(1, "Incorrect KDiv\n");
1446 }
1447
1448 params->qdiv_ratio = p1;
1449 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1450
1451 dco_freq = p0 * p1 * p2 * afe_clock;
1452
1453 /*
1454 * Intermediate values are in Hz.
1455 * Divide by MHz to match bsepc
1456 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001457 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001458 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001459 div_u64((div_u64(dco_freq, 24) -
1460 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001461}
1462
Damien Lespiau318bd822015-05-07 18:38:40 +01001463static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001464skl_ddi_calculate_wrpll(int clock /* in Hz */,
1465 struct skl_wrpll_params *wrpll_params)
1466{
1467 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001468 uint64_t dco_central_freq[3] = {8400000000ULL,
1469 9000000000ULL,
1470 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001471 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1472 24, 28, 30, 32, 36, 40, 42, 44,
1473 48, 52, 54, 56, 60, 64, 66, 68,
1474 70, 72, 76, 78, 80, 84, 88, 90,
1475 92, 96, 98 };
1476 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1477 static const struct {
1478 const int *list;
1479 int n_dividers;
1480 } dividers[] = {
1481 { even_dividers, ARRAY_SIZE(even_dividers) },
1482 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1483 };
1484 struct skl_wrpll_context ctx;
1485 unsigned int dco, d, i;
1486 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001487
Damien Lespiaudc253812015-06-25 16:15:06 +01001488 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001489
Damien Lespiaudc253812015-06-25 16:15:06 +01001490 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1491 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1492 for (i = 0; i < dividers[d].n_dividers; i++) {
1493 unsigned int p = dividers[d].list[i];
1494 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001495
Damien Lespiaudc253812015-06-25 16:15:06 +01001496 skl_wrpll_try_divider(&ctx,
1497 dco_central_freq[dco],
1498 dco_freq,
1499 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001500 /*
1501 * Skip the remaining dividers if we're sure to
1502 * have found the definitive divider, we can't
1503 * improve a 0 deviation.
1504 */
1505 if (ctx.min_deviation == 0)
1506 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001507 }
1508 }
Damien Lespiau267db662015-06-25 16:19:24 +01001509
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001510skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001511 /*
1512 * If a solution is found with an even divider, prefer
1513 * this one.
1514 */
1515 if (d == 0 && ctx.p)
1516 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001517 }
1518
Damien Lespiaudc253812015-06-25 16:15:06 +01001519 if (!ctx.p) {
1520 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001521 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001522 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001523
Damien Lespiaudc253812015-06-25 16:15:06 +01001524 /*
1525 * gcc incorrectly analyses that these can be used without being
1526 * initialized. To be fair, it's hard to guess.
1527 */
1528 p0 = p1 = p2 = 0;
1529 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1530 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1531 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001532
Damien Lespiau318bd822015-05-07 18:38:40 +01001533 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001534}
1535
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001536static bool
1537skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001538 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001539 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001540{
1541 struct intel_shared_dpll *pll;
1542 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001543 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001544
1545 /*
1546 * See comment in intel_dpll_hw_state to understand why we always use 0
1547 * as the DPLL id in this function.
1548 */
1549
1550 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1551
1552 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1553 struct skl_wrpll_params wrpll_params = { 0, };
1554
1555 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1556
Damien Lespiau318bd822015-05-07 18:38:40 +01001557 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1558 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001559
1560 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1561 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1562 wrpll_params.dco_integer;
1563
1564 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1565 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1566 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1567 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1568 wrpll_params.central_freq;
1569 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001570 switch (crtc_state->port_clock / 2) {
1571 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001572 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001573 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001574 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001575 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001576 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001577 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001578 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001579 break;
1580 }
1581
1582 cfgcr1 = cfgcr2 = 0;
1583 } else /* eDP */
1584 return true;
1585
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001586 memset(&crtc_state->dpll_hw_state, 0,
1587 sizeof(crtc_state->dpll_hw_state));
1588
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001589 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1590 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1591 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001592
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001593 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001594 if (pll == NULL) {
1595 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1596 pipe_name(intel_crtc->pipe));
1597 return false;
1598 }
1599
1600 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001601 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001602
1603 return true;
1604}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001605
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301606/* bxt clock parameters */
1607struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301608 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301609 uint32_t p1;
1610 uint32_t p2;
1611 uint32_t m2_int;
1612 uint32_t m2_frac;
1613 bool m2_frac_en;
1614 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301615};
1616
1617/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301618static const struct bxt_clk_div bxt_dp_clk_val[] = {
1619 {162000, 4, 2, 32, 1677722, 1, 1},
1620 {270000, 4, 1, 27, 0, 0, 1},
1621 {540000, 2, 1, 27, 0, 0, 1},
1622 {216000, 3, 2, 32, 1677722, 1, 1},
1623 {243000, 4, 1, 24, 1258291, 1, 1},
1624 {324000, 4, 1, 32, 1677722, 1, 1},
1625 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301626};
1627
1628static bool
1629bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1630 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001631 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301632{
1633 struct intel_shared_dpll *pll;
1634 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301635 int vco = 0;
1636 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301637 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001638 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301639
1640 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1641 intel_clock_t best_clock;
1642
1643 /* Calculate HDMI div */
1644 /*
1645 * FIXME: tie the following calculation into
1646 * i9xx_crtc_compute_clock
1647 */
1648 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1649 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1650 clock, pipe_name(intel_crtc->pipe));
1651 return false;
1652 }
1653
1654 clk_div.p1 = best_clock.p1;
1655 clk_div.p2 = best_clock.p2;
1656 WARN_ON(best_clock.m1 != 2);
1657 clk_div.n = best_clock.n;
1658 clk_div.m2_int = best_clock.m2 >> 22;
1659 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1660 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1661
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301662 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301663 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1664 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301665 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301666
Sonika Jindal64987fc2015-05-26 17:50:13 +05301667 clk_div = bxt_dp_clk_val[0];
1668 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1669 if (bxt_dp_clk_val[i].clock == clock) {
1670 clk_div = bxt_dp_clk_val[i];
1671 break;
1672 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301673 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301674 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1675 }
1676
Vandana Kannane6292552015-07-01 17:02:57 +05301677 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301678 prop_coef = 4;
1679 int_coef = 9;
1680 gain_ctl = 3;
1681 targ_cnt = 8;
1682 } else if ((vco > 5400000 && vco < 6200000) ||
1683 (vco >= 4800000 && vco < 5400000)) {
1684 prop_coef = 5;
1685 int_coef = 11;
1686 gain_ctl = 3;
1687 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301688 } else if (vco == 5400000) {
1689 prop_coef = 3;
1690 int_coef = 8;
1691 gain_ctl = 1;
1692 targ_cnt = 9;
1693 } else {
1694 DRM_ERROR("Invalid VCO\n");
1695 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301696 }
1697
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001698 memset(&crtc_state->dpll_hw_state, 0,
1699 sizeof(crtc_state->dpll_hw_state));
1700
Vandana Kannane0681e32015-05-13 12:20:35 +05301701 if (clock > 270000)
1702 lanestagger = 0x18;
1703 else if (clock > 135000)
1704 lanestagger = 0x0d;
1705 else if (clock > 67000)
1706 lanestagger = 0x07;
1707 else if (clock > 33000)
1708 lanestagger = 0x04;
1709 else
1710 lanestagger = 0x02;
1711
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301712 crtc_state->dpll_hw_state.ebb0 =
1713 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1714 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1715 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1716 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1717
1718 if (clk_div.m2_frac_en)
1719 crtc_state->dpll_hw_state.pll3 =
1720 PORT_PLL_M2_FRAC_ENABLE;
1721
1722 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301723 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301724 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301725 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301726
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301727 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1728
Imre Deak05712c12015-06-18 17:25:54 +03001729 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1730
Vandana Kannane6292552015-07-01 17:02:57 +05301731 crtc_state->dpll_hw_state.pll10 =
1732 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1733 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301734
Imre Deak05712c12015-06-18 17:25:54 +03001735 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1736
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301737 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301738 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301739
1740 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1741 if (pll == NULL) {
1742 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1743 pipe_name(intel_crtc->pipe));
1744 return false;
1745 }
1746
1747 /* shared DPLL id 0 is DPLL A */
1748 crtc_state->ddi_pll_sel = pll->id;
1749
1750 return true;
1751}
1752
Damien Lespiau0220ab62014-07-29 18:06:22 +01001753/*
1754 * Tries to find a *shared* PLL for the CRTC and store it in
1755 * intel_crtc->ddi_pll_sel.
1756 *
1757 * For private DPLLs, compute_config() should do the selection for us. This
1758 * function should be folded into compute_config() eventually.
1759 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001760bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1761 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001762{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001763 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001764 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001765 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001766
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001767 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001768 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001769 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301770 else if (IS_BROXTON(dev))
1771 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001772 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001773 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001774 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001775 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001776}
1777
Paulo Zanonidae84792012-10-15 15:51:30 -03001778void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1779{
1780 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1781 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1782 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001783 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001784 int type = intel_encoder->type;
1785 uint32_t temp;
1786
Dave Airlie0e32b392014-05-02 14:02:48 +10001787 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001788 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001789 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001790 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001791 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001792 break;
1793 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001794 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001795 break;
1796 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001797 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001798 break;
1799 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001800 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001801 break;
1802 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001803 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001804 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001805 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001806 }
1807}
1808
Dave Airlie0e32b392014-05-02 14:02:48 +10001809void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1810{
1811 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1812 struct drm_device *dev = crtc->dev;
1813 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001814 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001815 uint32_t temp;
1816 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1817 if (state == true)
1818 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1819 else
1820 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1821 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1822}
1823
Damien Lespiau8228c252013-03-07 15:30:27 +00001824void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001825{
1826 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1827 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001828 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001829 struct drm_device *dev = crtc->dev;
1830 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001831 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001832 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001833 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001834 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001835 uint32_t temp;
1836
Paulo Zanoniad80a812012-10-24 16:06:19 -02001837 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1838 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001839 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001840
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001841 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001842 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001843 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001844 break;
1845 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001846 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001847 break;
1848 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001849 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001850 break;
1851 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001852 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001853 break;
1854 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001855 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001856 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001857
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001858 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001859 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001860 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001861 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001862
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001863 if (cpu_transcoder == TRANSCODER_EDP) {
1864 switch (pipe) {
1865 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001866 /* On Haswell, can only use the always-on power well for
1867 * eDP when not using the panel fitter, and when not
1868 * using motion blur mitigation (which we don't
1869 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001870 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001871 (intel_crtc->config->pch_pfit.enabled ||
1872 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001873 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1874 else
1875 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001876 break;
1877 case PIPE_B:
1878 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1879 break;
1880 case PIPE_C:
1881 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1882 break;
1883 default:
1884 BUG();
1885 break;
1886 }
1887 }
1888
Paulo Zanoni7739c332012-10-15 15:51:29 -03001889 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001890 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001891 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001892 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001893 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001894
Paulo Zanoni7739c332012-10-15 15:51:29 -03001895 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001896 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001897 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001898
1899 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1900 type == INTEL_OUTPUT_EDP) {
1901 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1902
Dave Airlie0e32b392014-05-02 14:02:48 +10001903 if (intel_dp->is_mst) {
1904 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1905 } else
1906 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1907
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001908 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001909 } else if (type == INTEL_OUTPUT_DP_MST) {
1910 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1911
1912 if (intel_dp->is_mst) {
1913 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1914 } else
1915 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001916
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001917 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001918 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001919 WARN(1, "Invalid encoder type %d for pipe %c\n",
1920 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001921 }
1922
Paulo Zanoniad80a812012-10-24 16:06:19 -02001923 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001924}
1925
Paulo Zanoniad80a812012-10-24 16:06:19 -02001926void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1927 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001928{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02001929 i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001930 uint32_t val = I915_READ(reg);
1931
Dave Airlie0e32b392014-05-02 14:02:48 +10001932 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001933 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001934 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001935}
1936
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001937bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1938{
1939 struct drm_device *dev = intel_connector->base.dev;
1940 struct drm_i915_private *dev_priv = dev->dev_private;
1941 struct intel_encoder *intel_encoder = intel_connector->encoder;
1942 int type = intel_connector->base.connector_type;
1943 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1944 enum pipe pipe = 0;
1945 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001946 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001947 uint32_t tmp;
1948
Paulo Zanoni882244a2014-04-01 14:55:12 -03001949 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001950 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001951 return false;
1952
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001953 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1954 return false;
1955
1956 if (port == PORT_A)
1957 cpu_transcoder = TRANSCODER_EDP;
1958 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001959 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001960
1961 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1962
1963 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1964 case TRANS_DDI_MODE_SELECT_HDMI:
1965 case TRANS_DDI_MODE_SELECT_DVI:
1966 return (type == DRM_MODE_CONNECTOR_HDMIA);
1967
1968 case TRANS_DDI_MODE_SELECT_DP_SST:
1969 if (type == DRM_MODE_CONNECTOR_eDP)
1970 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001971 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001972 case TRANS_DDI_MODE_SELECT_DP_MST:
1973 /* if the transcoder is in MST state then
1974 * connector isn't connected */
1975 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001976
1977 case TRANS_DDI_MODE_SELECT_FDI:
1978 return (type == DRM_MODE_CONNECTOR_VGA);
1979
1980 default:
1981 return false;
1982 }
1983}
1984
Daniel Vetter85234cd2012-07-02 13:27:29 +02001985bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1986 enum pipe *pipe)
1987{
1988 struct drm_device *dev = encoder->base.dev;
1989 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001990 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001991 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001992 u32 tmp;
1993 int i;
1994
Imre Deak6d129be2014-03-05 16:20:54 +02001995 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001996 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02001997 return false;
1998
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001999 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002000
2001 if (!(tmp & DDI_BUF_CTL_ENABLE))
2002 return false;
2003
Paulo Zanoniad80a812012-10-24 16:06:19 -02002004 if (port == PORT_A) {
2005 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002006
Paulo Zanoniad80a812012-10-24 16:06:19 -02002007 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2008 case TRANS_DDI_EDP_INPUT_A_ON:
2009 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2010 *pipe = PIPE_A;
2011 break;
2012 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2013 *pipe = PIPE_B;
2014 break;
2015 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2016 *pipe = PIPE_C;
2017 break;
2018 }
2019
2020 return true;
2021 } else {
2022 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2023 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2024
2025 if ((tmp & TRANS_DDI_PORT_MASK)
2026 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002027 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2028 return false;
2029
Paulo Zanoniad80a812012-10-24 16:06:19 -02002030 *pipe = i;
2031 return true;
2032 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002033 }
2034 }
2035
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002036 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002037
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002038 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002039}
2040
Paulo Zanonifc914632012-10-05 12:05:54 -03002041void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2042{
2043 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302044 struct drm_device *dev = crtc->dev;
2045 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002046 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2047 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002048 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002049
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002050 if (cpu_transcoder != TRANSCODER_EDP)
2051 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2052 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002053}
2054
2055void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2056{
2057 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002058 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002059
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002060 if (cpu_transcoder != TRANSCODER_EDP)
2061 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2062 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002063}
2064
David Weinehallf8896f52015-06-25 11:11:03 +03002065static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2066 enum port port, int type)
2067{
2068 struct drm_i915_private *dev_priv = dev->dev_private;
2069 const struct ddi_buf_trans *ddi_translations;
2070 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002071 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002072 int n_entries;
2073 u32 reg;
2074
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002075 /* VBT may override standard boost values */
2076 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2077 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2078
David Weinehallf8896f52015-06-25 11:11:03 +03002079 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002080 if (dp_iboost) {
2081 iboost = dp_iboost;
2082 } else {
2083 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002084 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002085 }
David Weinehallf8896f52015-06-25 11:11:03 +03002086 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002087 if (dp_iboost) {
2088 iboost = dp_iboost;
2089 } else {
2090 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002091 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002092 }
David Weinehallf8896f52015-06-25 11:11:03 +03002093 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002094 if (hdmi_iboost) {
2095 iboost = hdmi_iboost;
2096 } else {
2097 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002098 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002099 }
David Weinehallf8896f52015-06-25 11:11:03 +03002100 } else {
2101 return;
2102 }
2103
2104 /* Make sure that the requested I_boost is valid */
2105 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2106 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2107 return;
2108 }
2109
2110 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2111 reg &= ~BALANCE_LEG_MASK(port);
2112 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2113
2114 if (iboost)
2115 reg |= iboost << BALANCE_LEG_SHIFT(port);
2116 else
2117 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2118
2119 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2120}
2121
2122static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2123 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302124{
2125 struct drm_i915_private *dev_priv = dev->dev_private;
2126 const struct bxt_ddi_buf_trans *ddi_translations;
2127 u32 n_entries, i;
2128 uint32_t val;
2129
Sonika Jindald9d70002015-09-24 10:24:56 +05302130 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2131 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2132 ddi_translations = bxt_ddi_translations_edp;
2133 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2134 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302135 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2136 ddi_translations = bxt_ddi_translations_dp;
2137 } else if (type == INTEL_OUTPUT_HDMI) {
2138 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2139 ddi_translations = bxt_ddi_translations_hdmi;
2140 } else {
2141 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2142 type);
2143 return;
2144 }
2145
2146 /* Check if default value has to be used */
2147 if (level >= n_entries ||
2148 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2149 for (i = 0; i < n_entries; i++) {
2150 if (ddi_translations[i].default_index) {
2151 level = i;
2152 break;
2153 }
2154 }
2155 }
2156
2157 /*
2158 * While we write to the group register to program all lanes at once we
2159 * can read only lane registers and we pick lanes 0/1 for that.
2160 */
2161 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2162 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2163 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2164
2165 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2166 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2167 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2168 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2169 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2170
2171 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302172 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302173 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302174 val |= SCALE_DCOMP_METHOD;
2175
2176 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2177 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2178
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302179 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2180
2181 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2182 val &= ~DE_EMPHASIS;
2183 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2184 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2185
2186 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2187 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2188 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2189}
2190
David Weinehallf8896f52015-06-25 11:11:03 +03002191static uint32_t translate_signal_level(int signal_levels)
2192{
2193 uint32_t level;
2194
2195 switch (signal_levels) {
2196 default:
2197 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2198 signal_levels);
2199 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2200 level = 0;
2201 break;
2202 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2203 level = 1;
2204 break;
2205 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2206 level = 2;
2207 break;
2208 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2209 level = 3;
2210 break;
2211
2212 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2213 level = 4;
2214 break;
2215 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2216 level = 5;
2217 break;
2218 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2219 level = 6;
2220 break;
2221
2222 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2223 level = 7;
2224 break;
2225 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2226 level = 8;
2227 break;
2228
2229 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2230 level = 9;
2231 break;
2232 }
2233
2234 return level;
2235}
2236
2237uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2238{
2239 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2240 struct drm_device *dev = dport->base.base.dev;
2241 struct intel_encoder *encoder = &dport->base;
2242 uint8_t train_set = intel_dp->train_set[0];
2243 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2244 DP_TRAIN_PRE_EMPHASIS_MASK);
2245 enum port port = dport->port;
2246 uint32_t level;
2247
2248 level = translate_signal_level(signal_levels);
2249
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002250 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
David Weinehallf8896f52015-06-25 11:11:03 +03002251 skl_ddi_set_iboost(dev, level, port, encoder->type);
2252 else if (IS_BROXTON(dev))
2253 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2254
2255 return DDI_BUF_TRANS_SELECT(level);
2256}
2257
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002258void intel_ddi_clk_select(struct intel_encoder *encoder,
2259 const struct intel_crtc_state *pipe_config)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002260{
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002261 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2262 enum port port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002263
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002264 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
2265 uint32_t dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002266 uint32_t val;
2267
Damien Lespiau5416d872014-11-14 17:24:33 +00002268 /*
2269 * DPLL0 is used for eDP and is the only "private" DPLL (as
2270 * opposed to shared) on SKL
2271 */
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002272 if (encoder->type == INTEL_OUTPUT_EDP) {
Damien Lespiau5416d872014-11-14 17:24:33 +00002273 WARN_ON(dpll != SKL_DPLL0);
2274
2275 val = I915_READ(DPLL_CTRL1);
2276
2277 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2278 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002279 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002280 val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002281
2282 I915_WRITE(DPLL_CTRL1, val);
2283 POSTING_READ(DPLL_CTRL1);
2284 }
2285
2286 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002287 val = I915_READ(DPLL_CTRL2);
2288
2289 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2290 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2291 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2292 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2293
2294 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002295
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002296 } else if (INTEL_INFO(dev_priv)->gen < 9) {
2297 WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2298 I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002299 }
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002300}
2301
2302static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
2303{
2304 struct drm_encoder *encoder = &intel_encoder->base;
2305 struct drm_device *dev = encoder->dev;
2306 struct drm_i915_private *dev_priv = dev->dev_private;
2307 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
2308 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2309 int type = intel_encoder->type;
2310 int hdmi_level;
2311
2312 if (type == INTEL_OUTPUT_EDP) {
2313 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2314 intel_edp_panel_on(intel_dp);
2315 }
2316
2317 intel_ddi_clk_select(intel_encoder, crtc->config);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002318
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002319 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002320 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002321
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002322 intel_dp_set_link_params(intel_dp, crtc->config);
2323
Dave Airlie44905a272014-05-02 13:36:43 +10002324 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002325
2326 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2327 intel_dp_start_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002328 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002329 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002330 } else if (type == INTEL_OUTPUT_HDMI) {
2331 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2332
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302333 if (IS_BROXTON(dev)) {
2334 hdmi_level = dev_priv->vbt.
2335 ddi_port_info[port].hdmi_level_shift;
2336 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2337 INTEL_OUTPUT_HDMI);
2338 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002339 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002340 crtc->config->has_hdmi_sink,
2341 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002342 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002343}
2344
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002345static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002346{
2347 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002348 struct drm_device *dev = encoder->dev;
2349 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002350 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002351 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002352 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002353 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002354
2355 val = I915_READ(DDI_BUF_CTL(port));
2356 if (val & DDI_BUF_CTL_ENABLE) {
2357 val &= ~DDI_BUF_CTL_ENABLE;
2358 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002359 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002360 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002361
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002362 val = I915_READ(DP_TP_CTL(port));
2363 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2364 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2365 I915_WRITE(DP_TP_CTL(port), val);
2366
2367 if (wait)
2368 intel_wait_ddi_buf_idle(dev_priv, port);
2369
Jani Nikula76bb80e2013-11-15 15:29:57 +02002370 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002371 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002372 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002373 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002374 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002375 }
2376
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002377 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002378 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2379 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302380 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002381 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002382}
2383
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002384static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002385{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002386 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002387 struct drm_crtc *crtc = encoder->crtc;
2388 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002389 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002390 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002391 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2392 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002393
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002394 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002395 struct intel_digital_port *intel_dig_port =
2396 enc_to_dig_port(encoder);
2397
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002398 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2399 * are ignored so nothing special needs to be done besides
2400 * enabling the port.
2401 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002402 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de42013-07-12 13:54:41 -07002403 intel_dig_port->saved_port_bits |
2404 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002405 } else if (type == INTEL_OUTPUT_EDP) {
2406 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2407
Vandana Kannan23f08d82014-11-13 14:55:22 +00002408 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002409 intel_dp_stop_link_train(intel_dp);
2410
Daniel Vetter4be73782014-01-17 14:39:48 +01002411 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002412 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302413 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002414 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002415
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002416 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002417 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002418 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002419 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002420}
2421
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002422static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002423{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002424 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002425 struct drm_crtc *crtc = encoder->crtc;
2426 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002427 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002428 struct drm_device *dev = encoder->dev;
2429 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002430
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002431 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002432 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002433 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2434 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002435
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002436 if (type == INTEL_OUTPUT_EDP) {
2437 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2438
Vandana Kannanc3955782015-01-22 15:17:40 +05302439 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002440 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002441 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002442 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002443}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002444
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002445static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
Daniel Vettere0b01be2014-06-25 22:02:01 +03002446 struct intel_shared_dpll *pll)
2447{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002448 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002449 POSTING_READ(WRPLL_CTL(pll->id));
2450 udelay(20);
2451}
2452
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002453static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
Daniel Vetter12030432014-06-25 22:02:00 +03002454 struct intel_shared_dpll *pll)
2455{
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002456 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
2457 POSTING_READ(SPLL_CTL);
2458 udelay(20);
2459}
2460
2461static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
2462 struct intel_shared_dpll *pll)
2463{
Daniel Vetter12030432014-06-25 22:02:00 +03002464 uint32_t val;
2465
2466 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002467 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2468 POSTING_READ(WRPLL_CTL(pll->id));
2469}
2470
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002471static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
2472 struct intel_shared_dpll *pll)
2473{
2474 uint32_t val;
2475
2476 val = I915_READ(SPLL_CTL);
2477 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
2478 POSTING_READ(SPLL_CTL);
2479}
2480
2481static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
2482 struct intel_shared_dpll *pll,
2483 struct intel_dpll_hw_state *hw_state)
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002484{
2485 uint32_t val;
2486
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002487 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002488 return false;
2489
2490 val = I915_READ(WRPLL_CTL(pll->id));
2491 hw_state->wrpll = val;
2492
2493 return val & WRPLL_PLL_ENABLE;
2494}
2495
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002496static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
2497 struct intel_shared_dpll *pll,
2498 struct intel_dpll_hw_state *hw_state)
2499{
2500 uint32_t val;
2501
2502 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2503 return false;
2504
2505 val = I915_READ(SPLL_CTL);
2506 hw_state->spll = val;
2507
2508 return val & SPLL_PLL_ENABLE;
2509}
2510
2511
Damien Lespiauca1381b2014-07-15 15:05:33 +01002512static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002513 "WRPLL 1",
2514 "WRPLL 2",
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002515 "SPLL"
Daniel Vetter9cd86932014-06-25 22:01:57 +03002516};
2517
Damien Lespiau143b3072014-07-29 18:06:19 +01002518static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002519{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002520 int i;
2521
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002522 dev_priv->num_shared_dpll = 3;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002523
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002524 for (i = 0; i < 2; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002525 dev_priv->shared_dplls[i].id = i;
2526 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002527 dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
2528 dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002529 dev_priv->shared_dplls[i].get_hw_state =
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002530 hsw_ddi_wrpll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002531 }
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002532
2533 /* SPLL is special, but needs to be initialized anyway.. */
2534 dev_priv->shared_dplls[i].id = i;
2535 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
2536 dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
2537 dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
2538 dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
2539
Damien Lespiau143b3072014-07-29 18:06:19 +01002540}
2541
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002542static const char * const skl_ddi_pll_names[] = {
2543 "DPLL 1",
2544 "DPLL 2",
2545 "DPLL 3",
2546};
2547
2548struct skl_dpll_regs {
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02002549 i915_reg_t ctl, cfgcr1, cfgcr2;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002550};
2551
2552/* this array is indexed by the *shared* pll id */
2553static const struct skl_dpll_regs skl_dpll_regs[3] = {
2554 {
2555 /* DPLL 1 */
2556 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002557 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2558 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002559 },
2560 {
2561 /* DPLL 2 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002562 .ctl = WRPLL_CTL(0),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002563 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2564 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002565 },
2566 {
2567 /* DPLL 3 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002568 .ctl = WRPLL_CTL(1),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002569 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2570 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002571 },
2572};
2573
2574static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2575 struct intel_shared_dpll *pll)
2576{
2577 uint32_t val;
2578 unsigned int dpll;
2579 const struct skl_dpll_regs *regs = skl_dpll_regs;
2580
2581 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2582 dpll = pll->id + 1;
2583
2584 val = I915_READ(DPLL_CTRL1);
2585
2586 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002587 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002588 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2589
2590 I915_WRITE(DPLL_CTRL1, val);
2591 POSTING_READ(DPLL_CTRL1);
2592
2593 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2594 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2595 POSTING_READ(regs[pll->id].cfgcr1);
2596 POSTING_READ(regs[pll->id].cfgcr2);
2597
2598 /* the enable bit is always bit 31 */
2599 I915_WRITE(regs[pll->id].ctl,
2600 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2601
2602 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2603 DRM_ERROR("DPLL %d not locked\n", dpll);
2604}
2605
2606static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2607 struct intel_shared_dpll *pll)
2608{
2609 const struct skl_dpll_regs *regs = skl_dpll_regs;
2610
2611 /* the enable bit is always bit 31 */
2612 I915_WRITE(regs[pll->id].ctl,
2613 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2614 POSTING_READ(regs[pll->id].ctl);
2615}
2616
2617static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2618 struct intel_shared_dpll *pll,
2619 struct intel_dpll_hw_state *hw_state)
2620{
2621 uint32_t val;
2622 unsigned int dpll;
2623 const struct skl_dpll_regs *regs = skl_dpll_regs;
2624
2625 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2626 return false;
2627
2628 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2629 dpll = pll->id + 1;
2630
2631 val = I915_READ(regs[pll->id].ctl);
2632 if (!(val & LCPLL_PLL_ENABLE))
2633 return false;
2634
2635 val = I915_READ(DPLL_CTRL1);
2636 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2637
2638 /* avoid reading back stale values if HDMI mode is not enabled */
2639 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2640 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2641 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2642 }
2643
2644 return true;
2645}
2646
2647static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2648{
2649 int i;
2650
2651 dev_priv->num_shared_dpll = 3;
2652
2653 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2654 dev_priv->shared_dplls[i].id = i;
2655 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2656 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2657 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2658 dev_priv->shared_dplls[i].get_hw_state =
2659 skl_ddi_pll_get_hw_state;
2660 }
2661}
2662
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302663static void broxton_phy_init(struct drm_i915_private *dev_priv,
2664 enum dpio_phy phy)
2665{
2666 enum port port;
2667 uint32_t val;
2668
2669 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2670 val |= GT_DISPLAY_POWER_ON(phy);
2671 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2672
2673 /* Considering 10ms timeout until BSpec is updated */
2674 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2675 DRM_ERROR("timeout during PHY%d power on\n", phy);
2676
2677 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2678 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2679 int lane;
2680
2681 for (lane = 0; lane < 4; lane++) {
2682 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2683 /*
2684 * Note that on CHV this flag is called UPAR, but has
2685 * the same function.
2686 */
2687 val &= ~LATENCY_OPTIM;
2688 if (lane != 1)
2689 val |= LATENCY_OPTIM;
2690
2691 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2692 }
2693 }
2694
2695 /* Program PLL Rcomp code offset */
2696 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2697 val &= ~IREF0RC_OFFSET_MASK;
2698 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2699 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2700
2701 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2702 val &= ~IREF1RC_OFFSET_MASK;
2703 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2704 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2705
2706 /* Program power gating */
2707 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2708 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2709 SUS_CLK_CONFIG;
2710 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2711
2712 if (phy == DPIO_PHY0) {
2713 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2714 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2715 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2716 }
2717
2718 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2719 val &= ~OCL2_LDOFUSE_PWR_DIS;
2720 /*
2721 * On PHY1 disable power on the second channel, since no port is
2722 * connected there. On PHY0 both channels have a port, so leave it
2723 * enabled.
2724 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2725 * power down the second channel on PHY0 as well.
2726 */
2727 if (phy == DPIO_PHY1)
2728 val |= OCL2_LDOFUSE_PWR_DIS;
2729 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2730
2731 if (phy == DPIO_PHY0) {
2732 uint32_t grc_code;
2733 /*
2734 * PHY0 isn't connected to an RCOMP resistor so copy over
2735 * the corresponding calibrated value from PHY1, and disable
2736 * the automatic calibration on PHY0.
2737 */
2738 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2739 10))
2740 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2741
2742 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2743 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2744 grc_code = val << GRC_CODE_FAST_SHIFT |
2745 val << GRC_CODE_SLOW_SHIFT |
2746 val;
2747 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2748
2749 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2750 val |= GRC_DIS | GRC_RDY_OVRD;
2751 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2752 }
2753
2754 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2755 val |= COMMON_RESET_DIS;
2756 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2757}
2758
2759void broxton_ddi_phy_init(struct drm_device *dev)
2760{
2761 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2762 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2763 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2764}
2765
2766static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2767 enum dpio_phy phy)
2768{
2769 uint32_t val;
2770
2771 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2772 val &= ~COMMON_RESET_DIS;
2773 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2774}
2775
2776void broxton_ddi_phy_uninit(struct drm_device *dev)
2777{
2778 struct drm_i915_private *dev_priv = dev->dev_private;
2779
2780 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2781 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2782
2783 /* FIXME: do this in broxton_phy_uninit per phy */
2784 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2785}
2786
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302787static const char * const bxt_ddi_pll_names[] = {
2788 "PORT PLL A",
2789 "PORT PLL B",
2790 "PORT PLL C",
2791};
2792
2793static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2794 struct intel_shared_dpll *pll)
2795{
2796 uint32_t temp;
2797 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2798
2799 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2800 temp &= ~PORT_PLL_REF_SEL;
2801 /* Non-SSC reference */
2802 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2803
2804 /* Disable 10 bit clock */
2805 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2806 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2807 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2808
2809 /* Write P1 & P2 */
2810 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2811 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2812 temp |= pll->config.hw_state.ebb0;
2813 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2814
2815 /* Write M2 integer */
2816 temp = I915_READ(BXT_PORT_PLL(port, 0));
2817 temp &= ~PORT_PLL_M2_MASK;
2818 temp |= pll->config.hw_state.pll0;
2819 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2820
2821 /* Write N */
2822 temp = I915_READ(BXT_PORT_PLL(port, 1));
2823 temp &= ~PORT_PLL_N_MASK;
2824 temp |= pll->config.hw_state.pll1;
2825 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2826
2827 /* Write M2 fraction */
2828 temp = I915_READ(BXT_PORT_PLL(port, 2));
2829 temp &= ~PORT_PLL_M2_FRAC_MASK;
2830 temp |= pll->config.hw_state.pll2;
2831 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2832
2833 /* Write M2 fraction enable */
2834 temp = I915_READ(BXT_PORT_PLL(port, 3));
2835 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2836 temp |= pll->config.hw_state.pll3;
2837 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2838
2839 /* Write coeff */
2840 temp = I915_READ(BXT_PORT_PLL(port, 6));
2841 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2842 temp &= ~PORT_PLL_INT_COEFF_MASK;
2843 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2844 temp |= pll->config.hw_state.pll6;
2845 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2846
2847 /* Write calibration val */
2848 temp = I915_READ(BXT_PORT_PLL(port, 8));
2849 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2850 temp |= pll->config.hw_state.pll8;
2851 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2852
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302853 temp = I915_READ(BXT_PORT_PLL(port, 9));
2854 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002855 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302856 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2857
2858 temp = I915_READ(BXT_PORT_PLL(port, 10));
2859 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2860 temp &= ~PORT_PLL_DCO_AMP_MASK;
2861 temp |= pll->config.hw_state.pll10;
2862 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302863
2864 /* Recalibrate with new settings */
2865 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2866 temp |= PORT_PLL_RECALIBRATE;
2867 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002868 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2869 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302870 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2871
2872 /* Enable PLL */
2873 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2874 temp |= PORT_PLL_ENABLE;
2875 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2876 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2877
2878 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2879 PORT_PLL_LOCK), 200))
2880 DRM_ERROR("PLL %d not locked\n", port);
2881
2882 /*
2883 * While we write to the group register to program all lanes at once we
2884 * can read only lane registers and we pick lanes 0/1 for that.
2885 */
2886 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2887 temp &= ~LANE_STAGGER_MASK;
2888 temp &= ~LANESTAGGER_STRAP_OVRD;
2889 temp |= pll->config.hw_state.pcsdw12;
2890 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2891}
2892
2893static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2894 struct intel_shared_dpll *pll)
2895{
2896 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2897 uint32_t temp;
2898
2899 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2900 temp &= ~PORT_PLL_ENABLE;
2901 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2902 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2903}
2904
2905static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2906 struct intel_shared_dpll *pll,
2907 struct intel_dpll_hw_state *hw_state)
2908{
2909 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2910 uint32_t val;
2911
2912 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2913 return false;
2914
2915 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2916 if (!(val & PORT_PLL_ENABLE))
2917 return false;
2918
2919 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002920 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2921
Imre Deak05712c12015-06-18 17:25:54 +03002922 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2923 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2924
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302925 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002926 hw_state->pll0 &= PORT_PLL_M2_MASK;
2927
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302928 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002929 hw_state->pll1 &= PORT_PLL_N_MASK;
2930
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302931 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002932 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2933
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302934 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002935 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2936
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302937 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002938 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2939 PORT_PLL_INT_COEFF_MASK |
2940 PORT_PLL_GAIN_CTL_MASK;
2941
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302942 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002943 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2944
Imre Deak05712c12015-06-18 17:25:54 +03002945 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2946 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2947
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302948 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002949 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2950 PORT_PLL_DCO_AMP_MASK;
2951
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302952 /*
2953 * While we write to the group register to program all lanes at once we
2954 * can read only lane registers. We configure all lanes the same way, so
2955 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2956 */
2957 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002958 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302959 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2960 hw_state->pcsdw12,
2961 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002962 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302963
2964 return true;
2965}
2966
2967static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2968{
2969 int i;
2970
2971 dev_priv->num_shared_dpll = 3;
2972
2973 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2974 dev_priv->shared_dplls[i].id = i;
2975 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2976 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2977 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2978 dev_priv->shared_dplls[i].get_hw_state =
2979 bxt_ddi_pll_get_hw_state;
2980 }
2981}
2982
Damien Lespiau143b3072014-07-29 18:06:19 +01002983void intel_ddi_pll_init(struct drm_device *dev)
2984{
2985 struct drm_i915_private *dev_priv = dev->dev_private;
2986 uint32_t val = I915_READ(LCPLL_CTL);
2987
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002988 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002989 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302990 else if (IS_BROXTON(dev))
2991 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002992 else
2993 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002994
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002995 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002996 int cdclk_freq;
2997
2998 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002999 dev_priv->skl_boot_cdclk = cdclk_freq;
Shobhit Kumarc73666f2015-10-20 18:13:12 +05303000 if (skl_sanitize_cdclk(dev_priv))
3001 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
Damien Lespiau2f693e22015-11-04 19:24:12 +02003002 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
3003 DRM_ERROR("LCPLL1 is disabled\n");
Vandana Kannanf8437dd12014-11-24 13:37:39 +05303004 } else if (IS_BROXTON(dev)) {
3005 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05303006 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003007 } else {
3008 /*
3009 * The LCPLL register should be turned on by the BIOS. For now
3010 * let's just check its state and print errors in case
3011 * something is wrong. Don't even try to turn it on.
3012 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003013
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003014 if (val & LCPLL_CD_SOURCE_FCLK)
3015 DRM_ERROR("CDCLK source is not LCPLL\n");
3016
3017 if (val & LCPLL_PLL_DISABLE)
3018 DRM_ERROR("LCPLL is disabled\n");
3019 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003020}
Paulo Zanonic19b0662012-10-15 15:51:41 -03003021
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003022void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
Paulo Zanonic19b0662012-10-15 15:51:41 -03003023{
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003024 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3025 struct drm_i915_private *dev_priv =
3026 to_i915(intel_dig_port->base.base.dev);
Paulo Zanoni174edf12012-10-26 19:05:50 -02003027 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003028 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05303029 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003030
3031 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
3032 val = I915_READ(DDI_BUF_CTL(port));
3033 if (val & DDI_BUF_CTL_ENABLE) {
3034 val &= ~DDI_BUF_CTL_ENABLE;
3035 I915_WRITE(DDI_BUF_CTL(port), val);
3036 wait = true;
3037 }
3038
3039 val = I915_READ(DP_TP_CTL(port));
3040 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3041 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3042 I915_WRITE(DP_TP_CTL(port), val);
3043 POSTING_READ(DP_TP_CTL(port));
3044
3045 if (wait)
3046 intel_wait_ddi_buf_idle(dev_priv, port);
3047 }
3048
Dave Airlie0e32b392014-05-02 14:02:48 +10003049 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003050 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003051 if (intel_dp->is_mst)
3052 val |= DP_TP_CTL_MODE_MST;
3053 else {
3054 val |= DP_TP_CTL_MODE_SST;
3055 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3056 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3057 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003058 I915_WRITE(DP_TP_CTL(port), val);
3059 POSTING_READ(DP_TP_CTL(port));
3060
3061 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3062 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3063 POSTING_READ(DDI_BUF_CTL(port));
3064
3065 udelay(600);
3066}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003067
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003068void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3069{
3070 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3071 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3072 uint32_t val;
3073
3074 intel_ddi_post_disable(intel_encoder);
3075
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003076 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003077 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003078 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003079
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003080 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003081 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3082 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003083 I915_WRITE(FDI_RX_MISC(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003084
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003085 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003086 val &= ~FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003087 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003088
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003089 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003090 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003091 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003092}
3093
Libin Yang3d52ccf2015-12-02 14:09:44 +08003094bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
3095 struct intel_crtc *intel_crtc)
3096{
3097 u32 temp;
3098
3099 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
3100 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
3101 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
3102 return true;
3103 }
3104 return false;
3105}
3106
Ville Syrjälä6801c182013-09-24 14:24:05 +03003107void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003108 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003109{
3110 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3111 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003112 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003113 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003114 u32 temp, flags = 0;
3115
3116 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3117 if (temp & TRANS_DDI_PHSYNC)
3118 flags |= DRM_MODE_FLAG_PHSYNC;
3119 else
3120 flags |= DRM_MODE_FLAG_NHSYNC;
3121 if (temp & TRANS_DDI_PVSYNC)
3122 flags |= DRM_MODE_FLAG_PVSYNC;
3123 else
3124 flags |= DRM_MODE_FLAG_NVSYNC;
3125
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003126 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003127
3128 switch (temp & TRANS_DDI_BPC_MASK) {
3129 case TRANS_DDI_BPC_6:
3130 pipe_config->pipe_bpp = 18;
3131 break;
3132 case TRANS_DDI_BPC_8:
3133 pipe_config->pipe_bpp = 24;
3134 break;
3135 case TRANS_DDI_BPC_10:
3136 pipe_config->pipe_bpp = 30;
3137 break;
3138 case TRANS_DDI_BPC_12:
3139 pipe_config->pipe_bpp = 36;
3140 break;
3141 default:
3142 break;
3143 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003144
3145 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3146 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003147 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003148 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3149
Ville Syrjäläcda0aaa2015-11-26 18:27:07 +02003150 if (intel_hdmi->infoframe_enabled(&encoder->base, pipe_config))
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003151 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003152 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003153 case TRANS_DDI_MODE_SELECT_DVI:
3154 case TRANS_DDI_MODE_SELECT_FDI:
3155 break;
3156 case TRANS_DDI_MODE_SELECT_DP_SST:
3157 case TRANS_DDI_MODE_SELECT_DP_MST:
3158 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003159 pipe_config->lane_count =
3160 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003161 intel_dp_get_m_n(intel_crtc, pipe_config);
3162 break;
3163 default:
3164 break;
3165 }
Daniel Vetter10214422013-11-18 07:38:16 +01003166
Libin Yang3d52ccf2015-12-02 14:09:44 +08003167 pipe_config->has_audio =
3168 intel_ddi_is_audio_enabled(dev_priv, intel_crtc);
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003169
Daniel Vetter10214422013-11-18 07:38:16 +01003170 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3171 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3172 /*
3173 * This is a big fat ugly hack.
3174 *
3175 * Some machines in UEFI boot mode provide us a VBT that has 18
3176 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3177 * unknown we fail to light up. Yet the same BIOS boots up with
3178 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3179 * max, not what it tells us to use.
3180 *
3181 * Note: This will still be broken if the eDP panel is not lit
3182 * up by the BIOS, and thus we can't get the mode at module
3183 * load.
3184 */
3185 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3186 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3187 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3188 }
Jesse Barnes11578552014-01-21 12:42:10 -08003189
Damien Lespiau22606a12014-12-12 14:26:57 +00003190 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003191}
3192
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003193static void intel_ddi_destroy(struct drm_encoder *encoder)
3194{
3195 /* HDMI has nothing special to destroy, so we can go with this. */
3196 intel_dp_encoder_destroy(encoder);
3197}
3198
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003199static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003200 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003201{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003202 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003203 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003204
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003205 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003206
Daniel Vettereccb1402013-05-22 00:50:22 +02003207 if (port == PORT_A)
3208 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3209
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003210 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003211 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003212 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003213 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003214}
3215
3216static const struct drm_encoder_funcs intel_ddi_funcs = {
3217 .destroy = intel_ddi_destroy,
3218};
3219
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003220static struct intel_connector *
3221intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3222{
3223 struct intel_connector *connector;
3224 enum port port = intel_dig_port->port;
3225
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003226 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003227 if (!connector)
3228 return NULL;
3229
3230 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3231 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3232 kfree(connector);
3233 return NULL;
3234 }
3235
3236 return connector;
3237}
3238
3239static struct intel_connector *
3240intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3241{
3242 struct intel_connector *connector;
3243 enum port port = intel_dig_port->port;
3244
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003245 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003246 if (!connector)
3247 return NULL;
3248
3249 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3250 intel_hdmi_init_connector(intel_dig_port, connector);
3251
3252 return connector;
3253}
3254
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003255void intel_ddi_init(struct drm_device *dev, enum port port)
3256{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003257 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003258 struct intel_digital_port *intel_dig_port;
3259 struct intel_encoder *intel_encoder;
3260 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003261 bool init_hdmi, init_dp;
Ville Syrjälä10e7bec2015-12-08 19:59:37 +02003262 int max_lanes;
3263
3264 if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
3265 switch (port) {
3266 case PORT_A:
3267 max_lanes = 4;
3268 break;
3269 case PORT_E:
3270 max_lanes = 0;
3271 break;
3272 default:
3273 max_lanes = 4;
3274 break;
3275 }
3276 } else {
3277 switch (port) {
3278 case PORT_A:
3279 max_lanes = 2;
3280 break;
3281 case PORT_E:
3282 max_lanes = 2;
3283 break;
3284 default:
3285 max_lanes = 4;
3286 break;
3287 }
3288 }
Paulo Zanoni311a2092013-09-12 17:12:18 -03003289
3290 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3291 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3292 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3293 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003294 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003295 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003296 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003297 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003298
Daniel Vetterb14c5672013-09-19 12:18:32 +02003299 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003300 if (!intel_dig_port)
3301 return;
3302
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003303 intel_encoder = &intel_dig_port->base;
3304 encoder = &intel_encoder->base;
3305
3306 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3307 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003308
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003309 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003310 intel_encoder->enable = intel_enable_ddi;
3311 intel_encoder->pre_enable = intel_ddi_pre_enable;
3312 intel_encoder->disable = intel_disable_ddi;
3313 intel_encoder->post_disable = intel_ddi_post_disable;
3314 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003315 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003316
3317 intel_dig_port->port = port;
Takashi Iwai0bdf5a02015-11-30 18:19:39 +01003318 dev_priv->dig_port_map[port] = intel_encoder;
Stéphane Marchesinbcf53de42013-07-12 13:54:41 -07003319 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3320 (DDI_BUF_PORT_REVERSAL |
3321 DDI_A_4_LANES);
Ville Syrjäläccb1a832015-12-08 19:59:38 +02003322 intel_dig_port->max_lanes = max_lanes;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003323
Matt Roper6c566dc2015-11-05 14:53:32 -08003324 /*
3325 * Bspec says that DDI_A_4_LANES is the only supported configuration
3326 * for Broxton. Yet some BIOS fail to set this bit on port A if eDP
3327 * wasn't lit up at boot. Force this bit on in our internal
3328 * configuration so that we use the proper lane count for our
3329 * calculations.
3330 */
3331 if (IS_BROXTON(dev) && port == PORT_A) {
3332 if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) {
3333 DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
3334 intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
3335 }
3336 }
3337
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003338 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003339 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003340 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003341
Chris Wilsonf68d6972014-08-04 07:15:09 +01003342 if (init_dp) {
3343 if (!intel_ddi_init_dp_connector(intel_dig_port))
3344 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003345
Chris Wilsonf68d6972014-08-04 07:15:09 +01003346 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303347 /*
3348 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3349 * interrupts to check the external panel connection.
3350 */
Jani Nikulae87a0052015-10-20 15:22:02 +03003351 if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303352 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3353 else
3354 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003355 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003356
Paulo Zanoni311a2092013-09-12 17:12:18 -03003357 /* In theory we don't need the encoder->type check, but leave it just in
3358 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003359 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3360 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3361 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003362 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003363
3364 return;
3365
3366err:
3367 drm_encoder_cleanup(encoder);
3368 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003369}