1df0566a6SJani Nikula /*
2df0566a6SJani Nikula * Copyright © 2014-2016 Intel Corporation
3df0566a6SJani Nikula *
4df0566a6SJani Nikula * Permission is hereby granted, free of charge, to any person obtaining a
5df0566a6SJani Nikula * copy of this software and associated documentation files (the "Software"),
6df0566a6SJani Nikula * to deal in the Software without restriction, including without limitation
7df0566a6SJani Nikula * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8df0566a6SJani Nikula * and/or sell copies of the Software, and to permit persons to whom the
9df0566a6SJani Nikula * Software is furnished to do so, subject to the following conditions:
10df0566a6SJani Nikula *
11df0566a6SJani Nikula * The above copyright notice and this permission notice (including the next
12df0566a6SJani Nikula * paragraph) shall be included in all copies or substantial portions of the
13df0566a6SJani Nikula * Software.
14df0566a6SJani Nikula *
15df0566a6SJani Nikula * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16df0566a6SJani Nikula * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17df0566a6SJani Nikula * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18df0566a6SJani Nikula * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19df0566a6SJani Nikula * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20df0566a6SJani Nikula * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21df0566a6SJani Nikula * DEALINGS IN THE SOFTWARE.
22df0566a6SJani Nikula */
23df0566a6SJani Nikula
24801543b2SJani Nikula #include "i915_reg.h"
255f5ada0bSVille Syrjälä #include "intel_ddi.h"
265f5ada0bSVille Syrjälä #include "intel_ddi_buf_trans.h"
277785ae0bSVille Syrjälä #include "intel_de.h"
282cef3595SImre Deak #include "intel_display_power_well.h"
291d455f8dSJani Nikula #include "intel_display_types.h"
301eecf31eSJani Nikula #include "intel_dp.h"
31df0566a6SJani Nikula #include "intel_dpio_phy.h"
321eecf31eSJani Nikula #include "vlv_sideband.h"
33df0566a6SJani Nikula
34df0566a6SJani Nikula /**
35df0566a6SJani Nikula * DOC: DPIO
36df0566a6SJani Nikula *
37df0566a6SJani Nikula * VLV, CHV and BXT have slightly peculiar display PHYs for driving DP/HDMI
38df0566a6SJani Nikula * ports. DPIO is the name given to such a display PHY. These PHYs
39df0566a6SJani Nikula * don't follow the standard programming model using direct MMIO
40df0566a6SJani Nikula * registers, and instead their registers must be accessed trough IOSF
41df0566a6SJani Nikula * sideband. VLV has one such PHY for driving ports B and C, and CHV
42df0566a6SJani Nikula * adds another PHY for driving port D. Each PHY responds to specific
43df0566a6SJani Nikula * IOSF-SB port.
44df0566a6SJani Nikula *
45df0566a6SJani Nikula * Each display PHY is made up of one or two channels. Each channel
46df0566a6SJani Nikula * houses a common lane part which contains the PLL and other common
47df0566a6SJani Nikula * logic. CH0 common lane also contains the IOSF-SB logic for the
48df0566a6SJani Nikula * Common Register Interface (CRI) ie. the DPIO registers. CRI clock
49df0566a6SJani Nikula * must be running when any DPIO registers are accessed.
50df0566a6SJani Nikula *
51df0566a6SJani Nikula * In addition to having their own registers, the PHYs are also
52df0566a6SJani Nikula * controlled through some dedicated signals from the display
53df0566a6SJani Nikula * controller. These include PLL reference clock enable, PLL enable,
54df0566a6SJani Nikula * and CRI clock selection, for example.
55df0566a6SJani Nikula *
56df0566a6SJani Nikula * Eeach channel also has two splines (also called data lanes), and
57df0566a6SJani Nikula * each spline is made up of one Physical Access Coding Sub-Layer
58df0566a6SJani Nikula * (PCS) block and two TX lanes. So each channel has two PCS blocks
59df0566a6SJani Nikula * and four TX lanes. The TX lanes are used as DP lanes or TMDS
60df0566a6SJani Nikula * data/clock pairs depending on the output type.
61df0566a6SJani Nikula *
62df0566a6SJani Nikula * Additionally the PHY also contains an AUX lane with AUX blocks
63df0566a6SJani Nikula * for each channel. This is used for DP AUX communication, but
64df0566a6SJani Nikula * this fact isn't really relevant for the driver since AUX is
65df0566a6SJani Nikula * controlled from the display controller side. No DPIO registers
66df0566a6SJani Nikula * need to be accessed during AUX communication,
67df0566a6SJani Nikula *
68df0566a6SJani Nikula * Generally on VLV/CHV the common lane corresponds to the pipe and
69df0566a6SJani Nikula * the spline (PCS/TX) corresponds to the port.
70df0566a6SJani Nikula *
71df0566a6SJani Nikula * For dual channel PHY (VLV/CHV):
72df0566a6SJani Nikula *
73df0566a6SJani Nikula * pipe A == CMN/PLL/REF CH0
74df0566a6SJani Nikula *
75df0566a6SJani Nikula * pipe B == CMN/PLL/REF CH1
76df0566a6SJani Nikula *
77df0566a6SJani Nikula * port B == PCS/TX CH0
78df0566a6SJani Nikula *
79df0566a6SJani Nikula * port C == PCS/TX CH1
80df0566a6SJani Nikula *
81df0566a6SJani Nikula * This is especially important when we cross the streams
82df0566a6SJani Nikula * ie. drive port B with pipe B, or port C with pipe A.
83df0566a6SJani Nikula *
84df0566a6SJani Nikula * For single channel PHY (CHV):
85df0566a6SJani Nikula *
86df0566a6SJani Nikula * pipe C == CMN/PLL/REF CH0
87df0566a6SJani Nikula *
88df0566a6SJani Nikula * port D == PCS/TX CH0
89df0566a6SJani Nikula *
90df0566a6SJani Nikula * On BXT the entire PHY channel corresponds to the port. That means
91df0566a6SJani Nikula * the PLL is also now associated with the port rather than the pipe,
92df0566a6SJani Nikula * and so the clock needs to be routed to the appropriate transcoder.
93df0566a6SJani Nikula * Port A PLL is directly connected to transcoder EDP and port B/C
94df0566a6SJani Nikula * PLLs can be routed to any transcoder A/B/C.
95df0566a6SJani Nikula *
96df0566a6SJani Nikula * Note: DDI0 is digital port B, DD1 is digital port C, and DDI2 is
97df0566a6SJani Nikula * digital port D (CHV) or port A (BXT). ::
98df0566a6SJani Nikula *
99df0566a6SJani Nikula *
100df0566a6SJani Nikula * Dual channel PHY (VLV/CHV/BXT)
101df0566a6SJani Nikula * ---------------------------------
102df0566a6SJani Nikula * | CH0 | CH1 |
103df0566a6SJani Nikula * | CMN/PLL/REF | CMN/PLL/REF |
104df0566a6SJani Nikula * |---------------|---------------| Display PHY
105df0566a6SJani Nikula * | PCS01 | PCS23 | PCS01 | PCS23 |
106df0566a6SJani Nikula * |-------|-------|-------|-------|
107df0566a6SJani Nikula * |TX0|TX1|TX2|TX3|TX0|TX1|TX2|TX3|
108df0566a6SJani Nikula * ---------------------------------
109df0566a6SJani Nikula * | DDI0 | DDI1 | DP/HDMI ports
110df0566a6SJani Nikula * ---------------------------------
111df0566a6SJani Nikula *
112df0566a6SJani Nikula * Single channel PHY (CHV/BXT)
113df0566a6SJani Nikula * -----------------
114df0566a6SJani Nikula * | CH0 |
115df0566a6SJani Nikula * | CMN/PLL/REF |
116df0566a6SJani Nikula * |---------------| Display PHY
117df0566a6SJani Nikula * | PCS01 | PCS23 |
118df0566a6SJani Nikula * |-------|-------|
119df0566a6SJani Nikula * |TX0|TX1|TX2|TX3|
120df0566a6SJani Nikula * -----------------
121df0566a6SJani Nikula * | DDI2 | DP/HDMI port
122df0566a6SJani Nikula * -----------------
123df0566a6SJani Nikula */
124df0566a6SJani Nikula
125df0566a6SJani Nikula /**
126df0566a6SJani Nikula * struct bxt_ddi_phy_info - Hold info for a broxton DDI phy
127df0566a6SJani Nikula */
128df0566a6SJani Nikula struct bxt_ddi_phy_info {
129df0566a6SJani Nikula /**
130df0566a6SJani Nikula * @dual_channel: true if this phy has a second channel.
131df0566a6SJani Nikula */
132df0566a6SJani Nikula bool dual_channel;
133df0566a6SJani Nikula
134df0566a6SJani Nikula /**
135df0566a6SJani Nikula * @rcomp_phy: If -1, indicates this phy has its own rcomp resistor.
136df0566a6SJani Nikula * Otherwise the GRC value will be copied from the phy indicated by
137df0566a6SJani Nikula * this field.
138df0566a6SJani Nikula */
139df0566a6SJani Nikula enum dpio_phy rcomp_phy;
140df0566a6SJani Nikula
141df0566a6SJani Nikula /**
142df0566a6SJani Nikula * @reset_delay: delay in us to wait before setting the common reset
143df0566a6SJani Nikula * bit in BXT_PHY_CTL_FAMILY, which effectively enables the phy.
144df0566a6SJani Nikula */
145df0566a6SJani Nikula int reset_delay;
146df0566a6SJani Nikula
147df0566a6SJani Nikula /**
148df0566a6SJani Nikula * @pwron_mask: Mask with the appropriate bit set that would cause the
149df0566a6SJani Nikula * punit to power this phy if written to BXT_P_CR_GT_DISP_PWRON.
150df0566a6SJani Nikula */
151df0566a6SJani Nikula u32 pwron_mask;
152df0566a6SJani Nikula
153df0566a6SJani Nikula /**
154df0566a6SJani Nikula * @channel: struct containing per channel information.
155df0566a6SJani Nikula */
156df0566a6SJani Nikula struct {
157df0566a6SJani Nikula /**
158df0566a6SJani Nikula * @channel.port: which port maps to this channel.
159df0566a6SJani Nikula */
160df0566a6SJani Nikula enum port port;
161df0566a6SJani Nikula } channel[2];
162df0566a6SJani Nikula };
163df0566a6SJani Nikula
164df0566a6SJani Nikula static const struct bxt_ddi_phy_info bxt_ddi_phy_info[] = {
165df0566a6SJani Nikula [DPIO_PHY0] = {
166df0566a6SJani Nikula .dual_channel = true,
167df0566a6SJani Nikula .rcomp_phy = DPIO_PHY1,
168df0566a6SJani Nikula .pwron_mask = BIT(0),
169df0566a6SJani Nikula
170df0566a6SJani Nikula .channel = {
171df0566a6SJani Nikula [DPIO_CH0] = { .port = PORT_B },
172df0566a6SJani Nikula [DPIO_CH1] = { .port = PORT_C },
173df0566a6SJani Nikula }
174df0566a6SJani Nikula },
175df0566a6SJani Nikula [DPIO_PHY1] = {
176df0566a6SJani Nikula .dual_channel = false,
177df0566a6SJani Nikula .rcomp_phy = -1,
178df0566a6SJani Nikula .pwron_mask = BIT(1),
179df0566a6SJani Nikula
180df0566a6SJani Nikula .channel = {
181df0566a6SJani Nikula [DPIO_CH0] = { .port = PORT_A },
182df0566a6SJani Nikula }
183df0566a6SJani Nikula },
184df0566a6SJani Nikula };
185df0566a6SJani Nikula
186df0566a6SJani Nikula static const struct bxt_ddi_phy_info glk_ddi_phy_info[] = {
187df0566a6SJani Nikula [DPIO_PHY0] = {
188df0566a6SJani Nikula .dual_channel = false,
189df0566a6SJani Nikula .rcomp_phy = DPIO_PHY1,
190df0566a6SJani Nikula .pwron_mask = BIT(0),
191df0566a6SJani Nikula .reset_delay = 20,
192df0566a6SJani Nikula
193df0566a6SJani Nikula .channel = {
194df0566a6SJani Nikula [DPIO_CH0] = { .port = PORT_B },
195df0566a6SJani Nikula }
196df0566a6SJani Nikula },
197df0566a6SJani Nikula [DPIO_PHY1] = {
198df0566a6SJani Nikula .dual_channel = false,
199df0566a6SJani Nikula .rcomp_phy = -1,
200df0566a6SJani Nikula .pwron_mask = BIT(3),
201df0566a6SJani Nikula .reset_delay = 20,
202df0566a6SJani Nikula
203df0566a6SJani Nikula .channel = {
204df0566a6SJani Nikula [DPIO_CH0] = { .port = PORT_A },
205df0566a6SJani Nikula }
206df0566a6SJani Nikula },
207df0566a6SJani Nikula [DPIO_PHY2] = {
208df0566a6SJani Nikula .dual_channel = false,
209df0566a6SJani Nikula .rcomp_phy = DPIO_PHY1,
210df0566a6SJani Nikula .pwron_mask = BIT(1),
211df0566a6SJani Nikula .reset_delay = 20,
212df0566a6SJani Nikula
213df0566a6SJani Nikula .channel = {
214df0566a6SJani Nikula [DPIO_CH0] = { .port = PORT_C },
215df0566a6SJani Nikula }
216df0566a6SJani Nikula },
217df0566a6SJani Nikula };
218df0566a6SJani Nikula
219df0566a6SJani Nikula static const struct bxt_ddi_phy_info *
bxt_get_phy_list(struct drm_i915_private * dev_priv,int * count)220df0566a6SJani Nikula bxt_get_phy_list(struct drm_i915_private *dev_priv, int *count)
221df0566a6SJani Nikula {
222df0566a6SJani Nikula if (IS_GEMINILAKE(dev_priv)) {
223df0566a6SJani Nikula *count = ARRAY_SIZE(glk_ddi_phy_info);
224df0566a6SJani Nikula return glk_ddi_phy_info;
225df0566a6SJani Nikula } else {
226df0566a6SJani Nikula *count = ARRAY_SIZE(bxt_ddi_phy_info);
227df0566a6SJani Nikula return bxt_ddi_phy_info;
228df0566a6SJani Nikula }
229df0566a6SJani Nikula }
230df0566a6SJani Nikula
231df0566a6SJani Nikula static const struct bxt_ddi_phy_info *
bxt_get_phy_info(struct drm_i915_private * dev_priv,enum dpio_phy phy)232df0566a6SJani Nikula bxt_get_phy_info(struct drm_i915_private *dev_priv, enum dpio_phy phy)
233df0566a6SJani Nikula {
234df0566a6SJani Nikula int count;
235df0566a6SJani Nikula const struct bxt_ddi_phy_info *phy_list =
236df0566a6SJani Nikula bxt_get_phy_list(dev_priv, &count);
237df0566a6SJani Nikula
238df0566a6SJani Nikula return &phy_list[phy];
239df0566a6SJani Nikula }
240df0566a6SJani Nikula
bxt_port_to_phy_channel(struct drm_i915_private * dev_priv,enum port port,enum dpio_phy * phy,enum dpio_channel * ch)241df0566a6SJani Nikula void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
242df0566a6SJani Nikula enum dpio_phy *phy, enum dpio_channel *ch)
243df0566a6SJani Nikula {
244df0566a6SJani Nikula const struct bxt_ddi_phy_info *phy_info, *phys;
245df0566a6SJani Nikula int i, count;
246df0566a6SJani Nikula
247df0566a6SJani Nikula phys = bxt_get_phy_list(dev_priv, &count);
248df0566a6SJani Nikula
249df0566a6SJani Nikula for (i = 0; i < count; i++) {
250df0566a6SJani Nikula phy_info = &phys[i];
251df0566a6SJani Nikula
252df0566a6SJani Nikula if (port == phy_info->channel[DPIO_CH0].port) {
253df0566a6SJani Nikula *phy = i;
254df0566a6SJani Nikula *ch = DPIO_CH0;
255df0566a6SJani Nikula return;
256df0566a6SJani Nikula }
257df0566a6SJani Nikula
258df0566a6SJani Nikula if (phy_info->dual_channel &&
259df0566a6SJani Nikula port == phy_info->channel[DPIO_CH1].port) {
260df0566a6SJani Nikula *phy = i;
261df0566a6SJani Nikula *ch = DPIO_CH1;
262df0566a6SJani Nikula return;
263df0566a6SJani Nikula }
264df0566a6SJani Nikula }
265df0566a6SJani Nikula
266f4224a4cSPankaj Bharadiya drm_WARN(&dev_priv->drm, 1, "PHY not found for PORT %c",
267f4224a4cSPankaj Bharadiya port_name(port));
268df0566a6SJani Nikula *phy = DPIO_PHY0;
269df0566a6SJani Nikula *ch = DPIO_CH0;
270df0566a6SJani Nikula }
271df0566a6SJani Nikula
bxt_ddi_phy_set_signal_levels(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)2725f5ada0bSVille Syrjälä void bxt_ddi_phy_set_signal_levels(struct intel_encoder *encoder,
2735f5ada0bSVille Syrjälä const struct intel_crtc_state *crtc_state)
274df0566a6SJani Nikula {
2755f5ada0bSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
276d0920a45SVille Syrjälä int level = intel_ddi_level(encoder, crtc_state, 0);
2775f5ada0bSVille Syrjälä const struct intel_ddi_buf_trans *trans;
278df0566a6SJani Nikula enum dpio_channel ch;
2795f5ada0bSVille Syrjälä enum dpio_phy phy;
2805f5ada0bSVille Syrjälä int n_entries;
2815f5ada0bSVille Syrjälä u32 val;
282df0566a6SJani Nikula
2835f5ada0bSVille Syrjälä trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
2845f5ada0bSVille Syrjälä if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))
2855f5ada0bSVille Syrjälä return;
2865f5ada0bSVille Syrjälä
2875f5ada0bSVille Syrjälä bxt_port_to_phy_channel(dev_priv, encoder->port, &phy, &ch);
288df0566a6SJani Nikula
289df0566a6SJani Nikula /*
290df0566a6SJani Nikula * While we write to the group register to program all lanes at once we
291df0566a6SJani Nikula * can read only lane registers and we pick lanes 0/1 for that.
292df0566a6SJani Nikula */
293ee8845a2SJani Nikula val = intel_de_read(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch));
294df0566a6SJani Nikula val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
295ee8845a2SJani Nikula intel_de_write(dev_priv, BXT_PORT_PCS_DW10_GRP(phy, ch), val);
296df0566a6SJani Nikula
297ee8845a2SJani Nikula val = intel_de_read(dev_priv, BXT_PORT_TX_DW2_LN0(phy, ch));
298df0566a6SJani Nikula val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2995f5ada0bSVille Syrjälä val |= trans->entries[level].bxt.margin << MARGIN_000_SHIFT |
3005f5ada0bSVille Syrjälä trans->entries[level].bxt.scale << UNIQ_TRANS_SCALE_SHIFT;
301ee8845a2SJani Nikula intel_de_write(dev_priv, BXT_PORT_TX_DW2_GRP(phy, ch), val);
302df0566a6SJani Nikula
303ee8845a2SJani Nikula val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN0(phy, ch));
304df0566a6SJani Nikula val &= ~SCALE_DCOMP_METHOD;
3055f5ada0bSVille Syrjälä if (trans->entries[level].bxt.enable)
306df0566a6SJani Nikula val |= SCALE_DCOMP_METHOD;
307df0566a6SJani Nikula
308df0566a6SJani Nikula if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
3092fbfc595SWambui Karuga drm_err(&dev_priv->drm,
3102fbfc595SWambui Karuga "Disabled scaling while ouniqetrangenmethod was set");
311df0566a6SJani Nikula
312ee8845a2SJani Nikula intel_de_write(dev_priv, BXT_PORT_TX_DW3_GRP(phy, ch), val);
313df0566a6SJani Nikula
314ee8845a2SJani Nikula val = intel_de_read(dev_priv, BXT_PORT_TX_DW4_LN0(phy, ch));
315df0566a6SJani Nikula val &= ~DE_EMPHASIS;
3165f5ada0bSVille Syrjälä val |= trans->entries[level].bxt.deemphasis << DEEMPH_SHIFT;
317ee8845a2SJani Nikula intel_de_write(dev_priv, BXT_PORT_TX_DW4_GRP(phy, ch), val);
318df0566a6SJani Nikula
319ee8845a2SJani Nikula val = intel_de_read(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch));
320df0566a6SJani Nikula val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
321ee8845a2SJani Nikula intel_de_write(dev_priv, BXT_PORT_PCS_DW10_GRP(phy, ch), val);
322df0566a6SJani Nikula }
323df0566a6SJani Nikula
bxt_ddi_phy_is_enabled(struct drm_i915_private * dev_priv,enum dpio_phy phy)324df0566a6SJani Nikula bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv,
325df0566a6SJani Nikula enum dpio_phy phy)
326df0566a6SJani Nikula {
327df0566a6SJani Nikula const struct bxt_ddi_phy_info *phy_info;
328df0566a6SJani Nikula
329df0566a6SJani Nikula phy_info = bxt_get_phy_info(dev_priv, phy);
330df0566a6SJani Nikula
331ee8845a2SJani Nikula if (!(intel_de_read(dev_priv, BXT_P_CR_GT_DISP_PWRON) & phy_info->pwron_mask))
332df0566a6SJani Nikula return false;
333df0566a6SJani Nikula
334ee8845a2SJani Nikula if ((intel_de_read(dev_priv, BXT_PORT_CL1CM_DW0(phy)) &
335df0566a6SJani Nikula (PHY_POWER_GOOD | PHY_RESERVED)) != PHY_POWER_GOOD) {
3362fbfc595SWambui Karuga drm_dbg(&dev_priv->drm,
3372fbfc595SWambui Karuga "DDI PHY %d powered, but power hasn't settled\n", phy);
338df0566a6SJani Nikula
339df0566a6SJani Nikula return false;
340df0566a6SJani Nikula }
341df0566a6SJani Nikula
342ee8845a2SJani Nikula if (!(intel_de_read(dev_priv, BXT_PHY_CTL_FAMILY(phy)) & COMMON_RESET_DIS)) {
3432fbfc595SWambui Karuga drm_dbg(&dev_priv->drm,
3442fbfc595SWambui Karuga "DDI PHY %d powered, but still in reset\n", phy);
345df0566a6SJani Nikula
346df0566a6SJani Nikula return false;
347df0566a6SJani Nikula }
348df0566a6SJani Nikula
349df0566a6SJani Nikula return true;
350df0566a6SJani Nikula }
351df0566a6SJani Nikula
bxt_get_grc(struct drm_i915_private * dev_priv,enum dpio_phy phy)352df0566a6SJani Nikula static u32 bxt_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy)
353df0566a6SJani Nikula {
354ee8845a2SJani Nikula u32 val = intel_de_read(dev_priv, BXT_PORT_REF_DW6(phy));
355df0566a6SJani Nikula
356df0566a6SJani Nikula return (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
357df0566a6SJani Nikula }
358df0566a6SJani Nikula
bxt_phy_wait_grc_done(struct drm_i915_private * dev_priv,enum dpio_phy phy)359df0566a6SJani Nikula static void bxt_phy_wait_grc_done(struct drm_i915_private *dev_priv,
360df0566a6SJani Nikula enum dpio_phy phy)
361df0566a6SJani Nikula {
3624cb3b44dSDaniele Ceraolo Spurio if (intel_de_wait_for_set(dev_priv, BXT_PORT_REF_DW3(phy),
3634cb3b44dSDaniele Ceraolo Spurio GRC_DONE, 10))
3642fbfc595SWambui Karuga drm_err(&dev_priv->drm, "timeout waiting for PHY%d GRC\n",
3652fbfc595SWambui Karuga phy);
366df0566a6SJani Nikula }
367df0566a6SJani Nikula
_bxt_ddi_phy_init(struct drm_i915_private * dev_priv,enum dpio_phy phy)368df0566a6SJani Nikula static void _bxt_ddi_phy_init(struct drm_i915_private *dev_priv,
369df0566a6SJani Nikula enum dpio_phy phy)
370df0566a6SJani Nikula {
371df0566a6SJani Nikula const struct bxt_ddi_phy_info *phy_info;
372df0566a6SJani Nikula u32 val;
373df0566a6SJani Nikula
374df0566a6SJani Nikula phy_info = bxt_get_phy_info(dev_priv, phy);
375df0566a6SJani Nikula
376df0566a6SJani Nikula if (bxt_ddi_phy_is_enabled(dev_priv, phy)) {
377df0566a6SJani Nikula /* Still read out the GRC value for state verification */
378df0566a6SJani Nikula if (phy_info->rcomp_phy != -1)
379e2855f8eSJani Nikula dev_priv->display.state.bxt_phy_grc = bxt_get_grc(dev_priv, phy);
380df0566a6SJani Nikula
381df0566a6SJani Nikula if (bxt_ddi_phy_verify_state(dev_priv, phy)) {
3822fbfc595SWambui Karuga drm_dbg(&dev_priv->drm, "DDI PHY %d already enabled, "
383df0566a6SJani Nikula "won't reprogram it\n", phy);
384df0566a6SJani Nikula return;
385df0566a6SJani Nikula }
386df0566a6SJani Nikula
3872fbfc595SWambui Karuga drm_dbg(&dev_priv->drm,
3882fbfc595SWambui Karuga "DDI PHY %d enabled with invalid state, "
389df0566a6SJani Nikula "force reprogramming it\n", phy);
390df0566a6SJani Nikula }
391df0566a6SJani Nikula
392*bdfee324SAndrzej Hajda intel_de_rmw(dev_priv, BXT_P_CR_GT_DISP_PWRON, 0, phy_info->pwron_mask);
393df0566a6SJani Nikula
394df0566a6SJani Nikula /*
395df0566a6SJani Nikula * The PHY registers start out inaccessible and respond to reads with
396df0566a6SJani Nikula * all 1s. Eventually they become accessible as they power up, then
397df0566a6SJani Nikula * the reserved bit will give the default 0. Poll on the reserved bit
398df0566a6SJani Nikula * becoming 0 to find when the PHY is accessible.
399df0566a6SJani Nikula * The flag should get set in 100us according to the HW team, but
400df0566a6SJani Nikula * use 1ms due to occasional timeouts observed with that.
401df0566a6SJani Nikula */
402df0566a6SJani Nikula if (intel_wait_for_register_fw(&dev_priv->uncore,
403df0566a6SJani Nikula BXT_PORT_CL1CM_DW0(phy),
404df0566a6SJani Nikula PHY_RESERVED | PHY_POWER_GOOD,
405df0566a6SJani Nikula PHY_POWER_GOOD,
406df0566a6SJani Nikula 1))
4072fbfc595SWambui Karuga drm_err(&dev_priv->drm, "timeout during PHY%d power on\n",
4082fbfc595SWambui Karuga phy);
409df0566a6SJani Nikula
410df0566a6SJani Nikula /* Program PLL Rcomp code offset */
411*bdfee324SAndrzej Hajda intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW9(phy), IREF0RC_OFFSET_MASK,
412*bdfee324SAndrzej Hajda 0xE4 << IREF0RC_OFFSET_SHIFT);
413df0566a6SJani Nikula
414*bdfee324SAndrzej Hajda intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW10(phy), IREF1RC_OFFSET_MASK,
415*bdfee324SAndrzej Hajda 0xE4 << IREF1RC_OFFSET_SHIFT);
416df0566a6SJani Nikula
417df0566a6SJani Nikula /* Program power gating */
418*bdfee324SAndrzej Hajda intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW28(phy), 0,
419*bdfee324SAndrzej Hajda OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | SUS_CLK_CONFIG);
420df0566a6SJani Nikula
421*bdfee324SAndrzej Hajda if (phy_info->dual_channel)
422*bdfee324SAndrzej Hajda intel_de_rmw(dev_priv, BXT_PORT_CL2CM_DW6(phy), 0,
423*bdfee324SAndrzej Hajda DW6_OLDO_DYN_PWR_DOWN_EN);
424df0566a6SJani Nikula
425df0566a6SJani Nikula if (phy_info->rcomp_phy != -1) {
426df0566a6SJani Nikula u32 grc_code;
427df0566a6SJani Nikula
428df0566a6SJani Nikula bxt_phy_wait_grc_done(dev_priv, phy_info->rcomp_phy);
429df0566a6SJani Nikula
430df0566a6SJani Nikula /*
431df0566a6SJani Nikula * PHY0 isn't connected to an RCOMP resistor so copy over
432df0566a6SJani Nikula * the corresponding calibrated value from PHY1, and disable
433df0566a6SJani Nikula * the automatic calibration on PHY0.
434df0566a6SJani Nikula */
435e2855f8eSJani Nikula val = bxt_get_grc(dev_priv, phy_info->rcomp_phy);
436e2855f8eSJani Nikula dev_priv->display.state.bxt_phy_grc = val;
437e2855f8eSJani Nikula
438df0566a6SJani Nikula grc_code = val << GRC_CODE_FAST_SHIFT |
439df0566a6SJani Nikula val << GRC_CODE_SLOW_SHIFT |
440df0566a6SJani Nikula val;
441ee8845a2SJani Nikula intel_de_write(dev_priv, BXT_PORT_REF_DW6(phy), grc_code);
442*bdfee324SAndrzej Hajda intel_de_rmw(dev_priv, BXT_PORT_REF_DW8(phy),
443*bdfee324SAndrzej Hajda 0, GRC_DIS | GRC_RDY_OVRD);
444df0566a6SJani Nikula }
445df0566a6SJani Nikula
446df0566a6SJani Nikula if (phy_info->reset_delay)
447df0566a6SJani Nikula udelay(phy_info->reset_delay);
448df0566a6SJani Nikula
449*bdfee324SAndrzej Hajda intel_de_rmw(dev_priv, BXT_PHY_CTL_FAMILY(phy), 0, COMMON_RESET_DIS);
450df0566a6SJani Nikula }
451df0566a6SJani Nikula
bxt_ddi_phy_uninit(struct drm_i915_private * dev_priv,enum dpio_phy phy)452df0566a6SJani Nikula void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy)
453df0566a6SJani Nikula {
454df0566a6SJani Nikula const struct bxt_ddi_phy_info *phy_info;
455df0566a6SJani Nikula
456df0566a6SJani Nikula phy_info = bxt_get_phy_info(dev_priv, phy);
457df0566a6SJani Nikula
458*bdfee324SAndrzej Hajda intel_de_rmw(dev_priv, BXT_PHY_CTL_FAMILY(phy), COMMON_RESET_DIS, 0);
459df0566a6SJani Nikula
460*bdfee324SAndrzej Hajda intel_de_rmw(dev_priv, BXT_P_CR_GT_DISP_PWRON, phy_info->pwron_mask, 0);
461df0566a6SJani Nikula }
462df0566a6SJani Nikula
bxt_ddi_phy_init(struct drm_i915_private * dev_priv,enum dpio_phy phy)463df0566a6SJani Nikula void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy)
464df0566a6SJani Nikula {
465df0566a6SJani Nikula const struct bxt_ddi_phy_info *phy_info =
466df0566a6SJani Nikula bxt_get_phy_info(dev_priv, phy);
467df0566a6SJani Nikula enum dpio_phy rcomp_phy = phy_info->rcomp_phy;
468df0566a6SJani Nikula bool was_enabled;
469df0566a6SJani Nikula
470e3e8148fSJani Nikula lockdep_assert_held(&dev_priv->display.power.domains.lock);
471df0566a6SJani Nikula
472df0566a6SJani Nikula was_enabled = true;
473df0566a6SJani Nikula if (rcomp_phy != -1)
474df0566a6SJani Nikula was_enabled = bxt_ddi_phy_is_enabled(dev_priv, rcomp_phy);
475df0566a6SJani Nikula
476df0566a6SJani Nikula /*
477df0566a6SJani Nikula * We need to copy the GRC calibration value from rcomp_phy,
478df0566a6SJani Nikula * so make sure it's powered up.
479df0566a6SJani Nikula */
480df0566a6SJani Nikula if (!was_enabled)
481df0566a6SJani Nikula _bxt_ddi_phy_init(dev_priv, rcomp_phy);
482df0566a6SJani Nikula
483df0566a6SJani Nikula _bxt_ddi_phy_init(dev_priv, phy);
484df0566a6SJani Nikula
485df0566a6SJani Nikula if (!was_enabled)
486df0566a6SJani Nikula bxt_ddi_phy_uninit(dev_priv, rcomp_phy);
487df0566a6SJani Nikula }
488df0566a6SJani Nikula
489df0566a6SJani Nikula static bool __printf(6, 7)
__phy_reg_verify_state(struct drm_i915_private * dev_priv,enum dpio_phy phy,i915_reg_t reg,u32 mask,u32 expected,const char * reg_fmt,...)490df0566a6SJani Nikula __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
491df0566a6SJani Nikula i915_reg_t reg, u32 mask, u32 expected,
492df0566a6SJani Nikula const char *reg_fmt, ...)
493df0566a6SJani Nikula {
494df0566a6SJani Nikula struct va_format vaf;
495df0566a6SJani Nikula va_list args;
496df0566a6SJani Nikula u32 val;
497df0566a6SJani Nikula
498ee8845a2SJani Nikula val = intel_de_read(dev_priv, reg);
499df0566a6SJani Nikula if ((val & mask) == expected)
500df0566a6SJani Nikula return true;
501df0566a6SJani Nikula
502df0566a6SJani Nikula va_start(args, reg_fmt);
503df0566a6SJani Nikula vaf.fmt = reg_fmt;
504df0566a6SJani Nikula vaf.va = &args;
505df0566a6SJani Nikula
5062fbfc595SWambui Karuga drm_dbg(&dev_priv->drm, "DDI PHY %d reg %pV [%08x] state mismatch: "
507df0566a6SJani Nikula "current %08x, expected %08x (mask %08x)\n",
508df0566a6SJani Nikula phy, &vaf, reg.reg, val, (val & ~mask) | expected,
509df0566a6SJani Nikula mask);
510df0566a6SJani Nikula
511df0566a6SJani Nikula va_end(args);
512df0566a6SJani Nikula
513df0566a6SJani Nikula return false;
514df0566a6SJani Nikula }
515df0566a6SJani Nikula
bxt_ddi_phy_verify_state(struct drm_i915_private * dev_priv,enum dpio_phy phy)516df0566a6SJani Nikula bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv,
517df0566a6SJani Nikula enum dpio_phy phy)
518df0566a6SJani Nikula {
519df0566a6SJani Nikula const struct bxt_ddi_phy_info *phy_info;
520df0566a6SJani Nikula u32 mask;
521df0566a6SJani Nikula bool ok;
522df0566a6SJani Nikula
523df0566a6SJani Nikula phy_info = bxt_get_phy_info(dev_priv, phy);
524df0566a6SJani Nikula
525df0566a6SJani Nikula #define _CHK(reg, mask, exp, fmt, ...) \
526df0566a6SJani Nikula __phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt, \
527df0566a6SJani Nikula ## __VA_ARGS__)
528df0566a6SJani Nikula
529df0566a6SJani Nikula if (!bxt_ddi_phy_is_enabled(dev_priv, phy))
530df0566a6SJani Nikula return false;
531df0566a6SJani Nikula
532df0566a6SJani Nikula ok = true;
533df0566a6SJani Nikula
534df0566a6SJani Nikula /* PLL Rcomp code offset */
535df0566a6SJani Nikula ok &= _CHK(BXT_PORT_CL1CM_DW9(phy),
536df0566a6SJani Nikula IREF0RC_OFFSET_MASK, 0xe4 << IREF0RC_OFFSET_SHIFT,
537df0566a6SJani Nikula "BXT_PORT_CL1CM_DW9(%d)", phy);
538df0566a6SJani Nikula ok &= _CHK(BXT_PORT_CL1CM_DW10(phy),
539df0566a6SJani Nikula IREF1RC_OFFSET_MASK, 0xe4 << IREF1RC_OFFSET_SHIFT,
540df0566a6SJani Nikula "BXT_PORT_CL1CM_DW10(%d)", phy);
541df0566a6SJani Nikula
542df0566a6SJani Nikula /* Power gating */
543df0566a6SJani Nikula mask = OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | SUS_CLK_CONFIG;
544df0566a6SJani Nikula ok &= _CHK(BXT_PORT_CL1CM_DW28(phy), mask, mask,
545df0566a6SJani Nikula "BXT_PORT_CL1CM_DW28(%d)", phy);
546df0566a6SJani Nikula
547df0566a6SJani Nikula if (phy_info->dual_channel)
548df0566a6SJani Nikula ok &= _CHK(BXT_PORT_CL2CM_DW6(phy),
549df0566a6SJani Nikula DW6_OLDO_DYN_PWR_DOWN_EN, DW6_OLDO_DYN_PWR_DOWN_EN,
550df0566a6SJani Nikula "BXT_PORT_CL2CM_DW6(%d)", phy);
551df0566a6SJani Nikula
552df0566a6SJani Nikula if (phy_info->rcomp_phy != -1) {
553e2855f8eSJani Nikula u32 grc_code = dev_priv->display.state.bxt_phy_grc;
554df0566a6SJani Nikula
555df0566a6SJani Nikula grc_code = grc_code << GRC_CODE_FAST_SHIFT |
556df0566a6SJani Nikula grc_code << GRC_CODE_SLOW_SHIFT |
557df0566a6SJani Nikula grc_code;
558df0566a6SJani Nikula mask = GRC_CODE_FAST_MASK | GRC_CODE_SLOW_MASK |
559df0566a6SJani Nikula GRC_CODE_NOM_MASK;
560df0566a6SJani Nikula ok &= _CHK(BXT_PORT_REF_DW6(phy), mask, grc_code,
561df0566a6SJani Nikula "BXT_PORT_REF_DW6(%d)", phy);
562df0566a6SJani Nikula
563df0566a6SJani Nikula mask = GRC_DIS | GRC_RDY_OVRD;
564df0566a6SJani Nikula ok &= _CHK(BXT_PORT_REF_DW8(phy), mask, mask,
565df0566a6SJani Nikula "BXT_PORT_REF_DW8(%d)", phy);
566df0566a6SJani Nikula }
567df0566a6SJani Nikula
568df0566a6SJani Nikula return ok;
569df0566a6SJani Nikula #undef _CHK
570df0566a6SJani Nikula }
571df0566a6SJani Nikula
572df0566a6SJani Nikula u8
bxt_ddi_phy_calc_lane_lat_optim_mask(u8 lane_count)573df0566a6SJani Nikula bxt_ddi_phy_calc_lane_lat_optim_mask(u8 lane_count)
574df0566a6SJani Nikula {
575df0566a6SJani Nikula switch (lane_count) {
576df0566a6SJani Nikula case 1:
577df0566a6SJani Nikula return 0;
578df0566a6SJani Nikula case 2:
579df0566a6SJani Nikula return BIT(2) | BIT(0);
580df0566a6SJani Nikula case 4:
581df0566a6SJani Nikula return BIT(3) | BIT(2) | BIT(0);
582df0566a6SJani Nikula default:
583df0566a6SJani Nikula MISSING_CASE(lane_count);
584df0566a6SJani Nikula
585df0566a6SJani Nikula return 0;
586df0566a6SJani Nikula }
587df0566a6SJani Nikula }
588df0566a6SJani Nikula
bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder * encoder,u8 lane_lat_optim_mask)589df0566a6SJani Nikula void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder,
590df0566a6SJani Nikula u8 lane_lat_optim_mask)
591df0566a6SJani Nikula {
592df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
593df0566a6SJani Nikula enum port port = encoder->port;
594df0566a6SJani Nikula enum dpio_phy phy;
595df0566a6SJani Nikula enum dpio_channel ch;
596df0566a6SJani Nikula int lane;
597df0566a6SJani Nikula
598df0566a6SJani Nikula bxt_port_to_phy_channel(dev_priv, port, &phy, &ch);
599df0566a6SJani Nikula
600df0566a6SJani Nikula for (lane = 0; lane < 4; lane++) {
601ee8845a2SJani Nikula u32 val = intel_de_read(dev_priv,
602ee8845a2SJani Nikula BXT_PORT_TX_DW14_LN(phy, ch, lane));
603df0566a6SJani Nikula
604df0566a6SJani Nikula /*
605df0566a6SJani Nikula * Note that on CHV this flag is called UPAR, but has
606df0566a6SJani Nikula * the same function.
607df0566a6SJani Nikula */
608df0566a6SJani Nikula val &= ~LATENCY_OPTIM;
609df0566a6SJani Nikula if (lane_lat_optim_mask & BIT(lane))
610df0566a6SJani Nikula val |= LATENCY_OPTIM;
611df0566a6SJani Nikula
612ee8845a2SJani Nikula intel_de_write(dev_priv, BXT_PORT_TX_DW14_LN(phy, ch, lane),
613ee8845a2SJani Nikula val);
614df0566a6SJani Nikula }
615df0566a6SJani Nikula }
616df0566a6SJani Nikula
617df0566a6SJani Nikula u8
bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder * encoder)618df0566a6SJani Nikula bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder)
619df0566a6SJani Nikula {
620df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
621df0566a6SJani Nikula enum port port = encoder->port;
622df0566a6SJani Nikula enum dpio_phy phy;
623df0566a6SJani Nikula enum dpio_channel ch;
624df0566a6SJani Nikula int lane;
625df0566a6SJani Nikula u8 mask;
626df0566a6SJani Nikula
627df0566a6SJani Nikula bxt_port_to_phy_channel(dev_priv, port, &phy, &ch);
628df0566a6SJani Nikula
629df0566a6SJani Nikula mask = 0;
630df0566a6SJani Nikula for (lane = 0; lane < 4; lane++) {
631ee8845a2SJani Nikula u32 val = intel_de_read(dev_priv,
632ee8845a2SJani Nikula BXT_PORT_TX_DW14_LN(phy, ch, lane));
633df0566a6SJani Nikula
634df0566a6SJani Nikula if (val & LATENCY_OPTIM)
635df0566a6SJani Nikula mask |= BIT(lane);
636df0566a6SJani Nikula }
637df0566a6SJani Nikula
638df0566a6SJani Nikula return mask;
639df0566a6SJani Nikula }
640df0566a6SJani Nikula
vlv_dig_port_to_channel(struct intel_digital_port * dig_port)6412461bdb3SJani Nikula enum dpio_channel vlv_dig_port_to_channel(struct intel_digital_port *dig_port)
6422461bdb3SJani Nikula {
6432461bdb3SJani Nikula switch (dig_port->base.port) {
6442461bdb3SJani Nikula default:
6452461bdb3SJani Nikula MISSING_CASE(dig_port->base.port);
6462461bdb3SJani Nikula fallthrough;
6472461bdb3SJani Nikula case PORT_B:
6482461bdb3SJani Nikula case PORT_D:
6492461bdb3SJani Nikula return DPIO_CH0;
6502461bdb3SJani Nikula case PORT_C:
6512461bdb3SJani Nikula return DPIO_CH1;
6522461bdb3SJani Nikula }
6532461bdb3SJani Nikula }
6542461bdb3SJani Nikula
vlv_dig_port_to_phy(struct intel_digital_port * dig_port)6552461bdb3SJani Nikula enum dpio_phy vlv_dig_port_to_phy(struct intel_digital_port *dig_port)
6562461bdb3SJani Nikula {
6572461bdb3SJani Nikula switch (dig_port->base.port) {
6582461bdb3SJani Nikula default:
6592461bdb3SJani Nikula MISSING_CASE(dig_port->base.port);
6602461bdb3SJani Nikula fallthrough;
6612461bdb3SJani Nikula case PORT_B:
6622461bdb3SJani Nikula case PORT_C:
6632461bdb3SJani Nikula return DPIO_PHY0;
6642461bdb3SJani Nikula case PORT_D:
6652461bdb3SJani Nikula return DPIO_PHY1;
6662461bdb3SJani Nikula }
6672461bdb3SJani Nikula }
6682461bdb3SJani Nikula
vlv_pipe_to_channel(enum pipe pipe)6692461bdb3SJani Nikula enum dpio_channel vlv_pipe_to_channel(enum pipe pipe)
6702461bdb3SJani Nikula {
6712461bdb3SJani Nikula switch (pipe) {
6722461bdb3SJani Nikula default:
6732461bdb3SJani Nikula MISSING_CASE(pipe);
6742461bdb3SJani Nikula fallthrough;
6752461bdb3SJani Nikula case PIPE_A:
6762461bdb3SJani Nikula case PIPE_C:
6772461bdb3SJani Nikula return DPIO_CH0;
6782461bdb3SJani Nikula case PIPE_B:
6792461bdb3SJani Nikula return DPIO_CH1;
6802461bdb3SJani Nikula }
6812461bdb3SJani Nikula }
6822461bdb3SJani Nikula
chv_set_phy_signal_level(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,u32 deemph_reg_value,u32 margin_reg_value,bool uniq_trans_scale)683df0566a6SJani Nikula void chv_set_phy_signal_level(struct intel_encoder *encoder,
684a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state,
685df0566a6SJani Nikula u32 deemph_reg_value, u32 margin_reg_value,
686df0566a6SJani Nikula bool uniq_trans_scale)
687df0566a6SJani Nikula {
688df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
6897801f3b7SLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
690a621860aSVille Syrjälä struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
6917801f3b7SLucas De Marchi enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
692a621860aSVille Syrjälä enum pipe pipe = crtc->pipe;
693df0566a6SJani Nikula u32 val;
694df0566a6SJani Nikula int i;
695df0566a6SJani Nikula
696df0566a6SJani Nikula vlv_dpio_get(dev_priv);
697df0566a6SJani Nikula
698df0566a6SJani Nikula /* Clear calc init */
699df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
700df0566a6SJani Nikula val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
701df0566a6SJani Nikula val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
702df0566a6SJani Nikula val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
703df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
704df0566a6SJani Nikula
705a621860aSVille Syrjälä if (crtc_state->lane_count > 2) {
706df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
707df0566a6SJani Nikula val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
708df0566a6SJani Nikula val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
709df0566a6SJani Nikula val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
710df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
711df0566a6SJani Nikula }
712df0566a6SJani Nikula
713df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
714df0566a6SJani Nikula val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
715df0566a6SJani Nikula val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
716df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
717df0566a6SJani Nikula
718a621860aSVille Syrjälä if (crtc_state->lane_count > 2) {
719df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
720df0566a6SJani Nikula val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
721df0566a6SJani Nikula val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
722df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
723df0566a6SJani Nikula }
724df0566a6SJani Nikula
725df0566a6SJani Nikula /* Program swing deemph */
726a621860aSVille Syrjälä for (i = 0; i < crtc_state->lane_count; i++) {
727df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
728df0566a6SJani Nikula val &= ~DPIO_SWING_DEEMPH9P5_MASK;
729df0566a6SJani Nikula val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
730df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, CHV_TX_DW4(ch, i), val);
731df0566a6SJani Nikula }
732df0566a6SJani Nikula
733df0566a6SJani Nikula /* Program swing margin */
734a621860aSVille Syrjälä for (i = 0; i < crtc_state->lane_count; i++) {
735df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
736df0566a6SJani Nikula
737df0566a6SJani Nikula val &= ~DPIO_SWING_MARGIN000_MASK;
738df0566a6SJani Nikula val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
739df0566a6SJani Nikula
740df0566a6SJani Nikula /*
741df0566a6SJani Nikula * Supposedly this value shouldn't matter when unique transition
742df0566a6SJani Nikula * scale is disabled, but in fact it does matter. Let's just
743df0566a6SJani Nikula * always program the same value and hope it's OK.
744df0566a6SJani Nikula */
745df0566a6SJani Nikula val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
746df0566a6SJani Nikula val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT;
747df0566a6SJani Nikula
748df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
749df0566a6SJani Nikula }
750df0566a6SJani Nikula
751df0566a6SJani Nikula /*
752df0566a6SJani Nikula * The document said it needs to set bit 27 for ch0 and bit 26
753df0566a6SJani Nikula * for ch1. Might be a typo in the doc.
754df0566a6SJani Nikula * For now, for this unique transition scale selection, set bit
755df0566a6SJani Nikula * 27 for ch0 and ch1.
756df0566a6SJani Nikula */
757a621860aSVille Syrjälä for (i = 0; i < crtc_state->lane_count; i++) {
758df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
759df0566a6SJani Nikula if (uniq_trans_scale)
760df0566a6SJani Nikula val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
761df0566a6SJani Nikula else
762df0566a6SJani Nikula val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
763df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
764df0566a6SJani Nikula }
765df0566a6SJani Nikula
766df0566a6SJani Nikula /* Start swing calculation */
767df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
768df0566a6SJani Nikula val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
769df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
770df0566a6SJani Nikula
771a621860aSVille Syrjälä if (crtc_state->lane_count > 2) {
772df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
773df0566a6SJani Nikula val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
774df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
775df0566a6SJani Nikula }
776df0566a6SJani Nikula
777df0566a6SJani Nikula vlv_dpio_put(dev_priv);
778df0566a6SJani Nikula }
779df0566a6SJani Nikula
chv_data_lane_soft_reset(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,bool reset)780df0566a6SJani Nikula void chv_data_lane_soft_reset(struct intel_encoder *encoder,
781df0566a6SJani Nikula const struct intel_crtc_state *crtc_state,
782df0566a6SJani Nikula bool reset)
783df0566a6SJani Nikula {
784df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
7857801f3b7SLucas De Marchi enum dpio_channel ch = vlv_dig_port_to_channel(enc_to_dig_port(encoder));
7862225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
787df0566a6SJani Nikula enum pipe pipe = crtc->pipe;
788df0566a6SJani Nikula u32 val;
789df0566a6SJani Nikula
790df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch));
791df0566a6SJani Nikula if (reset)
792df0566a6SJani Nikula val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
793df0566a6SJani Nikula else
794df0566a6SJani Nikula val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
795df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val);
796df0566a6SJani Nikula
797df0566a6SJani Nikula if (crtc_state->lane_count > 2) {
798df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch));
799df0566a6SJani Nikula if (reset)
800df0566a6SJani Nikula val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
801df0566a6SJani Nikula else
802df0566a6SJani Nikula val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
803df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val);
804df0566a6SJani Nikula }
805df0566a6SJani Nikula
806df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch));
807df0566a6SJani Nikula val |= CHV_PCS_REQ_SOFTRESET_EN;
808df0566a6SJani Nikula if (reset)
809df0566a6SJani Nikula val &= ~DPIO_PCS_CLK_SOFT_RESET;
810df0566a6SJani Nikula else
811df0566a6SJani Nikula val |= DPIO_PCS_CLK_SOFT_RESET;
812df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val);
813df0566a6SJani Nikula
814df0566a6SJani Nikula if (crtc_state->lane_count > 2) {
815df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch));
816df0566a6SJani Nikula val |= CHV_PCS_REQ_SOFTRESET_EN;
817df0566a6SJani Nikula if (reset)
818df0566a6SJani Nikula val &= ~DPIO_PCS_CLK_SOFT_RESET;
819df0566a6SJani Nikula else
820df0566a6SJani Nikula val |= DPIO_PCS_CLK_SOFT_RESET;
821df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val);
822df0566a6SJani Nikula }
823df0566a6SJani Nikula }
824df0566a6SJani Nikula
chv_phy_pre_pll_enable(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)825df0566a6SJani Nikula void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
826df0566a6SJani Nikula const struct intel_crtc_state *crtc_state)
827df0566a6SJani Nikula {
8287801f3b7SLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
829df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
8302225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
8317801f3b7SLucas De Marchi enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
832df0566a6SJani Nikula enum pipe pipe = crtc->pipe;
833df0566a6SJani Nikula unsigned int lane_mask =
834df0566a6SJani Nikula intel_dp_unused_lane_mask(crtc_state->lane_count);
835df0566a6SJani Nikula u32 val;
836df0566a6SJani Nikula
837df0566a6SJani Nikula /*
838df0566a6SJani Nikula * Must trick the second common lane into life.
839df0566a6SJani Nikula * Otherwise we can't even access the PLL.
840df0566a6SJani Nikula */
841df0566a6SJani Nikula if (ch == DPIO_CH0 && pipe == PIPE_B)
8427801f3b7SLucas De Marchi dig_port->release_cl2_override =
843df0566a6SJani Nikula !chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, true);
844df0566a6SJani Nikula
845df0566a6SJani Nikula chv_phy_powergate_lanes(encoder, true, lane_mask);
846df0566a6SJani Nikula
847df0566a6SJani Nikula vlv_dpio_get(dev_priv);
848df0566a6SJani Nikula
849df0566a6SJani Nikula /* Assert data lane reset */
850df0566a6SJani Nikula chv_data_lane_soft_reset(encoder, crtc_state, true);
851df0566a6SJani Nikula
852df0566a6SJani Nikula /* program left/right clock distribution */
853df0566a6SJani Nikula if (pipe != PIPE_B) {
854df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
855df0566a6SJani Nikula val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
856df0566a6SJani Nikula if (ch == DPIO_CH0)
857df0566a6SJani Nikula val |= CHV_BUFLEFTENA1_FORCE;
858df0566a6SJani Nikula if (ch == DPIO_CH1)
859df0566a6SJani Nikula val |= CHV_BUFRIGHTENA1_FORCE;
860df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
861df0566a6SJani Nikula } else {
862df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
863df0566a6SJani Nikula val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
864df0566a6SJani Nikula if (ch == DPIO_CH0)
865df0566a6SJani Nikula val |= CHV_BUFLEFTENA2_FORCE;
866df0566a6SJani Nikula if (ch == DPIO_CH1)
867df0566a6SJani Nikula val |= CHV_BUFRIGHTENA2_FORCE;
868df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
869df0566a6SJani Nikula }
870df0566a6SJani Nikula
871df0566a6SJani Nikula /* program clock channel usage */
872df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(ch));
873df0566a6SJani Nikula val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
874df0566a6SJani Nikula if (pipe != PIPE_B)
875df0566a6SJani Nikula val &= ~CHV_PCS_USEDCLKCHANNEL;
876df0566a6SJani Nikula else
877df0566a6SJani Nikula val |= CHV_PCS_USEDCLKCHANNEL;
878df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val);
879df0566a6SJani Nikula
880df0566a6SJani Nikula if (crtc_state->lane_count > 2) {
881df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch));
882df0566a6SJani Nikula val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
883df0566a6SJani Nikula if (pipe != PIPE_B)
884df0566a6SJani Nikula val &= ~CHV_PCS_USEDCLKCHANNEL;
885df0566a6SJani Nikula else
886df0566a6SJani Nikula val |= CHV_PCS_USEDCLKCHANNEL;
887df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val);
888df0566a6SJani Nikula }
889df0566a6SJani Nikula
890df0566a6SJani Nikula /*
891df0566a6SJani Nikula * This a a bit weird since generally CL
892df0566a6SJani Nikula * matches the pipe, but here we need to
893df0566a6SJani Nikula * pick the CL based on the port.
894df0566a6SJani Nikula */
895df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW19(ch));
896df0566a6SJani Nikula if (pipe != PIPE_B)
897df0566a6SJani Nikula val &= ~CHV_CMN_USEDCLKCHANNEL;
898df0566a6SJani Nikula else
899df0566a6SJani Nikula val |= CHV_CMN_USEDCLKCHANNEL;
900df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val);
901df0566a6SJani Nikula
902df0566a6SJani Nikula vlv_dpio_put(dev_priv);
903df0566a6SJani Nikula }
904df0566a6SJani Nikula
chv_phy_pre_encoder_enable(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)905df0566a6SJani Nikula void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
906df0566a6SJani Nikula const struct intel_crtc_state *crtc_state)
907df0566a6SJani Nikula {
908b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
9097801f3b7SLucas De Marchi struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
910df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
9112225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
9127801f3b7SLucas De Marchi enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
913df0566a6SJani Nikula enum pipe pipe = crtc->pipe;
914df0566a6SJani Nikula int data, i, stagger;
915df0566a6SJani Nikula u32 val;
916df0566a6SJani Nikula
917df0566a6SJani Nikula vlv_dpio_get(dev_priv);
918df0566a6SJani Nikula
919df0566a6SJani Nikula /* allow hardware to manage TX FIFO reset source */
920df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch));
921df0566a6SJani Nikula val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
922df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val);
923df0566a6SJani Nikula
924df0566a6SJani Nikula if (crtc_state->lane_count > 2) {
925df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
926df0566a6SJani Nikula val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
927df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
928df0566a6SJani Nikula }
929df0566a6SJani Nikula
930df0566a6SJani Nikula /* Program Tx lane latency optimal setting*/
931df0566a6SJani Nikula for (i = 0; i < crtc_state->lane_count; i++) {
932df0566a6SJani Nikula /* Set the upar bit */
933df0566a6SJani Nikula if (crtc_state->lane_count == 1)
934df0566a6SJani Nikula data = 0x0;
935df0566a6SJani Nikula else
936df0566a6SJani Nikula data = (i == 1) ? 0x0 : 0x1;
937df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, CHV_TX_DW14(ch, i),
938df0566a6SJani Nikula data << DPIO_UPAR_SHIFT);
939df0566a6SJani Nikula }
940df0566a6SJani Nikula
941df0566a6SJani Nikula /* Data lane stagger programming */
942df0566a6SJani Nikula if (crtc_state->port_clock > 270000)
943df0566a6SJani Nikula stagger = 0x18;
944df0566a6SJani Nikula else if (crtc_state->port_clock > 135000)
945df0566a6SJani Nikula stagger = 0xd;
946df0566a6SJani Nikula else if (crtc_state->port_clock > 67500)
947df0566a6SJani Nikula stagger = 0x7;
948df0566a6SJani Nikula else if (crtc_state->port_clock > 33750)
949df0566a6SJani Nikula stagger = 0x4;
950df0566a6SJani Nikula else
951df0566a6SJani Nikula stagger = 0x2;
952df0566a6SJani Nikula
953df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch));
954df0566a6SJani Nikula val |= DPIO_TX2_STAGGER_MASK(0x1f);
955df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val);
956df0566a6SJani Nikula
957df0566a6SJani Nikula if (crtc_state->lane_count > 2) {
958df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch));
959df0566a6SJani Nikula val |= DPIO_TX2_STAGGER_MASK(0x1f);
960df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val);
961df0566a6SJani Nikula }
962df0566a6SJani Nikula
963df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW12(ch),
964df0566a6SJani Nikula DPIO_LANESTAGGER_STRAP(stagger) |
965df0566a6SJani Nikula DPIO_LANESTAGGER_STRAP_OVRD |
966df0566a6SJani Nikula DPIO_TX1_STAGGER_MASK(0x1f) |
967df0566a6SJani Nikula DPIO_TX1_STAGGER_MULT(6) |
968df0566a6SJani Nikula DPIO_TX2_STAGGER_MULT(0));
969df0566a6SJani Nikula
970df0566a6SJani Nikula if (crtc_state->lane_count > 2) {
971df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW12(ch),
972df0566a6SJani Nikula DPIO_LANESTAGGER_STRAP(stagger) |
973df0566a6SJani Nikula DPIO_LANESTAGGER_STRAP_OVRD |
974df0566a6SJani Nikula DPIO_TX1_STAGGER_MASK(0x1f) |
975df0566a6SJani Nikula DPIO_TX1_STAGGER_MULT(7) |
976df0566a6SJani Nikula DPIO_TX2_STAGGER_MULT(5));
977df0566a6SJani Nikula }
978df0566a6SJani Nikula
979df0566a6SJani Nikula /* Deassert data lane reset */
980df0566a6SJani Nikula chv_data_lane_soft_reset(encoder, crtc_state, false);
981df0566a6SJani Nikula
982df0566a6SJani Nikula vlv_dpio_put(dev_priv);
983df0566a6SJani Nikula }
984df0566a6SJani Nikula
chv_phy_release_cl2_override(struct intel_encoder * encoder)985df0566a6SJani Nikula void chv_phy_release_cl2_override(struct intel_encoder *encoder)
986df0566a6SJani Nikula {
9877801f3b7SLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
988df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
989df0566a6SJani Nikula
9907801f3b7SLucas De Marchi if (dig_port->release_cl2_override) {
991df0566a6SJani Nikula chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, false);
9927801f3b7SLucas De Marchi dig_port->release_cl2_override = false;
993df0566a6SJani Nikula }
994df0566a6SJani Nikula }
995df0566a6SJani Nikula
chv_phy_post_pll_disable(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state)996df0566a6SJani Nikula void chv_phy_post_pll_disable(struct intel_encoder *encoder,
997df0566a6SJani Nikula const struct intel_crtc_state *old_crtc_state)
998df0566a6SJani Nikula {
999df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
10002225f3c6SMaarten Lankhorst enum pipe pipe = to_intel_crtc(old_crtc_state->uapi.crtc)->pipe;
1001df0566a6SJani Nikula u32 val;
1002df0566a6SJani Nikula
1003df0566a6SJani Nikula vlv_dpio_get(dev_priv);
1004df0566a6SJani Nikula
1005df0566a6SJani Nikula /* disable left/right clock distribution */
1006df0566a6SJani Nikula if (pipe != PIPE_B) {
1007df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
1008df0566a6SJani Nikula val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
1009df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
1010df0566a6SJani Nikula } else {
1011df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
1012df0566a6SJani Nikula val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
1013df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
1014df0566a6SJani Nikula }
1015df0566a6SJani Nikula
1016df0566a6SJani Nikula vlv_dpio_put(dev_priv);
1017df0566a6SJani Nikula
1018df0566a6SJani Nikula /*
1019df0566a6SJani Nikula * Leave the power down bit cleared for at least one
1020df0566a6SJani Nikula * lane so that chv_powergate_phy_ch() will power
1021df0566a6SJani Nikula * on something when the channel is otherwise unused.
1022df0566a6SJani Nikula * When the port is off and the override is removed
1023df0566a6SJani Nikula * the lanes power down anyway, so otherwise it doesn't
1024df0566a6SJani Nikula * really matter what the state of power down bits is
1025df0566a6SJani Nikula * after this.
1026df0566a6SJani Nikula */
1027df0566a6SJani Nikula chv_phy_powergate_lanes(encoder, false, 0x0);
1028df0566a6SJani Nikula }
1029df0566a6SJani Nikula
vlv_set_phy_signal_level(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,u32 demph_reg_value,u32 preemph_reg_value,u32 uniqtranscale_reg_value,u32 tx3_demph)1030df0566a6SJani Nikula void vlv_set_phy_signal_level(struct intel_encoder *encoder,
1031a621860aSVille Syrjälä const struct intel_crtc_state *crtc_state,
1032df0566a6SJani Nikula u32 demph_reg_value, u32 preemph_reg_value,
1033df0566a6SJani Nikula u32 uniqtranscale_reg_value, u32 tx3_demph)
1034df0566a6SJani Nikula {
1035df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
10367801f3b7SLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
1037a621860aSVille Syrjälä struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
10387801f3b7SLucas De Marchi enum dpio_channel port = vlv_dig_port_to_channel(dig_port);
1039a621860aSVille Syrjälä enum pipe pipe = crtc->pipe;
1040df0566a6SJani Nikula
1041df0566a6SJani Nikula vlv_dpio_get(dev_priv);
1042df0566a6SJani Nikula
1043df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
1044df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
1045df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
1046df0566a6SJani Nikula uniqtranscale_reg_value);
1047df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0C782040);
1048df0566a6SJani Nikula
1049df0566a6SJani Nikula if (tx3_demph)
1050df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_TX3_DW4(port), tx3_demph);
1051df0566a6SJani Nikula
1052df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
1053df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
1054df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), DPIO_TX_OCALINIT_EN);
1055df0566a6SJani Nikula
1056df0566a6SJani Nikula vlv_dpio_put(dev_priv);
1057df0566a6SJani Nikula }
1058df0566a6SJani Nikula
vlv_phy_pre_pll_enable(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)1059df0566a6SJani Nikula void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
1060df0566a6SJani Nikula const struct intel_crtc_state *crtc_state)
1061df0566a6SJani Nikula {
10627801f3b7SLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
1063df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
10642225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
10657801f3b7SLucas De Marchi enum dpio_channel port = vlv_dig_port_to_channel(dig_port);
1066df0566a6SJani Nikula enum pipe pipe = crtc->pipe;
1067df0566a6SJani Nikula
1068df0566a6SJani Nikula /* Program Tx lane resets to default */
1069df0566a6SJani Nikula vlv_dpio_get(dev_priv);
1070df0566a6SJani Nikula
1071df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port),
1072df0566a6SJani Nikula DPIO_PCS_TX_LANE2_RESET |
1073df0566a6SJani Nikula DPIO_PCS_TX_LANE1_RESET);
1074df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port),
1075df0566a6SJani Nikula DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
1076df0566a6SJani Nikula DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
1077df0566a6SJani Nikula (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
1078df0566a6SJani Nikula DPIO_PCS_CLK_SOFT_RESET);
1079df0566a6SJani Nikula
1080df0566a6SJani Nikula /* Fix up inter-pair skew failure */
1081df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW12(port), 0x00750f00);
1082df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_TX_DW11(port), 0x00001500);
1083df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_TX_DW14(port), 0x40400000);
1084df0566a6SJani Nikula
1085df0566a6SJani Nikula vlv_dpio_put(dev_priv);
1086df0566a6SJani Nikula }
1087df0566a6SJani Nikula
vlv_phy_pre_encoder_enable(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)1088df0566a6SJani Nikula void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
1089df0566a6SJani Nikula const struct intel_crtc_state *crtc_state)
1090df0566a6SJani Nikula {
1091b7d02c3aSVille Syrjälä struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
10927801f3b7SLucas De Marchi struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
1093df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
10942225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
10957801f3b7SLucas De Marchi enum dpio_channel port = vlv_dig_port_to_channel(dig_port);
1096df0566a6SJani Nikula enum pipe pipe = crtc->pipe;
1097df0566a6SJani Nikula u32 val;
1098df0566a6SJani Nikula
1099df0566a6SJani Nikula vlv_dpio_get(dev_priv);
1100df0566a6SJani Nikula
1101df0566a6SJani Nikula /* Enable clock channels for this port */
1102df0566a6SJani Nikula val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(port));
1103df0566a6SJani Nikula val = 0;
1104df0566a6SJani Nikula if (pipe)
1105df0566a6SJani Nikula val |= (1<<21);
1106df0566a6SJani Nikula else
1107df0566a6SJani Nikula val &= ~(1<<21);
1108df0566a6SJani Nikula val |= 0x001000c4;
1109df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW8(port), val);
1110df0566a6SJani Nikula
1111df0566a6SJani Nikula /* Program lane clock */
1112df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW14(port), 0x00760018);
1113df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888);
1114df0566a6SJani Nikula
1115df0566a6SJani Nikula vlv_dpio_put(dev_priv);
1116df0566a6SJani Nikula }
1117df0566a6SJani Nikula
vlv_phy_reset_lanes(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state)1118df0566a6SJani Nikula void vlv_phy_reset_lanes(struct intel_encoder *encoder,
1119df0566a6SJani Nikula const struct intel_crtc_state *old_crtc_state)
1120df0566a6SJani Nikula {
11217801f3b7SLucas De Marchi struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
1122df0566a6SJani Nikula struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
11232225f3c6SMaarten Lankhorst struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
11247801f3b7SLucas De Marchi enum dpio_channel port = vlv_dig_port_to_channel(dig_port);
1125df0566a6SJani Nikula enum pipe pipe = crtc->pipe;
1126df0566a6SJani Nikula
1127df0566a6SJani Nikula vlv_dpio_get(dev_priv);
1128df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), 0x00000000);
1129df0566a6SJani Nikula vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port), 0x00e00060);
1130df0566a6SJani Nikula vlv_dpio_put(dev_priv);
1131df0566a6SJani Nikula }
1132