xref: /linux/drivers/gpu/drm/i915/display/intel_lt_phy.c (revision 24f171c7e145f43b9f187578e89b0982ce87e54c)
1154ebdb7SSuraj Kandpal // SPDX-License-Identifier: MIT
2154ebdb7SSuraj Kandpal /*
3154ebdb7SSuraj Kandpal  * Copyright © 2025 Intel Corporation
4154ebdb7SSuraj Kandpal  */
5154ebdb7SSuraj Kandpal 
6154ebdb7SSuraj Kandpal #include <drm/drm_print.h>
7154ebdb7SSuraj Kandpal 
8154ebdb7SSuraj Kandpal #include "i915_reg.h"
9154ebdb7SSuraj Kandpal #include "intel_cx0_phy.h"
10154ebdb7SSuraj Kandpal #include "intel_cx0_phy_regs.h"
1113ba213fSSuraj Kandpal #include "intel_ddi.h"
1213ba213fSSuraj Kandpal #include "intel_ddi_buf_trans.h"
13154ebdb7SSuraj Kandpal #include "intel_de.h"
14154ebdb7SSuraj Kandpal #include "intel_display.h"
15154ebdb7SSuraj Kandpal #include "intel_display_types.h"
16*4341dd24SJani Nikula #include "intel_display_utils.h"
17dc5742b6SSuraj Kandpal #include "intel_dpll_mgr.h"
183a323c7eSSuraj Kandpal #include "intel_hdmi.h"
19154ebdb7SSuraj Kandpal #include "intel_lt_phy.h"
20154ebdb7SSuraj Kandpal #include "intel_lt_phy_regs.h"
213383ba24SSuraj Kandpal #include "intel_panel.h"
22e1455196SSuraj Kandpal #include "intel_psr.h"
23154ebdb7SSuraj Kandpal #include "intel_tc.h"
24154ebdb7SSuraj Kandpal 
2541d07bd2SSuraj Kandpal #define for_each_lt_phy_lane_in_mask(__lane_mask, __lane) \
2641d07bd2SSuraj Kandpal 	for ((__lane) = 0; (__lane) < 2; (__lane)++) \
2741d07bd2SSuraj Kandpal 		for_each_if((__lane_mask) & BIT(__lane))
2841d07bd2SSuraj Kandpal 
29154ebdb7SSuraj Kandpal #define INTEL_LT_PHY_LANE0		BIT(0)
30154ebdb7SSuraj Kandpal #define INTEL_LT_PHY_LANE1		BIT(1)
31154ebdb7SSuraj Kandpal #define INTEL_LT_PHY_BOTH_LANES		(INTEL_LT_PHY_LANE1 |\
32154ebdb7SSuraj Kandpal 					 INTEL_LT_PHY_LANE0)
33e1455196SSuraj Kandpal #define MODE_DP				3
346fedb7bfSSuraj Kandpal #define Q32_TO_INT(x)	((x) >> 32)
356fedb7bfSSuraj Kandpal #define Q32_TO_FRAC(x)	((x) & 0xFFFFFFFF)
366fedb7bfSSuraj Kandpal #define DCO_MIN_FREQ_MHZ	11850
376fedb7bfSSuraj Kandpal #define REF_CLK_KHZ	38400
386fedb7bfSSuraj Kandpal #define TDC_RES_MULTIPLIER	10000000ULL
396fedb7bfSSuraj Kandpal 
406fedb7bfSSuraj Kandpal struct phy_param_t {
416fedb7bfSSuraj Kandpal 	u32 val;
426fedb7bfSSuraj Kandpal 	u32 addr;
436fedb7bfSSuraj Kandpal };
446fedb7bfSSuraj Kandpal 
456fedb7bfSSuraj Kandpal struct lt_phy_params {
466fedb7bfSSuraj Kandpal 	struct phy_param_t pll_reg4;
476fedb7bfSSuraj Kandpal 	struct phy_param_t pll_reg3;
486fedb7bfSSuraj Kandpal 	struct phy_param_t pll_reg5;
496fedb7bfSSuraj Kandpal 	struct phy_param_t pll_reg57;
506fedb7bfSSuraj Kandpal 	struct phy_param_t lf;
516fedb7bfSSuraj Kandpal 	struct phy_param_t tdc;
526fedb7bfSSuraj Kandpal 	struct phy_param_t ssc;
536fedb7bfSSuraj Kandpal 	struct phy_param_t bias2;
546fedb7bfSSuraj Kandpal 	struct phy_param_t bias_trim;
556fedb7bfSSuraj Kandpal 	struct phy_param_t dco_med;
566fedb7bfSSuraj Kandpal 	struct phy_param_t dco_fine;
576fedb7bfSSuraj Kandpal 	struct phy_param_t ssc_inj;
586fedb7bfSSuraj Kandpal 	struct phy_param_t surv_bonus;
596fedb7bfSSuraj Kandpal };
60154ebdb7SSuraj Kandpal 
61dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_rbr = {
62dc5742b6SSuraj Kandpal 	.clock = 162000,
63dc5742b6SSuraj Kandpal 	.config = {
64dc5742b6SSuraj Kandpal 		0x83,
65dc5742b6SSuraj Kandpal 		0x2d,
66dc5742b6SSuraj Kandpal 		0x0,
67dc5742b6SSuraj Kandpal 	},
68dc5742b6SSuraj Kandpal 	.addr_msb = {
69dc5742b6SSuraj Kandpal 		0x87,
70dc5742b6SSuraj Kandpal 		0x87,
71dc5742b6SSuraj Kandpal 		0x87,
72dc5742b6SSuraj Kandpal 		0x87,
73dc5742b6SSuraj Kandpal 		0x88,
74dc5742b6SSuraj Kandpal 		0x88,
75dc5742b6SSuraj Kandpal 		0x88,
76dc5742b6SSuraj Kandpal 		0x88,
77dc5742b6SSuraj Kandpal 		0x88,
78dc5742b6SSuraj Kandpal 		0x88,
79dc5742b6SSuraj Kandpal 		0x88,
80dc5742b6SSuraj Kandpal 		0x88,
81dc5742b6SSuraj Kandpal 		0x88,
82dc5742b6SSuraj Kandpal 	},
83dc5742b6SSuraj Kandpal 	.addr_lsb = {
84dc5742b6SSuraj Kandpal 		0x10,
85dc5742b6SSuraj Kandpal 		0x0c,
86dc5742b6SSuraj Kandpal 		0x14,
87dc5742b6SSuraj Kandpal 		0xe4,
88dc5742b6SSuraj Kandpal 		0x0c,
89dc5742b6SSuraj Kandpal 		0x10,
90dc5742b6SSuraj Kandpal 		0x14,
91dc5742b6SSuraj Kandpal 		0x18,
92dc5742b6SSuraj Kandpal 		0x48,
93dc5742b6SSuraj Kandpal 		0x40,
94dc5742b6SSuraj Kandpal 		0x4c,
95dc5742b6SSuraj Kandpal 		0x24,
96dc5742b6SSuraj Kandpal 		0x44,
97dc5742b6SSuraj Kandpal 	},
98dc5742b6SSuraj Kandpal 	.data = {
99dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
100dc5742b6SSuraj Kandpal 		{ 0x5,  0xa,  0x2a, 0x20 },
101dc5742b6SSuraj Kandpal 		{ 0x80, 0x0,  0x0,  0x0  },
102dc5742b6SSuraj Kandpal 		{ 0x4,  0x4,  0x82, 0x28 },
103dc5742b6SSuraj Kandpal 		{ 0xfa, 0x16, 0x83, 0x11 },
104dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
105dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x5,  0x4  },
106dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
107dc5742b6SSuraj Kandpal 		{ 0x4b, 0x48, 0x0,  0x0  },
108dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
109dc5742b6SSuraj Kandpal 		{ 0x5a, 0x13, 0x29, 0x13 },
110dc5742b6SSuraj Kandpal 		{ 0x0,  0x5b, 0xe0, 0x0a },
111dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
112dc5742b6SSuraj Kandpal 	},
113dc5742b6SSuraj Kandpal };
114dc5742b6SSuraj Kandpal 
115dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_hbr1 = {
116dc5742b6SSuraj Kandpal 	.clock = 270000,
117dc5742b6SSuraj Kandpal 	.config = {
118dc5742b6SSuraj Kandpal 		0x8b,
119dc5742b6SSuraj Kandpal 		0x2d,
120dc5742b6SSuraj Kandpal 		0x0,
121dc5742b6SSuraj Kandpal 	},
122dc5742b6SSuraj Kandpal 	.addr_msb = {
123dc5742b6SSuraj Kandpal 		0x87,
124dc5742b6SSuraj Kandpal 		0x87,
125dc5742b6SSuraj Kandpal 		0x87,
126dc5742b6SSuraj Kandpal 		0x87,
127dc5742b6SSuraj Kandpal 		0x88,
128dc5742b6SSuraj Kandpal 		0x88,
129dc5742b6SSuraj Kandpal 		0x88,
130dc5742b6SSuraj Kandpal 		0x88,
131dc5742b6SSuraj Kandpal 		0x88,
132dc5742b6SSuraj Kandpal 		0x88,
133dc5742b6SSuraj Kandpal 		0x88,
134dc5742b6SSuraj Kandpal 		0x88,
135dc5742b6SSuraj Kandpal 		0x88,
136dc5742b6SSuraj Kandpal 	},
137dc5742b6SSuraj Kandpal 	.addr_lsb = {
138dc5742b6SSuraj Kandpal 		0x10,
139dc5742b6SSuraj Kandpal 		0x0c,
140dc5742b6SSuraj Kandpal 		0x14,
141dc5742b6SSuraj Kandpal 		0xe4,
142dc5742b6SSuraj Kandpal 		0x0c,
143dc5742b6SSuraj Kandpal 		0x10,
144dc5742b6SSuraj Kandpal 		0x14,
145dc5742b6SSuraj Kandpal 		0x18,
146dc5742b6SSuraj Kandpal 		0x48,
147dc5742b6SSuraj Kandpal 		0x40,
148dc5742b6SSuraj Kandpal 		0x4c,
149dc5742b6SSuraj Kandpal 		0x24,
150dc5742b6SSuraj Kandpal 		0x44,
151dc5742b6SSuraj Kandpal 	},
152dc5742b6SSuraj Kandpal 	.data = {
153dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
154dc5742b6SSuraj Kandpal 		{ 0x3,  0xca, 0x34, 0xa0 },
155dc5742b6SSuraj Kandpal 		{ 0xe0, 0x0,  0x0,  0x0  },
156dc5742b6SSuraj Kandpal 		{ 0x5,  0x4,  0x81, 0xad },
157dc5742b6SSuraj Kandpal 		{ 0xfa, 0x11, 0x83, 0x11 },
158dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
159dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x7,  0x4  },
160dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
161dc5742b6SSuraj Kandpal 		{ 0x43, 0x48, 0x0,  0x0  },
162dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
163dc5742b6SSuraj Kandpal 		{ 0x5a, 0x13, 0x29, 0x13 },
164dc5742b6SSuraj Kandpal 		{ 0x0,  0x5b, 0xe0, 0x0d },
165dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
166dc5742b6SSuraj Kandpal 	},
167dc5742b6SSuraj Kandpal };
168dc5742b6SSuraj Kandpal 
169dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_hbr2 = {
170dc5742b6SSuraj Kandpal 	.clock = 540000,
171dc5742b6SSuraj Kandpal 	.config = {
172dc5742b6SSuraj Kandpal 		0x93,
173dc5742b6SSuraj Kandpal 		0x2d,
174dc5742b6SSuraj Kandpal 		0x0,
175dc5742b6SSuraj Kandpal 	},
176dc5742b6SSuraj Kandpal 	.addr_msb = {
177dc5742b6SSuraj Kandpal 		0x87,
178dc5742b6SSuraj Kandpal 		0x87,
179dc5742b6SSuraj Kandpal 		0x87,
180dc5742b6SSuraj Kandpal 		0x87,
181dc5742b6SSuraj Kandpal 		0x88,
182dc5742b6SSuraj Kandpal 		0x88,
183dc5742b6SSuraj Kandpal 		0x88,
184dc5742b6SSuraj Kandpal 		0x88,
185dc5742b6SSuraj Kandpal 		0x88,
186dc5742b6SSuraj Kandpal 		0x88,
187dc5742b6SSuraj Kandpal 		0x88,
188dc5742b6SSuraj Kandpal 		0x88,
189dc5742b6SSuraj Kandpal 		0x88,
190dc5742b6SSuraj Kandpal 	},
191dc5742b6SSuraj Kandpal 	.addr_lsb = {
192dc5742b6SSuraj Kandpal 		0x10,
193dc5742b6SSuraj Kandpal 		0x0c,
194dc5742b6SSuraj Kandpal 		0x14,
195dc5742b6SSuraj Kandpal 		0xe4,
196dc5742b6SSuraj Kandpal 		0x0c,
197dc5742b6SSuraj Kandpal 		0x10,
198dc5742b6SSuraj Kandpal 		0x14,
199dc5742b6SSuraj Kandpal 		0x18,
200dc5742b6SSuraj Kandpal 		0x48,
201dc5742b6SSuraj Kandpal 		0x40,
202dc5742b6SSuraj Kandpal 		0x4c,
203dc5742b6SSuraj Kandpal 		0x24,
204dc5742b6SSuraj Kandpal 		0x44,
205dc5742b6SSuraj Kandpal 	},
206dc5742b6SSuraj Kandpal 	.data = {
207dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
208dc5742b6SSuraj Kandpal 		{ 0x1,  0x4d, 0x34, 0xa0 },
209dc5742b6SSuraj Kandpal 		{ 0xe0, 0x0,  0x0,  0x0  },
210dc5742b6SSuraj Kandpal 		{ 0xa,  0x4,  0x81, 0xda },
211dc5742b6SSuraj Kandpal 		{ 0xfa, 0x11, 0x83, 0x11 },
212dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
213dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x7,  0x4  },
214dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
215dc5742b6SSuraj Kandpal 		{ 0x43, 0x48, 0x0,  0x0  },
216dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
217dc5742b6SSuraj Kandpal 		{ 0x5a, 0x13, 0x29, 0x13 },
218dc5742b6SSuraj Kandpal 		{ 0x0,  0x5b, 0xe0, 0x0d },
219dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
220dc5742b6SSuraj Kandpal 	},
221dc5742b6SSuraj Kandpal };
222dc5742b6SSuraj Kandpal 
223dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_hbr3 = {
224dc5742b6SSuraj Kandpal 	.clock = 810000,
225dc5742b6SSuraj Kandpal 	.config = {
226dc5742b6SSuraj Kandpal 		0x9b,
227dc5742b6SSuraj Kandpal 		0x2d,
228dc5742b6SSuraj Kandpal 		0x0,
229dc5742b6SSuraj Kandpal 	},
230dc5742b6SSuraj Kandpal 	.addr_msb = {
231dc5742b6SSuraj Kandpal 		0x87,
232dc5742b6SSuraj Kandpal 		0x87,
233dc5742b6SSuraj Kandpal 		0x87,
234dc5742b6SSuraj Kandpal 		0x87,
235dc5742b6SSuraj Kandpal 		0x88,
236dc5742b6SSuraj Kandpal 		0x88,
237dc5742b6SSuraj Kandpal 		0x88,
238dc5742b6SSuraj Kandpal 		0x88,
239dc5742b6SSuraj Kandpal 		0x88,
240dc5742b6SSuraj Kandpal 		0x88,
241dc5742b6SSuraj Kandpal 		0x88,
242dc5742b6SSuraj Kandpal 		0x88,
243dc5742b6SSuraj Kandpal 		0x88,
244dc5742b6SSuraj Kandpal 	},
245dc5742b6SSuraj Kandpal 	.addr_lsb = {
246dc5742b6SSuraj Kandpal 		0x10,
247dc5742b6SSuraj Kandpal 		0x0c,
248dc5742b6SSuraj Kandpal 		0x14,
249dc5742b6SSuraj Kandpal 		0xe4,
250dc5742b6SSuraj Kandpal 		0x0c,
251dc5742b6SSuraj Kandpal 		0x10,
252dc5742b6SSuraj Kandpal 		0x14,
253dc5742b6SSuraj Kandpal 		0x18,
254dc5742b6SSuraj Kandpal 		0x48,
255dc5742b6SSuraj Kandpal 		0x40,
256dc5742b6SSuraj Kandpal 		0x4c,
257dc5742b6SSuraj Kandpal 		0x24,
258dc5742b6SSuraj Kandpal 		0x44,
259dc5742b6SSuraj Kandpal 	},
260dc5742b6SSuraj Kandpal 	.data = {
261dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
262dc5742b6SSuraj Kandpal 		{ 0x1,  0x4a, 0x34, 0xa0 },
263dc5742b6SSuraj Kandpal 		{ 0xe0, 0x0,  0x0,  0x0  },
264dc5742b6SSuraj Kandpal 		{ 0x5,  0x4,  0x80, 0xa8 },
265dc5742b6SSuraj Kandpal 		{ 0xfa, 0x11, 0x83, 0x11 },
266dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
267dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x7,  0x4  },
268dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
269dc5742b6SSuraj Kandpal 		{ 0x43, 0x48, 0x0,  0x0  },
270dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
271dc5742b6SSuraj Kandpal 		{ 0x5a, 0x13, 0x29, 0x13 },
272dc5742b6SSuraj Kandpal 		{ 0x0,  0x5b, 0xe0, 0x0d },
273dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
274dc5742b6SSuraj Kandpal 	},
275dc5742b6SSuraj Kandpal };
276dc5742b6SSuraj Kandpal 
277dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_uhbr10 = {
278dc5742b6SSuraj Kandpal 	.clock = 1000000,
279dc5742b6SSuraj Kandpal 	.config = {
280dc5742b6SSuraj Kandpal 		0x43,
281dc5742b6SSuraj Kandpal 		0x2d,
282dc5742b6SSuraj Kandpal 		0x0,
283dc5742b6SSuraj Kandpal 	},
284dc5742b6SSuraj Kandpal 	.addr_msb = {
285dc5742b6SSuraj Kandpal 		0x85,
286dc5742b6SSuraj Kandpal 		0x85,
287dc5742b6SSuraj Kandpal 		0x85,
288dc5742b6SSuraj Kandpal 		0x85,
289dc5742b6SSuraj Kandpal 		0x86,
290dc5742b6SSuraj Kandpal 		0x86,
291dc5742b6SSuraj Kandpal 		0x86,
292dc5742b6SSuraj Kandpal 		0x86,
293dc5742b6SSuraj Kandpal 		0x86,
294dc5742b6SSuraj Kandpal 		0x86,
295dc5742b6SSuraj Kandpal 		0x86,
296dc5742b6SSuraj Kandpal 		0x86,
297dc5742b6SSuraj Kandpal 		0x86,
298dc5742b6SSuraj Kandpal 	},
299dc5742b6SSuraj Kandpal 	.addr_lsb = {
300dc5742b6SSuraj Kandpal 		0x10,
301dc5742b6SSuraj Kandpal 		0x0c,
302dc5742b6SSuraj Kandpal 		0x14,
303dc5742b6SSuraj Kandpal 		0xe4,
304dc5742b6SSuraj Kandpal 		0x0c,
305dc5742b6SSuraj Kandpal 		0x10,
306dc5742b6SSuraj Kandpal 		0x14,
307dc5742b6SSuraj Kandpal 		0x18,
308dc5742b6SSuraj Kandpal 		0x48,
309dc5742b6SSuraj Kandpal 		0x40,
310dc5742b6SSuraj Kandpal 		0x4c,
311dc5742b6SSuraj Kandpal 		0x24,
312dc5742b6SSuraj Kandpal 		0x44,
313dc5742b6SSuraj Kandpal 	},
314dc5742b6SSuraj Kandpal 	.data = {
315dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
316dc5742b6SSuraj Kandpal 		{ 0x1,  0xa,  0x20, 0x80 },
317dc5742b6SSuraj Kandpal 		{ 0x6a, 0xaa, 0xaa, 0xab },
318dc5742b6SSuraj Kandpal 		{ 0x0,  0x3,  0x4,  0x94 },
319dc5742b6SSuraj Kandpal 		{ 0xfa, 0x1c, 0x83, 0x11 },
320dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
321dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x4,  0x4  },
322dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
323dc5742b6SSuraj Kandpal 		{ 0x45, 0x48, 0x0,  0x0  },
324dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
325dc5742b6SSuraj Kandpal 		{ 0x5a, 0x14, 0x2a, 0x14 },
326dc5742b6SSuraj Kandpal 		{ 0x0,  0x5b, 0xe0, 0x8  },
327dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
328dc5742b6SSuraj Kandpal 	},
329dc5742b6SSuraj Kandpal };
330dc5742b6SSuraj Kandpal 
331dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_uhbr13_5 = {
332dc5742b6SSuraj Kandpal 	.clock = 1350000,
333dc5742b6SSuraj Kandpal 	.config = {
334dc5742b6SSuraj Kandpal 		0xcb,
335dc5742b6SSuraj Kandpal 		0x2d,
336dc5742b6SSuraj Kandpal 		0x0,
337dc5742b6SSuraj Kandpal 	},
338dc5742b6SSuraj Kandpal 	.addr_msb = {
339dc5742b6SSuraj Kandpal 		0x87,
340dc5742b6SSuraj Kandpal 		0x87,
341dc5742b6SSuraj Kandpal 		0x87,
342dc5742b6SSuraj Kandpal 		0x87,
343dc5742b6SSuraj Kandpal 		0x88,
344dc5742b6SSuraj Kandpal 		0x88,
345dc5742b6SSuraj Kandpal 		0x88,
346dc5742b6SSuraj Kandpal 		0x88,
347dc5742b6SSuraj Kandpal 		0x88,
348dc5742b6SSuraj Kandpal 		0x88,
349dc5742b6SSuraj Kandpal 		0x88,
350dc5742b6SSuraj Kandpal 		0x88,
351dc5742b6SSuraj Kandpal 		0x88,
352dc5742b6SSuraj Kandpal 	},
353dc5742b6SSuraj Kandpal 	.addr_lsb = {
354dc5742b6SSuraj Kandpal 		0x10,
355dc5742b6SSuraj Kandpal 		0x0c,
356dc5742b6SSuraj Kandpal 		0x14,
357dc5742b6SSuraj Kandpal 		0xe4,
358dc5742b6SSuraj Kandpal 		0x0c,
359dc5742b6SSuraj Kandpal 		0x10,
360dc5742b6SSuraj Kandpal 		0x14,
361dc5742b6SSuraj Kandpal 		0x18,
362dc5742b6SSuraj Kandpal 		0x48,
363dc5742b6SSuraj Kandpal 		0x40,
364dc5742b6SSuraj Kandpal 		0x4c,
365dc5742b6SSuraj Kandpal 		0x24,
366dc5742b6SSuraj Kandpal 		0x44,
367dc5742b6SSuraj Kandpal 	},
368dc5742b6SSuraj Kandpal 	.data = {
369dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
370dc5742b6SSuraj Kandpal 		{ 0x2,  0x9,  0x2b, 0xe0 },
371dc5742b6SSuraj Kandpal 		{ 0x90, 0x0,  0x0,  0x0  },
372dc5742b6SSuraj Kandpal 		{ 0x8,  0x4,  0x80, 0xe0 },
373dc5742b6SSuraj Kandpal 		{ 0xfa, 0x15, 0x83, 0x11 },
374dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
375dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x6,  0x4  },
376dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
377dc5742b6SSuraj Kandpal 		{ 0x49, 0x48, 0x0,  0x0  },
378dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
379dc5742b6SSuraj Kandpal 		{ 0x5a, 0x13, 0x29, 0x13 },
380dc5742b6SSuraj Kandpal 		{ 0x0,  0x57, 0xe0, 0x0c },
381dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
382dc5742b6SSuraj Kandpal 	},
383dc5742b6SSuraj Kandpal };
384dc5742b6SSuraj Kandpal 
385dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_uhbr20 = {
386dc5742b6SSuraj Kandpal 	.clock = 2000000,
387dc5742b6SSuraj Kandpal 	.config = {
388dc5742b6SSuraj Kandpal 		0x53,
389dc5742b6SSuraj Kandpal 		0x2d,
390dc5742b6SSuraj Kandpal 		0x0,
391dc5742b6SSuraj Kandpal 	},
392dc5742b6SSuraj Kandpal 	.addr_msb = {
393dc5742b6SSuraj Kandpal 		0x85,
394dc5742b6SSuraj Kandpal 		0x85,
395dc5742b6SSuraj Kandpal 		0x85,
396dc5742b6SSuraj Kandpal 		0x85,
397dc5742b6SSuraj Kandpal 		0x86,
398dc5742b6SSuraj Kandpal 		0x86,
399dc5742b6SSuraj Kandpal 		0x86,
400dc5742b6SSuraj Kandpal 		0x86,
401dc5742b6SSuraj Kandpal 		0x86,
402dc5742b6SSuraj Kandpal 		0x86,
403dc5742b6SSuraj Kandpal 		0x86,
404dc5742b6SSuraj Kandpal 		0x86,
405dc5742b6SSuraj Kandpal 		0x86,
406dc5742b6SSuraj Kandpal 	},
407dc5742b6SSuraj Kandpal 	.addr_lsb = {
408dc5742b6SSuraj Kandpal 		0x10,
409dc5742b6SSuraj Kandpal 		0x0c,
410dc5742b6SSuraj Kandpal 		0x14,
411dc5742b6SSuraj Kandpal 		0xe4,
412dc5742b6SSuraj Kandpal 		0x0c,
413dc5742b6SSuraj Kandpal 		0x10,
414dc5742b6SSuraj Kandpal 		0x14,
415dc5742b6SSuraj Kandpal 		0x18,
416dc5742b6SSuraj Kandpal 		0x48,
417dc5742b6SSuraj Kandpal 		0x40,
418dc5742b6SSuraj Kandpal 		0x4c,
419dc5742b6SSuraj Kandpal 		0x24,
420dc5742b6SSuraj Kandpal 		0x44,
421dc5742b6SSuraj Kandpal 	},
422dc5742b6SSuraj Kandpal 	.data = {
423dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
424dc5742b6SSuraj Kandpal 		{ 0x1,  0xa,  0x20, 0x80 },
425dc5742b6SSuraj Kandpal 		{ 0x6a, 0xaa, 0xaa, 0xab },
426dc5742b6SSuraj Kandpal 		{ 0x0,  0x3,  0x4,  0x94 },
427dc5742b6SSuraj Kandpal 		{ 0xfa, 0x1c, 0x83, 0x11 },
428dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
429dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x4,  0x4  },
430dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
431dc5742b6SSuraj Kandpal 		{ 0x45, 0x48, 0x0,  0x0  },
432dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
433dc5742b6SSuraj Kandpal 		{ 0x5a, 0x14, 0x2a, 0x14 },
434dc5742b6SSuraj Kandpal 		{ 0x0,  0x5b, 0xe0, 0x8  },
435dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
436dc5742b6SSuraj Kandpal 	},
437dc5742b6SSuraj Kandpal };
438dc5742b6SSuraj Kandpal 
439dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state * const xe3plpd_lt_dp_tables[] = {
440dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_rbr,
441dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_hbr1,
442dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_hbr2,
443dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_hbr3,
444dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_uhbr10,
445dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_uhbr13_5,
446dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_uhbr20,
447dc5742b6SSuraj Kandpal 	NULL,
448dc5742b6SSuraj Kandpal };
449dc5742b6SSuraj Kandpal 
450dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_edp_2_16 = {
451dc5742b6SSuraj Kandpal 	.clock = 216000,
452dc5742b6SSuraj Kandpal 	.config = {
453dc5742b6SSuraj Kandpal 		0xa3,
454dc5742b6SSuraj Kandpal 		0x2d,
455dc5742b6SSuraj Kandpal 		0x1,
456dc5742b6SSuraj Kandpal 	},
457dc5742b6SSuraj Kandpal 	.addr_msb = {
458dc5742b6SSuraj Kandpal 		0x87,
459dc5742b6SSuraj Kandpal 		0x87,
460dc5742b6SSuraj Kandpal 		0x87,
461dc5742b6SSuraj Kandpal 		0x87,
462dc5742b6SSuraj Kandpal 		0x88,
463dc5742b6SSuraj Kandpal 		0x88,
464dc5742b6SSuraj Kandpal 		0x88,
465dc5742b6SSuraj Kandpal 		0x88,
466dc5742b6SSuraj Kandpal 		0x88,
467dc5742b6SSuraj Kandpal 		0x88,
468dc5742b6SSuraj Kandpal 		0x88,
469dc5742b6SSuraj Kandpal 		0x88,
470dc5742b6SSuraj Kandpal 		0x88,
471dc5742b6SSuraj Kandpal 	},
472dc5742b6SSuraj Kandpal 	.addr_lsb = {
473dc5742b6SSuraj Kandpal 		0x10,
474dc5742b6SSuraj Kandpal 		0x0c,
475dc5742b6SSuraj Kandpal 		0x14,
476dc5742b6SSuraj Kandpal 		0xe4,
477dc5742b6SSuraj Kandpal 		0x0c,
478dc5742b6SSuraj Kandpal 		0x10,
479dc5742b6SSuraj Kandpal 		0x14,
480dc5742b6SSuraj Kandpal 		0x18,
481dc5742b6SSuraj Kandpal 		0x48,
482dc5742b6SSuraj Kandpal 		0x40,
483dc5742b6SSuraj Kandpal 		0x4c,
484dc5742b6SSuraj Kandpal 		0x24,
485dc5742b6SSuraj Kandpal 		0x44,
486dc5742b6SSuraj Kandpal 	},
487dc5742b6SSuraj Kandpal 	.data = {
488dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
489dc5742b6SSuraj Kandpal 		{ 0x3,  0xca, 0x2a, 0x20 },
490dc5742b6SSuraj Kandpal 		{ 0x80, 0x0,  0x0,  0x0  },
491dc5742b6SSuraj Kandpal 		{ 0x6,  0x4,  0x81, 0xbc },
492dc5742b6SSuraj Kandpal 		{ 0xfa, 0x16, 0x83, 0x11 },
493dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
494dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x5,  0x4  },
495dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
496dc5742b6SSuraj Kandpal 		{ 0x4b, 0x48, 0x0,  0x0  },
497dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
498dc5742b6SSuraj Kandpal 		{ 0x5a, 0x13, 0x29, 0x13 },
499dc5742b6SSuraj Kandpal 		{ 0x0,  0x5b, 0xe0, 0x0a },
500dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
501dc5742b6SSuraj Kandpal 	},
502dc5742b6SSuraj Kandpal };
503dc5742b6SSuraj Kandpal 
504dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_edp_2_43 = {
505dc5742b6SSuraj Kandpal 	.clock = 243000,
506dc5742b6SSuraj Kandpal 	.config = {
507dc5742b6SSuraj Kandpal 		0xab,
508dc5742b6SSuraj Kandpal 		0x2d,
509dc5742b6SSuraj Kandpal 		0x1,
510dc5742b6SSuraj Kandpal 	},
511dc5742b6SSuraj Kandpal 	.addr_msb = {
512dc5742b6SSuraj Kandpal 		0x87,
513dc5742b6SSuraj Kandpal 		0x87,
514dc5742b6SSuraj Kandpal 		0x87,
515dc5742b6SSuraj Kandpal 		0x87,
516dc5742b6SSuraj Kandpal 		0x88,
517dc5742b6SSuraj Kandpal 		0x88,
518dc5742b6SSuraj Kandpal 		0x88,
519dc5742b6SSuraj Kandpal 		0x88,
520dc5742b6SSuraj Kandpal 		0x88,
521dc5742b6SSuraj Kandpal 		0x88,
522dc5742b6SSuraj Kandpal 		0x88,
523dc5742b6SSuraj Kandpal 		0x88,
524dc5742b6SSuraj Kandpal 		0x88,
525dc5742b6SSuraj Kandpal 	},
526dc5742b6SSuraj Kandpal 	.addr_lsb = {
527dc5742b6SSuraj Kandpal 		0x10,
528dc5742b6SSuraj Kandpal 		0x0c,
529dc5742b6SSuraj Kandpal 		0x14,
530dc5742b6SSuraj Kandpal 		0xe4,
531dc5742b6SSuraj Kandpal 		0x0c,
532dc5742b6SSuraj Kandpal 		0x10,
533dc5742b6SSuraj Kandpal 		0x14,
534dc5742b6SSuraj Kandpal 		0x18,
535dc5742b6SSuraj Kandpal 		0x48,
536dc5742b6SSuraj Kandpal 		0x40,
537dc5742b6SSuraj Kandpal 		0x4c,
538dc5742b6SSuraj Kandpal 		0x24,
539dc5742b6SSuraj Kandpal 		0x44,
540dc5742b6SSuraj Kandpal 	},
541dc5742b6SSuraj Kandpal 	.data = {
542dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
543dc5742b6SSuraj Kandpal 		{ 0x3,  0xca, 0x2f, 0x60 },
544dc5742b6SSuraj Kandpal 		{ 0xb0, 0x0,  0x0,  0x0  },
545dc5742b6SSuraj Kandpal 		{ 0x6,  0x4,  0x81, 0xbc },
546dc5742b6SSuraj Kandpal 		{ 0xfa, 0x13, 0x83, 0x11 },
547dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
548dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x6,  0x4  },
549dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
550dc5742b6SSuraj Kandpal 		{ 0x47, 0x48, 0x0,  0x0  },
551dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
552dc5742b6SSuraj Kandpal 		{ 0x5a, 0x13, 0x29, 0x13 },
553dc5742b6SSuraj Kandpal 		{ 0x0,  0x5b, 0xe0, 0x0c },
554dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
555dc5742b6SSuraj Kandpal 	},
556dc5742b6SSuraj Kandpal };
557dc5742b6SSuraj Kandpal 
558dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_edp_3_24 = {
559dc5742b6SSuraj Kandpal 	.clock = 324000,
560dc5742b6SSuraj Kandpal 	.config = {
561dc5742b6SSuraj Kandpal 		0xb3,
562dc5742b6SSuraj Kandpal 		0x2d,
563dc5742b6SSuraj Kandpal 		0x1,
564dc5742b6SSuraj Kandpal 	},
565dc5742b6SSuraj Kandpal 	.addr_msb = {
566dc5742b6SSuraj Kandpal 		0x87,
567dc5742b6SSuraj Kandpal 		0x87,
568dc5742b6SSuraj Kandpal 		0x87,
569dc5742b6SSuraj Kandpal 		0x87,
570dc5742b6SSuraj Kandpal 		0x88,
571dc5742b6SSuraj Kandpal 		0x88,
572dc5742b6SSuraj Kandpal 		0x88,
573dc5742b6SSuraj Kandpal 		0x88,
574dc5742b6SSuraj Kandpal 		0x88,
575dc5742b6SSuraj Kandpal 		0x88,
576dc5742b6SSuraj Kandpal 		0x88,
577dc5742b6SSuraj Kandpal 		0x88,
578dc5742b6SSuraj Kandpal 		0x88,
579dc5742b6SSuraj Kandpal 	},
580dc5742b6SSuraj Kandpal 	.addr_lsb = {
581dc5742b6SSuraj Kandpal 		0x10,
582dc5742b6SSuraj Kandpal 		0x0c,
583dc5742b6SSuraj Kandpal 		0x14,
584dc5742b6SSuraj Kandpal 		0xe4,
585dc5742b6SSuraj Kandpal 		0x0c,
586dc5742b6SSuraj Kandpal 		0x10,
587dc5742b6SSuraj Kandpal 		0x14,
588dc5742b6SSuraj Kandpal 		0x18,
589dc5742b6SSuraj Kandpal 		0x48,
590dc5742b6SSuraj Kandpal 		0x40,
591dc5742b6SSuraj Kandpal 		0x4c,
592dc5742b6SSuraj Kandpal 		0x24,
593dc5742b6SSuraj Kandpal 		0x44,
594dc5742b6SSuraj Kandpal 	},
595dc5742b6SSuraj Kandpal 	.data = {
596dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
597dc5742b6SSuraj Kandpal 		{ 0x2,  0x8a, 0x2a, 0x20 },
598dc5742b6SSuraj Kandpal 		{ 0x80, 0x0,  0x0,  0x0  },
599dc5742b6SSuraj Kandpal 		{ 0x6,  0x4,  0x81, 0x28 },
600dc5742b6SSuraj Kandpal 		{ 0xfa, 0x16, 0x83, 0x11 },
601dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
602dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x5,  0x4  },
603dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
604dc5742b6SSuraj Kandpal 		{ 0x4b, 0x48, 0x0,  0x0  },
605dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
606dc5742b6SSuraj Kandpal 		{ 0x5a, 0x13, 0x29, 0x13 },
607dc5742b6SSuraj Kandpal 		{ 0x0,  0x5b, 0xe0, 0x0a },
608dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
609dc5742b6SSuraj Kandpal 	},
610dc5742b6SSuraj Kandpal };
611dc5742b6SSuraj Kandpal 
612dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_edp_4_32 = {
613dc5742b6SSuraj Kandpal 	.clock = 432000,
614dc5742b6SSuraj Kandpal 	.config = {
615dc5742b6SSuraj Kandpal 		0xbb,
616dc5742b6SSuraj Kandpal 		0x2d,
617dc5742b6SSuraj Kandpal 		0x1,
618dc5742b6SSuraj Kandpal 	},
619dc5742b6SSuraj Kandpal 	.addr_msb = {
620dc5742b6SSuraj Kandpal 		0x87,
621dc5742b6SSuraj Kandpal 		0x87,
622dc5742b6SSuraj Kandpal 		0x87,
623dc5742b6SSuraj Kandpal 		0x87,
624dc5742b6SSuraj Kandpal 		0x88,
625dc5742b6SSuraj Kandpal 		0x88,
626dc5742b6SSuraj Kandpal 		0x88,
627dc5742b6SSuraj Kandpal 		0x88,
628dc5742b6SSuraj Kandpal 		0x88,
629dc5742b6SSuraj Kandpal 		0x88,
630dc5742b6SSuraj Kandpal 		0x88,
631dc5742b6SSuraj Kandpal 		0x88,
632dc5742b6SSuraj Kandpal 		0x88,
633dc5742b6SSuraj Kandpal 	},
634dc5742b6SSuraj Kandpal 	.addr_lsb = {
635dc5742b6SSuraj Kandpal 		0x10,
636dc5742b6SSuraj Kandpal 		0x0c,
637dc5742b6SSuraj Kandpal 		0x14,
638dc5742b6SSuraj Kandpal 		0xe4,
639dc5742b6SSuraj Kandpal 		0x0c,
640dc5742b6SSuraj Kandpal 		0x10,
641dc5742b6SSuraj Kandpal 		0x14,
642dc5742b6SSuraj Kandpal 		0x18,
643dc5742b6SSuraj Kandpal 		0x48,
644dc5742b6SSuraj Kandpal 		0x40,
645dc5742b6SSuraj Kandpal 		0x4c,
646dc5742b6SSuraj Kandpal 		0x24,
647dc5742b6SSuraj Kandpal 		0x44,
648dc5742b6SSuraj Kandpal 	},
649dc5742b6SSuraj Kandpal 	.data = {
650dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
651dc5742b6SSuraj Kandpal 		{ 0x1,  0x4d, 0x2a, 0x20 },
652dc5742b6SSuraj Kandpal 		{ 0x80, 0x0,  0x0,  0x0  },
653dc5742b6SSuraj Kandpal 		{ 0xc,  0x4,  0x81, 0xbc },
654dc5742b6SSuraj Kandpal 		{ 0xfa, 0x16, 0x83, 0x11 },
655dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
656dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x5,  0x4  },
657dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
658dc5742b6SSuraj Kandpal 		{ 0x4b, 0x48, 0x0,  0x0  },
659dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
660dc5742b6SSuraj Kandpal 		{ 0x5a, 0x13, 0x29, 0x13 },
661dc5742b6SSuraj Kandpal 		{ 0x0,  0x5b, 0xe0, 0x0a },
662dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
663dc5742b6SSuraj Kandpal 	},
664dc5742b6SSuraj Kandpal };
665dc5742b6SSuraj Kandpal 
666dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_edp_6_75 = {
667dc5742b6SSuraj Kandpal 	.clock = 675000,
668dc5742b6SSuraj Kandpal 	.config = {
669dc5742b6SSuraj Kandpal 		0xdb,
670dc5742b6SSuraj Kandpal 		0x2d,
671dc5742b6SSuraj Kandpal 		0x1,
672dc5742b6SSuraj Kandpal 	},
673dc5742b6SSuraj Kandpal 	.addr_msb = {
674dc5742b6SSuraj Kandpal 		0x87,
675dc5742b6SSuraj Kandpal 		0x87,
676dc5742b6SSuraj Kandpal 		0x87,
677dc5742b6SSuraj Kandpal 		0x87,
678dc5742b6SSuraj Kandpal 		0x88,
679dc5742b6SSuraj Kandpal 		0x88,
680dc5742b6SSuraj Kandpal 		0x88,
681dc5742b6SSuraj Kandpal 		0x88,
682dc5742b6SSuraj Kandpal 		0x88,
683dc5742b6SSuraj Kandpal 		0x88,
684dc5742b6SSuraj Kandpal 		0x88,
685dc5742b6SSuraj Kandpal 		0x88,
686dc5742b6SSuraj Kandpal 		0x88,
687dc5742b6SSuraj Kandpal 	},
688dc5742b6SSuraj Kandpal 	.addr_lsb = {
689dc5742b6SSuraj Kandpal 		0x10,
690dc5742b6SSuraj Kandpal 		0x0c,
691dc5742b6SSuraj Kandpal 		0x14,
692dc5742b6SSuraj Kandpal 		0xe4,
693dc5742b6SSuraj Kandpal 		0x0c,
694dc5742b6SSuraj Kandpal 		0x10,
695dc5742b6SSuraj Kandpal 		0x14,
696dc5742b6SSuraj Kandpal 		0x18,
697dc5742b6SSuraj Kandpal 		0x48,
698dc5742b6SSuraj Kandpal 		0x40,
699dc5742b6SSuraj Kandpal 		0x4c,
700dc5742b6SSuraj Kandpal 		0x24,
701dc5742b6SSuraj Kandpal 		0x44,
702dc5742b6SSuraj Kandpal 	},
703dc5742b6SSuraj Kandpal 	.data = {
704dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
705dc5742b6SSuraj Kandpal 		{ 0x1,  0x4a, 0x2b, 0xe0 },
706dc5742b6SSuraj Kandpal 		{ 0x90, 0x0,  0x0,  0x0  },
707dc5742b6SSuraj Kandpal 		{ 0x6,  0x4,  0x80, 0xa8 },
708dc5742b6SSuraj Kandpal 		{ 0xfa, 0x15, 0x83, 0x11 },
709dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xf9, 0x53 },
710dc5742b6SSuraj Kandpal 		{ 0x84, 0x26, 0x6,  0x4  },
711dc5742b6SSuraj Kandpal 		{ 0x0,  0xe0, 0x1,  0x0  },
712dc5742b6SSuraj Kandpal 		{ 0x49, 0x48, 0x0,  0x0  },
713dc5742b6SSuraj Kandpal 		{ 0x27, 0x8,  0x0,  0x0  },
714dc5742b6SSuraj Kandpal 		{ 0x5a, 0x13, 0x29, 0x13 },
715dc5742b6SSuraj Kandpal 		{ 0x0,  0x57, 0xe0, 0x0c },
716dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
717dc5742b6SSuraj Kandpal 	},
718dc5742b6SSuraj Kandpal };
719dc5742b6SSuraj Kandpal 
720dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state * const xe3plpd_lt_edp_tables[] = {
721dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_rbr,
722dc5742b6SSuraj Kandpal 	&xe3plpd_lt_edp_2_16,
723dc5742b6SSuraj Kandpal 	&xe3plpd_lt_edp_2_43,
724dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_hbr1,
725dc5742b6SSuraj Kandpal 	&xe3plpd_lt_edp_3_24,
726dc5742b6SSuraj Kandpal 	&xe3plpd_lt_edp_4_32,
727dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_hbr2,
728dc5742b6SSuraj Kandpal 	&xe3plpd_lt_edp_6_75,
729dc5742b6SSuraj Kandpal 	&xe3plpd_lt_dp_hbr3,
730dc5742b6SSuraj Kandpal 	NULL,
731dc5742b6SSuraj Kandpal };
732dc5742b6SSuraj Kandpal 
733dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_hdmi_252 = {
734dc5742b6SSuraj Kandpal 	.clock = 25200,
735dc5742b6SSuraj Kandpal 	.config = {
736dc5742b6SSuraj Kandpal 		0x84,
737dc5742b6SSuraj Kandpal 		0x2d,
738dc5742b6SSuraj Kandpal 		0x0,
739dc5742b6SSuraj Kandpal 	},
740dc5742b6SSuraj Kandpal 	.addr_msb = {
741dc5742b6SSuraj Kandpal 		0x87,
742dc5742b6SSuraj Kandpal 		0x87,
743dc5742b6SSuraj Kandpal 		0x87,
744dc5742b6SSuraj Kandpal 		0x87,
745dc5742b6SSuraj Kandpal 		0x88,
746dc5742b6SSuraj Kandpal 		0x88,
747dc5742b6SSuraj Kandpal 		0x88,
748dc5742b6SSuraj Kandpal 		0x88,
749dc5742b6SSuraj Kandpal 		0x88,
750dc5742b6SSuraj Kandpal 		0x88,
751dc5742b6SSuraj Kandpal 		0x88,
752dc5742b6SSuraj Kandpal 		0x88,
753dc5742b6SSuraj Kandpal 		0x88,
754dc5742b6SSuraj Kandpal 	},
755dc5742b6SSuraj Kandpal 	.addr_lsb = {
756dc5742b6SSuraj Kandpal 		0x10,
757dc5742b6SSuraj Kandpal 		0x0c,
758dc5742b6SSuraj Kandpal 		0x14,
759dc5742b6SSuraj Kandpal 		0xe4,
760dc5742b6SSuraj Kandpal 		0x0c,
761dc5742b6SSuraj Kandpal 		0x10,
762dc5742b6SSuraj Kandpal 		0x14,
763dc5742b6SSuraj Kandpal 		0x18,
764dc5742b6SSuraj Kandpal 		0x48,
765dc5742b6SSuraj Kandpal 		0x40,
766dc5742b6SSuraj Kandpal 		0x4c,
767dc5742b6SSuraj Kandpal 		0x24,
768dc5742b6SSuraj Kandpal 		0x44,
769dc5742b6SSuraj Kandpal 	},
770dc5742b6SSuraj Kandpal 	.data = {
771dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
772dc5742b6SSuraj Kandpal 		{ 0x0c, 0x15, 0x27, 0x60 },
773dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
774dc5742b6SSuraj Kandpal 		{ 0x8,  0x4,  0x98, 0x28 },
775dc5742b6SSuraj Kandpal 		{ 0x42, 0x0,  0x84, 0x10 },
776dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xd9, 0xb5 },
777dc5742b6SSuraj Kandpal 		{ 0x86, 0x0,  0x0,  0x0  },
778dc5742b6SSuraj Kandpal 		{ 0x1,  0xa0, 0x1,  0x0  },
779dc5742b6SSuraj Kandpal 		{ 0x4b, 0x0,  0x0,  0x0  },
780dc5742b6SSuraj Kandpal 		{ 0x28, 0x0,  0x0,  0x0  },
781dc5742b6SSuraj Kandpal 		{ 0x0,  0x14, 0x2a, 0x14 },
782dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
783dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
784dc5742b6SSuraj Kandpal 	},
785dc5742b6SSuraj Kandpal };
786dc5742b6SSuraj Kandpal 
787dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_hdmi_272 = {
788dc5742b6SSuraj Kandpal 	.clock = 27200,
789dc5742b6SSuraj Kandpal 	.config = {
790dc5742b6SSuraj Kandpal 		0x84,
791dc5742b6SSuraj Kandpal 		0x2d,
792dc5742b6SSuraj Kandpal 		0x0,
793dc5742b6SSuraj Kandpal 	},
794dc5742b6SSuraj Kandpal 	.addr_msb = {
795dc5742b6SSuraj Kandpal 		0x87,
796dc5742b6SSuraj Kandpal 		0x87,
797dc5742b6SSuraj Kandpal 		0x87,
798dc5742b6SSuraj Kandpal 		0x87,
799dc5742b6SSuraj Kandpal 		0x88,
800dc5742b6SSuraj Kandpal 		0x88,
801dc5742b6SSuraj Kandpal 		0x88,
802dc5742b6SSuraj Kandpal 		0x88,
803dc5742b6SSuraj Kandpal 		0x88,
804dc5742b6SSuraj Kandpal 		0x88,
805dc5742b6SSuraj Kandpal 		0x88,
806dc5742b6SSuraj Kandpal 		0x88,
807dc5742b6SSuraj Kandpal 		0x88,
808dc5742b6SSuraj Kandpal 	},
809dc5742b6SSuraj Kandpal 	.addr_lsb = {
810dc5742b6SSuraj Kandpal 		0x10,
811dc5742b6SSuraj Kandpal 		0x0c,
812dc5742b6SSuraj Kandpal 		0x14,
813dc5742b6SSuraj Kandpal 		0xe4,
814dc5742b6SSuraj Kandpal 		0x0c,
815dc5742b6SSuraj Kandpal 		0x10,
816dc5742b6SSuraj Kandpal 		0x14,
817dc5742b6SSuraj Kandpal 		0x18,
818dc5742b6SSuraj Kandpal 		0x48,
819dc5742b6SSuraj Kandpal 		0x40,
820dc5742b6SSuraj Kandpal 		0x4c,
821dc5742b6SSuraj Kandpal 		0x24,
822dc5742b6SSuraj Kandpal 		0x44,
823dc5742b6SSuraj Kandpal 	},
824dc5742b6SSuraj Kandpal 	.data = {
825dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
826dc5742b6SSuraj Kandpal 		{ 0x0b, 0x15, 0x26, 0xa0 },
827dc5742b6SSuraj Kandpal 		{ 0x60, 0x0,  0x0,  0x0  },
828dc5742b6SSuraj Kandpal 		{ 0x8,  0x4,  0x96, 0x28 },
829dc5742b6SSuraj Kandpal 		{ 0xfa, 0x0c, 0x84, 0x11 },
830dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xd9, 0x53 },
831dc5742b6SSuraj Kandpal 		{ 0x86, 0x0,  0x0,  0x0  },
832dc5742b6SSuraj Kandpal 		{ 0x1,  0xa0, 0x1,  0x0  },
833dc5742b6SSuraj Kandpal 		{ 0x4b, 0x0,  0x0,  0x0  },
834dc5742b6SSuraj Kandpal 		{ 0x28, 0x0,  0x0,  0x0  },
835dc5742b6SSuraj Kandpal 		{ 0x0,  0x14, 0x2a, 0x14 },
836dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
837dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
838dc5742b6SSuraj Kandpal 	},
839dc5742b6SSuraj Kandpal };
840dc5742b6SSuraj Kandpal 
841dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_hdmi_742p5 = {
842dc5742b6SSuraj Kandpal 	.clock = 74250,
843dc5742b6SSuraj Kandpal 	.config = {
844dc5742b6SSuraj Kandpal 		0x84,
845dc5742b6SSuraj Kandpal 		0x2d,
846dc5742b6SSuraj Kandpal 		0x0,
847dc5742b6SSuraj Kandpal 	},
848dc5742b6SSuraj Kandpal 	.addr_msb = {
849dc5742b6SSuraj Kandpal 		0x87,
850dc5742b6SSuraj Kandpal 		0x87,
851dc5742b6SSuraj Kandpal 		0x87,
852dc5742b6SSuraj Kandpal 		0x87,
853dc5742b6SSuraj Kandpal 		0x88,
854dc5742b6SSuraj Kandpal 		0x88,
855dc5742b6SSuraj Kandpal 		0x88,
856dc5742b6SSuraj Kandpal 		0x88,
857dc5742b6SSuraj Kandpal 		0x88,
858dc5742b6SSuraj Kandpal 		0x88,
859dc5742b6SSuraj Kandpal 		0x88,
860dc5742b6SSuraj Kandpal 		0x88,
861dc5742b6SSuraj Kandpal 		0x88,
862dc5742b6SSuraj Kandpal 	},
863dc5742b6SSuraj Kandpal 	.addr_lsb = {
864dc5742b6SSuraj Kandpal 		0x10,
865dc5742b6SSuraj Kandpal 		0x0c,
866dc5742b6SSuraj Kandpal 		0x14,
867dc5742b6SSuraj Kandpal 		0xe4,
868dc5742b6SSuraj Kandpal 		0x0c,
869dc5742b6SSuraj Kandpal 		0x10,
870dc5742b6SSuraj Kandpal 		0x14,
871dc5742b6SSuraj Kandpal 		0x18,
872dc5742b6SSuraj Kandpal 		0x48,
873dc5742b6SSuraj Kandpal 		0x40,
874dc5742b6SSuraj Kandpal 		0x4c,
875dc5742b6SSuraj Kandpal 		0x24,
876dc5742b6SSuraj Kandpal 		0x44,
877dc5742b6SSuraj Kandpal 	},
878dc5742b6SSuraj Kandpal 	.data = {
879dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
880dc5742b6SSuraj Kandpal 		{ 0x4,  0x15, 0x26, 0xa0 },
881dc5742b6SSuraj Kandpal 		{ 0x60, 0x0,  0x0,  0x0  },
882dc5742b6SSuraj Kandpal 		{ 0x8,  0x4,  0x88, 0x28 },
883dc5742b6SSuraj Kandpal 		{ 0xfa, 0x0c, 0x84, 0x11 },
884dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xd9, 0x53 },
885dc5742b6SSuraj Kandpal 		{ 0x86, 0x0,  0x0,  0x0  },
886dc5742b6SSuraj Kandpal 		{ 0x1,  0xa0, 0x1,  0x0  },
887dc5742b6SSuraj Kandpal 		{ 0x4b, 0x0,  0x0,  0x0  },
888dc5742b6SSuraj Kandpal 		{ 0x28, 0x0,  0x0,  0x0  },
889dc5742b6SSuraj Kandpal 		{ 0x0,  0x14, 0x2a, 0x14 },
890dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
891dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
892dc5742b6SSuraj Kandpal 	},
893dc5742b6SSuraj Kandpal };
894dc5742b6SSuraj Kandpal 
895dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_hdmi_1p485 = {
896dc5742b6SSuraj Kandpal 	.clock = 148500,
897dc5742b6SSuraj Kandpal 	.config = {
898dc5742b6SSuraj Kandpal 		0x84,
899dc5742b6SSuraj Kandpal 		0x2d,
900dc5742b6SSuraj Kandpal 		0x0,
901dc5742b6SSuraj Kandpal 	},
902dc5742b6SSuraj Kandpal 	.addr_msb = {
903dc5742b6SSuraj Kandpal 		0x87,
904dc5742b6SSuraj Kandpal 		0x87,
905dc5742b6SSuraj Kandpal 		0x87,
906dc5742b6SSuraj Kandpal 		0x87,
907dc5742b6SSuraj Kandpal 		0x88,
908dc5742b6SSuraj Kandpal 		0x88,
909dc5742b6SSuraj Kandpal 		0x88,
910dc5742b6SSuraj Kandpal 		0x88,
911dc5742b6SSuraj Kandpal 		0x88,
912dc5742b6SSuraj Kandpal 		0x88,
913dc5742b6SSuraj Kandpal 		0x88,
914dc5742b6SSuraj Kandpal 		0x88,
915dc5742b6SSuraj Kandpal 		0x88,
916dc5742b6SSuraj Kandpal 	},
917dc5742b6SSuraj Kandpal 	.addr_lsb = {
918dc5742b6SSuraj Kandpal 		0x10,
919dc5742b6SSuraj Kandpal 		0x0c,
920dc5742b6SSuraj Kandpal 		0x14,
921dc5742b6SSuraj Kandpal 		0xe4,
922dc5742b6SSuraj Kandpal 		0x0c,
923dc5742b6SSuraj Kandpal 		0x10,
924dc5742b6SSuraj Kandpal 		0x14,
925dc5742b6SSuraj Kandpal 		0x18,
926dc5742b6SSuraj Kandpal 		0x48,
927dc5742b6SSuraj Kandpal 		0x40,
928dc5742b6SSuraj Kandpal 		0x4c,
929dc5742b6SSuraj Kandpal 		0x24,
930dc5742b6SSuraj Kandpal 		0x44,
931dc5742b6SSuraj Kandpal 	},
932dc5742b6SSuraj Kandpal 	.data = {
933dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
934dc5742b6SSuraj Kandpal 		{ 0x2,  0x15, 0x26, 0xa0 },
935dc5742b6SSuraj Kandpal 		{ 0x60, 0x0,  0x0,  0x0  },
936dc5742b6SSuraj Kandpal 		{ 0x8,  0x4,  0x84, 0x28 },
937dc5742b6SSuraj Kandpal 		{ 0xfa, 0x0c, 0x84, 0x11 },
938dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xd9, 0x53 },
939dc5742b6SSuraj Kandpal 		{ 0x86, 0x0,  0x0,  0x0  },
940dc5742b6SSuraj Kandpal 		{ 0x1,  0xa0, 0x1,  0x0  },
941dc5742b6SSuraj Kandpal 		{ 0x4b, 0x0,  0x0,  0x0  },
942dc5742b6SSuraj Kandpal 		{ 0x28, 0x0,  0x0,  0x0  },
943dc5742b6SSuraj Kandpal 		{ 0x0,  0x14, 0x2a, 0x14 },
944dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
945dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
946dc5742b6SSuraj Kandpal 	},
947dc5742b6SSuraj Kandpal };
948dc5742b6SSuraj Kandpal 
949dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_hdmi_5p94 = {
950dc5742b6SSuraj Kandpal 	.clock = 594000,
951dc5742b6SSuraj Kandpal 	.config = {
952dc5742b6SSuraj Kandpal 		0x84,
953dc5742b6SSuraj Kandpal 		0x2d,
954dc5742b6SSuraj Kandpal 		0x0,
955dc5742b6SSuraj Kandpal 	},
956dc5742b6SSuraj Kandpal 	.addr_msb = {
957dc5742b6SSuraj Kandpal 		0x87,
958dc5742b6SSuraj Kandpal 		0x87,
959dc5742b6SSuraj Kandpal 		0x87,
960dc5742b6SSuraj Kandpal 		0x87,
961dc5742b6SSuraj Kandpal 		0x88,
962dc5742b6SSuraj Kandpal 		0x88,
963dc5742b6SSuraj Kandpal 		0x88,
964dc5742b6SSuraj Kandpal 		0x88,
965dc5742b6SSuraj Kandpal 		0x88,
966dc5742b6SSuraj Kandpal 		0x88,
967dc5742b6SSuraj Kandpal 		0x88,
968dc5742b6SSuraj Kandpal 		0x88,
969dc5742b6SSuraj Kandpal 		0x88,
970dc5742b6SSuraj Kandpal 	},
971dc5742b6SSuraj Kandpal 	.addr_lsb = {
972dc5742b6SSuraj Kandpal 		0x10,
973dc5742b6SSuraj Kandpal 		0x0c,
974dc5742b6SSuraj Kandpal 		0x14,
975dc5742b6SSuraj Kandpal 		0xe4,
976dc5742b6SSuraj Kandpal 		0x0c,
977dc5742b6SSuraj Kandpal 		0x10,
978dc5742b6SSuraj Kandpal 		0x14,
979dc5742b6SSuraj Kandpal 		0x18,
980dc5742b6SSuraj Kandpal 		0x48,
981dc5742b6SSuraj Kandpal 		0x40,
982dc5742b6SSuraj Kandpal 		0x4c,
983dc5742b6SSuraj Kandpal 		0x24,
984dc5742b6SSuraj Kandpal 		0x44,
985dc5742b6SSuraj Kandpal 	},
986dc5742b6SSuraj Kandpal 	.data = {
987dc5742b6SSuraj Kandpal 		{ 0x0,  0x4c, 0x2,  0x0  },
988dc5742b6SSuraj Kandpal 		{ 0x0,  0x95, 0x26, 0xa0 },
989dc5742b6SSuraj Kandpal 		{ 0x60, 0x0,  0x0,  0x0  },
990dc5742b6SSuraj Kandpal 		{ 0x8,  0x4,  0x81, 0x28 },
991dc5742b6SSuraj Kandpal 		{ 0xfa, 0x0c, 0x84, 0x11 },
992dc5742b6SSuraj Kandpal 		{ 0x80, 0x0f, 0xd9, 0x53 },
993dc5742b6SSuraj Kandpal 		{ 0x86, 0x0,  0x0,  0x0  },
994dc5742b6SSuraj Kandpal 		{ 0x1,  0xa0, 0x1,  0x0  },
995dc5742b6SSuraj Kandpal 		{ 0x4b, 0x0,  0x0,  0x0  },
996dc5742b6SSuraj Kandpal 		{ 0x28, 0x0,  0x0,  0x0  },
997dc5742b6SSuraj Kandpal 		{ 0x0,  0x14, 0x2a, 0x14 },
998dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
999dc5742b6SSuraj Kandpal 		{ 0x0,  0x0,  0x0,  0x0  },
1000dc5742b6SSuraj Kandpal 	},
1001dc5742b6SSuraj Kandpal };
1002dc5742b6SSuraj Kandpal 
1003dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state * const xe3plpd_lt_hdmi_tables[] = {
1004dc5742b6SSuraj Kandpal 	&xe3plpd_lt_hdmi_252,
1005dc5742b6SSuraj Kandpal 	&xe3plpd_lt_hdmi_272,
1006dc5742b6SSuraj Kandpal 	&xe3plpd_lt_hdmi_742p5,
1007dc5742b6SSuraj Kandpal 	&xe3plpd_lt_hdmi_1p485,
1008dc5742b6SSuraj Kandpal 	&xe3plpd_lt_hdmi_5p94,
1009dc5742b6SSuraj Kandpal 	NULL,
1010dc5742b6SSuraj Kandpal };
1011dc5742b6SSuraj Kandpal 
1012154ebdb7SSuraj Kandpal static u8 intel_lt_phy_get_owned_lane_mask(struct intel_encoder *encoder)
1013154ebdb7SSuraj Kandpal {
1014154ebdb7SSuraj Kandpal 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
1015154ebdb7SSuraj Kandpal 
1016154ebdb7SSuraj Kandpal 	if (!intel_tc_port_in_dp_alt_mode(dig_port))
1017154ebdb7SSuraj Kandpal 		return INTEL_LT_PHY_BOTH_LANES;
1018154ebdb7SSuraj Kandpal 
1019154ebdb7SSuraj Kandpal 	return intel_tc_port_max_lane_count(dig_port) > 2
1020154ebdb7SSuraj Kandpal 		? INTEL_LT_PHY_BOTH_LANES : INTEL_LT_PHY_LANE0;
1021154ebdb7SSuraj Kandpal }
1022154ebdb7SSuraj Kandpal 
1023e1455196SSuraj Kandpal static u8 intel_lt_phy_read(struct intel_encoder *encoder, u8 lane_mask, u16 addr)
1024e1455196SSuraj Kandpal {
1025e1455196SSuraj Kandpal 	return intel_cx0_read(encoder, lane_mask, addr);
1026e1455196SSuraj Kandpal }
1027e1455196SSuraj Kandpal 
10281dd885d5SSuraj Kandpal static void intel_lt_phy_write(struct intel_encoder *encoder,
10291dd885d5SSuraj Kandpal 			       u8 lane_mask, u16 addr, u8 data, bool committed)
10301dd885d5SSuraj Kandpal {
10311dd885d5SSuraj Kandpal 	intel_cx0_write(encoder, lane_mask, addr, data, committed);
10321dd885d5SSuraj Kandpal }
10331dd885d5SSuraj Kandpal 
103413ba213fSSuraj Kandpal static void intel_lt_phy_rmw(struct intel_encoder *encoder,
103513ba213fSSuraj Kandpal 			     u8 lane_mask, u16 addr, u8 clear, u8 set, bool committed)
103613ba213fSSuraj Kandpal {
103713ba213fSSuraj Kandpal 	intel_cx0_rmw(encoder, lane_mask, addr, clear, set, committed);
103813ba213fSSuraj Kandpal }
103913ba213fSSuraj Kandpal 
104041d07bd2SSuraj Kandpal static void intel_lt_phy_clear_status_p2p(struct intel_encoder *encoder,
104141d07bd2SSuraj Kandpal 					  int lane)
104241d07bd2SSuraj Kandpal {
104341d07bd2SSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
104441d07bd2SSuraj Kandpal 
104541d07bd2SSuraj Kandpal 	intel_de_rmw(display,
104641d07bd2SSuraj Kandpal 		     XE3PLPD_PORT_P2M_MSGBUS_STATUS_P2P(encoder->port, lane),
104741d07bd2SSuraj Kandpal 		     XELPDP_PORT_P2M_RESPONSE_READY, 0);
104841d07bd2SSuraj Kandpal }
104941d07bd2SSuraj Kandpal 
105041d07bd2SSuraj Kandpal static void
105141d07bd2SSuraj Kandpal assert_dc_off(struct intel_display *display)
105241d07bd2SSuraj Kandpal {
105341d07bd2SSuraj Kandpal 	bool enabled;
105441d07bd2SSuraj Kandpal 
105541d07bd2SSuraj Kandpal 	enabled = intel_display_power_is_enabled(display, POWER_DOMAIN_DC_OFF);
105641d07bd2SSuraj Kandpal 	drm_WARN_ON(display->drm, !enabled);
105741d07bd2SSuraj Kandpal }
105841d07bd2SSuraj Kandpal 
105941d07bd2SSuraj Kandpal static int __intel_lt_phy_p2p_write_once(struct intel_encoder *encoder,
106041d07bd2SSuraj Kandpal 					 int lane, u16 addr, u8 data,
106141d07bd2SSuraj Kandpal 					 i915_reg_t mac_reg_addr,
106241d07bd2SSuraj Kandpal 					 u8 expected_mac_val)
106341d07bd2SSuraj Kandpal {
106441d07bd2SSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
106541d07bd2SSuraj Kandpal 	enum port port = encoder->port;
106641d07bd2SSuraj Kandpal 	enum phy phy = intel_encoder_to_phy(encoder);
106741d07bd2SSuraj Kandpal 	int ack;
106841d07bd2SSuraj Kandpal 	u32 val;
106941d07bd2SSuraj Kandpal 
107093e0f7c8SVille Syrjälä 	if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
107141d07bd2SSuraj Kandpal 				       XELPDP_PORT_P2P_TRANSACTION_PENDING,
10722d41de25SVille Syrjälä 				       XELPDP_MSGBUS_TIMEOUT_MS)) {
107341d07bd2SSuraj Kandpal 		drm_dbg_kms(display->drm,
107441d07bd2SSuraj Kandpal 			    "PHY %c Timeout waiting for previous transaction to complete. Resetting bus.\n",
107541d07bd2SSuraj Kandpal 			    phy_name(phy));
107641d07bd2SSuraj Kandpal 		intel_cx0_bus_reset(encoder, lane);
107741d07bd2SSuraj Kandpal 		return -ETIMEDOUT;
107841d07bd2SSuraj Kandpal 	}
107941d07bd2SSuraj Kandpal 
108041d07bd2SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_P2M_MSGBUS_STATUS(display, port, lane), 0, 0);
108141d07bd2SSuraj Kandpal 
108241d07bd2SSuraj Kandpal 	intel_de_write(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
108341d07bd2SSuraj Kandpal 		       XELPDP_PORT_P2P_TRANSACTION_PENDING |
108441d07bd2SSuraj Kandpal 		       XELPDP_PORT_M2P_COMMAND_WRITE_COMMITTED |
108541d07bd2SSuraj Kandpal 		       XELPDP_PORT_M2P_DATA(data) |
108641d07bd2SSuraj Kandpal 		       XELPDP_PORT_M2P_ADDRESS(addr));
108741d07bd2SSuraj Kandpal 
108841d07bd2SSuraj Kandpal 	ack = intel_cx0_wait_for_ack(encoder, XELPDP_PORT_P2M_COMMAND_WRITE_ACK, lane, &val);
108941d07bd2SSuraj Kandpal 	if (ack < 0)
109041d07bd2SSuraj Kandpal 		return ack;
109141d07bd2SSuraj Kandpal 
109241d07bd2SSuraj Kandpal 	if (val & XELPDP_PORT_P2M_ERROR_SET) {
109341d07bd2SSuraj Kandpal 		drm_dbg_kms(display->drm,
109441d07bd2SSuraj Kandpal 			    "PHY %c Error occurred during P2P write command. Status: 0x%x\n",
109541d07bd2SSuraj Kandpal 			    phy_name(phy), val);
109641d07bd2SSuraj Kandpal 		intel_lt_phy_clear_status_p2p(encoder, lane);
109741d07bd2SSuraj Kandpal 		intel_cx0_bus_reset(encoder, lane);
109841d07bd2SSuraj Kandpal 		return -EINVAL;
109941d07bd2SSuraj Kandpal 	}
110041d07bd2SSuraj Kandpal 
110141d07bd2SSuraj Kandpal 	/*
110241d07bd2SSuraj Kandpal 	 * RE-VISIT:
110341d07bd2SSuraj Kandpal 	 * This needs to be added to give PHY time to set everything up this was a requirement
110441d07bd2SSuraj Kandpal 	 * to get the display up and running
110541d07bd2SSuraj Kandpal 	 * This is the time PHY takes to settle down after programming the PHY.
110641d07bd2SSuraj Kandpal 	 */
110741d07bd2SSuraj Kandpal 	udelay(150);
110841d07bd2SSuraj Kandpal 	intel_clear_response_ready_flag(encoder, lane);
110941d07bd2SSuraj Kandpal 	intel_lt_phy_clear_status_p2p(encoder, lane);
111041d07bd2SSuraj Kandpal 
111141d07bd2SSuraj Kandpal 	return 0;
111241d07bd2SSuraj Kandpal }
111341d07bd2SSuraj Kandpal 
111441d07bd2SSuraj Kandpal static void __intel_lt_phy_p2p_write(struct intel_encoder *encoder,
111541d07bd2SSuraj Kandpal 				     int lane, u16 addr, u8 data,
111641d07bd2SSuraj Kandpal 				     i915_reg_t mac_reg_addr,
111741d07bd2SSuraj Kandpal 				     u8 expected_mac_val)
111841d07bd2SSuraj Kandpal {
111941d07bd2SSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
112041d07bd2SSuraj Kandpal 	enum phy phy = intel_encoder_to_phy(encoder);
112141d07bd2SSuraj Kandpal 	int i, status;
112241d07bd2SSuraj Kandpal 
112341d07bd2SSuraj Kandpal 	assert_dc_off(display);
112441d07bd2SSuraj Kandpal 
112541d07bd2SSuraj Kandpal 	/* 3 tries is assumed to be enough to write successfully */
112641d07bd2SSuraj Kandpal 	for (i = 0; i < 3; i++) {
112741d07bd2SSuraj Kandpal 		status = __intel_lt_phy_p2p_write_once(encoder, lane, addr, data, mac_reg_addr,
112841d07bd2SSuraj Kandpal 						       expected_mac_val);
112941d07bd2SSuraj Kandpal 
113041d07bd2SSuraj Kandpal 		if (status == 0)
113141d07bd2SSuraj Kandpal 			return;
113241d07bd2SSuraj Kandpal 	}
113341d07bd2SSuraj Kandpal 
113441d07bd2SSuraj Kandpal 	drm_err_once(display->drm,
113541d07bd2SSuraj Kandpal 		     "PHY %c P2P Write %04x failed after %d retries.\n", phy_name(phy), addr, i);
113641d07bd2SSuraj Kandpal }
113741d07bd2SSuraj Kandpal 
113841d07bd2SSuraj Kandpal static void intel_lt_phy_p2p_write(struct intel_encoder *encoder,
113941d07bd2SSuraj Kandpal 				   u8 lane_mask, u16 addr, u8 data,
114041d07bd2SSuraj Kandpal 				   i915_reg_t mac_reg_addr,
114141d07bd2SSuraj Kandpal 				   u8 expected_mac_val)
114241d07bd2SSuraj Kandpal {
114341d07bd2SSuraj Kandpal 	int lane;
114441d07bd2SSuraj Kandpal 
114541d07bd2SSuraj Kandpal 	for_each_lt_phy_lane_in_mask(lane_mask, lane)
114641d07bd2SSuraj Kandpal 		__intel_lt_phy_p2p_write(encoder, lane, addr, data, mac_reg_addr, expected_mac_val);
114741d07bd2SSuraj Kandpal }
114841d07bd2SSuraj Kandpal 
1149154ebdb7SSuraj Kandpal static void
1150154ebdb7SSuraj Kandpal intel_lt_phy_setup_powerdown(struct intel_encoder *encoder, u8 lane_count)
1151154ebdb7SSuraj Kandpal {
1152154ebdb7SSuraj Kandpal 	/*
1153154ebdb7SSuraj Kandpal 	 * The new PORT_BUF_CTL6 stuff for dc5 entry and exit needs to be handled
1154154ebdb7SSuraj Kandpal 	 * by dmc firmware not explicitly mentioned in Bspec. This leaves this
1155154ebdb7SSuraj Kandpal 	 * function as a wrapper only but keeping it expecting future changes.
1156154ebdb7SSuraj Kandpal 	 */
1157154ebdb7SSuraj Kandpal 	intel_cx0_setup_powerdown(encoder);
1158154ebdb7SSuraj Kandpal }
1159154ebdb7SSuraj Kandpal 
1160154ebdb7SSuraj Kandpal static void
1161fc9be0a1SSuraj Kandpal intel_lt_phy_powerdown_change_sequence(struct intel_encoder *encoder,
1162fc9be0a1SSuraj Kandpal 				       u8 lane_mask, u8 state)
1163fc9be0a1SSuraj Kandpal {
1164fc9be0a1SSuraj Kandpal 	intel_cx0_powerdown_change_sequence(encoder, lane_mask, state);
1165fc9be0a1SSuraj Kandpal }
1166fc9be0a1SSuraj Kandpal 
1167fc9be0a1SSuraj Kandpal static void
1168154ebdb7SSuraj Kandpal intel_lt_phy_lane_reset(struct intel_encoder *encoder,
1169154ebdb7SSuraj Kandpal 			u8 lane_count)
1170154ebdb7SSuraj Kandpal {
1171154ebdb7SSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
1172154ebdb7SSuraj Kandpal 	enum port port = encoder->port;
1173154ebdb7SSuraj Kandpal 	enum phy phy = intel_encoder_to_phy(encoder);
1174154ebdb7SSuraj Kandpal 	u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
1175154ebdb7SSuraj Kandpal 	u32 lane_pipe_reset = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES
1176154ebdb7SSuraj Kandpal 				? XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1)
1177154ebdb7SSuraj Kandpal 				: XELPDP_LANE_PIPE_RESET(0);
1178154ebdb7SSuraj Kandpal 	u32 lane_phy_current_status = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES
1179154ebdb7SSuraj Kandpal 					? (XELPDP_LANE_PHY_CURRENT_STATUS(0) |
1180154ebdb7SSuraj Kandpal 					   XELPDP_LANE_PHY_CURRENT_STATUS(1))
1181154ebdb7SSuraj Kandpal 					: XELPDP_LANE_PHY_CURRENT_STATUS(0);
1182154ebdb7SSuraj Kandpal 	u32 lane_phy_pulse_status = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES
1183154ebdb7SSuraj Kandpal 					? (XE3PLPDP_LANE_PHY_PULSE_STATUS(0) |
1184154ebdb7SSuraj Kandpal 					   XE3PLPDP_LANE_PHY_PULSE_STATUS(1))
1185154ebdb7SSuraj Kandpal 					: XE3PLPDP_LANE_PHY_PULSE_STATUS(0);
1186154ebdb7SSuraj Kandpal 
1187154ebdb7SSuraj Kandpal 	intel_de_rmw(display, XE3PLPD_PORT_BUF_CTL5(port),
1188154ebdb7SSuraj Kandpal 		     XE3PLPD_MACCLK_RATE_MASK, XE3PLPD_MACCLK_RATE_DEF);
1189154ebdb7SSuraj Kandpal 
1190154ebdb7SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, port),
1191154ebdb7SSuraj Kandpal 		     XE3PLPDP_PHY_MODE_MASK, XE3PLPDP_PHY_MODE_DP);
1192154ebdb7SSuraj Kandpal 
1193154ebdb7SSuraj Kandpal 	intel_lt_phy_setup_powerdown(encoder, lane_count);
1194fc9be0a1SSuraj Kandpal 	intel_lt_phy_powerdown_change_sequence(encoder, owned_lane_mask,
1195fc9be0a1SSuraj Kandpal 					       XELPDP_P2_STATE_RESET);
1196154ebdb7SSuraj Kandpal 
1197154ebdb7SSuraj Kandpal 	intel_de_rmw(display, XE3PLPD_PORT_BUF_CTL5(port),
1198154ebdb7SSuraj Kandpal 		     XE3PLPD_MACCLK_RESET_0, 0);
1199154ebdb7SSuraj Kandpal 
1200154ebdb7SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
1201154ebdb7SSuraj Kandpal 		     XELPDP_LANE_PCLK_PLL_REQUEST(0),
1202154ebdb7SSuraj Kandpal 		     XELPDP_LANE_PCLK_PLL_REQUEST(0));
1203154ebdb7SSuraj Kandpal 
12046be05d5bSVille Syrjälä 	if (intel_de_wait_for_set_ms(display, XELPDP_PORT_CLOCK_CTL(display, port),
12056be05d5bSVille Syrjälä 				     XELPDP_LANE_PCLK_PLL_ACK(0),
12066be05d5bSVille Syrjälä 				     XE3PLPD_MACCLK_TURNON_LATENCY_MS))
1207dfd58249SVille Syrjälä 		drm_warn(display->drm, "PHY %c PLL MacCLK assertion ack not done\n",
1208dfd58249SVille Syrjälä 			 phy_name(phy));
1209154ebdb7SSuraj Kandpal 
1210154ebdb7SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
1211154ebdb7SSuraj Kandpal 		     XELPDP_FORWARD_CLOCK_UNGATE,
1212154ebdb7SSuraj Kandpal 		     XELPDP_FORWARD_CLOCK_UNGATE);
1213154ebdb7SSuraj Kandpal 
1214154ebdb7SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port),
1215154ebdb7SSuraj Kandpal 		     lane_pipe_reset | lane_phy_pulse_status, 0);
1216154ebdb7SSuraj Kandpal 
12176be05d5bSVille Syrjälä 	if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_BUF_CTL2(display, port),
12186be05d5bSVille Syrjälä 				       lane_phy_current_status,
12196be05d5bSVille Syrjälä 				       XE3PLPD_RESET_END_LATENCY_MS))
1220dfd58249SVille Syrjälä 		drm_warn(display->drm, "PHY %c failed to bring out of lane reset\n",
1221dfd58249SVille Syrjälä 			 phy_name(phy));
1222154ebdb7SSuraj Kandpal 
12236be05d5bSVille Syrjälä 	if (intel_de_wait_for_set_ms(display, XELPDP_PORT_BUF_CTL2(display, port),
12246be05d5bSVille Syrjälä 				     lane_phy_pulse_status,
12256be05d5bSVille Syrjälä 				     XE3PLPD_RATE_CALIB_DONE_LATENCY_MS))
1226dfd58249SVille Syrjälä 		drm_warn(display->drm, "PHY %c PLL rate not changed\n",
1227dfd58249SVille Syrjälä 			 phy_name(phy));
1228154ebdb7SSuraj Kandpal 
1229154ebdb7SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_phy_pulse_status, 0);
1230154ebdb7SSuraj Kandpal }
1231154ebdb7SSuraj Kandpal 
12323a323c7eSSuraj Kandpal static void
12333a323c7eSSuraj Kandpal intel_lt_phy_program_port_clock_ctl(struct intel_encoder *encoder,
12343a323c7eSSuraj Kandpal 				    const struct intel_crtc_state *crtc_state,
12353a323c7eSSuraj Kandpal 				    bool lane_reversal)
12363a323c7eSSuraj Kandpal {
12373a323c7eSSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
12383a323c7eSSuraj Kandpal 	u32 val = 0;
12393a323c7eSSuraj Kandpal 
12403a323c7eSSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, encoder->port),
12413a323c7eSSuraj Kandpal 		     XELPDP_PORT_REVERSAL,
12423a323c7eSSuraj Kandpal 		     lane_reversal ? XELPDP_PORT_REVERSAL : 0);
12433a323c7eSSuraj Kandpal 
12443a323c7eSSuraj Kandpal 	val |= XELPDP_FORWARD_CLOCK_UNGATE;
12453a323c7eSSuraj Kandpal 
12463a323c7eSSuraj Kandpal 	/*
12473a323c7eSSuraj Kandpal 	 * We actually mean MACCLK here and not MAXPCLK when using LT Phy
12483a323c7eSSuraj Kandpal 	 * but since the register bits still remain the same we use
12493a323c7eSSuraj Kandpal 	 * the same definition
12503a323c7eSSuraj Kandpal 	 */
12513a323c7eSSuraj Kandpal 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
12523a323c7eSSuraj Kandpal 	    intel_hdmi_is_frl(crtc_state->port_clock))
12533a323c7eSSuraj Kandpal 		val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_DIV18CLK);
12543a323c7eSSuraj Kandpal 	else
12553a323c7eSSuraj Kandpal 		val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_MAXPCLK);
12563a323c7eSSuraj Kandpal 
12573383ba24SSuraj Kandpal 	 /* DP2.0 10G and 20G rates enable MPLLA*/
12583383ba24SSuraj Kandpal 	if (crtc_state->port_clock == 1000000 || crtc_state->port_clock == 2000000)
12593383ba24SSuraj Kandpal 		val |= XELPDP_SSC_ENABLE_PLLA;
12603383ba24SSuraj Kandpal 	else
12613383ba24SSuraj Kandpal 		val |= crtc_state->dpll_hw_state.ltpll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
12623383ba24SSuraj Kandpal 
12633a323c7eSSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
12643a323c7eSSuraj Kandpal 		     XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE |
12653a323c7eSSuraj Kandpal 		     XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_SSC_ENABLE_PLLA |
12663a323c7eSSuraj Kandpal 		     XELPDP_SSC_ENABLE_PLLB, val);
12673a323c7eSSuraj Kandpal }
12683a323c7eSSuraj Kandpal 
1269e1455196SSuraj Kandpal static u32 intel_lt_phy_get_dp_clock(u8 rate)
1270e1455196SSuraj Kandpal {
1271e1455196SSuraj Kandpal 	switch (rate) {
1272e1455196SSuraj Kandpal 	case 0:
1273e1455196SSuraj Kandpal 		return 162000;
1274e1455196SSuraj Kandpal 	case 1:
1275e1455196SSuraj Kandpal 		return 270000;
1276e1455196SSuraj Kandpal 	case 2:
1277e1455196SSuraj Kandpal 		return 540000;
1278e1455196SSuraj Kandpal 	case 3:
1279e1455196SSuraj Kandpal 		return 810000;
1280e1455196SSuraj Kandpal 	case 4:
1281e1455196SSuraj Kandpal 		return 216000;
1282e1455196SSuraj Kandpal 	case 5:
1283e1455196SSuraj Kandpal 		return 243000;
1284e1455196SSuraj Kandpal 	case 6:
1285e1455196SSuraj Kandpal 		return 324000;
1286e1455196SSuraj Kandpal 	case 7:
1287e1455196SSuraj Kandpal 		return 432000;
1288e1455196SSuraj Kandpal 	case 8:
1289e1455196SSuraj Kandpal 		return 1000000;
1290e1455196SSuraj Kandpal 	case 9:
1291e1455196SSuraj Kandpal 		return 1350000;
1292e1455196SSuraj Kandpal 	case 10:
1293e1455196SSuraj Kandpal 		return 2000000;
1294e1455196SSuraj Kandpal 	case 11:
1295e1455196SSuraj Kandpal 		return 675000;
1296e1455196SSuraj Kandpal 	default:
1297e1455196SSuraj Kandpal 		MISSING_CASE(rate);
1298e1455196SSuraj Kandpal 		return 0;
1299e1455196SSuraj Kandpal 	}
1300e1455196SSuraj Kandpal }
1301e1455196SSuraj Kandpal 
1302e1455196SSuraj Kandpal static bool
1303e1455196SSuraj Kandpal intel_lt_phy_config_changed(struct intel_encoder *encoder,
1304e1455196SSuraj Kandpal 			    const struct intel_crtc_state *crtc_state)
1305e1455196SSuraj Kandpal {
1306e1455196SSuraj Kandpal 	u8 val, rate;
1307e1455196SSuraj Kandpal 	u32 clock;
1308e1455196SSuraj Kandpal 
1309e1455196SSuraj Kandpal 	val = intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0,
1310e1455196SSuraj Kandpal 				LT_PHY_VDR_0_CONFIG);
1311e1455196SSuraj Kandpal 	rate = REG_FIELD_GET8(LT_PHY_VDR_RATE_ENCODING_MASK, val);
1312e1455196SSuraj Kandpal 
1313e1455196SSuraj Kandpal 	/*
1314e1455196SSuraj Kandpal 	 * The only time we do not reconfigure the PLL is when we are
1315e1455196SSuraj Kandpal 	 * using 1.62 Gbps clock since PHY PLL defaults to that
1316e1455196SSuraj Kandpal 	 * otherwise we always need to reconfigure it.
1317e1455196SSuraj Kandpal 	 */
1318e1455196SSuraj Kandpal 	if (intel_crtc_has_dp_encoder(crtc_state)) {
1319e1455196SSuraj Kandpal 		clock = intel_lt_phy_get_dp_clock(rate);
1320e1455196SSuraj Kandpal 		if (crtc_state->port_clock == 1620000 && crtc_state->port_clock == clock)
1321e1455196SSuraj Kandpal 			return false;
1322e1455196SSuraj Kandpal 	}
1323e1455196SSuraj Kandpal 
1324e1455196SSuraj Kandpal 	return true;
1325e1455196SSuraj Kandpal }
1326e1455196SSuraj Kandpal 
1327e1455196SSuraj Kandpal static intel_wakeref_t intel_lt_phy_transaction_begin(struct intel_encoder *encoder)
1328e1455196SSuraj Kandpal {
1329e1455196SSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
1330e1455196SSuraj Kandpal 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1331e1455196SSuraj Kandpal 	intel_wakeref_t wakeref;
1332e1455196SSuraj Kandpal 
1333e1455196SSuraj Kandpal 	intel_psr_pause(intel_dp);
1334e1455196SSuraj Kandpal 	wakeref = intel_display_power_get(display, POWER_DOMAIN_DC_OFF);
1335e1455196SSuraj Kandpal 
1336e1455196SSuraj Kandpal 	return wakeref;
1337e1455196SSuraj Kandpal }
1338e1455196SSuraj Kandpal 
1339e1455196SSuraj Kandpal static void intel_lt_phy_transaction_end(struct intel_encoder *encoder, intel_wakeref_t wakeref)
1340e1455196SSuraj Kandpal {
1341e1455196SSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
1342e1455196SSuraj Kandpal 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1343e1455196SSuraj Kandpal 
1344e1455196SSuraj Kandpal 	intel_psr_resume(intel_dp);
1345e1455196SSuraj Kandpal 	intel_display_power_put(display, POWER_DOMAIN_DC_OFF, wakeref);
1346e1455196SSuraj Kandpal }
1347e1455196SSuraj Kandpal 
1348dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state * const *
1349dc5742b6SSuraj Kandpal intel_lt_phy_pll_tables_get(struct intel_crtc_state *crtc_state,
1350dc5742b6SSuraj Kandpal 			    struct intel_encoder *encoder)
1351dc5742b6SSuraj Kandpal {
1352dc5742b6SSuraj Kandpal 	if (intel_crtc_has_dp_encoder(crtc_state)) {
1353dc5742b6SSuraj Kandpal 		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
1354dc5742b6SSuraj Kandpal 			return xe3plpd_lt_edp_tables;
1355dc5742b6SSuraj Kandpal 
1356dc5742b6SSuraj Kandpal 		return xe3plpd_lt_dp_tables;
1357dc5742b6SSuraj Kandpal 	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
1358dc5742b6SSuraj Kandpal 		return xe3plpd_lt_hdmi_tables;
1359dc5742b6SSuraj Kandpal 	}
1360dc5742b6SSuraj Kandpal 
1361dc5742b6SSuraj Kandpal 	MISSING_CASE(encoder->type);
1362dc5742b6SSuraj Kandpal 	return NULL;
1363dc5742b6SSuraj Kandpal }
1364dc5742b6SSuraj Kandpal 
13653383ba24SSuraj Kandpal static bool
13663383ba24SSuraj Kandpal intel_lt_phy_pll_is_ssc_enabled(struct intel_crtc_state *crtc_state,
13673383ba24SSuraj Kandpal 				struct intel_encoder *encoder)
13683383ba24SSuraj Kandpal {
13693383ba24SSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
13703383ba24SSuraj Kandpal 
13713383ba24SSuraj Kandpal 	if (intel_crtc_has_dp_encoder(crtc_state)) {
13723383ba24SSuraj Kandpal 		if (intel_panel_use_ssc(display)) {
13733383ba24SSuraj Kandpal 			struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
13743383ba24SSuraj Kandpal 
13753383ba24SSuraj Kandpal 			return (intel_dp->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
13763383ba24SSuraj Kandpal 		}
13773383ba24SSuraj Kandpal 	}
13783383ba24SSuraj Kandpal 
13793383ba24SSuraj Kandpal 	return false;
13803383ba24SSuraj Kandpal }
13813383ba24SSuraj Kandpal 
13826fedb7bfSSuraj Kandpal static u64 mul_q32_u32(u64 a_q32, u32 b)
13836fedb7bfSSuraj Kandpal {
13846fedb7bfSSuraj Kandpal 	u64 p0, p1, carry, result;
13856fedb7bfSSuraj Kandpal 	u64 x_hi = a_q32 >> 32;
13866fedb7bfSSuraj Kandpal 	u64 x_lo = a_q32 & 0xFFFFFFFFULL;
13876fedb7bfSSuraj Kandpal 
13886fedb7bfSSuraj Kandpal 	p0 = x_lo * (u64)b;
13896fedb7bfSSuraj Kandpal 	p1 = x_hi * (u64)b;
13906fedb7bfSSuraj Kandpal 	carry = p0 >> 32;
13916fedb7bfSSuraj Kandpal 	result = (p1 << 32) + (carry << 32) + (p0 & 0xFFFFFFFFULL);
13926fedb7bfSSuraj Kandpal 
13936fedb7bfSSuraj Kandpal 	return result;
13946fedb7bfSSuraj Kandpal }
13956fedb7bfSSuraj Kandpal 
13966fedb7bfSSuraj Kandpal static bool
13976fedb7bfSSuraj Kandpal calculate_target_dco_and_loop_cnt(u32 frequency_khz, u64 *target_dco_mhz, u32 *loop_cnt)
13986fedb7bfSSuraj Kandpal {
13996fedb7bfSSuraj Kandpal 	u32 ppm_value = 1;
14006fedb7bfSSuraj Kandpal 	u32 dco_min_freq = DCO_MIN_FREQ_MHZ;
14016fedb7bfSSuraj Kandpal 	u32 dco_max_freq = 16200;
14026fedb7bfSSuraj Kandpal 	u32 dco_min_freq_low = 10000;
14036fedb7bfSSuraj Kandpal 	u32 dco_max_freq_low = 12000;
14046fedb7bfSSuraj Kandpal 	u64 val = 0;
14056fedb7bfSSuraj Kandpal 	u64 refclk_khz = REF_CLK_KHZ;
14066fedb7bfSSuraj Kandpal 	u64 m2div = 0;
14076fedb7bfSSuraj Kandpal 	u64 val_with_frac = 0;
14086fedb7bfSSuraj Kandpal 	u64 ppm = 0;
14096fedb7bfSSuraj Kandpal 	u64 temp0 = 0, temp1, scale;
14106fedb7bfSSuraj Kandpal 	int ppm_cnt, dco_count, y;
14116fedb7bfSSuraj Kandpal 
14126fedb7bfSSuraj Kandpal 	for (ppm_cnt = 0; ppm_cnt < 5; ppm_cnt++) {
14136fedb7bfSSuraj Kandpal 		ppm_value = ppm_cnt == 2 ? 2 : 1;
14146fedb7bfSSuraj Kandpal 		for (dco_count = 0; dco_count < 2; dco_count++) {
14156fedb7bfSSuraj Kandpal 			if (dco_count == 1) {
14166fedb7bfSSuraj Kandpal 				dco_min_freq = dco_min_freq_low;
14176fedb7bfSSuraj Kandpal 				dco_max_freq = dco_max_freq_low;
14186fedb7bfSSuraj Kandpal 			}
14196fedb7bfSSuraj Kandpal 			for (y = 2; y <= 255; y += 2) {
14206fedb7bfSSuraj Kandpal 				val = div64_u64((u64)y * frequency_khz, 200);
14216fedb7bfSSuraj Kandpal 				m2div = div64_u64(((u64)(val) << 32), refclk_khz);
14226fedb7bfSSuraj Kandpal 				m2div = mul_q32_u32(m2div, 500);
14236fedb7bfSSuraj Kandpal 				val_with_frac = mul_q32_u32(m2div, refclk_khz);
14246fedb7bfSSuraj Kandpal 				val_with_frac = div64_u64(val_with_frac, 500);
14256fedb7bfSSuraj Kandpal 				temp1 = Q32_TO_INT(val_with_frac);
14266fedb7bfSSuraj Kandpal 				temp0 = (temp1 > val) ? (temp1 - val) :
14276fedb7bfSSuraj Kandpal 					(val - temp1);
14286fedb7bfSSuraj Kandpal 				ppm = div64_u64(temp0, val);
14296fedb7bfSSuraj Kandpal 				if (temp1 >= dco_min_freq &&
14306fedb7bfSSuraj Kandpal 				    temp1 <= dco_max_freq &&
14316fedb7bfSSuraj Kandpal 				    ppm < ppm_value) {
14326fedb7bfSSuraj Kandpal 					/* Round to two places */
14336fedb7bfSSuraj Kandpal 					scale = (1ULL << 32) / 100;
14346fedb7bfSSuraj Kandpal 					temp0 = DIV_ROUND_UP_ULL(val_with_frac,
14356fedb7bfSSuraj Kandpal 								 scale);
14366fedb7bfSSuraj Kandpal 					*target_dco_mhz = temp0 * scale;
14376fedb7bfSSuraj Kandpal 					*loop_cnt = y;
14386fedb7bfSSuraj Kandpal 					return true;
14396fedb7bfSSuraj Kandpal 				}
14406fedb7bfSSuraj Kandpal 			}
14416fedb7bfSSuraj Kandpal 		}
14426fedb7bfSSuraj Kandpal 	}
14436fedb7bfSSuraj Kandpal 
14446fedb7bfSSuraj Kandpal 	return false;
14456fedb7bfSSuraj Kandpal }
14466fedb7bfSSuraj Kandpal 
14476fedb7bfSSuraj Kandpal static void set_phy_vdr_addresses(struct lt_phy_params *p, int pll_type)
14486fedb7bfSSuraj Kandpal {
14496fedb7bfSSuraj Kandpal 	p->pll_reg4.addr = PLL_REG_ADDR(PLL_REG4_ADDR, pll_type);
14506fedb7bfSSuraj Kandpal 	p->pll_reg3.addr = PLL_REG_ADDR(PLL_REG3_ADDR, pll_type);
14516fedb7bfSSuraj Kandpal 	p->pll_reg5.addr = PLL_REG_ADDR(PLL_REG5_ADDR, pll_type);
14526fedb7bfSSuraj Kandpal 	p->pll_reg57.addr = PLL_REG_ADDR(PLL_REG57_ADDR, pll_type);
14536fedb7bfSSuraj Kandpal 	p->lf.addr = PLL_REG_ADDR(PLL_LF_ADDR, pll_type);
14546fedb7bfSSuraj Kandpal 	p->tdc.addr = PLL_REG_ADDR(PLL_TDC_ADDR, pll_type);
14556fedb7bfSSuraj Kandpal 	p->ssc.addr = PLL_REG_ADDR(PLL_SSC_ADDR, pll_type);
14566fedb7bfSSuraj Kandpal 	p->bias2.addr = PLL_REG_ADDR(PLL_BIAS2_ADDR, pll_type);
14576fedb7bfSSuraj Kandpal 	p->bias_trim.addr = PLL_REG_ADDR(PLL_BIAS_TRIM_ADDR, pll_type);
14586fedb7bfSSuraj Kandpal 	p->dco_med.addr = PLL_REG_ADDR(PLL_DCO_MED_ADDR, pll_type);
14596fedb7bfSSuraj Kandpal 	p->dco_fine.addr = PLL_REG_ADDR(PLL_DCO_FINE_ADDR, pll_type);
14606fedb7bfSSuraj Kandpal 	p->ssc_inj.addr = PLL_REG_ADDR(PLL_SSC_INJ_ADDR, pll_type);
14616fedb7bfSSuraj Kandpal 	p->surv_bonus.addr = PLL_REG_ADDR(PLL_SURV_BONUS_ADDR, pll_type);
14626fedb7bfSSuraj Kandpal }
14636fedb7bfSSuraj Kandpal 
14646fedb7bfSSuraj Kandpal static void compute_ssc(struct lt_phy_params *p, u32 ana_cfg)
14656fedb7bfSSuraj Kandpal {
14666fedb7bfSSuraj Kandpal 	int ssc_stepsize = 0;
14676fedb7bfSSuraj Kandpal 	int ssc_steplen = 0;
14686fedb7bfSSuraj Kandpal 	int ssc_steplog = 0;
14696fedb7bfSSuraj Kandpal 
14706fedb7bfSSuraj Kandpal 	p->ssc.val = (1 << 31) | (ana_cfg << 24) | (ssc_steplog << 16) |
14716fedb7bfSSuraj Kandpal 		(ssc_stepsize << 8) | ssc_steplen;
14726fedb7bfSSuraj Kandpal }
14736fedb7bfSSuraj Kandpal 
14746fedb7bfSSuraj Kandpal static void compute_bias2(struct lt_phy_params *p)
14756fedb7bfSSuraj Kandpal {
14766fedb7bfSSuraj Kandpal 	u32 ssc_en_local = 0;
14776fedb7bfSSuraj Kandpal 	u64 dynctrl_ovrd_en = 0;
14786fedb7bfSSuraj Kandpal 
14796fedb7bfSSuraj Kandpal 	p->bias2.val = (dynctrl_ovrd_en << 31) | (ssc_en_local << 30) |
14806fedb7bfSSuraj Kandpal 		(1 << 23) | (1 << 24) | (32 << 16) | (1 << 8);
14816fedb7bfSSuraj Kandpal }
14826fedb7bfSSuraj Kandpal 
14836fedb7bfSSuraj Kandpal static void compute_tdc(struct lt_phy_params *p, u64 tdc_fine)
14846fedb7bfSSuraj Kandpal {
14856fedb7bfSSuraj Kandpal 	u32 settling_time = 15;
14866fedb7bfSSuraj Kandpal 	u32 bias_ovr_en = 1;
14876fedb7bfSSuraj Kandpal 	u32 coldstart = 1;
14886fedb7bfSSuraj Kandpal 	u32 true_lock = 2;
14896fedb7bfSSuraj Kandpal 	u32 early_lock = 1;
14906fedb7bfSSuraj Kandpal 	u32 lock_ovr_en = 1;
14916fedb7bfSSuraj Kandpal 	u32 lock_thr = tdc_fine ? 3 : 5;
14926fedb7bfSSuraj Kandpal 	u32 unlock_thr = tdc_fine ? 5 : 11;
14936fedb7bfSSuraj Kandpal 
14946fedb7bfSSuraj Kandpal 	p->tdc.val = (u32)((2 << 30) + (settling_time << 16) + (bias_ovr_en << 15) +
14956fedb7bfSSuraj Kandpal 		    (lock_ovr_en << 14) + (coldstart << 12) + (true_lock << 10) +
14966fedb7bfSSuraj Kandpal 		    (early_lock << 8) + (unlock_thr << 4) + lock_thr);
14976fedb7bfSSuraj Kandpal }
14986fedb7bfSSuraj Kandpal 
14996fedb7bfSSuraj Kandpal static void compute_dco_med(struct lt_phy_params *p)
15006fedb7bfSSuraj Kandpal {
15016fedb7bfSSuraj Kandpal 	u32 cselmed_en = 0;
15026fedb7bfSSuraj Kandpal 	u32 cselmed_dyn_adj = 0;
15036fedb7bfSSuraj Kandpal 	u32 cselmed_ratio = 39;
15046fedb7bfSSuraj Kandpal 	u32 cselmed_thr = 8;
15056fedb7bfSSuraj Kandpal 
15066fedb7bfSSuraj Kandpal 	p->dco_med.val = (cselmed_en << 31) + (cselmed_dyn_adj << 30) +
15076fedb7bfSSuraj Kandpal 		(cselmed_ratio << 24) + (cselmed_thr << 21);
15086fedb7bfSSuraj Kandpal }
15096fedb7bfSSuraj Kandpal 
15106fedb7bfSSuraj Kandpal static void compute_dco_fine(struct lt_phy_params *p, u32 dco_12g)
15116fedb7bfSSuraj Kandpal {
15126fedb7bfSSuraj Kandpal 	u32 dco_fine0_tune_2_0 = 0;
15136fedb7bfSSuraj Kandpal 	u32 dco_fine1_tune_2_0 = 0;
15146fedb7bfSSuraj Kandpal 	u32 dco_fine2_tune_2_0 = 0;
15156fedb7bfSSuraj Kandpal 	u32 dco_fine3_tune_2_0 = 0;
15166fedb7bfSSuraj Kandpal 	u32 dco_dith0_tune_2_0 = 0;
15176fedb7bfSSuraj Kandpal 	u32 dco_dith1_tune_2_0 = 0;
15186fedb7bfSSuraj Kandpal 
15196fedb7bfSSuraj Kandpal 	dco_fine0_tune_2_0 = dco_12g ? 4 : 3;
15206fedb7bfSSuraj Kandpal 	dco_fine1_tune_2_0 = 2;
15216fedb7bfSSuraj Kandpal 	dco_fine2_tune_2_0 = dco_12g ? 2 : 1;
15226fedb7bfSSuraj Kandpal 	dco_fine3_tune_2_0 = 5;
15236fedb7bfSSuraj Kandpal 	dco_dith0_tune_2_0 = dco_12g ? 4 : 3;
15246fedb7bfSSuraj Kandpal 	dco_dith1_tune_2_0 = 2;
15256fedb7bfSSuraj Kandpal 
15266fedb7bfSSuraj Kandpal 	p->dco_fine.val = (dco_dith1_tune_2_0 << 19) +
15276fedb7bfSSuraj Kandpal 		(dco_dith0_tune_2_0 << 16) +
15286fedb7bfSSuraj Kandpal 		(dco_fine3_tune_2_0 << 11) +
15296fedb7bfSSuraj Kandpal 		(dco_fine2_tune_2_0 << 8) +
15306fedb7bfSSuraj Kandpal 		(dco_fine1_tune_2_0 << 3) +
15316fedb7bfSSuraj Kandpal 		dco_fine0_tune_2_0;
15326fedb7bfSSuraj Kandpal }
15336fedb7bfSSuraj Kandpal 
15346fedb7bfSSuraj Kandpal int
15356fedb7bfSSuraj Kandpal intel_lt_phy_calculate_hdmi_state(struct intel_lt_phy_pll_state *lt_state,
15366fedb7bfSSuraj Kandpal 				  u32 frequency_khz)
15376fedb7bfSSuraj Kandpal {
15386fedb7bfSSuraj Kandpal #define DATA_ASSIGN(i, pll_reg)	\
15396fedb7bfSSuraj Kandpal 	do {			\
15406fedb7bfSSuraj Kandpal 		lt_state->data[i][0] = (u8)((((pll_reg).val) & 0xFF000000) >> 24); \
15416fedb7bfSSuraj Kandpal 		lt_state->data[i][1] = (u8)((((pll_reg).val) & 0x00FF0000) >> 16); \
15426fedb7bfSSuraj Kandpal 		lt_state->data[i][2] = (u8)((((pll_reg).val) & 0x0000FF00) >> 8); \
15436fedb7bfSSuraj Kandpal 		lt_state->data[i][3] = (u8)((((pll_reg).val) & 0x000000FF));	\
15446fedb7bfSSuraj Kandpal 	} while (0)
15456fedb7bfSSuraj Kandpal #define ADDR_ASSIGN(i, pll_reg)	\
15466fedb7bfSSuraj Kandpal 	do {			\
15476fedb7bfSSuraj Kandpal 		lt_state->addr_msb[i] = ((pll_reg).addr >> 8) & 0xFF;	\
15486fedb7bfSSuraj Kandpal 		lt_state->addr_lsb[i] = (pll_reg).addr & 0xFF;		\
15496fedb7bfSSuraj Kandpal 	} while (0)
15506fedb7bfSSuraj Kandpal 
15516fedb7bfSSuraj Kandpal 	bool found = false;
15526fedb7bfSSuraj Kandpal 	struct lt_phy_params p;
15536fedb7bfSSuraj Kandpal 	u32 dco_fmin = DCO_MIN_FREQ_MHZ;
15546fedb7bfSSuraj Kandpal 	u64 refclk_khz = REF_CLK_KHZ;
15556fedb7bfSSuraj Kandpal 	u32 refclk_mhz_int = REF_CLK_KHZ / 1000;
15566fedb7bfSSuraj Kandpal 	u64 m2div = 0;
15576fedb7bfSSuraj Kandpal 	u64 target_dco_mhz = 0;
15586fedb7bfSSuraj Kandpal 	u64 tdc_fine, tdc_targetcnt;
15596fedb7bfSSuraj Kandpal 	u64 feedfwd_gain ,feedfwd_cal_en;
15606fedb7bfSSuraj Kandpal 	u64 tdc_res = 30;
15616fedb7bfSSuraj Kandpal 	u32 prop_coeff;
15626fedb7bfSSuraj Kandpal 	u32 int_coeff;
15636fedb7bfSSuraj Kandpal 	u32 ndiv = 1;
15646fedb7bfSSuraj Kandpal 	u32 m1div = 1, m2div_int, m2div_frac;
15656fedb7bfSSuraj Kandpal 	u32 frac_en;
15666fedb7bfSSuraj Kandpal 	u32 ana_cfg;
15676fedb7bfSSuraj Kandpal 	u32 loop_cnt = 0;
15686fedb7bfSSuraj Kandpal 	u32 gain_ctrl = 2;
15696fedb7bfSSuraj Kandpal 	u32 postdiv = 0;
15706fedb7bfSSuraj Kandpal 	u32 dco_12g = 0;
15716fedb7bfSSuraj Kandpal 	u32 pll_type = 0;
15726fedb7bfSSuraj Kandpal 	u32 d1 = 2, d3 = 5, d4 = 0, d5 = 0;
15736fedb7bfSSuraj Kandpal 	u32 d6 = 0, d6_new = 0;
15746fedb7bfSSuraj Kandpal 	u32 d7, d8 = 0;
15756fedb7bfSSuraj Kandpal 	u32 bonus_7_0 = 0;
15766fedb7bfSSuraj Kandpal 	u32 csel2fo = 11;
15776fedb7bfSSuraj Kandpal 	u32 csel2fo_ovrd_en = 1;
15786fedb7bfSSuraj Kandpal 	u64 temp0, temp1, temp2, temp3;
15796fedb7bfSSuraj Kandpal 
15806fedb7bfSSuraj Kandpal 	p.surv_bonus.val = (bonus_7_0 << 16);
15816fedb7bfSSuraj Kandpal 	p.pll_reg4.val = (refclk_mhz_int << 17) +
15826fedb7bfSSuraj Kandpal 		(ndiv << 9) + (1 << 4);
15836fedb7bfSSuraj Kandpal 	p.bias_trim.val = (csel2fo_ovrd_en << 30) + (csel2fo << 24);
15846fedb7bfSSuraj Kandpal 	p.ssc_inj.val = 0;
15856fedb7bfSSuraj Kandpal 	found = calculate_target_dco_and_loop_cnt(frequency_khz, &target_dco_mhz, &loop_cnt);
15866fedb7bfSSuraj Kandpal 	if (!found)
15876fedb7bfSSuraj Kandpal 		return -EINVAL;
15886fedb7bfSSuraj Kandpal 
15896fedb7bfSSuraj Kandpal 	m2div = div64_u64(target_dco_mhz, (refclk_khz * ndiv * m1div));
15906fedb7bfSSuraj Kandpal 	m2div = mul_q32_u32(m2div, 1000);
15916fedb7bfSSuraj Kandpal 	if (Q32_TO_INT(m2div) > 511)
15926fedb7bfSSuraj Kandpal 		return -EINVAL;
15936fedb7bfSSuraj Kandpal 
15946fedb7bfSSuraj Kandpal 	m2div_int = (u32)Q32_TO_INT(m2div);
15956fedb7bfSSuraj Kandpal 	m2div_frac = (u32)(Q32_TO_FRAC(m2div));
15966fedb7bfSSuraj Kandpal 	frac_en = (m2div_frac > 0) ? 1 : 0;
15976fedb7bfSSuraj Kandpal 
15986fedb7bfSSuraj Kandpal 	if (frac_en > 0)
15996fedb7bfSSuraj Kandpal 		tdc_res = 70;
16006fedb7bfSSuraj Kandpal 	else
16016fedb7bfSSuraj Kandpal 		tdc_res = 36;
16026fedb7bfSSuraj Kandpal 	tdc_fine = tdc_res > 50 ? 1 : 0;
16036fedb7bfSSuraj Kandpal 	temp0 = tdc_res * 40 * 11;
16046fedb7bfSSuraj Kandpal 	temp1 = div64_u64(((4 * TDC_RES_MULTIPLIER) + temp0) * 500, temp0 * refclk_khz);
16056fedb7bfSSuraj Kandpal 	temp2 = div64_u64(temp0 * refclk_khz, 1000);
16066fedb7bfSSuraj Kandpal 	temp3 = div64_u64(((8 * TDC_RES_MULTIPLIER) + temp2), temp2);
16076fedb7bfSSuraj Kandpal 	tdc_targetcnt = tdc_res < 50 ? (int)(temp1) : (int)(temp3);
16086fedb7bfSSuraj Kandpal 	tdc_targetcnt = (int)(tdc_targetcnt / 2);
16096fedb7bfSSuraj Kandpal 	temp0 = mul_q32_u32(target_dco_mhz, tdc_res);
16106fedb7bfSSuraj Kandpal 	temp0 >>= 32;
16116fedb7bfSSuraj Kandpal 	feedfwd_gain = (m2div_frac > 0) ? div64_u64(m1div * TDC_RES_MULTIPLIER, temp0) : 0;
16126fedb7bfSSuraj Kandpal 	feedfwd_cal_en = frac_en;
16136fedb7bfSSuraj Kandpal 
16146fedb7bfSSuraj Kandpal 	temp0 = (u32)Q32_TO_INT(target_dco_mhz);
16156fedb7bfSSuraj Kandpal 	prop_coeff = (temp0 >= dco_fmin) ? 3 : 4;
16166fedb7bfSSuraj Kandpal 	int_coeff = (temp0 >= dco_fmin) ? 7 : 8;
16176fedb7bfSSuraj Kandpal 	ana_cfg = (temp0 >= dco_fmin) ? 8 : 6;
16186fedb7bfSSuraj Kandpal 	dco_12g = (temp0 >= dco_fmin) ? 0 : 1;
16196fedb7bfSSuraj Kandpal 
16206fedb7bfSSuraj Kandpal 	if (temp0 > 12960)
16216fedb7bfSSuraj Kandpal 		d7 = 10;
16226fedb7bfSSuraj Kandpal 	else
16236fedb7bfSSuraj Kandpal 		d7 = 8;
16246fedb7bfSSuraj Kandpal 
16256fedb7bfSSuraj Kandpal 	d8 = loop_cnt / 2;
16266fedb7bfSSuraj Kandpal 	d4 = d8 * 2;
16276fedb7bfSSuraj Kandpal 
16286fedb7bfSSuraj Kandpal 	/* Compute pll_reg3,5,57 & lf */
16296fedb7bfSSuraj Kandpal 	p.pll_reg3.val = (u32)((d4 << 21) + (d3 << 18) + (d1 << 15) + (m2div_int << 5));
16306fedb7bfSSuraj Kandpal 	p.pll_reg5.val = m2div_frac;
16316fedb7bfSSuraj Kandpal 	postdiv = (d5 == 0) ? 9 : d5;
16326fedb7bfSSuraj Kandpal 	d6_new = (d6 == 0) ? 40 : d6;
16336fedb7bfSSuraj Kandpal 	p.pll_reg57.val = (d7 << 24) + (postdiv << 15) + (d8 << 7) + d6_new;
16346fedb7bfSSuraj Kandpal 	p.lf.val = (u32)((frac_en << 31) + (1 << 30) + (frac_en << 29) +
16356fedb7bfSSuraj Kandpal 		   (feedfwd_cal_en << 28) + (tdc_fine << 27) +
16366fedb7bfSSuraj Kandpal 		   (gain_ctrl << 24) + (feedfwd_gain << 16) +
16376fedb7bfSSuraj Kandpal 		   (int_coeff << 12) + (prop_coeff << 8) + tdc_targetcnt);
16386fedb7bfSSuraj Kandpal 
16396fedb7bfSSuraj Kandpal 	compute_ssc(&p, ana_cfg);
16406fedb7bfSSuraj Kandpal 	compute_bias2(&p);
16416fedb7bfSSuraj Kandpal 	compute_tdc(&p, tdc_fine);
16426fedb7bfSSuraj Kandpal 	compute_dco_med(&p);
16436fedb7bfSSuraj Kandpal 	compute_dco_fine(&p, dco_12g);
16446fedb7bfSSuraj Kandpal 
16456fedb7bfSSuraj Kandpal 	pll_type = ((frequency_khz == 10000) || (frequency_khz == 20000) ||
16466fedb7bfSSuraj Kandpal 		    (frequency_khz == 2500) || (dco_12g == 1)) ? 0 : 1;
16476fedb7bfSSuraj Kandpal 	set_phy_vdr_addresses(&p, pll_type);
16486fedb7bfSSuraj Kandpal 
16496fedb7bfSSuraj Kandpal 	lt_state->config[0] = 0x84;
16506fedb7bfSSuraj Kandpal 	lt_state->config[1] = 0x2d;
16516fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(0, p.pll_reg4);
16526fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(1, p.pll_reg3);
16536fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(2, p.pll_reg5);
16546fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(3, p.pll_reg57);
16556fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(4, p.lf);
16566fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(5, p.tdc);
16576fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(6, p.ssc);
16586fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(7, p.bias2);
16596fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(8, p.bias_trim);
16606fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(9, p.dco_med);
16616fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(10, p.dco_fine);
16626fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(11, p.ssc_inj);
16636fedb7bfSSuraj Kandpal 	ADDR_ASSIGN(12, p.surv_bonus);
16646fedb7bfSSuraj Kandpal 	DATA_ASSIGN(0, p.pll_reg4);
16656fedb7bfSSuraj Kandpal 	DATA_ASSIGN(1, p.pll_reg3);
16666fedb7bfSSuraj Kandpal 	DATA_ASSIGN(2, p.pll_reg5);
16676fedb7bfSSuraj Kandpal 	DATA_ASSIGN(3, p.pll_reg57);
16686fedb7bfSSuraj Kandpal 	DATA_ASSIGN(4, p.lf);
16696fedb7bfSSuraj Kandpal 	DATA_ASSIGN(5, p.tdc);
16706fedb7bfSSuraj Kandpal 	DATA_ASSIGN(6, p.ssc);
16716fedb7bfSSuraj Kandpal 	DATA_ASSIGN(7, p.bias2);
16726fedb7bfSSuraj Kandpal 	DATA_ASSIGN(8, p.bias_trim);
16736fedb7bfSSuraj Kandpal 	DATA_ASSIGN(9, p.dco_med);
16746fedb7bfSSuraj Kandpal 	DATA_ASSIGN(10, p.dco_fine);
16756fedb7bfSSuraj Kandpal 	DATA_ASSIGN(11, p.ssc_inj);
16766fedb7bfSSuraj Kandpal 	DATA_ASSIGN(12, p.surv_bonus);
16776fedb7bfSSuraj Kandpal 
16786fedb7bfSSuraj Kandpal 	return 0;
16796fedb7bfSSuraj Kandpal }
16806fedb7bfSSuraj Kandpal 
16812435a11dSSuraj Kandpal static int
1682fa4aa0b2SSuraj Kandpal intel_lt_phy_calc_hdmi_port_clock(const struct intel_crtc_state *crtc_state)
16832435a11dSSuraj Kandpal {
16842435a11dSSuraj Kandpal #define REGVAL(i) (				\
16852435a11dSSuraj Kandpal 	(lt_state->data[i][3])		|	\
16862435a11dSSuraj Kandpal 	(lt_state->data[i][2] << 8)	|	\
16872435a11dSSuraj Kandpal 	(lt_state->data[i][1] << 16)	|	\
16882435a11dSSuraj Kandpal 	(lt_state->data[i][0] << 24)		\
16892435a11dSSuraj Kandpal )
16902435a11dSSuraj Kandpal 
1691fa4aa0b2SSuraj Kandpal 	struct intel_display *display = to_intel_display(crtc_state);
1692fa4aa0b2SSuraj Kandpal 	const struct intel_lt_phy_pll_state *lt_state =
1693fa4aa0b2SSuraj Kandpal 		&crtc_state->dpll_hw_state.ltpll;
16942435a11dSSuraj Kandpal 	int clk = 0;
16952435a11dSSuraj Kandpal 	u32 d8, pll_reg_5, pll_reg_3, pll_reg_57, m2div_frac, m2div_int;
16962435a11dSSuraj Kandpal 	u64 temp0, temp1;
16972435a11dSSuraj Kandpal 	/*
16982435a11dSSuraj Kandpal 	 * The algorithm uses '+' to combine bitfields when
16992435a11dSSuraj Kandpal 	 * constructing PLL_reg3 and PLL_reg57:
17002435a11dSSuraj Kandpal 	 * PLL_reg57 = (D7 << 24) + (postdiv << 15) + (D8 << 7) + D6_new;
17012435a11dSSuraj Kandpal 	 * PLL_reg3 = (D4 << 21) + (D3 << 18) + (D1 << 15) + (m2div_int << 5);
17022435a11dSSuraj Kandpal 	 *
17032435a11dSSuraj Kandpal 	 * However, this is likely intended to be a bitwise OR operation,
17042435a11dSSuraj Kandpal 	 * as each field occupies distinct, non-overlapping bits in the register.
17052435a11dSSuraj Kandpal 	 *
17062435a11dSSuraj Kandpal 	 * PLL_reg57 is composed of following fields packed into a 32-bit value:
17072435a11dSSuraj Kandpal 	 * - D7: max value 10 -> fits in 4 bits -> placed at bits 24-27
17082435a11dSSuraj Kandpal 	 * - postdiv: max value 9 -> fits in 4 bits -> placed at bits 15-18
17092435a11dSSuraj Kandpal 	 * - D8: derived from loop_cnt / 2, max 127 -> fits in 7 bits
17102435a11dSSuraj Kandpal 	 *	(though 8 bits are given to it) -> placed at bits 7-14
17112435a11dSSuraj Kandpal 	 * - D6_new: fits in lower 7 bits -> placed at bits 0-6
17122435a11dSSuraj Kandpal 	 * PLL_reg57 = (D7 << 24) | (postdiv << 15) | (D8 << 7) | D6_new;
17132435a11dSSuraj Kandpal 	 *
17142435a11dSSuraj Kandpal 	 * Similarly, PLL_reg3 is packed as:
17152435a11dSSuraj Kandpal 	 * - D4: max value 256 -> fits in 9 bits -> placed at bits 21-29
17162435a11dSSuraj Kandpal 	 * - D3: max value 9 -> fits in 4 bits -> placed at bits 18-21
17172435a11dSSuraj Kandpal 	 * - D1: max value 2 -> fits in 2 bits -> placed at bits 15-16
17182435a11dSSuraj Kandpal 	 * - m2div_int: max value 511 -> fits in 9 bits (10 bits allocated)
17192435a11dSSuraj Kandpal 	 *   -> placed at bits 5-14
17202435a11dSSuraj Kandpal 	 * PLL_reg3 = (D4 << 21) | (D3 << 18) | (D1 << 15) | (m2div_int << 5);
17212435a11dSSuraj Kandpal 	 */
17222435a11dSSuraj Kandpal 	pll_reg_5 = REGVAL(2);
17232435a11dSSuraj Kandpal 	pll_reg_3 = REGVAL(1);
17242435a11dSSuraj Kandpal 	pll_reg_57 = REGVAL(3);
17252435a11dSSuraj Kandpal 	m2div_frac = pll_reg_5;
17262435a11dSSuraj Kandpal 
17272435a11dSSuraj Kandpal 	/*
17282435a11dSSuraj Kandpal 	 * From forward algorithm we know
17292435a11dSSuraj Kandpal 	 * m2div = 2 * m2
17302435a11dSSuraj Kandpal 	 * val = y * frequency * 5
17312435a11dSSuraj Kandpal 	 * So now,
17322435a11dSSuraj Kandpal 	 * frequency = (m2 * 2 * refclk_khz / (d8 * 10))
17332435a11dSSuraj Kandpal 	 * frequency = (m2div * refclk_khz / (d8 * 10))
17342435a11dSSuraj Kandpal 	 */
17352435a11dSSuraj Kandpal 	d8 = (pll_reg_57 & REG_GENMASK(14, 7)) >> 7;
1736fa4aa0b2SSuraj Kandpal 	if (d8 == 0) {
1737fa4aa0b2SSuraj Kandpal 		drm_WARN_ON(display->drm,
1738fa4aa0b2SSuraj Kandpal 			    "Invalid port clock using lowest HDMI portclock\n");
1739fa4aa0b2SSuraj Kandpal 		return xe3plpd_lt_hdmi_252.clock;
1740fa4aa0b2SSuraj Kandpal 	}
17412435a11dSSuraj Kandpal 	m2div_int = (pll_reg_3  & REG_GENMASK(14, 5)) >> 5;
17422435a11dSSuraj Kandpal 	temp0 = ((u64)m2div_frac * REF_CLK_KHZ) >> 32;
17432435a11dSSuraj Kandpal 	temp1 = (u64)m2div_int * REF_CLK_KHZ;
17442435a11dSSuraj Kandpal 
17452435a11dSSuraj Kandpal 	clk = div_u64((temp1 + temp0), d8 * 10);
17462435a11dSSuraj Kandpal 
17472435a11dSSuraj Kandpal 	return clk;
17482435a11dSSuraj Kandpal }
17492435a11dSSuraj Kandpal 
17502435a11dSSuraj Kandpal int
17512435a11dSSuraj Kandpal intel_lt_phy_calc_port_clock(struct intel_encoder *encoder,
17522435a11dSSuraj Kandpal 			     const struct intel_crtc_state *crtc_state)
17532435a11dSSuraj Kandpal {
17542435a11dSSuraj Kandpal 	int clk;
17552435a11dSSuraj Kandpal 	const struct intel_lt_phy_pll_state *lt_state =
17562435a11dSSuraj Kandpal 		&crtc_state->dpll_hw_state.ltpll;
17572435a11dSSuraj Kandpal 	u8 mode, rate;
17582435a11dSSuraj Kandpal 
17592435a11dSSuraj Kandpal 	mode = REG_FIELD_GET8(LT_PHY_VDR_MODE_ENCODING_MASK,
17602435a11dSSuraj Kandpal 			      lt_state->config[0]);
17612435a11dSSuraj Kandpal 	/*
17622435a11dSSuraj Kandpal 	 * For edp/dp read the clock value from the tables
17632435a11dSSuraj Kandpal 	 * and return the clock as the algorithm used for
17642435a11dSSuraj Kandpal 	 * calculating the port clock does not exactly matches
17652435a11dSSuraj Kandpal 	 * with edp/dp clock.
17662435a11dSSuraj Kandpal 	 */
17672435a11dSSuraj Kandpal 	if (mode == MODE_DP) {
17682435a11dSSuraj Kandpal 		rate = REG_FIELD_GET8(LT_PHY_VDR_RATE_ENCODING_MASK,
17692435a11dSSuraj Kandpal 				      lt_state->config[0]);
17702435a11dSSuraj Kandpal 		clk = intel_lt_phy_get_dp_clock(rate);
17712435a11dSSuraj Kandpal 	} else {
1772fa4aa0b2SSuraj Kandpal 		clk = intel_lt_phy_calc_hdmi_port_clock(crtc_state);
17732435a11dSSuraj Kandpal 	}
17742435a11dSSuraj Kandpal 
17752435a11dSSuraj Kandpal 	return clk;
17762435a11dSSuraj Kandpal }
17772435a11dSSuraj Kandpal 
1778dc5742b6SSuraj Kandpal int
1779dc5742b6SSuraj Kandpal intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state,
1780dc5742b6SSuraj Kandpal 			    struct intel_encoder *encoder)
1781dc5742b6SSuraj Kandpal {
1782dc5742b6SSuraj Kandpal 	const struct intel_lt_phy_pll_state * const *tables;
1783dc5742b6SSuraj Kandpal 	int i;
1784dc5742b6SSuraj Kandpal 
1785dc5742b6SSuraj Kandpal 	tables = intel_lt_phy_pll_tables_get(crtc_state, encoder);
1786dc5742b6SSuraj Kandpal 	if (!tables)
1787dc5742b6SSuraj Kandpal 		return -EINVAL;
1788dc5742b6SSuraj Kandpal 
1789dc5742b6SSuraj Kandpal 	for (i = 0; tables[i]; i++) {
1790dc5742b6SSuraj Kandpal 		if (crtc_state->port_clock == tables[i]->clock) {
1791dc5742b6SSuraj Kandpal 			crtc_state->dpll_hw_state.ltpll = *tables[i];
17924f1118bfSSuraj Kandpal 			if (intel_crtc_has_dp_encoder(crtc_state)) {
17934f1118bfSSuraj Kandpal 				if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
17944f1118bfSSuraj Kandpal 					crtc_state->dpll_hw_state.ltpll.config[2] = 1;
17954f1118bfSSuraj Kandpal 			}
17963383ba24SSuraj Kandpal 			crtc_state->dpll_hw_state.ltpll.ssc_enabled =
17973383ba24SSuraj Kandpal 				intel_lt_phy_pll_is_ssc_enabled(crtc_state, encoder);
1798dc5742b6SSuraj Kandpal 			return 0;
1799dc5742b6SSuraj Kandpal 		}
1800dc5742b6SSuraj Kandpal 	}
1801dc5742b6SSuraj Kandpal 
18026fedb7bfSSuraj Kandpal 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
18036fedb7bfSSuraj Kandpal 		return intel_lt_phy_calculate_hdmi_state(&crtc_state->dpll_hw_state.ltpll,
18046fedb7bfSSuraj Kandpal 							 crtc_state->port_clock);
18056fedb7bfSSuraj Kandpal 	}
1806dc5742b6SSuraj Kandpal 
1807dc5742b6SSuraj Kandpal 	return -EINVAL;
1808dc5742b6SSuraj Kandpal }
1809dc5742b6SSuraj Kandpal 
18101dd885d5SSuraj Kandpal static void
18111dd885d5SSuraj Kandpal intel_lt_phy_program_pll(struct intel_encoder *encoder,
18121dd885d5SSuraj Kandpal 			 const struct intel_crtc_state *crtc_state)
18131dd885d5SSuraj Kandpal {
18141dd885d5SSuraj Kandpal 	u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
18151dd885d5SSuraj Kandpal 	int i, j, k;
18161dd885d5SSuraj Kandpal 
18171dd885d5SSuraj Kandpal 	intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_VDR_0_CONFIG,
18181dd885d5SSuraj Kandpal 			   crtc_state->dpll_hw_state.ltpll.config[0], MB_WRITE_COMMITTED);
18191dd885d5SSuraj Kandpal 	intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_1_CONFIG,
18201dd885d5SSuraj Kandpal 			   crtc_state->dpll_hw_state.ltpll.config[1], MB_WRITE_COMMITTED);
18211dd885d5SSuraj Kandpal 	intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_VDR_2_CONFIG,
18221dd885d5SSuraj Kandpal 			   crtc_state->dpll_hw_state.ltpll.config[2], MB_WRITE_COMMITTED);
18231dd885d5SSuraj Kandpal 
18241dd885d5SSuraj Kandpal 	for (i = 0; i <= 12; i++) {
18251dd885d5SSuraj Kandpal 		intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_X_ADDR_MSB(i),
18261dd885d5SSuraj Kandpal 				   crtc_state->dpll_hw_state.ltpll.addr_msb[i],
18271dd885d5SSuraj Kandpal 				   MB_WRITE_COMMITTED);
18281dd885d5SSuraj Kandpal 		intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_X_ADDR_LSB(i),
18291dd885d5SSuraj Kandpal 				   crtc_state->dpll_hw_state.ltpll.addr_lsb[i],
18301dd885d5SSuraj Kandpal 				   MB_WRITE_COMMITTED);
18311dd885d5SSuraj Kandpal 
18321dd885d5SSuraj Kandpal 		for (j = 3, k = 0; j >= 0; j--, k++)
18331dd885d5SSuraj Kandpal 			intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0,
18341dd885d5SSuraj Kandpal 					   LT_PHY_VDR_X_DATAY(i, j),
18351dd885d5SSuraj Kandpal 					   crtc_state->dpll_hw_state.ltpll.data[i][k],
18361dd885d5SSuraj Kandpal 					   MB_WRITE_COMMITTED);
18371dd885d5SSuraj Kandpal 	}
18381dd885d5SSuraj Kandpal }
18391dd885d5SSuraj Kandpal 
1840a54bdcb7SSuraj Kandpal static void
1841a54bdcb7SSuraj Kandpal intel_lt_phy_enable_disable_tx(struct intel_encoder *encoder,
1842a54bdcb7SSuraj Kandpal 			       const struct intel_crtc_state *crtc_state)
1843a54bdcb7SSuraj Kandpal {
1844a54bdcb7SSuraj Kandpal 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
1845a54bdcb7SSuraj Kandpal 	bool lane_reversal = dig_port->lane_reversal;
1846a54bdcb7SSuraj Kandpal 	u8 lane_count = crtc_state->lane_count;
1847a54bdcb7SSuraj Kandpal 	bool is_dp_alt =
1848a54bdcb7SSuraj Kandpal 		intel_tc_port_in_dp_alt_mode(dig_port);
1849a54bdcb7SSuraj Kandpal 	enum intel_tc_pin_assignment tc_pin =
1850a54bdcb7SSuraj Kandpal 		intel_tc_port_get_pin_assignment(dig_port);
1851a54bdcb7SSuraj Kandpal 	u8 transmitter_mask = 0;
1852a54bdcb7SSuraj Kandpal 
1853a54bdcb7SSuraj Kandpal 	/*
1854a54bdcb7SSuraj Kandpal 	 * We have a two transmitters per lane and total of 2 PHY lanes so a total
1855a54bdcb7SSuraj Kandpal 	 * of 4 transmitters. We prepare a mask of the lanes that need to be activated
1856a54bdcb7SSuraj Kandpal 	 * and the transmitter which need to be activated for each lane. TX 0,1 correspond
1857a54bdcb7SSuraj Kandpal 	 * to LANE0 and TX 2, 3 correspond to LANE1.
1858a54bdcb7SSuraj Kandpal 	 */
1859a54bdcb7SSuraj Kandpal 
1860a54bdcb7SSuraj Kandpal 	switch (lane_count) {
1861a54bdcb7SSuraj Kandpal 	case 1:
1862a54bdcb7SSuraj Kandpal 		transmitter_mask = lane_reversal ? REG_BIT8(3) : REG_BIT8(0);
1863a54bdcb7SSuraj Kandpal 		if (is_dp_alt) {
1864a54bdcb7SSuraj Kandpal 			if (tc_pin == INTEL_TC_PIN_ASSIGNMENT_D)
1865a54bdcb7SSuraj Kandpal 				transmitter_mask = REG_BIT8(0);
1866a54bdcb7SSuraj Kandpal 			else
1867a54bdcb7SSuraj Kandpal 				transmitter_mask = REG_BIT8(1);
1868a54bdcb7SSuraj Kandpal 		}
1869a54bdcb7SSuraj Kandpal 		break;
1870a54bdcb7SSuraj Kandpal 	case 2:
1871a54bdcb7SSuraj Kandpal 		transmitter_mask = lane_reversal ? REG_GENMASK8(3, 2) : REG_GENMASK8(1, 0);
1872a54bdcb7SSuraj Kandpal 		if (is_dp_alt)
1873a54bdcb7SSuraj Kandpal 			transmitter_mask = REG_GENMASK8(1, 0);
1874a54bdcb7SSuraj Kandpal 		break;
1875a54bdcb7SSuraj Kandpal 	case 3:
1876a54bdcb7SSuraj Kandpal 		transmitter_mask = lane_reversal ? REG_GENMASK8(3, 1) : REG_GENMASK8(2, 0);
1877a54bdcb7SSuraj Kandpal 		if (is_dp_alt)
1878a54bdcb7SSuraj Kandpal 			transmitter_mask = REG_GENMASK8(2, 0);
1879a54bdcb7SSuraj Kandpal 		break;
1880a54bdcb7SSuraj Kandpal 	case 4:
1881a54bdcb7SSuraj Kandpal 		transmitter_mask = REG_GENMASK8(3, 0);
1882a54bdcb7SSuraj Kandpal 		break;
1883a54bdcb7SSuraj Kandpal 	default:
1884a54bdcb7SSuraj Kandpal 		MISSING_CASE(lane_count);
1885a54bdcb7SSuraj Kandpal 		transmitter_mask = REG_GENMASK8(3, 0);
1886a54bdcb7SSuraj Kandpal 		break;
1887a54bdcb7SSuraj Kandpal 	}
1888a54bdcb7SSuraj Kandpal 
1889a54bdcb7SSuraj Kandpal 	if (transmitter_mask & BIT(0)) {
1890a54bdcb7SSuraj Kandpal 		intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(0),
1891a54bdcb7SSuraj Kandpal 				       LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(0),
1892a54bdcb7SSuraj Kandpal 				       LT_PHY_TX_LANE_ENABLE);
1893a54bdcb7SSuraj Kandpal 	} else {
1894a54bdcb7SSuraj Kandpal 		intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(0),
1895a54bdcb7SSuraj Kandpal 				       0, LT_PHY_TXY_CTL10_MAC(0), 0);
1896a54bdcb7SSuraj Kandpal 	}
1897a54bdcb7SSuraj Kandpal 
1898a54bdcb7SSuraj Kandpal 	if (transmitter_mask & BIT(1)) {
1899a54bdcb7SSuraj Kandpal 		intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(1),
1900a54bdcb7SSuraj Kandpal 				       LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(1),
1901a54bdcb7SSuraj Kandpal 				       LT_PHY_TX_LANE_ENABLE);
1902a54bdcb7SSuraj Kandpal 	} else {
1903a54bdcb7SSuraj Kandpal 		intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(1),
1904a54bdcb7SSuraj Kandpal 				       0, LT_PHY_TXY_CTL10_MAC(1), 0);
1905a54bdcb7SSuraj Kandpal 	}
1906a54bdcb7SSuraj Kandpal 
1907a54bdcb7SSuraj Kandpal 	if (transmitter_mask & BIT(2)) {
1908a54bdcb7SSuraj Kandpal 		intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(0),
1909a54bdcb7SSuraj Kandpal 				       LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(0),
1910a54bdcb7SSuraj Kandpal 				       LT_PHY_TX_LANE_ENABLE);
1911a54bdcb7SSuraj Kandpal 	} else {
1912a54bdcb7SSuraj Kandpal 		intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(0),
1913a54bdcb7SSuraj Kandpal 				       0, LT_PHY_TXY_CTL10_MAC(0), 0);
1914a54bdcb7SSuraj Kandpal 	}
1915a54bdcb7SSuraj Kandpal 
1916a54bdcb7SSuraj Kandpal 	if (transmitter_mask & BIT(3)) {
1917a54bdcb7SSuraj Kandpal 		intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(1),
1918a54bdcb7SSuraj Kandpal 				       LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(1),
1919a54bdcb7SSuraj Kandpal 				       LT_PHY_TX_LANE_ENABLE);
1920a54bdcb7SSuraj Kandpal 	} else {
1921a54bdcb7SSuraj Kandpal 		intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(1),
1922a54bdcb7SSuraj Kandpal 				       0, LT_PHY_TXY_CTL10_MAC(1), 0);
1923a54bdcb7SSuraj Kandpal 	}
1924a54bdcb7SSuraj Kandpal }
1925a54bdcb7SSuraj Kandpal 
1926154ebdb7SSuraj Kandpal void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
1927154ebdb7SSuraj Kandpal 			     const struct intel_crtc_state *crtc_state)
1928154ebdb7SSuraj Kandpal {
1929e1455196SSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
19303a323c7eSSuraj Kandpal 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
19313a323c7eSSuraj Kandpal 	bool lane_reversal = dig_port->lane_reversal;
1932fc9be0a1SSuraj Kandpal 	u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
193382b46083SSuraj Kandpal 	enum phy phy = intel_encoder_to_phy(encoder);
193482b46083SSuraj Kandpal 	enum port port = encoder->port;
1935e1455196SSuraj Kandpal 	intel_wakeref_t wakeref = 0;
193632865c2dSSuraj Kandpal 	u32 lane_phy_pulse_status = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES
193732865c2dSSuraj Kandpal 					? (XE3PLPDP_LANE_PHY_PULSE_STATUS(0) |
193832865c2dSSuraj Kandpal 					   XE3PLPDP_LANE_PHY_PULSE_STATUS(1))
193932865c2dSSuraj Kandpal 					: XE3PLPDP_LANE_PHY_PULSE_STATUS(0);
194032865c2dSSuraj Kandpal 	u8 rate_update;
1941e1455196SSuraj Kandpal 
1942e1455196SSuraj Kandpal 	wakeref = intel_lt_phy_transaction_begin(encoder);
19433a323c7eSSuraj Kandpal 
1944154ebdb7SSuraj Kandpal 	/* 1. Enable MacCLK at default 162 MHz frequency. */
1945154ebdb7SSuraj Kandpal 	intel_lt_phy_lane_reset(encoder, crtc_state->lane_count);
1946154ebdb7SSuraj Kandpal 
1947154ebdb7SSuraj Kandpal 	/* 2. Program PORT_CLOCK_CTL register to configure clock muxes, gating, and SSC. */
19483a323c7eSSuraj Kandpal 	intel_lt_phy_program_port_clock_ctl(encoder, crtc_state, lane_reversal);
19493a323c7eSSuraj Kandpal 
1950154ebdb7SSuraj Kandpal 	/* 3. Change owned PHY lanes power to Ready state. */
1951fc9be0a1SSuraj Kandpal 	intel_lt_phy_powerdown_change_sequence(encoder, owned_lane_mask,
1952fc9be0a1SSuraj Kandpal 					       XELPDP_P2_STATE_READY);
1953fc9be0a1SSuraj Kandpal 
1954154ebdb7SSuraj Kandpal 	/*
1955154ebdb7SSuraj Kandpal 	 * 4. Read the PHY message bus VDR register PHY_VDR_0_Config check enabled PLL type,
1956154ebdb7SSuraj Kandpal 	 * encoded rate and encoded mode.
1957154ebdb7SSuraj Kandpal 	 */
1958e1455196SSuraj Kandpal 	if (intel_lt_phy_config_changed(encoder, crtc_state)) {
1959154ebdb7SSuraj Kandpal 		/*
1960154ebdb7SSuraj Kandpal 		 * 5. Program the PHY internal PLL registers over PHY message bus for the desired
1961154ebdb7SSuraj Kandpal 		 * frequency and protocol type
1962154ebdb7SSuraj Kandpal 		 */
19631dd885d5SSuraj Kandpal 		intel_lt_phy_program_pll(encoder, crtc_state);
19641dd885d5SSuraj Kandpal 
1965154ebdb7SSuraj Kandpal 		/* 6. Use the P2P transaction flow */
1966154ebdb7SSuraj Kandpal 		/*
1967154ebdb7SSuraj Kandpal 		 * 6.1. Set the PHY VDR register 0xCC4[Rate Control VDR Update] = 1 over PHY message
1968154ebdb7SSuraj Kandpal 		 * bus for Owned PHY Lanes.
1969154ebdb7SSuraj Kandpal 		 */
1970154ebdb7SSuraj Kandpal 		/*
1971e1455196SSuraj Kandpal 		 * 6.2. Poll for P2P Transaction Ready = "1" and read the MAC message bus VDR
1972e1455196SSuraj Kandpal 		 * register at offset 0xC00 for Owned PHY Lanes*.
1973154ebdb7SSuraj Kandpal 		 */
1974154ebdb7SSuraj Kandpal 		/* 6.3. Clear P2P transaction Ready bit. */
197541d07bd2SSuraj Kandpal 		intel_lt_phy_p2p_write(encoder, owned_lane_mask, LT_PHY_RATE_UPDATE,
197641d07bd2SSuraj Kandpal 				       LT_PHY_RATE_CONTROL_VDR_UPDATE, LT_PHY_MAC_VDR,
197741d07bd2SSuraj Kandpal 				       LT_PHY_PCLKIN_GATE);
197841d07bd2SSuraj Kandpal 
1979154ebdb7SSuraj Kandpal 		/* 7. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 0. */
198082b46083SSuraj Kandpal 		intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
198182b46083SSuraj Kandpal 			     XELPDP_LANE_PCLK_PLL_REQUEST(0), 0);
198282b46083SSuraj Kandpal 
1983154ebdb7SSuraj Kandpal 		/* 8. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 0. */
19840aed9d34SVille Syrjälä 		if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, port),
19850aed9d34SVille Syrjälä 					       XELPDP_LANE_PCLK_PLL_ACK(0),
19860aed9d34SVille Syrjälä 					       XE3PLPD_MACCLK_TURNOFF_LATENCY_US))
1987dfd58249SVille Syrjälä 			drm_warn(display->drm, "PHY %c PLL MacCLK ack deassertion timeout\n",
1988dfd58249SVille Syrjälä 				 phy_name(phy));
198982b46083SSuraj Kandpal 
1990154ebdb7SSuraj Kandpal 		/*
1991e1455196SSuraj Kandpal 		 * 9. Follow the Display Voltage Frequency Switching - Sequence Before Frequency
1992e1455196SSuraj Kandpal 		 * Change. We handle this step in bxt_set_cdclk().
1993154ebdb7SSuraj Kandpal 		 */
1994154ebdb7SSuraj Kandpal 		/* 10. Program DDI_CLK_VALFREQ to match intended DDI clock frequency. */
199532865c2dSSuraj Kandpal 		intel_de_write(display, DDI_CLK_VALFREQ(encoder->port),
199632865c2dSSuraj Kandpal 			       crtc_state->port_clock);
199732865c2dSSuraj Kandpal 
1998154ebdb7SSuraj Kandpal 		/* 11. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 1. */
199982b46083SSuraj Kandpal 		intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
200082b46083SSuraj Kandpal 			     XELPDP_LANE_PCLK_PLL_REQUEST(0),
200182b46083SSuraj Kandpal 			     XELPDP_LANE_PCLK_PLL_REQUEST(0));
200282b46083SSuraj Kandpal 
2003154ebdb7SSuraj Kandpal 		/* 12. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 1. */
20046be05d5bSVille Syrjälä 		if (intel_de_wait_for_set_ms(display, XELPDP_PORT_CLOCK_CTL(display, port),
20056be05d5bSVille Syrjälä 					     XELPDP_LANE_PCLK_PLL_ACK(0),
20066be05d5bSVille Syrjälä 					     XE3PLPD_MACCLK_TURNON_LATENCY_MS))
2007dfd58249SVille Syrjälä 			drm_warn(display->drm, "PHY %c PLL MacCLK ack assertion timeout\n",
2008dfd58249SVille Syrjälä 				 phy_name(phy));
2009e1455196SSuraj Kandpal 
2010ad7108f9SSuraj Kandpal 		/*
2011ad7108f9SSuraj Kandpal 		 * 13. Ungate the forward clock by setting
2012ad7108f9SSuraj Kandpal 		 * PORT_CLOCK_CTL[Forward Clock Ungate] = 1.
2013ad7108f9SSuraj Kandpal 		 */
201482b46083SSuraj Kandpal 		intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
201582b46083SSuraj Kandpal 			     XELPDP_FORWARD_CLOCK_UNGATE,
201682b46083SSuraj Kandpal 			     XELPDP_FORWARD_CLOCK_UNGATE);
201782b46083SSuraj Kandpal 
2018154ebdb7SSuraj Kandpal 		/* 14. SW clears PORT_BUF_CTL2 [PHY Pulse Status]. */
201932865c2dSSuraj Kandpal 		intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port),
202032865c2dSSuraj Kandpal 			     lane_phy_pulse_status,
202132865c2dSSuraj Kandpal 			     lane_phy_pulse_status);
2022154ebdb7SSuraj Kandpal 		/*
2023ad7108f9SSuraj Kandpal 		 * 15. Clear the PHY VDR register 0xCC4[Rate Control VDR Update] over
2024ad7108f9SSuraj Kandpal 		 * PHY message bus for Owned PHY Lanes.
2025154ebdb7SSuraj Kandpal 		 */
202632865c2dSSuraj Kandpal 		rate_update = intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0, LT_PHY_RATE_UPDATE);
202732865c2dSSuraj Kandpal 		rate_update &= ~LT_PHY_RATE_CONTROL_VDR_UPDATE;
202832865c2dSSuraj Kandpal 		intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_RATE_UPDATE,
202932865c2dSSuraj Kandpal 				   rate_update, MB_WRITE_COMMITTED);
203032865c2dSSuraj Kandpal 
2031154ebdb7SSuraj Kandpal 		/* 16. Poll for PORT_BUF_CTL2 register PHY Pulse Status = 1 for Owned PHY Lanes. */
20326be05d5bSVille Syrjälä 		if (intel_de_wait_for_set_ms(display, XELPDP_PORT_BUF_CTL2(display, port),
20336be05d5bSVille Syrjälä 					     lane_phy_pulse_status,
20346be05d5bSVille Syrjälä 					     XE3PLPD_RATE_CALIB_DONE_LATENCY_MS))
2035dfd58249SVille Syrjälä 			drm_warn(display->drm, "PHY %c PLL rate not changed\n",
2036dfd58249SVille Syrjälä 				 phy_name(phy));
203732865c2dSSuraj Kandpal 
2038154ebdb7SSuraj Kandpal 		/* 17. SW clears PORT_BUF_CTL2 [PHY Pulse Status]. */
203932865c2dSSuraj Kandpal 		intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port),
204032865c2dSSuraj Kandpal 			     lane_phy_pulse_status,
204132865c2dSSuraj Kandpal 			     lane_phy_pulse_status);
2042ad7108f9SSuraj Kandpal 	} else {
2043ad7108f9SSuraj Kandpal 		intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), crtc_state->port_clock);
2044ad7108f9SSuraj Kandpal 	}
204532865c2dSSuraj Kandpal 
2046154ebdb7SSuraj Kandpal 	/*
2047154ebdb7SSuraj Kandpal 	 * 18. Follow the Display Voltage Frequency Switching - Sequence After Frequency Change.
2048154ebdb7SSuraj Kandpal 	 * We handle this step in bxt_set_cdclk()
2049154ebdb7SSuraj Kandpal 	 */
2050154ebdb7SSuraj Kandpal 	/* 19. Move the PHY powerdown state to Active and program to enable/disable transmitters */
205132865c2dSSuraj Kandpal 	intel_lt_phy_powerdown_change_sequence(encoder, owned_lane_mask,
205232865c2dSSuraj Kandpal 					       XELPDP_P0_STATE_ACTIVE);
2053e1455196SSuraj Kandpal 
2054a54bdcb7SSuraj Kandpal 	intel_lt_phy_enable_disable_tx(encoder, crtc_state);
2055e1455196SSuraj Kandpal 	intel_lt_phy_transaction_end(encoder, wakeref);
2056154ebdb7SSuraj Kandpal }
2057fa5fd596SSuraj Kandpal 
2058fa5fd596SSuraj Kandpal void intel_lt_phy_pll_disable(struct intel_encoder *encoder)
2059fa5fd596SSuraj Kandpal {
2060fa5fd596SSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
2061fa5fd596SSuraj Kandpal 	enum phy phy = intel_encoder_to_phy(encoder);
2062fa5fd596SSuraj Kandpal 	enum port port = encoder->port;
2063fa5fd596SSuraj Kandpal 	intel_wakeref_t wakeref;
2064fa5fd596SSuraj Kandpal 	u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
2065fa5fd596SSuraj Kandpal 	u32 lane_pipe_reset = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES
2066fa5fd596SSuraj Kandpal 				? (XELPDP_LANE_PIPE_RESET(0) |
2067fa5fd596SSuraj Kandpal 				   XELPDP_LANE_PIPE_RESET(1))
2068fa5fd596SSuraj Kandpal 				: XELPDP_LANE_PIPE_RESET(0);
2069fa5fd596SSuraj Kandpal 	u32 lane_phy_current_status = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES
2070fa5fd596SSuraj Kandpal 					? (XELPDP_LANE_PHY_CURRENT_STATUS(0) |
2071fa5fd596SSuraj Kandpal 					   XELPDP_LANE_PHY_CURRENT_STATUS(1))
2072fa5fd596SSuraj Kandpal 					: XELPDP_LANE_PHY_CURRENT_STATUS(0);
2073fa5fd596SSuraj Kandpal 	u32 lane_phy_pulse_status = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES
2074fa5fd596SSuraj Kandpal 					? (XE3PLPDP_LANE_PHY_PULSE_STATUS(0) |
2075fa5fd596SSuraj Kandpal 					   XE3PLPDP_LANE_PHY_PULSE_STATUS(1))
2076fa5fd596SSuraj Kandpal 					: XE3PLPDP_LANE_PHY_PULSE_STATUS(0);
2077fa5fd596SSuraj Kandpal 
2078fa5fd596SSuraj Kandpal 	wakeref = intel_lt_phy_transaction_begin(encoder);
2079fa5fd596SSuraj Kandpal 
2080fa5fd596SSuraj Kandpal 	/* 1. Clear PORT_BUF_CTL2 [PHY Pulse Status]. */
2081fa5fd596SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port),
2082fa5fd596SSuraj Kandpal 		     lane_phy_pulse_status,
2083fa5fd596SSuraj Kandpal 		     lane_phy_pulse_status);
2084fa5fd596SSuraj Kandpal 
2085fa5fd596SSuraj Kandpal 	/* 2. Set PORT_BUF_CTL2<port> Lane<PHY Lanes Owned> Pipe Reset to 1. */
2086fa5fd596SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_pipe_reset,
2087fa5fd596SSuraj Kandpal 		     lane_pipe_reset);
2088fa5fd596SSuraj Kandpal 
2089fa5fd596SSuraj Kandpal 	/* 3. Poll for PORT_BUF_CTL2<port> Lane<PHY Lanes Owned> PHY Current Status == 1. */
20900aed9d34SVille Syrjälä 	if (intel_de_wait_for_set_us(display, XELPDP_PORT_BUF_CTL2(display, port),
20910aed9d34SVille Syrjälä 				     lane_phy_current_status,
20920aed9d34SVille Syrjälä 				     XE3PLPD_RESET_START_LATENCY_US))
2093dfd58249SVille Syrjälä 		drm_warn(display->drm, "PHY %c failed to reset lane\n",
2094dfd58249SVille Syrjälä 			 phy_name(phy));
2095fa5fd596SSuraj Kandpal 
2096fa5fd596SSuraj Kandpal 	/* 4. Clear for PHY pulse status on owned PHY lanes. */
2097fa5fd596SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port),
2098fa5fd596SSuraj Kandpal 		     lane_phy_pulse_status,
2099fa5fd596SSuraj Kandpal 		     lane_phy_pulse_status);
2100fa5fd596SSuraj Kandpal 
2101fa5fd596SSuraj Kandpal 	/*
2102fa5fd596SSuraj Kandpal 	 * 5. Follow the Display Voltage Frequency Switching -
2103fa5fd596SSuraj Kandpal 	 * Sequence Before Frequency Change. We handle this step in bxt_set_cdclk().
2104fa5fd596SSuraj Kandpal 	 */
2105fa5fd596SSuraj Kandpal 	/* 6. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 0. */
2106fa5fd596SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
2107fa5fd596SSuraj Kandpal 		     XELPDP_LANE_PCLK_PLL_REQUEST(0), 0);
2108fa5fd596SSuraj Kandpal 
2109fa5fd596SSuraj Kandpal 	/* 7. Program DDI_CLK_VALFREQ to 0. */
2110fa5fd596SSuraj Kandpal 	intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), 0);
2111fa5fd596SSuraj Kandpal 
2112fa5fd596SSuraj Kandpal 	/* 8. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 0. */
21130aed9d34SVille Syrjälä 	if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, port),
21140aed9d34SVille Syrjälä 				       XELPDP_LANE_PCLK_PLL_ACK(0),
21150aed9d34SVille Syrjälä 				       XE3PLPD_MACCLK_TURNOFF_LATENCY_US))
2116dfd58249SVille Syrjälä 		drm_warn(display->drm, "PHY %c PLL MacCLK ack deassertion timeout\n",
2117dfd58249SVille Syrjälä 			 phy_name(phy));
2118fa5fd596SSuraj Kandpal 
2119fa5fd596SSuraj Kandpal 	/*
2120fa5fd596SSuraj Kandpal 	 *  9. Follow the Display Voltage Frequency Switching -
2121fa5fd596SSuraj Kandpal 	 *  Sequence After Frequency Change. We handle this step in bxt_set_cdclk().
2122fa5fd596SSuraj Kandpal 	 */
2123fa5fd596SSuraj Kandpal 	/* 10. Program PORT_CLOCK_CTL register to disable and gate clocks. */
2124fa5fd596SSuraj Kandpal 	intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
2125fa5fd596SSuraj Kandpal 		     XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_FORWARD_CLOCK_UNGATE, 0);
2126fa5fd596SSuraj Kandpal 
2127fa5fd596SSuraj Kandpal 	/* 11. Program PORT_BUF_CTL5[MacCLK Reset_0] = 1 to assert MacCLK reset. */
2128fa5fd596SSuraj Kandpal 	intel_de_rmw(display, XE3PLPD_PORT_BUF_CTL5(port),
2129fa5fd596SSuraj Kandpal 		     XE3PLPD_MACCLK_RESET_0, XE3PLPD_MACCLK_RESET_0);
2130fa5fd596SSuraj Kandpal 
2131fa5fd596SSuraj Kandpal 	intel_lt_phy_transaction_end(encoder, wakeref);
2132fa5fd596SSuraj Kandpal }
213310928925SSuraj Kandpal 
213413ba213fSSuraj Kandpal void intel_lt_phy_set_signal_levels(struct intel_encoder *encoder,
213513ba213fSSuraj Kandpal 				    const struct intel_crtc_state *crtc_state)
213613ba213fSSuraj Kandpal {
213713ba213fSSuraj Kandpal 	struct intel_display *display = to_intel_display(encoder);
213813ba213fSSuraj Kandpal 	const struct intel_ddi_buf_trans *trans;
213913ba213fSSuraj Kandpal 	u8 owned_lane_mask;
214013ba213fSSuraj Kandpal 	intel_wakeref_t wakeref;
214113ba213fSSuraj Kandpal 	int n_entries, ln;
214213ba213fSSuraj Kandpal 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
214313ba213fSSuraj Kandpal 
214413ba213fSSuraj Kandpal 	if (intel_tc_port_in_tbt_alt_mode(dig_port))
214513ba213fSSuraj Kandpal 		return;
214613ba213fSSuraj Kandpal 
214713ba213fSSuraj Kandpal 	owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
214813ba213fSSuraj Kandpal 
214913ba213fSSuraj Kandpal 	wakeref = intel_lt_phy_transaction_begin(encoder);
215013ba213fSSuraj Kandpal 
215113ba213fSSuraj Kandpal 	trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
215213ba213fSSuraj Kandpal 	if (drm_WARN_ON_ONCE(display->drm, !trans)) {
215313ba213fSSuraj Kandpal 		intel_lt_phy_transaction_end(encoder, wakeref);
215413ba213fSSuraj Kandpal 		return;
215513ba213fSSuraj Kandpal 	}
215613ba213fSSuraj Kandpal 
215713ba213fSSuraj Kandpal 	for (ln = 0; ln < crtc_state->lane_count; ln++) {
215813ba213fSSuraj Kandpal 		int level = intel_ddi_level(encoder, crtc_state, ln);
215913ba213fSSuraj Kandpal 		int lane = ln / 2;
216013ba213fSSuraj Kandpal 		int tx = ln % 2;
216113ba213fSSuraj Kandpal 		u8 lane_mask = lane == 0 ? INTEL_LT_PHY_LANE0 : INTEL_LT_PHY_LANE1;
216213ba213fSSuraj Kandpal 
216313ba213fSSuraj Kandpal 		if (!(lane_mask & owned_lane_mask))
216413ba213fSSuraj Kandpal 			continue;
216513ba213fSSuraj Kandpal 
216613ba213fSSuraj Kandpal 		intel_lt_phy_rmw(encoder, lane_mask, LT_PHY_TXY_CTL8(tx),
216713ba213fSSuraj Kandpal 				 LT_PHY_TX_SWING_LEVEL_MASK | LT_PHY_TX_SWING_MASK,
216813ba213fSSuraj Kandpal 				 LT_PHY_TX_SWING_LEVEL(trans->entries[level].lt.txswing_level) |
216913ba213fSSuraj Kandpal 				 LT_PHY_TX_SWING(trans->entries[level].lt.txswing),
217013ba213fSSuraj Kandpal 				 MB_WRITE_COMMITTED);
217113ba213fSSuraj Kandpal 
217213ba213fSSuraj Kandpal 		intel_lt_phy_rmw(encoder, lane_mask, LT_PHY_TXY_CTL2(tx),
217313ba213fSSuraj Kandpal 				 LT_PHY_TX_CURSOR_MASK,
217413ba213fSSuraj Kandpal 				 LT_PHY_TX_CURSOR(trans->entries[level].lt.pre_cursor),
217513ba213fSSuraj Kandpal 				 MB_WRITE_COMMITTED);
217613ba213fSSuraj Kandpal 		intel_lt_phy_rmw(encoder, lane_mask, LT_PHY_TXY_CTL3(tx),
217713ba213fSSuraj Kandpal 				 LT_PHY_TX_CURSOR_MASK,
217813ba213fSSuraj Kandpal 				 LT_PHY_TX_CURSOR(trans->entries[level].lt.main_cursor),
217913ba213fSSuraj Kandpal 				 MB_WRITE_COMMITTED);
218013ba213fSSuraj Kandpal 		intel_lt_phy_rmw(encoder, lane_mask, LT_PHY_TXY_CTL4(tx),
218113ba213fSSuraj Kandpal 				 LT_PHY_TX_CURSOR_MASK,
218213ba213fSSuraj Kandpal 				 LT_PHY_TX_CURSOR(trans->entries[level].lt.post_cursor),
218313ba213fSSuraj Kandpal 				 MB_WRITE_COMMITTED);
218413ba213fSSuraj Kandpal 	}
218513ba213fSSuraj Kandpal 
218613ba213fSSuraj Kandpal 	intel_lt_phy_transaction_end(encoder, wakeref);
218713ba213fSSuraj Kandpal }
218813ba213fSSuraj Kandpal 
21893a6f155cSSuraj Kandpal void intel_lt_phy_dump_hw_state(struct intel_display *display,
21903a6f155cSSuraj Kandpal 				const struct intel_lt_phy_pll_state *hw_state)
21913a6f155cSSuraj Kandpal {
21923a6f155cSSuraj Kandpal 	int i, j;
21933a6f155cSSuraj Kandpal 
21943a6f155cSSuraj Kandpal 	drm_dbg_kms(display->drm, "lt_phy_pll_hw_state:\n");
21953a6f155cSSuraj Kandpal 	for (i = 0; i < 3; i++) {
21963a6f155cSSuraj Kandpal 		drm_dbg_kms(display->drm, "config[%d] = 0x%.4x,\n",
21973a6f155cSSuraj Kandpal 			    i, hw_state->config[i]);
21983a6f155cSSuraj Kandpal 	}
21993a6f155cSSuraj Kandpal 
22003a6f155cSSuraj Kandpal 	for (i = 0; i <= 12; i++)
22013a6f155cSSuraj Kandpal 		for (j = 3; j >= 0; j--)
22023a6f155cSSuraj Kandpal 			drm_dbg_kms(display->drm, "vdr_data[%d][%d] = 0x%.4x,\n",
22033a6f155cSSuraj Kandpal 				    i, j, hw_state->data[i][j]);
22043a6f155cSSuraj Kandpal }
22053a6f155cSSuraj Kandpal 
22063a6f155cSSuraj Kandpal bool
22073a6f155cSSuraj Kandpal intel_lt_phy_pll_compare_hw_state(const struct intel_lt_phy_pll_state *a,
22083a6f155cSSuraj Kandpal 				  const struct intel_lt_phy_pll_state *b)
22093a6f155cSSuraj Kandpal {
22103a6f155cSSuraj Kandpal 	if (memcmp(&a->config, &b->config, sizeof(a->config)) != 0)
22113a6f155cSSuraj Kandpal 		return false;
22123a6f155cSSuraj Kandpal 
22133a6f155cSSuraj Kandpal 	if (memcmp(&a->data, &b->data, sizeof(a->data)) != 0)
22143a6f155cSSuraj Kandpal 		return false;
22153a6f155cSSuraj Kandpal 
22163a6f155cSSuraj Kandpal 	return true;
22173a6f155cSSuraj Kandpal }
22183a6f155cSSuraj Kandpal 
221989e0a91eSSuraj Kandpal void intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder,
222089e0a91eSSuraj Kandpal 				       const struct intel_crtc_state *crtc_state,
222189e0a91eSSuraj Kandpal 				       struct intel_lt_phy_pll_state *pll_state)
222289e0a91eSSuraj Kandpal {
222389e0a91eSSuraj Kandpal 	u8 owned_lane_mask;
222489e0a91eSSuraj Kandpal 	u8 lane;
222589e0a91eSSuraj Kandpal 	intel_wakeref_t wakeref;
222689e0a91eSSuraj Kandpal 	int i, j, k;
222789e0a91eSSuraj Kandpal 
222889e0a91eSSuraj Kandpal 	pll_state->tbt_mode = intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder));
222989e0a91eSSuraj Kandpal 	if (pll_state->tbt_mode)
223089e0a91eSSuraj Kandpal 		return;
223189e0a91eSSuraj Kandpal 
223289e0a91eSSuraj Kandpal 	owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
223389e0a91eSSuraj Kandpal 	lane = owned_lane_mask & INTEL_LT_PHY_LANE0 ? : INTEL_LT_PHY_LANE1;
223489e0a91eSSuraj Kandpal 	wakeref = intel_lt_phy_transaction_begin(encoder);
223589e0a91eSSuraj Kandpal 
223689e0a91eSSuraj Kandpal 	pll_state->config[0] = intel_lt_phy_read(encoder, lane, LT_PHY_VDR_0_CONFIG);
223789e0a91eSSuraj Kandpal 	pll_state->config[1] = intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_1_CONFIG);
223889e0a91eSSuraj Kandpal 	pll_state->config[2] = intel_lt_phy_read(encoder, lane, LT_PHY_VDR_2_CONFIG);
223989e0a91eSSuraj Kandpal 
224089e0a91eSSuraj Kandpal 	for (i = 0; i <= 12; i++) {
224189e0a91eSSuraj Kandpal 		for (j = 3, k = 0; j >= 0; j--, k++)
224289e0a91eSSuraj Kandpal 			pll_state->data[i][k] =
224389e0a91eSSuraj Kandpal 				intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0,
224489e0a91eSSuraj Kandpal 						  LT_PHY_VDR_X_DATAY(i, j));
224589e0a91eSSuraj Kandpal 	}
224689e0a91eSSuraj Kandpal 
224789e0a91eSSuraj Kandpal 	pll_state->clock =
224889e0a91eSSuraj Kandpal 		intel_lt_phy_calc_port_clock(encoder, crtc_state);
224989e0a91eSSuraj Kandpal 	intel_lt_phy_transaction_end(encoder, wakeref);
225089e0a91eSSuraj Kandpal }
225189e0a91eSSuraj Kandpal 
22529dcf1836SSuraj Kandpal void intel_lt_phy_pll_state_verify(struct intel_atomic_state *state,
22539dcf1836SSuraj Kandpal 				   struct intel_crtc *crtc)
22549dcf1836SSuraj Kandpal {
22559dcf1836SSuraj Kandpal 	struct intel_display *display = to_intel_display(state);
22569dcf1836SSuraj Kandpal 	struct intel_digital_port *dig_port;
22579dcf1836SSuraj Kandpal 	const struct intel_crtc_state *new_crtc_state =
22589dcf1836SSuraj Kandpal 		intel_atomic_get_new_crtc_state(state, crtc);
22599dcf1836SSuraj Kandpal 	struct intel_encoder *encoder;
22609dcf1836SSuraj Kandpal 	struct intel_lt_phy_pll_state pll_hw_state = {};
22619dcf1836SSuraj Kandpal 	const struct intel_lt_phy_pll_state *pll_sw_state = &new_crtc_state->dpll_hw_state.ltpll;
22629dcf1836SSuraj Kandpal 	int clock;
22639dcf1836SSuraj Kandpal 	int i, j;
22649dcf1836SSuraj Kandpal 
22659dcf1836SSuraj Kandpal 	if (DISPLAY_VER(display) < 35)
22669dcf1836SSuraj Kandpal 		return;
22679dcf1836SSuraj Kandpal 
22689dcf1836SSuraj Kandpal 	if (!new_crtc_state->hw.active)
22699dcf1836SSuraj Kandpal 		return;
22709dcf1836SSuraj Kandpal 
22719dcf1836SSuraj Kandpal 	/* intel_get_crtc_new_encoder() only works for modeset/fastset commits */
22729dcf1836SSuraj Kandpal 	if (!intel_crtc_needs_modeset(new_crtc_state) &&
22739dcf1836SSuraj Kandpal 	    !intel_crtc_needs_fastset(new_crtc_state))
22749dcf1836SSuraj Kandpal 		return;
22759dcf1836SSuraj Kandpal 
22769dcf1836SSuraj Kandpal 	encoder = intel_get_crtc_new_encoder(state, new_crtc_state);
22779dcf1836SSuraj Kandpal 	intel_lt_phy_pll_readout_hw_state(encoder, new_crtc_state, &pll_hw_state);
22789dcf1836SSuraj Kandpal 	clock = intel_lt_phy_calc_port_clock(encoder, new_crtc_state);
22799dcf1836SSuraj Kandpal 
22809dcf1836SSuraj Kandpal 	dig_port = enc_to_dig_port(encoder);
22819dcf1836SSuraj Kandpal 	if (intel_tc_port_in_tbt_alt_mode(dig_port))
22829dcf1836SSuraj Kandpal 		return;
22839dcf1836SSuraj Kandpal 
22849dcf1836SSuraj Kandpal 	INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.clock != clock,
22859dcf1836SSuraj Kandpal 				 "[CRTC:%d:%s] mismatch in LT PHY: Register CLOCK (expected %d, found %d)",
22869dcf1836SSuraj Kandpal 				 crtc->base.base.id, crtc->base.name,
22879dcf1836SSuraj Kandpal 				 pll_sw_state->clock, pll_hw_state.clock);
22889dcf1836SSuraj Kandpal 
22899dcf1836SSuraj Kandpal 	for (i = 0; i < 3; i++) {
22909dcf1836SSuraj Kandpal 		INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.config[i] != pll_sw_state->config[i],
22919dcf1836SSuraj Kandpal 					 "[CRTC:%d:%s] mismatch in LT PHY PLL CONFIG%d: (expected 0x%04x, found 0x%04x)",
22929dcf1836SSuraj Kandpal 					 crtc->base.base.id, crtc->base.name, i,
22939dcf1836SSuraj Kandpal 					 pll_sw_state->config[i], pll_hw_state.config[i]);
22949dcf1836SSuraj Kandpal 	}
22959dcf1836SSuraj Kandpal 
22969dcf1836SSuraj Kandpal 	for (i = 0; i <= 12; i++) {
22979dcf1836SSuraj Kandpal 		for (j = 3; j >= 0; j--)
22989dcf1836SSuraj Kandpal 			INTEL_DISPLAY_STATE_WARN(display,
22999dcf1836SSuraj Kandpal 						 pll_hw_state.data[i][j] !=
23009dcf1836SSuraj Kandpal 						 pll_sw_state->data[i][j],
23019dcf1836SSuraj Kandpal 						 "[CRTC:%d:%s] mismatch in LT PHY PLL DATA[%d][%d]: (expected 0x%04x, found 0x%04x)",
23029dcf1836SSuraj Kandpal 						 crtc->base.base.id, crtc->base.name, i, j,
23039dcf1836SSuraj Kandpal 						 pll_sw_state->data[i][j], pll_hw_state.data[i][j]);
23049dcf1836SSuraj Kandpal 	}
23059dcf1836SSuraj Kandpal }
23069dcf1836SSuraj Kandpal 
230710928925SSuraj Kandpal void intel_xe3plpd_pll_enable(struct intel_encoder *encoder,
230810928925SSuraj Kandpal 			      const struct intel_crtc_state *crtc_state)
230910928925SSuraj Kandpal {
231010928925SSuraj Kandpal 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
231110928925SSuraj Kandpal 
231210928925SSuraj Kandpal 	if (intel_tc_port_in_tbt_alt_mode(dig_port))
231310928925SSuraj Kandpal 		intel_mtl_tbt_pll_enable(encoder, crtc_state);
231410928925SSuraj Kandpal 	else
231510928925SSuraj Kandpal 		intel_lt_phy_pll_enable(encoder, crtc_state);
231610928925SSuraj Kandpal }
231710928925SSuraj Kandpal 
231810928925SSuraj Kandpal void intel_xe3plpd_pll_disable(struct intel_encoder *encoder)
231910928925SSuraj Kandpal {
232010928925SSuraj Kandpal 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
232110928925SSuraj Kandpal 
232210928925SSuraj Kandpal 	if (intel_tc_port_in_tbt_alt_mode(dig_port))
232310928925SSuraj Kandpal 		intel_mtl_tbt_pll_disable(encoder);
232410928925SSuraj Kandpal 	else
232510928925SSuraj Kandpal 		intel_lt_phy_pll_disable(encoder);
23269dcf1836SSuraj Kandpal 
232710928925SSuraj Kandpal }
2328