blob: 3edb10a4f0b4d1182f00369483bf2d59cc31e243 [file] [log] [blame]
Eugeni Dodonov45244b82012-05-09 15:37:20 -03001/*
2 * Copyright © 2012 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eugeni Dodonov <eugeni.dodonov@intel.com>
25 *
26 */
27
28#include "i915_drv.h"
29#include "intel_drv.h"
30
Jani Nikula10122052014-08-27 16:27:30 +030031struct ddi_buf_trans {
32 u32 trans1; /* balance leg enable, de-emph level */
33 u32 trans2; /* vref sel, vswing */
David Weinehallf8896f52015-06-25 11:11:03 +030034 u8 i_boost; /* SKL: I_boost; valid: 0x0, 0x1, 0x3, 0x7 */
Jani Nikula10122052014-08-27 16:27:30 +030035};
36
Eugeni Dodonov45244b82012-05-09 15:37:20 -030037/* HDMI/DVI modes ignore everything but the last 2 items. So we share
38 * them for both DP and FDI transports, allowing those ports to
39 * automatically adapt to HDMI connections as well
40 */
Jani Nikula10122052014-08-27 16:27:30 +030041static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030042 { 0x00FFFFFF, 0x0006000E, 0x0 },
43 { 0x00D75FFF, 0x0005000A, 0x0 },
44 { 0x00C30FFF, 0x00040006, 0x0 },
45 { 0x80AAAFFF, 0x000B0000, 0x0 },
46 { 0x00FFFFFF, 0x0005000A, 0x0 },
47 { 0x00D75FFF, 0x000C0004, 0x0 },
48 { 0x80C30FFF, 0x000B0000, 0x0 },
49 { 0x00FFFFFF, 0x00040006, 0x0 },
50 { 0x80D75FFF, 0x000B0000, 0x0 },
Eugeni Dodonov45244b82012-05-09 15:37:20 -030051};
52
Jani Nikula10122052014-08-27 16:27:30 +030053static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030054 { 0x00FFFFFF, 0x0007000E, 0x0 },
55 { 0x00D75FFF, 0x000F000A, 0x0 },
56 { 0x00C30FFF, 0x00060006, 0x0 },
57 { 0x00AAAFFF, 0x001E0000, 0x0 },
58 { 0x00FFFFFF, 0x000F000A, 0x0 },
59 { 0x00D75FFF, 0x00160004, 0x0 },
60 { 0x00C30FFF, 0x001E0000, 0x0 },
61 { 0x00FFFFFF, 0x00060006, 0x0 },
62 { 0x00D75FFF, 0x001E0000, 0x0 },
Paulo Zanoni6acab152013-09-12 17:06:24 -030063};
64
Jani Nikula10122052014-08-27 16:27:30 +030065static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
66 /* Idx NT mV d T mV d db */
David Weinehallf8896f52015-06-25 11:11:03 +030067 { 0x00FFFFFF, 0x0006000E, 0x0 },/* 0: 400 400 0 */
68 { 0x00E79FFF, 0x000E000C, 0x0 },/* 1: 400 500 2 */
69 { 0x00D75FFF, 0x0005000A, 0x0 },/* 2: 400 600 3.5 */
70 { 0x00FFFFFF, 0x0005000A, 0x0 },/* 3: 600 600 0 */
71 { 0x00E79FFF, 0x001D0007, 0x0 },/* 4: 600 750 2 */
72 { 0x00D75FFF, 0x000C0004, 0x0 },/* 5: 600 900 3.5 */
73 { 0x00FFFFFF, 0x00040006, 0x0 },/* 6: 800 800 0 */
74 { 0x80E79FFF, 0x00030002, 0x0 },/* 7: 800 1000 2 */
75 { 0x00FFFFFF, 0x00140005, 0x0 },/* 8: 850 850 0 */
76 { 0x00FFFFFF, 0x000C0004, 0x0 },/* 9: 900 900 0 */
77 { 0x00FFFFFF, 0x001C0003, 0x0 },/* 10: 950 950 0 */
78 { 0x80FFFFFF, 0x00030002, 0x0 },/* 11: 1000 1000 0 */
Eugeni Dodonov45244b82012-05-09 15:37:20 -030079};
80
Jani Nikula10122052014-08-27 16:27:30 +030081static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030082 { 0x00FFFFFF, 0x00000012, 0x0 },
83 { 0x00EBAFFF, 0x00020011, 0x0 },
84 { 0x00C71FFF, 0x0006000F, 0x0 },
85 { 0x00AAAFFF, 0x000E000A, 0x0 },
86 { 0x00FFFFFF, 0x00020011, 0x0 },
87 { 0x00DB6FFF, 0x0005000F, 0x0 },
88 { 0x00BEEFFF, 0x000A000C, 0x0 },
89 { 0x00FFFFFF, 0x0005000F, 0x0 },
90 { 0x00DB6FFF, 0x000A000C, 0x0 },
Paulo Zanoni300644c2013-11-02 21:07:42 -070091};
92
Jani Nikula10122052014-08-27 16:27:30 +030093static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030094 { 0x00FFFFFF, 0x0007000E, 0x0 },
95 { 0x00D75FFF, 0x000E000A, 0x0 },
96 { 0x00BEFFFF, 0x00140006, 0x0 },
97 { 0x80B2CFFF, 0x001B0002, 0x0 },
98 { 0x00FFFFFF, 0x000E000A, 0x0 },
99 { 0x00DB6FFF, 0x00160005, 0x0 },
100 { 0x80C71FFF, 0x001A0002, 0x0 },
101 { 0x00F7DFFF, 0x00180004, 0x0 },
102 { 0x80D75FFF, 0x001B0002, 0x0 },
Art Runyane58623c2013-11-02 21:07:41 -0700103};
104
Jani Nikula10122052014-08-27 16:27:30 +0300105static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300106 { 0x00FFFFFF, 0x0001000E, 0x0 },
107 { 0x00D75FFF, 0x0004000A, 0x0 },
108 { 0x00C30FFF, 0x00070006, 0x0 },
109 { 0x00AAAFFF, 0x000C0000, 0x0 },
110 { 0x00FFFFFF, 0x0004000A, 0x0 },
111 { 0x00D75FFF, 0x00090004, 0x0 },
112 { 0x00C30FFF, 0x000C0000, 0x0 },
113 { 0x00FFFFFF, 0x00070006, 0x0 },
114 { 0x00D75FFF, 0x000C0000, 0x0 },
Art Runyane58623c2013-11-02 21:07:41 -0700115};
116
Jani Nikula10122052014-08-27 16:27:30 +0300117static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
118 /* Idx NT mV d T mV df db */
David Weinehallf8896f52015-06-25 11:11:03 +0300119 { 0x00FFFFFF, 0x0007000E, 0x0 },/* 0: 400 400 0 */
120 { 0x00D75FFF, 0x000E000A, 0x0 },/* 1: 400 600 3.5 */
121 { 0x00BEFFFF, 0x00140006, 0x0 },/* 2: 400 800 6 */
122 { 0x00FFFFFF, 0x0009000D, 0x0 },/* 3: 450 450 0 */
123 { 0x00FFFFFF, 0x000E000A, 0x0 },/* 4: 600 600 0 */
124 { 0x00D7FFFF, 0x00140006, 0x0 },/* 5: 600 800 2.5 */
125 { 0x80CB2FFF, 0x001B0002, 0x0 },/* 6: 600 1000 4.5 */
126 { 0x00FFFFFF, 0x00140006, 0x0 },/* 7: 800 800 0 */
127 { 0x80E79FFF, 0x001B0002, 0x0 },/* 8: 800 1000 2 */
128 { 0x80FFFFFF, 0x001B0002, 0x0 },/* 9: 1000 1000 0 */
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100129};
130
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700131/* Skylake H and S */
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000132static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300133 { 0x00002016, 0x000000A0, 0x0 },
134 { 0x00005012, 0x0000009B, 0x0 },
135 { 0x00007011, 0x00000088, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800136 { 0x80009010, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300137 { 0x00002016, 0x0000009B, 0x0 },
138 { 0x00005012, 0x00000088, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800139 { 0x80007011, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300140 { 0x00002016, 0x000000DF, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800141 { 0x80005012, 0x000000C0, 0x1 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000142};
143
David Weinehallf8896f52015-06-25 11:11:03 +0300144/* Skylake U */
145static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700146 { 0x0000201B, 0x000000A2, 0x0 },
David Weinehallf8896f52015-06-25 11:11:03 +0300147 { 0x00005012, 0x00000088, 0x0 },
Rodrigo Vivi63ebce12016-01-05 07:58:31 -0800148 { 0x80007011, 0x000000CD, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800149 { 0x80009010, 0x000000C0, 0x1 },
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700150 { 0x0000201B, 0x0000009D, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800151 { 0x80005012, 0x000000C0, 0x1 },
152 { 0x80007011, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300153 { 0x00002016, 0x00000088, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800154 { 0x80005012, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300155};
156
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700157/* Skylake Y */
158static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300159 { 0x00000018, 0x000000A2, 0x0 },
160 { 0x00005012, 0x00000088, 0x0 },
Rodrigo Vivi63ebce12016-01-05 07:58:31 -0800161 { 0x80007011, 0x000000CD, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800162 { 0x80009010, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300163 { 0x00000018, 0x0000009D, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800164 { 0x80005012, 0x000000C0, 0x3 },
165 { 0x80007011, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300166 { 0x00000018, 0x00000088, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800167 { 0x80005012, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300168};
169
170/*
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700171 * Skylake H and S
David Weinehallf8896f52015-06-25 11:11:03 +0300172 * eDP 1.4 low vswing translation parameters
173 */
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530174static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300175 { 0x00000018, 0x000000A8, 0x0 },
176 { 0x00004013, 0x000000A9, 0x0 },
177 { 0x00007011, 0x000000A2, 0x0 },
178 { 0x00009010, 0x0000009C, 0x0 },
179 { 0x00000018, 0x000000A9, 0x0 },
180 { 0x00006013, 0x000000A2, 0x0 },
181 { 0x00007011, 0x000000A6, 0x0 },
182 { 0x00000018, 0x000000AB, 0x0 },
183 { 0x00007013, 0x0000009F, 0x0 },
184 { 0x00000018, 0x000000DF, 0x0 },
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530185};
186
David Weinehallf8896f52015-06-25 11:11:03 +0300187/*
188 * Skylake U
189 * eDP 1.4 low vswing translation parameters
190 */
191static const struct ddi_buf_trans skl_u_ddi_translations_edp[] = {
192 { 0x00000018, 0x000000A8, 0x0 },
193 { 0x00004013, 0x000000A9, 0x0 },
194 { 0x00007011, 0x000000A2, 0x0 },
195 { 0x00009010, 0x0000009C, 0x0 },
196 { 0x00000018, 0x000000A9, 0x0 },
197 { 0x00006013, 0x000000A2, 0x0 },
198 { 0x00007011, 0x000000A6, 0x0 },
199 { 0x00002016, 0x000000AB, 0x0 },
200 { 0x00005013, 0x0000009F, 0x0 },
201 { 0x00000018, 0x000000DF, 0x0 },
202};
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530203
David Weinehallf8896f52015-06-25 11:11:03 +0300204/*
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700205 * Skylake Y
David Weinehallf8896f52015-06-25 11:11:03 +0300206 * eDP 1.4 low vswing translation parameters
207 */
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700208static const struct ddi_buf_trans skl_y_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300209 { 0x00000018, 0x000000A8, 0x0 },
210 { 0x00004013, 0x000000AB, 0x0 },
211 { 0x00007011, 0x000000A4, 0x0 },
212 { 0x00009010, 0x000000DF, 0x0 },
213 { 0x00000018, 0x000000AA, 0x0 },
214 { 0x00006013, 0x000000A4, 0x0 },
215 { 0x00007011, 0x0000009D, 0x0 },
216 { 0x00000018, 0x000000A0, 0x0 },
217 { 0x00006012, 0x000000DF, 0x0 },
218 { 0x00000018, 0x0000008A, 0x0 },
219};
220
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700221/* Skylake U, H and S */
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000222static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300223 { 0x00000018, 0x000000AC, 0x0 },
224 { 0x00005012, 0x0000009D, 0x0 },
225 { 0x00007011, 0x00000088, 0x0 },
226 { 0x00000018, 0x000000A1, 0x0 },
227 { 0x00000018, 0x00000098, 0x0 },
228 { 0x00004013, 0x00000088, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800229 { 0x80006012, 0x000000CD, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300230 { 0x00000018, 0x000000DF, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800231 { 0x80003015, 0x000000CD, 0x1 }, /* Default */
232 { 0x80003015, 0x000000C0, 0x1 },
233 { 0x80000018, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300234};
235
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700236/* Skylake Y */
237static const struct ddi_buf_trans skl_y_ddi_translations_hdmi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300238 { 0x00000018, 0x000000A1, 0x0 },
239 { 0x00005012, 0x000000DF, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800240 { 0x80007011, 0x000000CB, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300241 { 0x00000018, 0x000000A4, 0x0 },
242 { 0x00000018, 0x0000009D, 0x0 },
243 { 0x00004013, 0x00000080, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800244 { 0x80006013, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300245 { 0x00000018, 0x0000008A, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800246 { 0x80003015, 0x000000C0, 0x3 }, /* Default */
247 { 0x80003015, 0x000000C0, 0x3 },
248 { 0x80000018, 0x000000C0, 0x3 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000249};
250
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530251struct bxt_ddi_buf_trans {
252 u32 margin; /* swing value */
253 u32 scale; /* scale value */
254 u32 enable; /* scale enable */
255 u32 deemphasis;
256 bool default_index; /* true if the entry represents default value */
257};
258
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530259static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
260 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300261 { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */
262 { 78, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
263 { 104, 0x9A, 0, 64, false }, /* 2: 400 6 */
264 { 154, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
265 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
266 { 116, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
267 { 154, 0x9A, 0, 64, false }, /* 6: 600 6 */
268 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
269 { 154, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
David Weinehallf8896f52015-06-25 11:11:03 +0300270 { 154, 0x9A, 1, 128, false }, /* 9: 1200 0 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530271};
272
Sonika Jindald9d70002015-09-24 10:24:56 +0530273static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = {
274 /* Idx NT mV diff db */
275 { 26, 0, 0, 128, false }, /* 0: 200 0 */
276 { 38, 0, 0, 112, false }, /* 1: 200 1.5 */
277 { 48, 0, 0, 96, false }, /* 2: 200 4 */
278 { 54, 0, 0, 69, false }, /* 3: 200 6 */
279 { 32, 0, 0, 128, false }, /* 4: 250 0 */
280 { 48, 0, 0, 104, false }, /* 5: 250 1.5 */
281 { 54, 0, 0, 85, false }, /* 6: 250 4 */
282 { 43, 0, 0, 128, false }, /* 7: 300 0 */
283 { 54, 0, 0, 101, false }, /* 8: 300 1.5 */
284 { 48, 0, 0, 128, false }, /* 9: 300 0 */
285};
286
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530287/* BSpec has 2 recommended values - entries 0 and 8.
288 * Using the entry with higher vswing.
289 */
290static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
291 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300292 { 52, 0x9A, 0, 128, false }, /* 0: 400 0 */
293 { 52, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
294 { 52, 0x9A, 0, 64, false }, /* 2: 400 6 */
295 { 42, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
296 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
297 { 77, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
298 { 77, 0x9A, 0, 64, false }, /* 6: 600 6 */
299 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
300 { 102, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530301 { 154, 0x9A, 1, 128, true }, /* 9: 1200 0 */
302};
303
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200304static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
305 u32 level, enum port port, int type);
David Weinehallf8896f52015-06-25 11:11:03 +0300306
Imre Deaka1e6ad62015-04-17 19:31:21 +0300307static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
308 struct intel_digital_port **dig_port,
309 enum port *port)
Paulo Zanonifc914632012-10-05 12:05:54 -0300310{
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300311 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonifc914632012-10-05 12:05:54 -0300312
Jani Nikula8cd21b72015-09-29 10:24:26 +0300313 switch (intel_encoder->type) {
314 case INTEL_OUTPUT_DP_MST:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300315 *dig_port = enc_to_mst(encoder)->primary;
316 *port = (*dig_port)->port;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300317 break;
318 case INTEL_OUTPUT_DISPLAYPORT:
319 case INTEL_OUTPUT_EDP:
320 case INTEL_OUTPUT_HDMI:
321 case INTEL_OUTPUT_UNKNOWN:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300322 *dig_port = enc_to_dig_port(encoder);
323 *port = (*dig_port)->port;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300324 break;
325 case INTEL_OUTPUT_ANALOG:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300326 *dig_port = NULL;
327 *port = PORT_E;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300328 break;
329 default:
330 WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
331 break;
Paulo Zanonifc914632012-10-05 12:05:54 -0300332 }
333}
334
Imre Deaka1e6ad62015-04-17 19:31:21 +0300335enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
336{
337 struct intel_digital_port *dig_port;
338 enum port port;
339
340 ddi_get_encoder_port(intel_encoder, &dig_port, &port);
341
342 return port;
343}
344
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 *
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200352skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
David Weinehallf8896f52015-06-25 11:11:03 +0300353{
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200354 if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
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;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200357 } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) {
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ä78ab0ba2015-12-08 19:59:41 +0200367skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
David Weinehallf8896f52015-06-25 11:11:03 +0300368{
Ville Syrjäläcd1101c2015-12-08 19:59:40 +0200369 if (dev_priv->edp_low_vswing) {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200370 if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200371 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
372 return skl_y_ddi_translations_edp;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200373 } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200374 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
375 return skl_u_ddi_translations_edp;
376 } else {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200377 *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
378 return skl_ddi_translations_edp;
Ville Syrjäläacee2992015-12-08 19:59:39 +0200379 }
David Weinehallf8896f52015-06-25 11:11:03 +0300380 }
Ville Syrjäläcd1101c2015-12-08 19:59:40 +0200381
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200382 return skl_get_buf_trans_dp(dev_priv, n_entries);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200383}
David Weinehallf8896f52015-06-25 11:11:03 +0300384
Ville Syrjäläacee2992015-12-08 19:59:39 +0200385static const struct ddi_buf_trans *
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200386skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
Ville Syrjäläacee2992015-12-08 19:59:39 +0200387{
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200388 if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200389 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
390 return skl_y_ddi_translations_hdmi;
391 } else {
392 *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
393 return skl_ddi_translations_hdmi;
394 }
David Weinehallf8896f52015-06-25 11:11:03 +0300395}
396
Art Runyane58623c2013-11-02 21:07:41 -0700397/*
398 * Starting with Haswell, DDI port buffers must be programmed with correct
399 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300400 * but the HDMI/DVI fields are shared among those. So we program the DDI
401 * in either FDI or DP modes only, as HDMI connections will work with both
402 * of those
403 */
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200404static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv,
405 enum port port, bool supports_hdmi)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300406{
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300407 u32 iboost_bit = 0;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000408 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530409 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300410 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300411 const struct ddi_buf_trans *ddi_translations_fdi;
412 const struct ddi_buf_trans *ddi_translations_dp;
413 const struct ddi_buf_trans *ddi_translations_edp;
414 const struct ddi_buf_trans *ddi_translations_hdmi;
415 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700416
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200417 if (IS_BROXTON(dev_priv)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300418 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530419 return;
420
421 /* Vswing programming for HDMI */
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200422 bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530423 INTEL_OUTPUT_HDMI);
424 return;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200425 } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300426 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300427 ddi_translations_dp =
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200428 skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
David Weinehallf8896f52015-06-25 11:11:03 +0300429 ddi_translations_edp =
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200430 skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
David Weinehallf8896f52015-06-25 11:11:03 +0300431 ddi_translations_hdmi =
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200432 skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
David Weinehallf8896f52015-06-25 11:11:03 +0300433 hdmi_default_entry = 8;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300434 /* If we're boosting the current, set bit 31 of trans1 */
435 if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
436 dev_priv->vbt.ddi_port_info[port].dp_boost_level)
437 iboost_bit = 1<<31;
Ville Syrjälä10afa0b2015-12-08 19:59:43 +0200438
439 if (WARN_ON(port != PORT_A &&
440 port != PORT_E && n_edp_entries > 9))
441 n_edp_entries = 9;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200442 } else if (IS_BROADWELL(dev_priv)) {
Art Runyane58623c2013-11-02 21:07:41 -0700443 ddi_translations_fdi = bdw_ddi_translations_fdi;
444 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700445 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100446 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530447 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
448 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300449 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000450 hdmi_default_entry = 7;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200451 } else if (IS_HASWELL(dev_priv)) {
Art Runyane58623c2013-11-02 21:07:41 -0700452 ddi_translations_fdi = hsw_ddi_translations_fdi;
453 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700454 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100455 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530456 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300457 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000458 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700459 } else {
460 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700461 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700462 ddi_translations_fdi = bdw_ddi_translations_fdi;
463 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100464 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530465 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
466 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300467 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000468 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700469 }
470
Paulo Zanoni300644c2013-11-02 21:07:42 -0700471 switch (port) {
472 case PORT_A:
473 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530474 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700475 break;
476 case PORT_B:
477 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700478 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530479 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700480 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700481 case PORT_D:
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200482 if (intel_dp_is_edp(dev_priv->dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700483 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530484 size = n_edp_entries;
485 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700486 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530487 size = n_dp_entries;
488 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700489 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700490 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000491 if (ddi_translations_fdi)
492 ddi_translations = ddi_translations_fdi;
493 else
494 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530495 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700496 break;
497 default:
498 BUG();
499 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300500
Ville Syrjälä9712e682015-09-18 20:03:22 +0300501 for (i = 0; i < size; i++) {
502 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
503 ddi_translations[i].trans1 | iboost_bit);
504 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
505 ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300506 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100507
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300508 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100509 return;
510
Damien Lespiauce4dd492014-08-01 11:07:54 +0100511 /* Choose a good default if VBT is badly populated */
512 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
513 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000514 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100515
Paulo Zanoni6acab152013-09-12 17:06:24 -0300516 /* Entry 9 is for HDMI: */
Ville Syrjälä9712e682015-09-18 20:03:22 +0300517 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
518 ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
519 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
520 ddi_translations_hdmi[hdmi_level].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300521}
522
523/* Program DDI buffers translations for DP. By default, program ports A-D in DP
524 * mode and port E for FDI.
525 */
526void intel_prepare_ddi(struct drm_device *dev)
527{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300528 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100529 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300530
Paulo Zanoni0d536cb42012-11-23 16:46:41 -0200531 if (!HAS_DDI(dev))
532 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300533
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300534 for_each_intel_encoder(dev, intel_encoder) {
535 struct intel_digital_port *intel_dig_port;
536 enum port port;
537 bool supports_hdmi;
538
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530539 if (intel_encoder->type == INTEL_OUTPUT_DSI)
540 continue;
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300541
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530542 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300543 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100544 continue;
545
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300546 supports_hdmi = intel_dig_port &&
547 intel_dig_port_supports_hdmi(intel_dig_port);
548
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200549 intel_prepare_ddi_buffers(to_i915(dev), port, supports_hdmi);
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300550 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100551 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300552}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300553
Paulo Zanoni248138b2012-11-29 11:29:31 -0200554static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
555 enum port port)
556{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200557 i915_reg_t reg = DDI_BUF_CTL(port);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200558 int i;
559
Vandana Kannan3449ca82015-03-27 14:19:09 +0200560 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200561 udelay(1);
562 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
563 return;
564 }
565 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
566}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300567
568/* Starting with Haswell, different DDI ports can work in FDI mode for
569 * connection to the PCH-located connectors. For this, it is necessary to train
570 * both the DDI port and PCH receiver for the desired DDI buffer settings.
571 *
572 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
573 * please note that when FDI mode is active on DDI E, it shares 2 lines with
574 * DDI A (which is used for eDP)
575 */
576
577void hsw_fdi_link_train(struct drm_crtc *crtc)
578{
579 struct drm_device *dev = crtc->dev;
580 struct drm_i915_private *dev_priv = dev->dev_private;
581 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200582 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300583
Paulo Zanoni04945642012-11-01 21:00:59 -0200584 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
585 * mode set "sequence for CRT port" document:
586 * - TP1 to TP2 time with the default value
587 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100588 *
589 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200590 */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300591 I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) |
Paulo Zanoni04945642012-11-01 21:00:59 -0200592 FDI_RX_PWRDN_LANE0_VAL(2) |
593 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
594
595 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000596 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100597 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200598 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300599 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
600 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200601 udelay(220);
602
603 /* Switch from Rawclk to PCDclk */
604 rx_ctl_val |= FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300605 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
Paulo Zanoni04945642012-11-01 21:00:59 -0200606
607 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200608 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
609 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200610
611 /* Start the training iterating through available voltages and emphasis,
612 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300613 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300614 /* Configure DP_TP_CTL with auto-training */
615 I915_WRITE(DP_TP_CTL(PORT_E),
616 DP_TP_CTL_FDI_AUTOTRAIN |
617 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
618 DP_TP_CTL_LINK_TRAIN_PAT1 |
619 DP_TP_CTL_ENABLE);
620
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000621 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
622 * DDI E does not support port reversal, the functionality is
623 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
624 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300625 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200626 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200627 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530628 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200629 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300630
631 udelay(600);
632
Paulo Zanoni04945642012-11-01 21:00:59 -0200633 /* Program PCH FDI Receiver TU */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300634 I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300635
Paulo Zanoni04945642012-11-01 21:00:59 -0200636 /* Enable PCH FDI Receiver with auto-training */
637 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300638 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
639 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200640
641 /* Wait for FDI receiver lane calibration */
642 udelay(30);
643
644 /* Unset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300645 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200646 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300647 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
648 POSTING_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200649
650 /* Wait for FDI auto training time */
651 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300652
653 temp = I915_READ(DP_TP_STATUS(PORT_E));
654 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200655 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200656 break;
657 }
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300658
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200659 /*
660 * Leave things enabled even if we failed to train FDI.
661 * Results in less fireworks from the state checker.
662 */
663 if (i == ARRAY_SIZE(hsw_ddi_translations_fdi) * 2 - 1) {
664 DRM_ERROR("FDI link training failed!\n");
665 break;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300666 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200667
Paulo Zanoni248138b2012-11-29 11:29:31 -0200668 temp = I915_READ(DDI_BUF_CTL(PORT_E));
669 temp &= ~DDI_BUF_CTL_ENABLE;
670 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
671 POSTING_READ(DDI_BUF_CTL(PORT_E));
672
Paulo Zanoni04945642012-11-01 21:00:59 -0200673 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200674 temp = I915_READ(DP_TP_CTL(PORT_E));
675 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
676 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
677 I915_WRITE(DP_TP_CTL(PORT_E), temp);
678 POSTING_READ(DP_TP_CTL(PORT_E));
679
680 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200681
682 rx_ctl_val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300683 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
684 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200685
686 /* Reset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300687 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200688 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
689 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300690 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
691 POSTING_READ(FDI_RX_MISC(PIPE_A));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300692 }
693
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200694 /* Enable normal pixel sending for FDI */
695 I915_WRITE(DP_TP_CTL(PORT_E),
696 DP_TP_CTL_FDI_AUTOTRAIN |
697 DP_TP_CTL_LINK_TRAIN_NORMAL |
698 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
699 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300700}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300701
Dave Airlie44905a272014-05-02 13:36:43 +1000702void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
703{
704 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
705 struct intel_digital_port *intel_dig_port =
706 enc_to_dig_port(&encoder->base);
707
708 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530709 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300710 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a272014-05-02 13:36:43 +1000711}
712
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300713static struct intel_encoder *
714intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
715{
716 struct drm_device *dev = crtc->dev;
717 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
718 struct intel_encoder *intel_encoder, *ret = NULL;
719 int num_encoders = 0;
720
721 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
722 ret = intel_encoder;
723 num_encoders++;
724 }
725
726 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300727 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
728 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300729
730 BUG_ON(ret == NULL);
731 return ret;
732}
733
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530734struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200735intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200736{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200737 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
738 struct intel_encoder *ret = NULL;
739 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300740 struct drm_connector *connector;
741 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200742 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200743 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200744
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200745 state = crtc_state->base.state;
746
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300747 for_each_connector_in_state(state, connector, connector_state, i) {
748 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200749 continue;
750
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300751 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200752 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200753 }
754
755 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
756 pipe_name(crtc->pipe));
757
758 BUG_ON(ret == NULL);
759 return ret;
760}
761
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100762#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100763#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100764
765#define P_MIN 2
766#define P_MAX 64
767#define P_INC 2
768
769/* Constraints for PLL good behavior */
770#define REF_MIN 48
771#define REF_MAX 400
772#define VCO_MIN 2400
773#define VCO_MAX 4800
774
Damien Lespiau27893392014-09-04 12:27:23 +0100775#define abs_diff(a, b) ({ \
776 typeof(a) __a = (a); \
777 typeof(b) __b = (b); \
778 (void) (&__a == &__b); \
779 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100780
Damien Lespiau63582982015-05-07 18:38:46 +0100781struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100782 unsigned p, n2, r2;
783};
784
Damien Lespiau63582982015-05-07 18:38:46 +0100785static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300786{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100787 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300788
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100789 switch (clock) {
790 case 25175000:
791 case 25200000:
792 case 27000000:
793 case 27027000:
794 case 37762500:
795 case 37800000:
796 case 40500000:
797 case 40541000:
798 case 54000000:
799 case 54054000:
800 case 59341000:
801 case 59400000:
802 case 72000000:
803 case 74176000:
804 case 74250000:
805 case 81000000:
806 case 81081000:
807 case 89012000:
808 case 89100000:
809 case 108000000:
810 case 108108000:
811 case 111264000:
812 case 111375000:
813 case 148352000:
814 case 148500000:
815 case 162000000:
816 case 162162000:
817 case 222525000:
818 case 222750000:
819 case 296703000:
820 case 297000000:
821 budget = 0;
822 break;
823 case 233500000:
824 case 245250000:
825 case 247750000:
826 case 253250000:
827 case 298000000:
828 budget = 1500;
829 break;
830 case 169128000:
831 case 169500000:
832 case 179500000:
833 case 202000000:
834 budget = 2000;
835 break;
836 case 256250000:
837 case 262500000:
838 case 270000000:
839 case 272500000:
840 case 273750000:
841 case 280750000:
842 case 281250000:
843 case 286000000:
844 case 291750000:
845 budget = 4000;
846 break;
847 case 267250000:
848 case 268500000:
849 budget = 5000;
850 break;
851 default:
852 budget = 1000;
853 break;
854 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300855
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100856 return budget;
857}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300858
Damien Lespiau63582982015-05-07 18:38:46 +0100859static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
860 unsigned r2, unsigned n2, unsigned p,
861 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100862{
863 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300864
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100865 /* No best (r,n,p) yet */
866 if (best->p == 0) {
867 best->p = p;
868 best->n2 = n2;
869 best->r2 = r2;
870 return;
871 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300872
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100873 /*
874 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
875 * freq2k.
876 *
877 * delta = 1e6 *
878 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
879 * freq2k;
880 *
881 * and we would like delta <= budget.
882 *
883 * If the discrepancy is above the PPM-based budget, always prefer to
884 * improve upon the previous solution. However, if you're within the
885 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
886 */
887 a = freq2k * budget * p * r2;
888 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100889 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
890 diff_best = abs_diff(freq2k * best->p * best->r2,
891 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100892 c = 1000000 * diff;
893 d = 1000000 * diff_best;
894
895 if (a < c && b < d) {
896 /* If both are above the budget, pick the closer */
897 if (best->p * best->r2 * diff < p * r2 * diff_best) {
898 best->p = p;
899 best->n2 = n2;
900 best->r2 = r2;
901 }
902 } else if (a >= c && b < d) {
903 /* If A is below the threshold but B is above it? Update. */
904 best->p = p;
905 best->n2 = n2;
906 best->r2 = r2;
907 } else if (a >= c && b >= d) {
908 /* Both are below the limit, so pick the higher n2/(r2*r2) */
909 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
910 best->p = p;
911 best->n2 = n2;
912 best->r2 = r2;
913 }
914 }
915 /* Otherwise a < c && b >= d, do nothing */
916}
917
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200918static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
919 i915_reg_t reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800920{
921 int refclk = LC_FREQ;
922 int n, p, r;
923 u32 wrpll;
924
925 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300926 switch (wrpll & WRPLL_PLL_REF_MASK) {
927 case WRPLL_PLL_SSC:
928 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800929 /*
930 * We could calculate spread here, but our checking
931 * code only cares about 5% accuracy, and spread is a max of
932 * 0.5% downspread.
933 */
934 refclk = 135;
935 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300936 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800937 refclk = LC_FREQ;
938 break;
939 default:
940 WARN(1, "bad wrpll refclk\n");
941 return 0;
942 }
943
944 r = wrpll & WRPLL_DIVIDER_REF_MASK;
945 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
946 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
947
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800948 /* Convert to KHz, p & r have a fixed point portion */
949 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800950}
951
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000952static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
953 uint32_t dpll)
954{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200955 i915_reg_t cfgcr1_reg, cfgcr2_reg;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000956 uint32_t cfgcr1_val, cfgcr2_val;
957 uint32_t p0, p1, p2, dco_freq;
958
Ville Syrjälä923c12412015-09-30 17:06:43 +0300959 cfgcr1_reg = DPLL_CFGCR1(dpll);
960 cfgcr2_reg = DPLL_CFGCR2(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000961
962 cfgcr1_val = I915_READ(cfgcr1_reg);
963 cfgcr2_val = I915_READ(cfgcr2_reg);
964
965 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
966 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
967
968 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
969 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
970 else
971 p1 = 1;
972
973
974 switch (p0) {
975 case DPLL_CFGCR2_PDIV_1:
976 p0 = 1;
977 break;
978 case DPLL_CFGCR2_PDIV_2:
979 p0 = 2;
980 break;
981 case DPLL_CFGCR2_PDIV_3:
982 p0 = 3;
983 break;
984 case DPLL_CFGCR2_PDIV_7:
985 p0 = 7;
986 break;
987 }
988
989 switch (p2) {
990 case DPLL_CFGCR2_KDIV_5:
991 p2 = 5;
992 break;
993 case DPLL_CFGCR2_KDIV_2:
994 p2 = 2;
995 break;
996 case DPLL_CFGCR2_KDIV_3:
997 p2 = 3;
998 break;
999 case DPLL_CFGCR2_KDIV_1:
1000 p2 = 1;
1001 break;
1002 }
1003
1004 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1005
1006 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1007 1000) / 0x8000;
1008
1009 return dco_freq / (p0 * p1 * p2 * 5);
1010}
1011
Ville Syrjälä398a0172015-06-30 15:33:51 +03001012static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1013{
1014 int dotclock;
1015
1016 if (pipe_config->has_pch_encoder)
1017 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1018 &pipe_config->fdi_m_n);
1019 else if (pipe_config->has_dp_encoder)
1020 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1021 &pipe_config->dp_m_n);
1022 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1023 dotclock = pipe_config->port_clock * 2 / 3;
1024 else
1025 dotclock = pipe_config->port_clock;
1026
1027 if (pipe_config->pixel_multiplier)
1028 dotclock /= pipe_config->pixel_multiplier;
1029
1030 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1031}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001032
1033static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001034 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001035{
1036 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001037 int link_clock = 0;
1038 uint32_t dpll_ctl1, dpll;
1039
Damien Lespiau134ffa42014-11-14 17:24:34 +00001040 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001041
1042 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1043
1044 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1045 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1046 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001047 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1048 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001049
1050 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001051 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001052 link_clock = 81000;
1053 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001054 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301055 link_clock = 108000;
1056 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001057 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001058 link_clock = 135000;
1059 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001060 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301061 link_clock = 162000;
1062 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001063 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301064 link_clock = 216000;
1065 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001066 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001067 link_clock = 270000;
1068 break;
1069 default:
1070 WARN(1, "Unsupported link rate\n");
1071 break;
1072 }
1073 link_clock *= 2;
1074 }
1075
1076 pipe_config->port_clock = link_clock;
1077
Ville Syrjälä398a0172015-06-30 15:33:51 +03001078 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001079}
1080
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001081static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001082 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001083{
1084 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001085 int link_clock = 0;
1086 u32 val, pll;
1087
Daniel Vetter26804af2014-06-25 22:01:55 +03001088 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001089 switch (val & PORT_CLK_SEL_MASK) {
1090 case PORT_CLK_SEL_LCPLL_810:
1091 link_clock = 81000;
1092 break;
1093 case PORT_CLK_SEL_LCPLL_1350:
1094 link_clock = 135000;
1095 break;
1096 case PORT_CLK_SEL_LCPLL_2700:
1097 link_clock = 270000;
1098 break;
1099 case PORT_CLK_SEL_WRPLL1:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001100 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
Jesse Barnes11578552014-01-21 12:42:10 -08001101 break;
1102 case PORT_CLK_SEL_WRPLL2:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001103 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
Jesse Barnes11578552014-01-21 12:42:10 -08001104 break;
1105 case PORT_CLK_SEL_SPLL:
1106 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1107 if (pll == SPLL_PLL_FREQ_810MHz)
1108 link_clock = 81000;
1109 else if (pll == SPLL_PLL_FREQ_1350MHz)
1110 link_clock = 135000;
1111 else if (pll == SPLL_PLL_FREQ_2700MHz)
1112 link_clock = 270000;
1113 else {
1114 WARN(1, "bad spll freq\n");
1115 return;
1116 }
1117 break;
1118 default:
1119 WARN(1, "bad port clock sel\n");
1120 return;
1121 }
1122
1123 pipe_config->port_clock = link_clock * 2;
1124
Ville Syrjälä398a0172015-06-30 15:33:51 +03001125 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001126}
1127
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301128static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1129 enum intel_dpll_id dpll)
1130{
Imre Deakaa610dc2015-06-22 23:35:52 +03001131 struct intel_shared_dpll *pll;
1132 struct intel_dpll_hw_state *state;
1133 intel_clock_t clock;
1134
1135 /* For DDI ports we always use a shared PLL. */
1136 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1137 return 0;
1138
1139 pll = &dev_priv->shared_dplls[dpll];
1140 state = &pll->config.hw_state;
1141
1142 clock.m1 = 2;
1143 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1144 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1145 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1146 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1147 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1148 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1149
1150 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301151}
1152
1153static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1154 struct intel_crtc_state *pipe_config)
1155{
1156 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1157 enum port port = intel_ddi_get_encoder_port(encoder);
1158 uint32_t dpll = port;
1159
Ville Syrjälä398a0172015-06-30 15:33:51 +03001160 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301161
Ville Syrjälä398a0172015-06-30 15:33:51 +03001162 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301163}
1164
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001165void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001166 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001167{
Damien Lespiau22606a12014-12-12 14:26:57 +00001168 struct drm_device *dev = encoder->base.dev;
1169
1170 if (INTEL_INFO(dev)->gen <= 8)
1171 hsw_ddi_clock_get(encoder, pipe_config);
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001172 else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001173 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301174 else if (IS_BROXTON(dev))
1175 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001176}
1177
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001178static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001179hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1180 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001181{
1182 uint64_t freq2k;
1183 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001184 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001185 unsigned budget;
1186
1187 freq2k = clock / 100;
1188
Damien Lespiau63582982015-05-07 18:38:46 +01001189 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001190
1191 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1192 * and directly pass the LC PLL to it. */
1193 if (freq2k == 5400000) {
1194 *n2_out = 2;
1195 *p_out = 1;
1196 *r2_out = 2;
1197 return;
1198 }
1199
1200 /*
1201 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1202 * the WR PLL.
1203 *
1204 * We want R so that REF_MIN <= Ref <= REF_MAX.
1205 * Injecting R2 = 2 * R gives:
1206 * REF_MAX * r2 > LC_FREQ * 2 and
1207 * REF_MIN * r2 < LC_FREQ * 2
1208 *
1209 * Which means the desired boundaries for r2 are:
1210 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1211 *
1212 */
1213 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1214 r2 <= LC_FREQ * 2 / REF_MIN;
1215 r2++) {
1216
1217 /*
1218 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1219 *
1220 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1221 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1222 * VCO_MAX * r2 > n2 * LC_FREQ and
1223 * VCO_MIN * r2 < n2 * LC_FREQ)
1224 *
1225 * Which means the desired boundaries for n2 are:
1226 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1227 */
1228 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1229 n2 <= VCO_MAX * r2 / LC_FREQ;
1230 n2++) {
1231
1232 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001233 hsw_wrpll_update_rnp(freq2k, budget,
1234 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001235 }
1236 }
1237
1238 *n2_out = best.n2;
1239 *p_out = best.p;
1240 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001241}
1242
Damien Lespiau0220ab62014-07-29 18:06:22 +01001243static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001244hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001245 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001246 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001247{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001248 int clock = crtc_state->port_clock;
1249
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001250 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001251 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001252 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001253 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001254
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001255 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001256
Daniel Vetter114fe482014-06-25 22:01:48 +03001257 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001258 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1259 WRPLL_DIVIDER_POST(p);
1260
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001261 memset(&crtc_state->dpll_hw_state, 0,
1262 sizeof(crtc_state->dpll_hw_state));
1263
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001264 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001265
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001266 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001267 if (pll == NULL) {
1268 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1269 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001270 return false;
1271 }
1272
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001273 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Maarten Lankhorst00490c22015-11-16 14:42:12 +01001274 } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
1275 struct drm_atomic_state *state = crtc_state->base.state;
1276 struct intel_shared_dpll_config *spll =
1277 &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
1278
1279 if (spll->crtc_mask &&
1280 WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
1281 return false;
1282
1283 crtc_state->shared_dpll = DPLL_ID_SPLL;
1284 spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
1285 spll->crtc_mask |= 1 << intel_crtc->pipe;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001286 }
1287
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001288 return true;
1289}
1290
Damien Lespiaudc253812015-06-25 16:15:06 +01001291struct skl_wrpll_context {
1292 uint64_t min_deviation; /* current minimal deviation */
1293 uint64_t central_freq; /* chosen central freq */
1294 uint64_t dco_freq; /* chosen dco freq */
1295 unsigned int p; /* chosen divider */
1296};
1297
1298static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1299{
1300 memset(ctx, 0, sizeof(*ctx));
1301
1302 ctx->min_deviation = U64_MAX;
1303}
1304
1305/* DCO freq must be within +1%/-6% of the DCO central freq */
1306#define SKL_DCO_MAX_PDEVIATION 100
1307#define SKL_DCO_MAX_NDEVIATION 600
1308
1309static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1310 uint64_t central_freq,
1311 uint64_t dco_freq,
1312 unsigned int divider)
1313{
1314 uint64_t deviation;
1315
1316 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1317 central_freq);
1318
1319 /* positive deviation */
1320 if (dco_freq >= central_freq) {
1321 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1322 deviation < ctx->min_deviation) {
1323 ctx->min_deviation = deviation;
1324 ctx->central_freq = central_freq;
1325 ctx->dco_freq = dco_freq;
1326 ctx->p = divider;
1327 }
1328 /* negative deviation */
1329 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1330 deviation < ctx->min_deviation) {
1331 ctx->min_deviation = deviation;
1332 ctx->central_freq = central_freq;
1333 ctx->dco_freq = dco_freq;
1334 ctx->p = divider;
1335 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001336}
1337
1338static void skl_wrpll_get_multipliers(unsigned int p,
1339 unsigned int *p0 /* out */,
1340 unsigned int *p1 /* out */,
1341 unsigned int *p2 /* out */)
1342{
1343 /* even dividers */
1344 if (p % 2 == 0) {
1345 unsigned int half = p / 2;
1346
1347 if (half == 1 || half == 2 || half == 3 || half == 5) {
1348 *p0 = 2;
1349 *p1 = 1;
1350 *p2 = half;
1351 } else if (half % 2 == 0) {
1352 *p0 = 2;
1353 *p1 = half / 2;
1354 *p2 = 2;
1355 } else if (half % 3 == 0) {
1356 *p0 = 3;
1357 *p1 = half / 3;
1358 *p2 = 2;
1359 } else if (half % 7 == 0) {
1360 *p0 = 7;
1361 *p1 = half / 7;
1362 *p2 = 2;
1363 }
1364 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1365 *p0 = 3;
1366 *p1 = 1;
1367 *p2 = p / 3;
1368 } else if (p == 5 || p == 7) {
1369 *p0 = p;
1370 *p1 = 1;
1371 *p2 = 1;
1372 } else if (p == 15) {
1373 *p0 = 3;
1374 *p1 = 1;
1375 *p2 = 5;
1376 } else if (p == 21) {
1377 *p0 = 7;
1378 *p1 = 1;
1379 *p2 = 3;
1380 } else if (p == 35) {
1381 *p0 = 7;
1382 *p1 = 1;
1383 *p2 = 5;
1384 }
1385}
1386
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001387struct skl_wrpll_params {
1388 uint32_t dco_fraction;
1389 uint32_t dco_integer;
1390 uint32_t qdiv_ratio;
1391 uint32_t qdiv_mode;
1392 uint32_t kdiv;
1393 uint32_t pdiv;
1394 uint32_t central_freq;
1395};
1396
Damien Lespiau76516fb2015-05-07 18:38:42 +01001397static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1398 uint64_t afe_clock,
1399 uint64_t central_freq,
1400 uint32_t p0, uint32_t p1, uint32_t p2)
1401{
1402 uint64_t dco_freq;
1403
Damien Lespiau76516fb2015-05-07 18:38:42 +01001404 switch (central_freq) {
1405 case 9600000000ULL:
1406 params->central_freq = 0;
1407 break;
1408 case 9000000000ULL:
1409 params->central_freq = 1;
1410 break;
1411 case 8400000000ULL:
1412 params->central_freq = 3;
1413 }
1414
1415 switch (p0) {
1416 case 1:
1417 params->pdiv = 0;
1418 break;
1419 case 2:
1420 params->pdiv = 1;
1421 break;
1422 case 3:
1423 params->pdiv = 2;
1424 break;
1425 case 7:
1426 params->pdiv = 4;
1427 break;
1428 default:
1429 WARN(1, "Incorrect PDiv\n");
1430 }
1431
1432 switch (p2) {
1433 case 5:
1434 params->kdiv = 0;
1435 break;
1436 case 2:
1437 params->kdiv = 1;
1438 break;
1439 case 3:
1440 params->kdiv = 2;
1441 break;
1442 case 1:
1443 params->kdiv = 3;
1444 break;
1445 default:
1446 WARN(1, "Incorrect KDiv\n");
1447 }
1448
1449 params->qdiv_ratio = p1;
1450 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1451
1452 dco_freq = p0 * p1 * p2 * afe_clock;
1453
1454 /*
1455 * Intermediate values are in Hz.
1456 * Divide by MHz to match bsepc
1457 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001458 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001459 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001460 div_u64((div_u64(dco_freq, 24) -
1461 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001462}
1463
Damien Lespiau318bd822015-05-07 18:38:40 +01001464static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001465skl_ddi_calculate_wrpll(int clock /* in Hz */,
1466 struct skl_wrpll_params *wrpll_params)
1467{
1468 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001469 uint64_t dco_central_freq[3] = {8400000000ULL,
1470 9000000000ULL,
1471 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001472 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1473 24, 28, 30, 32, 36, 40, 42, 44,
1474 48, 52, 54, 56, 60, 64, 66, 68,
1475 70, 72, 76, 78, 80, 84, 88, 90,
1476 92, 96, 98 };
1477 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1478 static const struct {
1479 const int *list;
1480 int n_dividers;
1481 } dividers[] = {
1482 { even_dividers, ARRAY_SIZE(even_dividers) },
1483 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1484 };
1485 struct skl_wrpll_context ctx;
1486 unsigned int dco, d, i;
1487 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001488
Damien Lespiaudc253812015-06-25 16:15:06 +01001489 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001490
Damien Lespiaudc253812015-06-25 16:15:06 +01001491 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1492 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1493 for (i = 0; i < dividers[d].n_dividers; i++) {
1494 unsigned int p = dividers[d].list[i];
1495 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001496
Damien Lespiaudc253812015-06-25 16:15:06 +01001497 skl_wrpll_try_divider(&ctx,
1498 dco_central_freq[dco],
1499 dco_freq,
1500 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001501 /*
1502 * Skip the remaining dividers if we're sure to
1503 * have found the definitive divider, we can't
1504 * improve a 0 deviation.
1505 */
1506 if (ctx.min_deviation == 0)
1507 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001508 }
1509 }
Damien Lespiau267db662015-06-25 16:19:24 +01001510
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001511skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001512 /*
1513 * If a solution is found with an even divider, prefer
1514 * this one.
1515 */
1516 if (d == 0 && ctx.p)
1517 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001518 }
1519
Damien Lespiaudc253812015-06-25 16:15:06 +01001520 if (!ctx.p) {
1521 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001522 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001523 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001524
Damien Lespiaudc253812015-06-25 16:15:06 +01001525 /*
1526 * gcc incorrectly analyses that these can be used without being
1527 * initialized. To be fair, it's hard to guess.
1528 */
1529 p0 = p1 = p2 = 0;
1530 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1531 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1532 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001533
Damien Lespiau318bd822015-05-07 18:38:40 +01001534 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001535}
1536
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001537static bool
1538skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001539 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001540 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001541{
1542 struct intel_shared_dpll *pll;
1543 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001544 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001545
1546 /*
1547 * See comment in intel_dpll_hw_state to understand why we always use 0
1548 * as the DPLL id in this function.
1549 */
1550
1551 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1552
1553 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1554 struct skl_wrpll_params wrpll_params = { 0, };
1555
1556 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1557
Damien Lespiau318bd822015-05-07 18:38:40 +01001558 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1559 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001560
1561 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1562 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1563 wrpll_params.dco_integer;
1564
1565 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1566 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1567 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1568 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1569 wrpll_params.central_freq;
1570 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001571 switch (crtc_state->port_clock / 2) {
1572 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001573 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001574 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001575 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001576 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001577 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001578 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001579 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001580 break;
1581 }
1582
1583 cfgcr1 = cfgcr2 = 0;
1584 } else /* eDP */
1585 return true;
1586
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001587 memset(&crtc_state->dpll_hw_state, 0,
1588 sizeof(crtc_state->dpll_hw_state));
1589
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001590 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1591 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1592 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001593
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001594 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001595 if (pll == NULL) {
1596 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1597 pipe_name(intel_crtc->pipe));
1598 return false;
1599 }
1600
1601 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001602 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001603
1604 return true;
1605}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001606
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301607/* bxt clock parameters */
1608struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301609 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301610 uint32_t p1;
1611 uint32_t p2;
1612 uint32_t m2_int;
1613 uint32_t m2_frac;
1614 bool m2_frac_en;
1615 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301616};
1617
1618/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301619static const struct bxt_clk_div bxt_dp_clk_val[] = {
1620 {162000, 4, 2, 32, 1677722, 1, 1},
1621 {270000, 4, 1, 27, 0, 0, 1},
1622 {540000, 2, 1, 27, 0, 0, 1},
1623 {216000, 3, 2, 32, 1677722, 1, 1},
1624 {243000, 4, 1, 24, 1258291, 1, 1},
1625 {324000, 4, 1, 32, 1677722, 1, 1},
1626 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301627};
1628
1629static bool
1630bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1631 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001632 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301633{
1634 struct intel_shared_dpll *pll;
1635 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301636 int vco = 0;
1637 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301638 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001639 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301640
1641 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1642 intel_clock_t best_clock;
1643
1644 /* Calculate HDMI div */
1645 /*
1646 * FIXME: tie the following calculation into
1647 * i9xx_crtc_compute_clock
1648 */
1649 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1650 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1651 clock, pipe_name(intel_crtc->pipe));
1652 return false;
1653 }
1654
1655 clk_div.p1 = best_clock.p1;
1656 clk_div.p2 = best_clock.p2;
1657 WARN_ON(best_clock.m1 != 2);
1658 clk_div.n = best_clock.n;
1659 clk_div.m2_int = best_clock.m2 >> 22;
1660 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1661 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1662
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301663 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301664 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1665 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301666 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301667
Sonika Jindal64987fc2015-05-26 17:50:13 +05301668 clk_div = bxt_dp_clk_val[0];
1669 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1670 if (bxt_dp_clk_val[i].clock == clock) {
1671 clk_div = bxt_dp_clk_val[i];
1672 break;
1673 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301674 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301675 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1676 }
1677
Vandana Kannane6292552015-07-01 17:02:57 +05301678 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301679 prop_coef = 4;
1680 int_coef = 9;
1681 gain_ctl = 3;
1682 targ_cnt = 8;
1683 } else if ((vco > 5400000 && vco < 6200000) ||
1684 (vco >= 4800000 && vco < 5400000)) {
1685 prop_coef = 5;
1686 int_coef = 11;
1687 gain_ctl = 3;
1688 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301689 } else if (vco == 5400000) {
1690 prop_coef = 3;
1691 int_coef = 8;
1692 gain_ctl = 1;
1693 targ_cnt = 9;
1694 } else {
1695 DRM_ERROR("Invalid VCO\n");
1696 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301697 }
1698
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001699 memset(&crtc_state->dpll_hw_state, 0,
1700 sizeof(crtc_state->dpll_hw_state));
1701
Vandana Kannane0681e32015-05-13 12:20:35 +05301702 if (clock > 270000)
1703 lanestagger = 0x18;
1704 else if (clock > 135000)
1705 lanestagger = 0x0d;
1706 else if (clock > 67000)
1707 lanestagger = 0x07;
1708 else if (clock > 33000)
1709 lanestagger = 0x04;
1710 else
1711 lanestagger = 0x02;
1712
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301713 crtc_state->dpll_hw_state.ebb0 =
1714 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1715 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1716 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1717 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1718
1719 if (clk_div.m2_frac_en)
1720 crtc_state->dpll_hw_state.pll3 =
1721 PORT_PLL_M2_FRAC_ENABLE;
1722
1723 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301724 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301725 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301726 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301727
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301728 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1729
Imre Deak05712c12015-06-18 17:25:54 +03001730 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1731
Vandana Kannane6292552015-07-01 17:02:57 +05301732 crtc_state->dpll_hw_state.pll10 =
1733 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1734 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301735
Imre Deak05712c12015-06-18 17:25:54 +03001736 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1737
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301738 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301739 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301740
1741 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1742 if (pll == NULL) {
1743 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1744 pipe_name(intel_crtc->pipe));
1745 return false;
1746 }
1747
1748 /* shared DPLL id 0 is DPLL A */
1749 crtc_state->ddi_pll_sel = pll->id;
1750
1751 return true;
1752}
1753
Damien Lespiau0220ab62014-07-29 18:06:22 +01001754/*
1755 * Tries to find a *shared* PLL for the CRTC and store it in
1756 * intel_crtc->ddi_pll_sel.
1757 *
1758 * For private DPLLs, compute_config() should do the selection for us. This
1759 * function should be folded into compute_config() eventually.
1760 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001761bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1762 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001763{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001764 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001765 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001766 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001767
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001768 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001769 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001770 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301771 else if (IS_BROXTON(dev))
1772 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001773 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001774 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001775 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001776 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001777}
1778
Paulo Zanonidae84792012-10-15 15:51:30 -03001779void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1780{
1781 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1782 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1783 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001784 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001785 int type = intel_encoder->type;
1786 uint32_t temp;
1787
Dave Airlie0e32b392014-05-02 14:02:48 +10001788 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001789 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001790 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001791 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001792 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001793 break;
1794 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001795 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001796 break;
1797 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001798 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001799 break;
1800 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001801 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001802 break;
1803 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001804 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001805 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001806 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001807 }
1808}
1809
Dave Airlie0e32b392014-05-02 14:02:48 +10001810void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1811{
1812 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1813 struct drm_device *dev = crtc->dev;
1814 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001815 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001816 uint32_t temp;
1817 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1818 if (state == true)
1819 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1820 else
1821 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1822 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1823}
1824
Damien Lespiau8228c252013-03-07 15:30:27 +00001825void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001826{
1827 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1828 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001829 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001830 struct drm_device *dev = crtc->dev;
1831 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001832 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001833 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001834 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001835 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001836 uint32_t temp;
1837
Paulo Zanoniad80a812012-10-24 16:06:19 -02001838 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1839 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001840 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001841
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001842 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001843 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001844 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001845 break;
1846 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001847 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001848 break;
1849 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001850 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001851 break;
1852 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001853 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001854 break;
1855 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001856 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001857 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001858
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001859 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001860 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001861 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001862 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001863
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001864 if (cpu_transcoder == TRANSCODER_EDP) {
1865 switch (pipe) {
1866 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001867 /* On Haswell, can only use the always-on power well for
1868 * eDP when not using the panel fitter, and when not
1869 * using motion blur mitigation (which we don't
1870 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001871 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001872 (intel_crtc->config->pch_pfit.enabled ||
1873 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001874 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1875 else
1876 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001877 break;
1878 case PIPE_B:
1879 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1880 break;
1881 case PIPE_C:
1882 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1883 break;
1884 default:
1885 BUG();
1886 break;
1887 }
1888 }
1889
Paulo Zanoni7739c332012-10-15 15:51:29 -03001890 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001891 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001892 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001893 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001894 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001895
Paulo Zanoni7739c332012-10-15 15:51:29 -03001896 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001897 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001898 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001899
1900 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1901 type == INTEL_OUTPUT_EDP) {
1902 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1903
Dave Airlie0e32b392014-05-02 14:02:48 +10001904 if (intel_dp->is_mst) {
1905 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1906 } else
1907 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1908
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001909 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001910 } else if (type == INTEL_OUTPUT_DP_MST) {
1911 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1912
1913 if (intel_dp->is_mst) {
1914 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1915 } else
1916 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001917
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001918 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001919 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001920 WARN(1, "Invalid encoder type %d for pipe %c\n",
1921 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001922 }
1923
Paulo Zanoniad80a812012-10-24 16:06:19 -02001924 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001925}
1926
Paulo Zanoniad80a812012-10-24 16:06:19 -02001927void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1928 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001929{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02001930 i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001931 uint32_t val = I915_READ(reg);
1932
Dave Airlie0e32b392014-05-02 14:02:48 +10001933 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001934 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001935 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001936}
1937
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001938bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1939{
1940 struct drm_device *dev = intel_connector->base.dev;
1941 struct drm_i915_private *dev_priv = dev->dev_private;
1942 struct intel_encoder *intel_encoder = intel_connector->encoder;
1943 int type = intel_connector->base.connector_type;
1944 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1945 enum pipe pipe = 0;
1946 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001947 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001948 uint32_t tmp;
1949
Paulo Zanoni882244a2014-04-01 14:55:12 -03001950 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001951 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001952 return false;
1953
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001954 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1955 return false;
1956
1957 if (port == PORT_A)
1958 cpu_transcoder = TRANSCODER_EDP;
1959 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001960 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001961
1962 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1963
1964 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1965 case TRANS_DDI_MODE_SELECT_HDMI:
1966 case TRANS_DDI_MODE_SELECT_DVI:
1967 return (type == DRM_MODE_CONNECTOR_HDMIA);
1968
1969 case TRANS_DDI_MODE_SELECT_DP_SST:
1970 if (type == DRM_MODE_CONNECTOR_eDP)
1971 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001972 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001973 case TRANS_DDI_MODE_SELECT_DP_MST:
1974 /* if the transcoder is in MST state then
1975 * connector isn't connected */
1976 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001977
1978 case TRANS_DDI_MODE_SELECT_FDI:
1979 return (type == DRM_MODE_CONNECTOR_VGA);
1980
1981 default:
1982 return false;
1983 }
1984}
1985
Daniel Vetter85234cd2012-07-02 13:27:29 +02001986bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1987 enum pipe *pipe)
1988{
1989 struct drm_device *dev = encoder->base.dev;
1990 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001991 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001992 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001993 u32 tmp;
1994 int i;
1995
Imre Deak6d129be2014-03-05 16:20:54 +02001996 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001997 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02001998 return false;
1999
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002000 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002001
2002 if (!(tmp & DDI_BUF_CTL_ENABLE))
2003 return false;
2004
Paulo Zanoniad80a812012-10-24 16:06:19 -02002005 if (port == PORT_A) {
2006 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002007
Paulo Zanoniad80a812012-10-24 16:06:19 -02002008 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2009 case TRANS_DDI_EDP_INPUT_A_ON:
2010 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2011 *pipe = PIPE_A;
2012 break;
2013 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2014 *pipe = PIPE_B;
2015 break;
2016 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2017 *pipe = PIPE_C;
2018 break;
2019 }
2020
2021 return true;
2022 } else {
2023 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2024 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2025
2026 if ((tmp & TRANS_DDI_PORT_MASK)
2027 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002028 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2029 return false;
2030
Paulo Zanoniad80a812012-10-24 16:06:19 -02002031 *pipe = i;
2032 return true;
2033 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002034 }
2035 }
2036
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002037 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002038
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002039 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002040}
2041
Paulo Zanonifc914632012-10-05 12:05:54 -03002042void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2043{
2044 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302045 struct drm_device *dev = crtc->dev;
2046 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002047 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2048 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002049 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002050
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002051 if (cpu_transcoder != TRANSCODER_EDP)
2052 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2053 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002054}
2055
2056void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2057{
2058 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002059 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002060
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002061 if (cpu_transcoder != TRANSCODER_EDP)
2062 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2063 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002064}
2065
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002066static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
2067 u32 level, enum port port, int type)
David Weinehallf8896f52015-06-25 11:11:03 +03002068{
David Weinehallf8896f52015-06-25 11:11:03 +03002069 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 {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002083 ddi_translations = skl_get_buf_trans_dp(dev_priv, &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 {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002090 ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
Ville Syrjälä10afa0b2015-12-08 19:59:43 +02002091
2092 if (WARN_ON(port != PORT_A &&
2093 port != PORT_E && n_entries > 9))
2094 n_entries = 9;
2095
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002096 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002097 }
David Weinehallf8896f52015-06-25 11:11:03 +03002098 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002099 if (hdmi_iboost) {
2100 iboost = hdmi_iboost;
2101 } else {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002102 ddi_translations = skl_get_buf_trans_hdmi(dev_priv, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002103 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002104 }
David Weinehallf8896f52015-06-25 11:11:03 +03002105 } else {
2106 return;
2107 }
2108
2109 /* Make sure that the requested I_boost is valid */
2110 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2111 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2112 return;
2113 }
2114
2115 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2116 reg &= ~BALANCE_LEG_MASK(port);
2117 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2118
2119 if (iboost)
2120 reg |= iboost << BALANCE_LEG_SHIFT(port);
2121 else
2122 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2123
2124 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2125}
2126
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002127static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
2128 u32 level, enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302129{
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302130 const struct bxt_ddi_buf_trans *ddi_translations;
2131 u32 n_entries, i;
2132 uint32_t val;
2133
Sonika Jindald9d70002015-09-24 10:24:56 +05302134 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2135 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2136 ddi_translations = bxt_ddi_translations_edp;
2137 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2138 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302139 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2140 ddi_translations = bxt_ddi_translations_dp;
2141 } else if (type == INTEL_OUTPUT_HDMI) {
2142 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2143 ddi_translations = bxt_ddi_translations_hdmi;
2144 } else {
2145 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2146 type);
2147 return;
2148 }
2149
2150 /* Check if default value has to be used */
2151 if (level >= n_entries ||
2152 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2153 for (i = 0; i < n_entries; i++) {
2154 if (ddi_translations[i].default_index) {
2155 level = i;
2156 break;
2157 }
2158 }
2159 }
2160
2161 /*
2162 * While we write to the group register to program all lanes at once we
2163 * can read only lane registers and we pick lanes 0/1 for that.
2164 */
2165 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2166 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2167 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2168
2169 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2170 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2171 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2172 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2173 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2174
2175 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302176 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302177 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302178 val |= SCALE_DCOMP_METHOD;
2179
2180 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2181 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2182
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302183 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2184
2185 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2186 val &= ~DE_EMPHASIS;
2187 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2188 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2189
2190 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2191 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2192 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2193}
2194
David Weinehallf8896f52015-06-25 11:11:03 +03002195static uint32_t translate_signal_level(int signal_levels)
2196{
2197 uint32_t level;
2198
2199 switch (signal_levels) {
2200 default:
2201 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2202 signal_levels);
2203 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2204 level = 0;
2205 break;
2206 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2207 level = 1;
2208 break;
2209 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2210 level = 2;
2211 break;
2212 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2213 level = 3;
2214 break;
2215
2216 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2217 level = 4;
2218 break;
2219 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2220 level = 5;
2221 break;
2222 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2223 level = 6;
2224 break;
2225
2226 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2227 level = 7;
2228 break;
2229 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2230 level = 8;
2231 break;
2232
2233 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2234 level = 9;
2235 break;
2236 }
2237
2238 return level;
2239}
2240
2241uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2242{
2243 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002244 struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
David Weinehallf8896f52015-06-25 11:11:03 +03002245 struct intel_encoder *encoder = &dport->base;
2246 uint8_t train_set = intel_dp->train_set[0];
2247 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2248 DP_TRAIN_PRE_EMPHASIS_MASK);
2249 enum port port = dport->port;
2250 uint32_t level;
2251
2252 level = translate_signal_level(signal_levels);
2253
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002254 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
2255 skl_ddi_set_iboost(dev_priv, level, port, encoder->type);
2256 else if (IS_BROXTON(dev_priv))
2257 bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type);
David Weinehallf8896f52015-06-25 11:11:03 +03002258
2259 return DDI_BUF_TRANS_SELECT(level);
2260}
2261
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002262void intel_ddi_clk_select(struct intel_encoder *encoder,
2263 const struct intel_crtc_state *pipe_config)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002264{
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002265 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2266 enum port port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002267
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002268 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
2269 uint32_t dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002270 uint32_t val;
2271
Damien Lespiau5416d872014-11-14 17:24:33 +00002272 /*
2273 * DPLL0 is used for eDP and is the only "private" DPLL (as
2274 * opposed to shared) on SKL
2275 */
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002276 if (encoder->type == INTEL_OUTPUT_EDP) {
Damien Lespiau5416d872014-11-14 17:24:33 +00002277 WARN_ON(dpll != SKL_DPLL0);
2278
2279 val = I915_READ(DPLL_CTRL1);
2280
2281 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2282 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002283 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002284 val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002285
2286 I915_WRITE(DPLL_CTRL1, val);
2287 POSTING_READ(DPLL_CTRL1);
2288 }
2289
2290 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002291 val = I915_READ(DPLL_CTRL2);
2292
2293 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2294 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2295 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2296 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2297
2298 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002299
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002300 } else if (INTEL_INFO(dev_priv)->gen < 9) {
2301 WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2302 I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002303 }
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002304}
2305
2306static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
2307{
2308 struct drm_encoder *encoder = &intel_encoder->base;
2309 struct drm_device *dev = encoder->dev;
2310 struct drm_i915_private *dev_priv = dev->dev_private;
2311 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
2312 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2313 int type = intel_encoder->type;
2314 int hdmi_level;
2315
2316 if (type == INTEL_OUTPUT_EDP) {
2317 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2318 intel_edp_panel_on(intel_dp);
2319 }
2320
2321 intel_ddi_clk_select(intel_encoder, crtc->config);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002322
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002323 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002324 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002325
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002326 intel_dp_set_link_params(intel_dp, crtc->config);
2327
Dave Airlie44905a272014-05-02 13:36:43 +10002328 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002329
2330 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2331 intel_dp_start_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002332 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002333 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002334 } else if (type == INTEL_OUTPUT_HDMI) {
2335 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2336
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302337 if (IS_BROXTON(dev)) {
2338 hdmi_level = dev_priv->vbt.
2339 ddi_port_info[port].hdmi_level_shift;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002340 bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
2341 INTEL_OUTPUT_HDMI);
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302342 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002343 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002344 crtc->config->has_hdmi_sink,
2345 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002346 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002347}
2348
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002349static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002350{
2351 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002352 struct drm_device *dev = encoder->dev;
2353 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002354 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002355 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002356 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002357 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002358
2359 val = I915_READ(DDI_BUF_CTL(port));
2360 if (val & DDI_BUF_CTL_ENABLE) {
2361 val &= ~DDI_BUF_CTL_ENABLE;
2362 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002363 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002364 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002365
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002366 val = I915_READ(DP_TP_CTL(port));
2367 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2368 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2369 I915_WRITE(DP_TP_CTL(port), val);
2370
2371 if (wait)
2372 intel_wait_ddi_buf_idle(dev_priv, port);
2373
Jani Nikula76bb80e2013-11-15 15:29:57 +02002374 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002375 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002376 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002377 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002378 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002379 }
2380
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002381 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002382 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2383 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302384 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002385 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002386}
2387
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002388static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002389{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002390 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002391 struct drm_crtc *crtc = encoder->crtc;
2392 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002393 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002394 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002395 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2396 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002397
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002398 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002399 struct intel_digital_port *intel_dig_port =
2400 enc_to_dig_port(encoder);
2401
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002402 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2403 * are ignored so nothing special needs to be done besides
2404 * enabling the port.
2405 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002406 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de42013-07-12 13:54:41 -07002407 intel_dig_port->saved_port_bits |
2408 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002409 } else if (type == INTEL_OUTPUT_EDP) {
2410 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2411
Vandana Kannan23f08d82014-11-13 14:55:22 +00002412 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002413 intel_dp_stop_link_train(intel_dp);
2414
Daniel Vetter4be73782014-01-17 14:39:48 +01002415 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002416 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302417 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002418 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002419
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002420 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002421 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002422 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002423 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002424}
2425
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002426static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002427{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002428 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002429 struct drm_crtc *crtc = encoder->crtc;
2430 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002431 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002432 struct drm_device *dev = encoder->dev;
2433 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002434
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002435 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002436 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002437 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2438 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002439
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002440 if (type == INTEL_OUTPUT_EDP) {
2441 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2442
Vandana Kannanc3955782015-01-22 15:17:40 +05302443 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002444 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002445 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002446 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002447}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002448
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002449static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
Daniel Vettere0b01be2014-06-25 22:02:01 +03002450 struct intel_shared_dpll *pll)
2451{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002452 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002453 POSTING_READ(WRPLL_CTL(pll->id));
2454 udelay(20);
2455}
2456
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002457static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
Daniel Vetter12030432014-06-25 22:02:00 +03002458 struct intel_shared_dpll *pll)
2459{
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002460 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
2461 POSTING_READ(SPLL_CTL);
2462 udelay(20);
2463}
2464
2465static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
2466 struct intel_shared_dpll *pll)
2467{
Daniel Vetter12030432014-06-25 22:02:00 +03002468 uint32_t val;
2469
2470 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002471 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2472 POSTING_READ(WRPLL_CTL(pll->id));
2473}
2474
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002475static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
2476 struct intel_shared_dpll *pll)
2477{
2478 uint32_t val;
2479
2480 val = I915_READ(SPLL_CTL);
2481 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
2482 POSTING_READ(SPLL_CTL);
2483}
2484
2485static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
2486 struct intel_shared_dpll *pll,
2487 struct intel_dpll_hw_state *hw_state)
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002488{
2489 uint32_t val;
2490
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002491 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002492 return false;
2493
2494 val = I915_READ(WRPLL_CTL(pll->id));
2495 hw_state->wrpll = val;
2496
2497 return val & WRPLL_PLL_ENABLE;
2498}
2499
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002500static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
2501 struct intel_shared_dpll *pll,
2502 struct intel_dpll_hw_state *hw_state)
2503{
2504 uint32_t val;
2505
2506 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2507 return false;
2508
2509 val = I915_READ(SPLL_CTL);
2510 hw_state->spll = val;
2511
2512 return val & SPLL_PLL_ENABLE;
2513}
2514
2515
Damien Lespiauca1381b2014-07-15 15:05:33 +01002516static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002517 "WRPLL 1",
2518 "WRPLL 2",
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002519 "SPLL"
Daniel Vetter9cd86932014-06-25 22:01:57 +03002520};
2521
Damien Lespiau143b3072014-07-29 18:06:19 +01002522static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002523{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002524 int i;
2525
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002526 dev_priv->num_shared_dpll = 3;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002527
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002528 for (i = 0; i < 2; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002529 dev_priv->shared_dplls[i].id = i;
2530 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002531 dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
2532 dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002533 dev_priv->shared_dplls[i].get_hw_state =
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002534 hsw_ddi_wrpll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002535 }
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002536
2537 /* SPLL is special, but needs to be initialized anyway.. */
2538 dev_priv->shared_dplls[i].id = i;
2539 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
2540 dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
2541 dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
2542 dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
2543
Damien Lespiau143b3072014-07-29 18:06:19 +01002544}
2545
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002546static const char * const skl_ddi_pll_names[] = {
2547 "DPLL 1",
2548 "DPLL 2",
2549 "DPLL 3",
2550};
2551
2552struct skl_dpll_regs {
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02002553 i915_reg_t ctl, cfgcr1, cfgcr2;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002554};
2555
2556/* this array is indexed by the *shared* pll id */
2557static const struct skl_dpll_regs skl_dpll_regs[3] = {
2558 {
2559 /* DPLL 1 */
2560 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002561 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2562 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002563 },
2564 {
2565 /* DPLL 2 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002566 .ctl = WRPLL_CTL(0),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002567 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2568 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002569 },
2570 {
2571 /* DPLL 3 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002572 .ctl = WRPLL_CTL(1),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002573 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2574 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002575 },
2576};
2577
2578static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2579 struct intel_shared_dpll *pll)
2580{
2581 uint32_t val;
2582 unsigned int dpll;
2583 const struct skl_dpll_regs *regs = skl_dpll_regs;
2584
2585 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2586 dpll = pll->id + 1;
2587
2588 val = I915_READ(DPLL_CTRL1);
2589
2590 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002591 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002592 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2593
2594 I915_WRITE(DPLL_CTRL1, val);
2595 POSTING_READ(DPLL_CTRL1);
2596
2597 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2598 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2599 POSTING_READ(regs[pll->id].cfgcr1);
2600 POSTING_READ(regs[pll->id].cfgcr2);
2601
2602 /* the enable bit is always bit 31 */
2603 I915_WRITE(regs[pll->id].ctl,
2604 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2605
2606 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2607 DRM_ERROR("DPLL %d not locked\n", dpll);
2608}
2609
2610static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2611 struct intel_shared_dpll *pll)
2612{
2613 const struct skl_dpll_regs *regs = skl_dpll_regs;
2614
2615 /* the enable bit is always bit 31 */
2616 I915_WRITE(regs[pll->id].ctl,
2617 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2618 POSTING_READ(regs[pll->id].ctl);
2619}
2620
2621static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2622 struct intel_shared_dpll *pll,
2623 struct intel_dpll_hw_state *hw_state)
2624{
2625 uint32_t val;
2626 unsigned int dpll;
2627 const struct skl_dpll_regs *regs = skl_dpll_regs;
2628
2629 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2630 return false;
2631
2632 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2633 dpll = pll->id + 1;
2634
2635 val = I915_READ(regs[pll->id].ctl);
2636 if (!(val & LCPLL_PLL_ENABLE))
2637 return false;
2638
2639 val = I915_READ(DPLL_CTRL1);
2640 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2641
2642 /* avoid reading back stale values if HDMI mode is not enabled */
2643 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2644 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2645 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2646 }
2647
2648 return true;
2649}
2650
2651static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2652{
2653 int i;
2654
2655 dev_priv->num_shared_dpll = 3;
2656
2657 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2658 dev_priv->shared_dplls[i].id = i;
2659 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2660 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2661 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2662 dev_priv->shared_dplls[i].get_hw_state =
2663 skl_ddi_pll_get_hw_state;
2664 }
2665}
2666
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302667static void broxton_phy_init(struct drm_i915_private *dev_priv,
2668 enum dpio_phy phy)
2669{
2670 enum port port;
2671 uint32_t val;
2672
2673 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2674 val |= GT_DISPLAY_POWER_ON(phy);
2675 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2676
2677 /* Considering 10ms timeout until BSpec is updated */
2678 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2679 DRM_ERROR("timeout during PHY%d power on\n", phy);
2680
2681 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2682 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2683 int lane;
2684
2685 for (lane = 0; lane < 4; lane++) {
2686 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2687 /*
2688 * Note that on CHV this flag is called UPAR, but has
2689 * the same function.
2690 */
2691 val &= ~LATENCY_OPTIM;
2692 if (lane != 1)
2693 val |= LATENCY_OPTIM;
2694
2695 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2696 }
2697 }
2698
2699 /* Program PLL Rcomp code offset */
2700 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2701 val &= ~IREF0RC_OFFSET_MASK;
2702 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2703 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2704
2705 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2706 val &= ~IREF1RC_OFFSET_MASK;
2707 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2708 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2709
2710 /* Program power gating */
2711 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2712 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2713 SUS_CLK_CONFIG;
2714 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2715
2716 if (phy == DPIO_PHY0) {
2717 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2718 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2719 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2720 }
2721
2722 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2723 val &= ~OCL2_LDOFUSE_PWR_DIS;
2724 /*
2725 * On PHY1 disable power on the second channel, since no port is
2726 * connected there. On PHY0 both channels have a port, so leave it
2727 * enabled.
2728 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2729 * power down the second channel on PHY0 as well.
2730 */
2731 if (phy == DPIO_PHY1)
2732 val |= OCL2_LDOFUSE_PWR_DIS;
2733 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2734
2735 if (phy == DPIO_PHY0) {
2736 uint32_t grc_code;
2737 /*
2738 * PHY0 isn't connected to an RCOMP resistor so copy over
2739 * the corresponding calibrated value from PHY1, and disable
2740 * the automatic calibration on PHY0.
2741 */
2742 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2743 10))
2744 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2745
2746 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2747 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2748 grc_code = val << GRC_CODE_FAST_SHIFT |
2749 val << GRC_CODE_SLOW_SHIFT |
2750 val;
2751 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2752
2753 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2754 val |= GRC_DIS | GRC_RDY_OVRD;
2755 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2756 }
2757
2758 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2759 val |= COMMON_RESET_DIS;
2760 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2761}
2762
2763void broxton_ddi_phy_init(struct drm_device *dev)
2764{
2765 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2766 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2767 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2768}
2769
2770static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2771 enum dpio_phy phy)
2772{
2773 uint32_t val;
2774
2775 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2776 val &= ~COMMON_RESET_DIS;
2777 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2778}
2779
2780void broxton_ddi_phy_uninit(struct drm_device *dev)
2781{
2782 struct drm_i915_private *dev_priv = dev->dev_private;
2783
2784 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2785 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2786
2787 /* FIXME: do this in broxton_phy_uninit per phy */
2788 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2789}
2790
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302791static const char * const bxt_ddi_pll_names[] = {
2792 "PORT PLL A",
2793 "PORT PLL B",
2794 "PORT PLL C",
2795};
2796
2797static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2798 struct intel_shared_dpll *pll)
2799{
2800 uint32_t temp;
2801 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2802
2803 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2804 temp &= ~PORT_PLL_REF_SEL;
2805 /* Non-SSC reference */
2806 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2807
2808 /* Disable 10 bit clock */
2809 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2810 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2811 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2812
2813 /* Write P1 & P2 */
2814 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2815 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2816 temp |= pll->config.hw_state.ebb0;
2817 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2818
2819 /* Write M2 integer */
2820 temp = I915_READ(BXT_PORT_PLL(port, 0));
2821 temp &= ~PORT_PLL_M2_MASK;
2822 temp |= pll->config.hw_state.pll0;
2823 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2824
2825 /* Write N */
2826 temp = I915_READ(BXT_PORT_PLL(port, 1));
2827 temp &= ~PORT_PLL_N_MASK;
2828 temp |= pll->config.hw_state.pll1;
2829 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2830
2831 /* Write M2 fraction */
2832 temp = I915_READ(BXT_PORT_PLL(port, 2));
2833 temp &= ~PORT_PLL_M2_FRAC_MASK;
2834 temp |= pll->config.hw_state.pll2;
2835 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2836
2837 /* Write M2 fraction enable */
2838 temp = I915_READ(BXT_PORT_PLL(port, 3));
2839 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2840 temp |= pll->config.hw_state.pll3;
2841 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2842
2843 /* Write coeff */
2844 temp = I915_READ(BXT_PORT_PLL(port, 6));
2845 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2846 temp &= ~PORT_PLL_INT_COEFF_MASK;
2847 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2848 temp |= pll->config.hw_state.pll6;
2849 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2850
2851 /* Write calibration val */
2852 temp = I915_READ(BXT_PORT_PLL(port, 8));
2853 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2854 temp |= pll->config.hw_state.pll8;
2855 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2856
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302857 temp = I915_READ(BXT_PORT_PLL(port, 9));
2858 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002859 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302860 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2861
2862 temp = I915_READ(BXT_PORT_PLL(port, 10));
2863 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2864 temp &= ~PORT_PLL_DCO_AMP_MASK;
2865 temp |= pll->config.hw_state.pll10;
2866 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302867
2868 /* Recalibrate with new settings */
2869 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2870 temp |= PORT_PLL_RECALIBRATE;
2871 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002872 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2873 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302874 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2875
2876 /* Enable PLL */
2877 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2878 temp |= PORT_PLL_ENABLE;
2879 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2880 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2881
2882 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2883 PORT_PLL_LOCK), 200))
2884 DRM_ERROR("PLL %d not locked\n", port);
2885
2886 /*
2887 * While we write to the group register to program all lanes at once we
2888 * can read only lane registers and we pick lanes 0/1 for that.
2889 */
2890 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2891 temp &= ~LANE_STAGGER_MASK;
2892 temp &= ~LANESTAGGER_STRAP_OVRD;
2893 temp |= pll->config.hw_state.pcsdw12;
2894 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2895}
2896
2897static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2898 struct intel_shared_dpll *pll)
2899{
2900 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2901 uint32_t temp;
2902
2903 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2904 temp &= ~PORT_PLL_ENABLE;
2905 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2906 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2907}
2908
2909static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2910 struct intel_shared_dpll *pll,
2911 struct intel_dpll_hw_state *hw_state)
2912{
2913 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2914 uint32_t val;
2915
2916 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2917 return false;
2918
2919 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2920 if (!(val & PORT_PLL_ENABLE))
2921 return false;
2922
2923 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002924 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2925
Imre Deak05712c12015-06-18 17:25:54 +03002926 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2927 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2928
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302929 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002930 hw_state->pll0 &= PORT_PLL_M2_MASK;
2931
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302932 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002933 hw_state->pll1 &= PORT_PLL_N_MASK;
2934
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302935 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002936 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2937
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302938 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002939 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2940
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302941 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002942 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2943 PORT_PLL_INT_COEFF_MASK |
2944 PORT_PLL_GAIN_CTL_MASK;
2945
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302946 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002947 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2948
Imre Deak05712c12015-06-18 17:25:54 +03002949 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2950 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2951
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302952 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002953 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2954 PORT_PLL_DCO_AMP_MASK;
2955
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302956 /*
2957 * While we write to the group register to program all lanes at once we
2958 * can read only lane registers. We configure all lanes the same way, so
2959 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2960 */
2961 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002962 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302963 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2964 hw_state->pcsdw12,
2965 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002966 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302967
2968 return true;
2969}
2970
2971static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2972{
2973 int i;
2974
2975 dev_priv->num_shared_dpll = 3;
2976
2977 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2978 dev_priv->shared_dplls[i].id = i;
2979 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2980 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2981 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2982 dev_priv->shared_dplls[i].get_hw_state =
2983 bxt_ddi_pll_get_hw_state;
2984 }
2985}
2986
Damien Lespiau143b3072014-07-29 18:06:19 +01002987void intel_ddi_pll_init(struct drm_device *dev)
2988{
2989 struct drm_i915_private *dev_priv = dev->dev_private;
2990 uint32_t val = I915_READ(LCPLL_CTL);
2991
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002992 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002993 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302994 else if (IS_BROXTON(dev))
2995 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002996 else
2997 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002998
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002999 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01003000 int cdclk_freq;
3001
3002 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01003003 dev_priv->skl_boot_cdclk = cdclk_freq;
Shobhit Kumarc73666f2015-10-20 18:13:12 +05303004 if (skl_sanitize_cdclk(dev_priv))
3005 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
Damien Lespiau2f693e22015-11-04 19:24:12 +02003006 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
3007 DRM_ERROR("LCPLL1 is disabled\n");
Vandana Kannanf8437dd12014-11-24 13:37:39 +05303008 } else if (IS_BROXTON(dev)) {
3009 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05303010 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003011 } else {
3012 /*
3013 * The LCPLL register should be turned on by the BIOS. For now
3014 * let's just check its state and print errors in case
3015 * something is wrong. Don't even try to turn it on.
3016 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003017
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003018 if (val & LCPLL_CD_SOURCE_FCLK)
3019 DRM_ERROR("CDCLK source is not LCPLL\n");
3020
3021 if (val & LCPLL_PLL_DISABLE)
3022 DRM_ERROR("LCPLL is disabled\n");
3023 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003024}
Paulo Zanonic19b0662012-10-15 15:51:41 -03003025
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003026void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
Paulo Zanonic19b0662012-10-15 15:51:41 -03003027{
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003028 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3029 struct drm_i915_private *dev_priv =
3030 to_i915(intel_dig_port->base.base.dev);
Paulo Zanoni174edf12012-10-26 19:05:50 -02003031 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003032 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05303033 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003034
3035 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
3036 val = I915_READ(DDI_BUF_CTL(port));
3037 if (val & DDI_BUF_CTL_ENABLE) {
3038 val &= ~DDI_BUF_CTL_ENABLE;
3039 I915_WRITE(DDI_BUF_CTL(port), val);
3040 wait = true;
3041 }
3042
3043 val = I915_READ(DP_TP_CTL(port));
3044 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3045 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3046 I915_WRITE(DP_TP_CTL(port), val);
3047 POSTING_READ(DP_TP_CTL(port));
3048
3049 if (wait)
3050 intel_wait_ddi_buf_idle(dev_priv, port);
3051 }
3052
Dave Airlie0e32b392014-05-02 14:02:48 +10003053 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003054 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003055 if (intel_dp->is_mst)
3056 val |= DP_TP_CTL_MODE_MST;
3057 else {
3058 val |= DP_TP_CTL_MODE_SST;
3059 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3060 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3061 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003062 I915_WRITE(DP_TP_CTL(port), val);
3063 POSTING_READ(DP_TP_CTL(port));
3064
3065 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3066 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3067 POSTING_READ(DDI_BUF_CTL(port));
3068
3069 udelay(600);
3070}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003071
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003072void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3073{
3074 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3075 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3076 uint32_t val;
3077
3078 intel_ddi_post_disable(intel_encoder);
3079
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003080 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003081 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003082 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003083
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003084 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003085 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3086 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003087 I915_WRITE(FDI_RX_MISC(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_PCDCLK;
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
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003093 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003094 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003095 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003096}
3097
Libin Yang3d52ccf2015-12-02 14:09:44 +08003098bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
3099 struct intel_crtc *intel_crtc)
3100{
3101 u32 temp;
3102
3103 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
3104 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
3105 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
3106 return true;
3107 }
3108 return false;
3109}
3110
Ville Syrjälä6801c182013-09-24 14:24:05 +03003111void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003112 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003113{
3114 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3115 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003116 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003117 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003118 u32 temp, flags = 0;
3119
3120 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3121 if (temp & TRANS_DDI_PHSYNC)
3122 flags |= DRM_MODE_FLAG_PHSYNC;
3123 else
3124 flags |= DRM_MODE_FLAG_NHSYNC;
3125 if (temp & TRANS_DDI_PVSYNC)
3126 flags |= DRM_MODE_FLAG_PVSYNC;
3127 else
3128 flags |= DRM_MODE_FLAG_NVSYNC;
3129
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003130 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003131
3132 switch (temp & TRANS_DDI_BPC_MASK) {
3133 case TRANS_DDI_BPC_6:
3134 pipe_config->pipe_bpp = 18;
3135 break;
3136 case TRANS_DDI_BPC_8:
3137 pipe_config->pipe_bpp = 24;
3138 break;
3139 case TRANS_DDI_BPC_10:
3140 pipe_config->pipe_bpp = 30;
3141 break;
3142 case TRANS_DDI_BPC_12:
3143 pipe_config->pipe_bpp = 36;
3144 break;
3145 default:
3146 break;
3147 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003148
3149 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3150 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003151 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003152 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3153
Ville Syrjäläcda0aaa2015-11-26 18:27:07 +02003154 if (intel_hdmi->infoframe_enabled(&encoder->base, pipe_config))
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003155 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003156 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003157 case TRANS_DDI_MODE_SELECT_DVI:
3158 case TRANS_DDI_MODE_SELECT_FDI:
3159 break;
3160 case TRANS_DDI_MODE_SELECT_DP_SST:
3161 case TRANS_DDI_MODE_SELECT_DP_MST:
3162 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003163 pipe_config->lane_count =
3164 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003165 intel_dp_get_m_n(intel_crtc, pipe_config);
3166 break;
3167 default:
3168 break;
3169 }
Daniel Vetter10214422013-11-18 07:38:16 +01003170
Libin Yang3d52ccf2015-12-02 14:09:44 +08003171 pipe_config->has_audio =
3172 intel_ddi_is_audio_enabled(dev_priv, intel_crtc);
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003173
Daniel Vetter10214422013-11-18 07:38:16 +01003174 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3175 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3176 /*
3177 * This is a big fat ugly hack.
3178 *
3179 * Some machines in UEFI boot mode provide us a VBT that has 18
3180 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3181 * unknown we fail to light up. Yet the same BIOS boots up with
3182 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3183 * max, not what it tells us to use.
3184 *
3185 * Note: This will still be broken if the eDP panel is not lit
3186 * up by the BIOS, and thus we can't get the mode at module
3187 * load.
3188 */
3189 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3190 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3191 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3192 }
Jesse Barnes11578552014-01-21 12:42:10 -08003193
Damien Lespiau22606a12014-12-12 14:26:57 +00003194 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003195}
3196
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003197static void intel_ddi_destroy(struct drm_encoder *encoder)
3198{
3199 /* HDMI has nothing special to destroy, so we can go with this. */
3200 intel_dp_encoder_destroy(encoder);
3201}
3202
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003203static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003204 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003205{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003206 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003207 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003208
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003209 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003210
Daniel Vettereccb1402013-05-22 00:50:22 +02003211 if (port == PORT_A)
3212 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3213
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003214 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003215 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003216 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003217 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003218}
3219
3220static const struct drm_encoder_funcs intel_ddi_funcs = {
3221 .destroy = intel_ddi_destroy,
3222};
3223
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003224static struct intel_connector *
3225intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3226{
3227 struct intel_connector *connector;
3228 enum port port = intel_dig_port->port;
3229
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003230 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003231 if (!connector)
3232 return NULL;
3233
3234 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3235 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3236 kfree(connector);
3237 return NULL;
3238 }
3239
3240 return connector;
3241}
3242
3243static struct intel_connector *
3244intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3245{
3246 struct intel_connector *connector;
3247 enum port port = intel_dig_port->port;
3248
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003249 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003250 if (!connector)
3251 return NULL;
3252
3253 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3254 intel_hdmi_init_connector(intel_dig_port, connector);
3255
3256 return connector;
3257}
3258
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003259void intel_ddi_init(struct drm_device *dev, enum port port)
3260{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003261 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003262 struct intel_digital_port *intel_dig_port;
3263 struct intel_encoder *intel_encoder;
3264 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003265 bool init_hdmi, init_dp;
Ville Syrjälä10e7bec2015-12-08 19:59:37 +02003266 int max_lanes;
3267
3268 if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
3269 switch (port) {
3270 case PORT_A:
3271 max_lanes = 4;
3272 break;
3273 case PORT_E:
3274 max_lanes = 0;
3275 break;
3276 default:
3277 max_lanes = 4;
3278 break;
3279 }
3280 } else {
3281 switch (port) {
3282 case PORT_A:
3283 max_lanes = 2;
3284 break;
3285 case PORT_E:
3286 max_lanes = 2;
3287 break;
3288 default:
3289 max_lanes = 4;
3290 break;
3291 }
3292 }
Paulo Zanoni311a2092013-09-12 17:12:18 -03003293
3294 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3295 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3296 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3297 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003298 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003299 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003300 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003301 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003302
Daniel Vetterb14c5672013-09-19 12:18:32 +02003303 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003304 if (!intel_dig_port)
3305 return;
3306
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003307 intel_encoder = &intel_dig_port->base;
3308 encoder = &intel_encoder->base;
3309
3310 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3311 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003312
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003313 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003314 intel_encoder->enable = intel_enable_ddi;
3315 intel_encoder->pre_enable = intel_ddi_pre_enable;
3316 intel_encoder->disable = intel_disable_ddi;
3317 intel_encoder->post_disable = intel_ddi_post_disable;
3318 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003319 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003320
3321 intel_dig_port->port = port;
Takashi Iwai0bdf5a02015-11-30 18:19:39 +01003322 dev_priv->dig_port_map[port] = intel_encoder;
Stéphane Marchesinbcf53de42013-07-12 13:54:41 -07003323 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3324 (DDI_BUF_PORT_REVERSAL |
3325 DDI_A_4_LANES);
Ville Syrjäläccb1a832015-12-08 19:59:38 +02003326 intel_dig_port->max_lanes = max_lanes;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003327
Matt Roper6c566dc2015-11-05 14:53:32 -08003328 /*
3329 * Bspec says that DDI_A_4_LANES is the only supported configuration
3330 * for Broxton. Yet some BIOS fail to set this bit on port A if eDP
3331 * wasn't lit up at boot. Force this bit on in our internal
3332 * configuration so that we use the proper lane count for our
3333 * calculations.
3334 */
3335 if (IS_BROXTON(dev) && port == PORT_A) {
3336 if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) {
3337 DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
3338 intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
3339 }
3340 }
3341
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003342 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003343 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003344 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003345
Chris Wilsonf68d6972014-08-04 07:15:09 +01003346 if (init_dp) {
3347 if (!intel_ddi_init_dp_connector(intel_dig_port))
3348 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003349
Chris Wilsonf68d6972014-08-04 07:15:09 +01003350 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303351 /*
3352 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3353 * interrupts to check the external panel connection.
3354 */
Jani Nikulae87a0052015-10-20 15:22:02 +03003355 if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303356 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3357 else
3358 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003359 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003360
Paulo Zanoni311a2092013-09-12 17:12:18 -03003361 /* In theory we don't need the encoder->type check, but leave it just in
3362 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003363 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3364 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3365 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003366 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003367
3368 return;
3369
3370err:
3371 drm_encoder_cleanup(encoder);
3372 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003373}