Rev 3746 | Rev 4280 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3746 | Rev 4104 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright © 2012 Intel Corporation |
2 | * Copyright © 2012 Intel Corporation |
3 | * |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
10 | * |
11 | * The above copyright notice and this permission notice (including the next |
11 | * The above copyright notice and this permission notice (including the next |
12 | * paragraph) shall be included in all copies or substantial portions of the |
12 | * paragraph) shall be included in all copies or substantial portions of the |
13 | * Software. |
13 | * Software. |
14 | * |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
21 | * IN THE SOFTWARE. |
21 | * IN THE SOFTWARE. |
22 | * |
22 | * |
23 | * Authors: |
23 | * Authors: |
24 | * Eugeni Dodonov |
24 | * Eugeni Dodonov |
25 | * |
25 | * |
26 | */ |
26 | */ |
27 | 27 | ||
28 | #include "i915_drv.h" |
28 | #include "i915_drv.h" |
29 | #include "intel_drv.h" |
29 | #include "intel_drv.h" |
30 | 30 | ||
31 | /* HDMI/DVI modes ignore everything but the last 2 items. So we share |
31 | /* HDMI/DVI modes ignore everything but the last 2 items. So we share |
32 | * them for both DP and FDI transports, allowing those ports to |
32 | * them for both DP and FDI transports, allowing those ports to |
33 | * automatically adapt to HDMI connections as well |
33 | * automatically adapt to HDMI connections as well |
34 | */ |
34 | */ |
35 | static const u32 hsw_ddi_translations_dp[] = { |
35 | static const u32 hsw_ddi_translations_dp[] = { |
36 | 0x00FFFFFF, 0x0006000E, /* DP parameters */ |
36 | 0x00FFFFFF, 0x0006000E, /* DP parameters */ |
37 | 0x00D75FFF, 0x0005000A, |
37 | 0x00D75FFF, 0x0005000A, |
38 | 0x00C30FFF, 0x00040006, |
38 | 0x00C30FFF, 0x00040006, |
39 | 0x80AAAFFF, 0x000B0000, |
39 | 0x80AAAFFF, 0x000B0000, |
40 | 0x00FFFFFF, 0x0005000A, |
40 | 0x00FFFFFF, 0x0005000A, |
41 | 0x00D75FFF, 0x000C0004, |
41 | 0x00D75FFF, 0x000C0004, |
42 | 0x80C30FFF, 0x000B0000, |
42 | 0x80C30FFF, 0x000B0000, |
43 | 0x00FFFFFF, 0x00040006, |
43 | 0x00FFFFFF, 0x00040006, |
44 | 0x80D75FFF, 0x000B0000, |
44 | 0x80D75FFF, 0x000B0000, |
45 | 0x00FFFFFF, 0x00040006 /* HDMI parameters */ |
45 | 0x00FFFFFF, 0x00040006 /* HDMI parameters */ |
46 | }; |
46 | }; |
47 | 47 | ||
48 | static const u32 hsw_ddi_translations_fdi[] = { |
48 | static const u32 hsw_ddi_translations_fdi[] = { |
49 | 0x00FFFFFF, 0x0007000E, /* FDI parameters */ |
49 | 0x00FFFFFF, 0x0007000E, /* FDI parameters */ |
50 | 0x00D75FFF, 0x000F000A, |
50 | 0x00D75FFF, 0x000F000A, |
51 | 0x00C30FFF, 0x00060006, |
51 | 0x00C30FFF, 0x00060006, |
52 | 0x00AAAFFF, 0x001E0000, |
52 | 0x00AAAFFF, 0x001E0000, |
53 | 0x00FFFFFF, 0x000F000A, |
53 | 0x00FFFFFF, 0x000F000A, |
54 | 0x00D75FFF, 0x00160004, |
54 | 0x00D75FFF, 0x00160004, |
55 | 0x00C30FFF, 0x001E0000, |
55 | 0x00C30FFF, 0x001E0000, |
56 | 0x00FFFFFF, 0x00060006, |
56 | 0x00FFFFFF, 0x00060006, |
57 | 0x00D75FFF, 0x001E0000, |
57 | 0x00D75FFF, 0x001E0000, |
58 | 0x00FFFFFF, 0x00040006 /* HDMI parameters */ |
58 | 0x00FFFFFF, 0x00040006 /* HDMI parameters */ |
59 | }; |
59 | }; |
60 | 60 | ||
61 | static enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) |
61 | static enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) |
62 | { |
62 | { |
63 | struct drm_encoder *encoder = &intel_encoder->base; |
63 | struct drm_encoder *encoder = &intel_encoder->base; |
64 | int type = intel_encoder->type; |
64 | int type = intel_encoder->type; |
65 | 65 | ||
66 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || |
66 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || |
67 | type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_UNKNOWN) { |
67 | type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_UNKNOWN) { |
68 | struct intel_digital_port *intel_dig_port = |
68 | struct intel_digital_port *intel_dig_port = |
69 | enc_to_dig_port(encoder); |
69 | enc_to_dig_port(encoder); |
70 | return intel_dig_port->port; |
70 | return intel_dig_port->port; |
71 | 71 | ||
72 | } else if (type == INTEL_OUTPUT_ANALOG) { |
72 | } else if (type == INTEL_OUTPUT_ANALOG) { |
73 | return PORT_E; |
73 | return PORT_E; |
74 | 74 | ||
75 | } else { |
75 | } else { |
76 | DRM_ERROR("Invalid DDI encoder type %d\n", type); |
76 | DRM_ERROR("Invalid DDI encoder type %d\n", type); |
77 | BUG(); |
77 | BUG(); |
78 | } |
78 | } |
79 | } |
79 | } |
80 | 80 | ||
81 | /* On Haswell, DDI port buffers must be programmed with correct values |
81 | /* On Haswell, DDI port buffers must be programmed with correct values |
82 | * in advance. The buffer values are different for FDI and DP modes, |
82 | * in advance. The buffer values are different for FDI and DP modes, |
83 | * but the HDMI/DVI fields are shared among those. So we program the DDI |
83 | * but the HDMI/DVI fields are shared among those. So we program the DDI |
84 | * in either FDI or DP modes only, as HDMI connections will work with both |
84 | * in either FDI or DP modes only, as HDMI connections will work with both |
85 | * of those |
85 | * of those |
86 | */ |
86 | */ |
87 | static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, |
87 | static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) |
88 | bool use_fdi_mode) |
- | |
89 | { |
88 | { |
90 | struct drm_i915_private *dev_priv = dev->dev_private; |
89 | struct drm_i915_private *dev_priv = dev->dev_private; |
91 | u32 reg; |
90 | u32 reg; |
92 | int i; |
91 | int i; |
93 | const u32 *ddi_translations = ((use_fdi_mode) ? |
92 | const u32 *ddi_translations = (port == PORT_E) ? |
94 | hsw_ddi_translations_fdi : |
93 | hsw_ddi_translations_fdi : |
95 | hsw_ddi_translations_dp); |
94 | hsw_ddi_translations_dp; |
96 | - | ||
97 | DRM_DEBUG_DRIVER("Initializing DDI buffers for port %c in %s mode\n", |
- | |
98 | port_name(port), |
95 | |
99 | use_fdi_mode ? "FDI" : "DP"); |
- | |
100 | - | ||
101 | WARN((use_fdi_mode && (port != PORT_E)), |
- | |
102 | "Programming port %c in FDI mode, this probably will not work.\n", |
- | |
103 | port_name(port)); |
- | |
104 | 96 | for (i = 0, reg = DDI_BUF_TRANS(port); |
|
105 | for (i=0, reg=DDI_BUF_TRANS(port); i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { |
97 | i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { |
106 | I915_WRITE(reg, ddi_translations[i]); |
98 | I915_WRITE(reg, ddi_translations[i]); |
107 | reg += 4; |
99 | reg += 4; |
108 | } |
100 | } |
109 | } |
101 | } |
110 | 102 | ||
111 | /* Program DDI buffers translations for DP. By default, program ports A-D in DP |
103 | /* Program DDI buffers translations for DP. By default, program ports A-D in DP |
112 | * mode and port E for FDI. |
104 | * mode and port E for FDI. |
113 | */ |
105 | */ |
114 | void intel_prepare_ddi(struct drm_device *dev) |
106 | void intel_prepare_ddi(struct drm_device *dev) |
115 | { |
107 | { |
116 | int port; |
108 | int port; |
117 | 109 | ||
118 | if (!HAS_DDI(dev)) |
110 | if (!HAS_DDI(dev)) |
119 | return; |
111 | return; |
120 | 112 | ||
121 | for (port = PORT_A; port < PORT_E; port++) |
113 | for (port = PORT_A; port <= PORT_E; port++) |
122 | intel_prepare_ddi_buffers(dev, port, false); |
- | |
123 | - | ||
124 | /* DDI E is the suggested one to work in FDI mode, so program is as such |
- | |
125 | * by default. It will have to be re-programmed in case a digital DP |
- | |
126 | * output will be detected on it |
- | |
127 | */ |
- | |
128 | intel_prepare_ddi_buffers(dev, PORT_E, true); |
114 | intel_prepare_ddi_buffers(dev, port); |
129 | } |
115 | } |
130 | 116 | ||
131 | static const long hsw_ddi_buf_ctl_values[] = { |
117 | static const long hsw_ddi_buf_ctl_values[] = { |
132 | DDI_BUF_EMP_400MV_0DB_HSW, |
118 | DDI_BUF_EMP_400MV_0DB_HSW, |
133 | DDI_BUF_EMP_400MV_3_5DB_HSW, |
119 | DDI_BUF_EMP_400MV_3_5DB_HSW, |
134 | DDI_BUF_EMP_400MV_6DB_HSW, |
120 | DDI_BUF_EMP_400MV_6DB_HSW, |
135 | DDI_BUF_EMP_400MV_9_5DB_HSW, |
121 | DDI_BUF_EMP_400MV_9_5DB_HSW, |
136 | DDI_BUF_EMP_600MV_0DB_HSW, |
122 | DDI_BUF_EMP_600MV_0DB_HSW, |
137 | DDI_BUF_EMP_600MV_3_5DB_HSW, |
123 | DDI_BUF_EMP_600MV_3_5DB_HSW, |
138 | DDI_BUF_EMP_600MV_6DB_HSW, |
124 | DDI_BUF_EMP_600MV_6DB_HSW, |
139 | DDI_BUF_EMP_800MV_0DB_HSW, |
125 | DDI_BUF_EMP_800MV_0DB_HSW, |
140 | DDI_BUF_EMP_800MV_3_5DB_HSW |
126 | DDI_BUF_EMP_800MV_3_5DB_HSW |
141 | }; |
127 | }; |
142 | 128 | ||
143 | static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, |
129 | static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, |
144 | enum port port) |
130 | enum port port) |
145 | { |
131 | { |
146 | uint32_t reg = DDI_BUF_CTL(port); |
132 | uint32_t reg = DDI_BUF_CTL(port); |
147 | int i; |
133 | int i; |
148 | 134 | ||
149 | for (i = 0; i < 8; i++) { |
135 | for (i = 0; i < 8; i++) { |
150 | udelay(1); |
136 | udelay(1); |
151 | if (I915_READ(reg) & DDI_BUF_IS_IDLE) |
137 | if (I915_READ(reg) & DDI_BUF_IS_IDLE) |
152 | return; |
138 | return; |
153 | } |
139 | } |
154 | DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port)); |
140 | DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port)); |
155 | } |
141 | } |
156 | 142 | ||
157 | /* Starting with Haswell, different DDI ports can work in FDI mode for |
143 | /* Starting with Haswell, different DDI ports can work in FDI mode for |
158 | * connection to the PCH-located connectors. For this, it is necessary to train |
144 | * connection to the PCH-located connectors. For this, it is necessary to train |
159 | * both the DDI port and PCH receiver for the desired DDI buffer settings. |
145 | * both the DDI port and PCH receiver for the desired DDI buffer settings. |
160 | * |
146 | * |
161 | * The recommended port to work in FDI mode is DDI E, which we use here. Also, |
147 | * The recommended port to work in FDI mode is DDI E, which we use here. Also, |
162 | * please note that when FDI mode is active on DDI E, it shares 2 lines with |
148 | * please note that when FDI mode is active on DDI E, it shares 2 lines with |
163 | * DDI A (which is used for eDP) |
149 | * DDI A (which is used for eDP) |
164 | */ |
150 | */ |
165 | 151 | ||
166 | void hsw_fdi_link_train(struct drm_crtc *crtc) |
152 | void hsw_fdi_link_train(struct drm_crtc *crtc) |
167 | { |
153 | { |
168 | struct drm_device *dev = crtc->dev; |
154 | struct drm_device *dev = crtc->dev; |
169 | struct drm_i915_private *dev_priv = dev->dev_private; |
155 | struct drm_i915_private *dev_priv = dev->dev_private; |
170 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
156 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
171 | u32 temp, i, rx_ctl_val; |
157 | u32 temp, i, rx_ctl_val; |
172 | 158 | ||
173 | /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the |
159 | /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the |
174 | * mode set "sequence for CRT port" document: |
160 | * mode set "sequence for CRT port" document: |
175 | * - TP1 to TP2 time with the default value |
161 | * - TP1 to TP2 time with the default value |
176 | * - FDI delay to 90h |
162 | * - FDI delay to 90h |
- | 163 | * |
|
- | 164 | * WaFDIAutoLinkSetTimingOverrride:hsw |
|
177 | */ |
165 | */ |
178 | I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) | |
166 | I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) | |
179 | FDI_RX_PWRDN_LANE0_VAL(2) | |
167 | FDI_RX_PWRDN_LANE0_VAL(2) | |
180 | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); |
168 | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); |
181 | 169 | ||
182 | /* Enable the PCH Receiver FDI PLL */ |
170 | /* Enable the PCH Receiver FDI PLL */ |
183 | rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | |
171 | rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | |
- | 172 | FDI_RX_PLL_ENABLE | |
|
184 | FDI_RX_PLL_ENABLE | ((intel_crtc->fdi_lanes - 1) << 19); |
173 | FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); |
185 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
174 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
186 | POSTING_READ(_FDI_RXA_CTL); |
175 | POSTING_READ(_FDI_RXA_CTL); |
187 | udelay(220); |
176 | udelay(220); |
188 | 177 | ||
189 | /* Switch from Rawclk to PCDclk */ |
178 | /* Switch from Rawclk to PCDclk */ |
190 | rx_ctl_val |= FDI_PCDCLK; |
179 | rx_ctl_val |= FDI_PCDCLK; |
191 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
180 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
192 | 181 | ||
193 | /* Configure Port Clock Select */ |
182 | /* Configure Port Clock Select */ |
194 | I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->ddi_pll_sel); |
183 | I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->ddi_pll_sel); |
195 | 184 | ||
196 | /* Start the training iterating through available voltages and emphasis, |
185 | /* Start the training iterating through available voltages and emphasis, |
197 | * testing each value twice. */ |
186 | * testing each value twice. */ |
198 | for (i = 0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values) * 2; i++) { |
187 | for (i = 0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values) * 2; i++) { |
199 | /* Configure DP_TP_CTL with auto-training */ |
188 | /* Configure DP_TP_CTL with auto-training */ |
200 | I915_WRITE(DP_TP_CTL(PORT_E), |
189 | I915_WRITE(DP_TP_CTL(PORT_E), |
201 | DP_TP_CTL_FDI_AUTOTRAIN | |
190 | DP_TP_CTL_FDI_AUTOTRAIN | |
202 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
191 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
203 | DP_TP_CTL_LINK_TRAIN_PAT1 | |
192 | DP_TP_CTL_LINK_TRAIN_PAT1 | |
204 | DP_TP_CTL_ENABLE); |
193 | DP_TP_CTL_ENABLE); |
205 | 194 | ||
206 | /* Configure and enable DDI_BUF_CTL for DDI E with next voltage. |
195 | /* Configure and enable DDI_BUF_CTL for DDI E with next voltage. |
207 | * DDI E does not support port reversal, the functionality is |
196 | * DDI E does not support port reversal, the functionality is |
208 | * achieved on the PCH side in FDI_RX_CTL, so no need to set the |
197 | * achieved on the PCH side in FDI_RX_CTL, so no need to set the |
209 | * port reversal bit */ |
198 | * port reversal bit */ |
210 | I915_WRITE(DDI_BUF_CTL(PORT_E), |
199 | I915_WRITE(DDI_BUF_CTL(PORT_E), |
211 | DDI_BUF_CTL_ENABLE | |
200 | DDI_BUF_CTL_ENABLE | |
212 | ((intel_crtc->fdi_lanes - 1) << 1) | |
201 | ((intel_crtc->config.fdi_lanes - 1) << 1) | |
213 | hsw_ddi_buf_ctl_values[i / 2]); |
202 | hsw_ddi_buf_ctl_values[i / 2]); |
214 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
203 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
215 | 204 | ||
216 | udelay(600); |
205 | udelay(600); |
217 | 206 | ||
218 | /* Program PCH FDI Receiver TU */ |
207 | /* Program PCH FDI Receiver TU */ |
219 | I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64)); |
208 | I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64)); |
220 | 209 | ||
221 | /* Enable PCH FDI Receiver with auto-training */ |
210 | /* Enable PCH FDI Receiver with auto-training */ |
222 | rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO; |
211 | rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO; |
223 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
212 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
224 | POSTING_READ(_FDI_RXA_CTL); |
213 | POSTING_READ(_FDI_RXA_CTL); |
225 | 214 | ||
226 | /* Wait for FDI receiver lane calibration */ |
215 | /* Wait for FDI receiver lane calibration */ |
227 | udelay(30); |
216 | udelay(30); |
228 | 217 | ||
229 | /* Unset FDI_RX_MISC pwrdn lanes */ |
218 | /* Unset FDI_RX_MISC pwrdn lanes */ |
230 | temp = I915_READ(_FDI_RXA_MISC); |
219 | temp = I915_READ(_FDI_RXA_MISC); |
231 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
220 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
232 | I915_WRITE(_FDI_RXA_MISC, temp); |
221 | I915_WRITE(_FDI_RXA_MISC, temp); |
233 | POSTING_READ(_FDI_RXA_MISC); |
222 | POSTING_READ(_FDI_RXA_MISC); |
234 | 223 | ||
235 | /* Wait for FDI auto training time */ |
224 | /* Wait for FDI auto training time */ |
236 | udelay(5); |
225 | udelay(5); |
237 | 226 | ||
238 | temp = I915_READ(DP_TP_STATUS(PORT_E)); |
227 | temp = I915_READ(DP_TP_STATUS(PORT_E)); |
239 | if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) { |
228 | if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) { |
240 | DRM_DEBUG_KMS("FDI link training done on step %d\n", i); |
229 | DRM_DEBUG_KMS("FDI link training done on step %d\n", i); |
241 | 230 | ||
242 | /* Enable normal pixel sending for FDI */ |
231 | /* Enable normal pixel sending for FDI */ |
243 | I915_WRITE(DP_TP_CTL(PORT_E), |
232 | I915_WRITE(DP_TP_CTL(PORT_E), |
244 | DP_TP_CTL_FDI_AUTOTRAIN | |
233 | DP_TP_CTL_FDI_AUTOTRAIN | |
245 | DP_TP_CTL_LINK_TRAIN_NORMAL | |
234 | DP_TP_CTL_LINK_TRAIN_NORMAL | |
246 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
235 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
247 | DP_TP_CTL_ENABLE); |
236 | DP_TP_CTL_ENABLE); |
248 | 237 | ||
249 | return; |
238 | return; |
250 | } |
239 | } |
251 | 240 | ||
252 | temp = I915_READ(DDI_BUF_CTL(PORT_E)); |
241 | temp = I915_READ(DDI_BUF_CTL(PORT_E)); |
253 | temp &= ~DDI_BUF_CTL_ENABLE; |
242 | temp &= ~DDI_BUF_CTL_ENABLE; |
254 | I915_WRITE(DDI_BUF_CTL(PORT_E), temp); |
243 | I915_WRITE(DDI_BUF_CTL(PORT_E), temp); |
255 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
244 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
256 | 245 | ||
257 | /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ |
246 | /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ |
258 | temp = I915_READ(DP_TP_CTL(PORT_E)); |
247 | temp = I915_READ(DP_TP_CTL(PORT_E)); |
259 | temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
248 | temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
260 | temp |= DP_TP_CTL_LINK_TRAIN_PAT1; |
249 | temp |= DP_TP_CTL_LINK_TRAIN_PAT1; |
261 | I915_WRITE(DP_TP_CTL(PORT_E), temp); |
250 | I915_WRITE(DP_TP_CTL(PORT_E), temp); |
262 | POSTING_READ(DP_TP_CTL(PORT_E)); |
251 | POSTING_READ(DP_TP_CTL(PORT_E)); |
263 | 252 | ||
264 | intel_wait_ddi_buf_idle(dev_priv, PORT_E); |
253 | intel_wait_ddi_buf_idle(dev_priv, PORT_E); |
265 | 254 | ||
266 | rx_ctl_val &= ~FDI_RX_ENABLE; |
255 | rx_ctl_val &= ~FDI_RX_ENABLE; |
267 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
256 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
268 | POSTING_READ(_FDI_RXA_CTL); |
257 | POSTING_READ(_FDI_RXA_CTL); |
269 | 258 | ||
270 | /* Reset FDI_RX_MISC pwrdn lanes */ |
259 | /* Reset FDI_RX_MISC pwrdn lanes */ |
271 | temp = I915_READ(_FDI_RXA_MISC); |
260 | temp = I915_READ(_FDI_RXA_MISC); |
272 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
261 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
273 | temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
262 | temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
274 | I915_WRITE(_FDI_RXA_MISC, temp); |
263 | I915_WRITE(_FDI_RXA_MISC, temp); |
275 | POSTING_READ(_FDI_RXA_MISC); |
264 | POSTING_READ(_FDI_RXA_MISC); |
276 | } |
265 | } |
277 | 266 | ||
278 | DRM_ERROR("FDI link training failed!\n"); |
267 | DRM_ERROR("FDI link training failed!\n"); |
279 | } |
268 | } |
280 | - | ||
281 | /* WRPLL clock dividers */ |
- | |
282 | struct wrpll_tmds_clock { |
- | |
283 | u32 clock; |
- | |
284 | u16 p; /* Post divider */ |
- | |
285 | u16 n2; /* Feedback divider */ |
- | |
286 | u16 r2; /* Reference divider */ |
- | |
287 | }; |
- | |
288 | - | ||
289 | /* Table of matching values for WRPLL clocks programming for each frequency. |
- | |
290 | * The code assumes this table is sorted. */ |
- | |
291 | static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = { |
- | |
292 | {19750, 38, 25, 18}, |
- | |
293 | {20000, 48, 32, 18}, |
- | |
294 | {21000, 36, 21, 15}, |
- | |
295 | {21912, 42, 29, 17}, |
- | |
296 | {22000, 36, 22, 15}, |
- | |
297 | {23000, 36, 23, 15}, |
- | |
298 | {23500, 40, 40, 23}, |
- | |
299 | {23750, 26, 16, 14}, |
- | |
300 | {24000, 36, 24, 15}, |
- | |
301 | {25000, 36, 25, 15}, |
- | |
302 | {25175, 26, 40, 33}, |
- | |
303 | {25200, 30, 21, 15}, |
- | |
304 | {26000, 36, 26, 15}, |
- | |
305 | {27000, 30, 21, 14}, |
- | |
306 | {27027, 18, 100, 111}, |
- | |
307 | {27500, 30, 29, 19}, |
- | |
308 | {28000, 34, 30, 17}, |
- | |
309 | {28320, 26, 30, 22}, |
- | |
310 | {28322, 32, 42, 25}, |
- | |
311 | {28750, 24, 23, 18}, |
- | |
312 | {29000, 30, 29, 18}, |
- | |
313 | {29750, 32, 30, 17}, |
- | |
314 | {30000, 30, 25, 15}, |
- | |
315 | {30750, 30, 41, 24}, |
- | |
316 | {31000, 30, 31, 18}, |
- | |
317 | {31500, 30, 28, 16}, |
- | |
318 | {32000, 30, 32, 18}, |
- | |
319 | {32500, 28, 32, 19}, |
- | |
320 | {33000, 24, 22, 15}, |
- | |
321 | {34000, 28, 30, 17}, |
- | |
322 | {35000, 26, 32, 19}, |
- | |
323 | {35500, 24, 30, 19}, |
- | |
324 | {36000, 26, 26, 15}, |
- | |
325 | {36750, 26, 46, 26}, |
- | |
326 | {37000, 24, 23, 14}, |
- | |
327 | {37762, 22, 40, 26}, |
- | |
328 | {37800, 20, 21, 15}, |
- | |
329 | {38000, 24, 27, 16}, |
- | |
330 | {38250, 24, 34, 20}, |
- | |
331 | {39000, 24, 26, 15}, |
- | |
332 | {40000, 24, 32, 18}, |
- | |
333 | {40500, 20, 21, 14}, |
- | |
334 | {40541, 22, 147, 89}, |
- | |
335 | {40750, 18, 19, 14}, |
- | |
336 | {41000, 16, 17, 14}, |
- | |
337 | {41500, 22, 44, 26}, |
- | |
338 | {41540, 22, 44, 26}, |
- | |
339 | {42000, 18, 21, 15}, |
- | |
340 | {42500, 22, 45, 26}, |
- | |
341 | {43000, 20, 43, 27}, |
- | |
342 | {43163, 20, 24, 15}, |
- | |
343 | {44000, 18, 22, 15}, |
- | |
344 | {44900, 20, 108, 65}, |
- | |
345 | {45000, 20, 25, 15}, |
- | |
346 | {45250, 20, 52, 31}, |
- | |
347 | {46000, 18, 23, 15}, |
- | |
348 | {46750, 20, 45, 26}, |
- | |
349 | {47000, 20, 40, 23}, |
- | |
350 | {48000, 18, 24, 15}, |
- | |
351 | {49000, 18, 49, 30}, |
- | |
352 | {49500, 16, 22, 15}, |
- | |
353 | {50000, 18, 25, 15}, |
- | |
354 | {50500, 18, 32, 19}, |
- | |
355 | {51000, 18, 34, 20}, |
- | |
356 | {52000, 18, 26, 15}, |
- | |
357 | {52406, 14, 34, 25}, |
- | |
358 | {53000, 16, 22, 14}, |
- | |
359 | {54000, 16, 24, 15}, |
- | |
360 | {54054, 16, 173, 108}, |
- | |
361 | {54500, 14, 24, 17}, |
- | |
362 | {55000, 12, 22, 18}, |
- | |
363 | {56000, 14, 45, 31}, |
- | |
364 | {56250, 16, 25, 15}, |
- | |
365 | {56750, 14, 25, 17}, |
- | |
366 | {57000, 16, 27, 16}, |
- | |
367 | {58000, 16, 43, 25}, |
- | |
368 | {58250, 16, 38, 22}, |
- | |
369 | {58750, 16, 40, 23}, |
- | |
370 | {59000, 14, 26, 17}, |
- | |
371 | {59341, 14, 40, 26}, |
- | |
372 | {59400, 16, 44, 25}, |
- | |
373 | {60000, 16, 32, 18}, |
- | |
374 | {60500, 12, 39, 29}, |
- | |
375 | {61000, 14, 49, 31}, |
- | |
376 | {62000, 14, 37, 23}, |
- | |
377 | {62250, 14, 42, 26}, |
- | |
378 | {63000, 12, 21, 15}, |
- | |
379 | {63500, 14, 28, 17}, |
- | |
380 | {64000, 12, 27, 19}, |
- | |
381 | {65000, 14, 32, 19}, |
- | |
382 | {65250, 12, 29, 20}, |
- | |
383 | {65500, 12, 32, 22}, |
- | |
384 | {66000, 12, 22, 15}, |
- | |
385 | {66667, 14, 38, 22}, |
- | |
386 | {66750, 10, 21, 17}, |
- | |
387 | {67000, 14, 33, 19}, |
- | |
388 | {67750, 14, 58, 33}, |
- | |
389 | {68000, 14, 30, 17}, |
- | |
390 | {68179, 14, 46, 26}, |
- | |
391 | {68250, 14, 46, 26}, |
- | |
392 | {69000, 12, 23, 15}, |
- | |
393 | {70000, 12, 28, 18}, |
- | |
394 | {71000, 12, 30, 19}, |
- | |
395 | {72000, 12, 24, 15}, |
- | |
396 | {73000, 10, 23, 17}, |
- | |
397 | {74000, 12, 23, 14}, |
- | |
398 | {74176, 8, 100, 91}, |
- | |
399 | {74250, 10, 22, 16}, |
- | |
400 | {74481, 12, 43, 26}, |
- | |
401 | {74500, 10, 29, 21}, |
- | |
402 | {75000, 12, 25, 15}, |
- | |
403 | {75250, 10, 39, 28}, |
- | |
404 | {76000, 12, 27, 16}, |
- | |
405 | {77000, 12, 53, 31}, |
- | |
406 | {78000, 12, 26, 15}, |
- | |
407 | {78750, 12, 28, 16}, |
- | |
408 | {79000, 10, 38, 26}, |
- | |
409 | {79500, 10, 28, 19}, |
- | |
410 | {80000, 12, 32, 18}, |
- | |
411 | {81000, 10, 21, 14}, |
- | |
412 | {81081, 6, 100, 111}, |
- | |
413 | {81624, 8, 29, 24}, |
- | |
414 | {82000, 8, 17, 14}, |
- | |
415 | {83000, 10, 40, 26}, |
- | |
416 | {83950, 10, 28, 18}, |
- | |
417 | {84000, 10, 28, 18}, |
- | |
418 | {84750, 6, 16, 17}, |
- | |
419 | {85000, 6, 17, 18}, |
- | |
420 | {85250, 10, 30, 19}, |
- | |
421 | {85750, 10, 27, 17}, |
- | |
422 | {86000, 10, 43, 27}, |
- | |
423 | {87000, 10, 29, 18}, |
- | |
424 | {88000, 10, 44, 27}, |
- | |
425 | {88500, 10, 41, 25}, |
- | |
426 | {89000, 10, 28, 17}, |
- | |
427 | {89012, 6, 90, 91}, |
- | |
428 | {89100, 10, 33, 20}, |
- | |
429 | {90000, 10, 25, 15}, |
- | |
430 | {91000, 10, 32, 19}, |
- | |
431 | {92000, 10, 46, 27}, |
- | |
432 | {93000, 10, 31, 18}, |
- | |
433 | {94000, 10, 40, 23}, |
- | |
434 | {94500, 10, 28, 16}, |
- | |
435 | {95000, 10, 44, 25}, |
- | |
436 | {95654, 10, 39, 22}, |
- | |
437 | {95750, 10, 39, 22}, |
- | |
438 | {96000, 10, 32, 18}, |
- | |
439 | {97000, 8, 23, 16}, |
- | |
440 | {97750, 8, 42, 29}, |
- | |
441 | {98000, 8, 45, 31}, |
- | |
442 | {99000, 8, 22, 15}, |
- | |
443 | {99750, 8, 34, 23}, |
- | |
444 | {100000, 6, 20, 18}, |
- | |
445 | {100500, 6, 19, 17}, |
- | |
446 | {101000, 6, 37, 33}, |
- | |
447 | {101250, 8, 21, 14}, |
- | |
448 | {102000, 6, 17, 15}, |
- | |
449 | {102250, 6, 25, 22}, |
- | |
450 | {103000, 8, 29, 19}, |
- | |
451 | {104000, 8, 37, 24}, |
- | |
452 | {105000, 8, 28, 18}, |
- | |
453 | {106000, 8, 22, 14}, |
- | |
454 | {107000, 8, 46, 29}, |
- | |
455 | {107214, 8, 27, 17}, |
- | |
456 | {108000, 8, 24, 15}, |
- | |
457 | {108108, 8, 173, 108}, |
- | |
458 | {109000, 6, 23, 19}, |
- | |
459 | {110000, 6, 22, 18}, |
- | |
460 | {110013, 6, 22, 18}, |
- | |
461 | {110250, 8, 49, 30}, |
- | |
462 | {110500, 8, 36, 22}, |
- | |
463 | {111000, 8, 23, 14}, |
- | |
464 | {111264, 8, 150, 91}, |
- | |
465 | {111375, 8, 33, 20}, |
- | |
466 | {112000, 8, 63, 38}, |
- | |
467 | {112500, 8, 25, 15}, |
- | |
468 | {113100, 8, 57, 34}, |
- | |
469 | {113309, 8, 42, 25}, |
- | |
470 | {114000, 8, 27, 16}, |
- | |
471 | {115000, 6, 23, 18}, |
- | |
472 | {116000, 8, 43, 25}, |
- | |
473 | {117000, 8, 26, 15}, |
- | |
474 | {117500, 8, 40, 23}, |
- | |
475 | {118000, 6, 38, 29}, |
- | |
476 | {119000, 8, 30, 17}, |
- | |
477 | {119500, 8, 46, 26}, |
- | |
478 | {119651, 8, 39, 22}, |
- | |
479 | {120000, 8, 32, 18}, |
- | |
480 | {121000, 6, 39, 29}, |
- | |
481 | {121250, 6, 31, 23}, |
- | |
482 | {121750, 6, 23, 17}, |
- | |
483 | {122000, 6, 42, 31}, |
- | |
484 | {122614, 6, 30, 22}, |
- | |
485 | {123000, 6, 41, 30}, |
- | |
486 | {123379, 6, 37, 27}, |
- | |
487 | {124000, 6, 51, 37}, |
- | |
488 | {125000, 6, 25, 18}, |
- | |
489 | {125250, 4, 13, 14}, |
- | |
490 | {125750, 4, 27, 29}, |
- | |
491 | {126000, 6, 21, 15}, |
- | |
492 | {127000, 6, 24, 17}, |
- | |
493 | {127250, 6, 41, 29}, |
- | |
494 | {128000, 6, 27, 19}, |
- | |
495 | {129000, 6, 43, 30}, |
- | |
496 | {129859, 4, 25, 26}, |
- | |
497 | {130000, 6, 26, 18}, |
- | |
498 | {130250, 6, 42, 29}, |
- | |
499 | {131000, 6, 32, 22}, |
- | |
500 | {131500, 6, 38, 26}, |
- | |
501 | {131850, 6, 41, 28}, |
- | |
502 | {132000, 6, 22, 15}, |
- | |
503 | {132750, 6, 28, 19}, |
- | |
504 | {133000, 6, 34, 23}, |
- | |
505 | {133330, 6, 37, 25}, |
- | |
506 | {134000, 6, 61, 41}, |
- | |
507 | {135000, 6, 21, 14}, |
- | |
508 | {135250, 6, 167, 111}, |
- | |
509 | {136000, 6, 62, 41}, |
- | |
510 | {137000, 6, 35, 23}, |
- | |
511 | {138000, 6, 23, 15}, |
- | |
512 | {138500, 6, 40, 26}, |
- | |
513 | {138750, 6, 37, 24}, |
- | |
514 | {139000, 6, 34, 22}, |
- | |
515 | {139050, 6, 34, 22}, |
- | |
516 | {139054, 6, 34, 22}, |
- | |
517 | {140000, 6, 28, 18}, |
- | |
518 | {141000, 6, 36, 23}, |
- | |
519 | {141500, 6, 22, 14}, |
- | |
520 | {142000, 6, 30, 19}, |
- | |
521 | {143000, 6, 27, 17}, |
- | |
522 | {143472, 4, 17, 16}, |
- | |
523 | {144000, 6, 24, 15}, |
- | |
524 | {145000, 6, 29, 18}, |
- | |
525 | {146000, 6, 47, 29}, |
- | |
526 | {146250, 6, 26, 16}, |
- | |
527 | {147000, 6, 49, 30}, |
- | |
528 | {147891, 6, 23, 14}, |
- | |
529 | {148000, 6, 23, 14}, |
- | |
530 | {148250, 6, 28, 17}, |
- | |
531 | {148352, 4, 100, 91}, |
- | |
532 | {148500, 6, 33, 20}, |
- | |
533 | {149000, 6, 48, 29}, |
- | |
534 | {150000, 6, 25, 15}, |
- | |
535 | {151000, 4, 19, 17}, |
- | |
536 | {152000, 6, 27, 16}, |
- | |
537 | {152280, 6, 44, 26}, |
- | |
538 | {153000, 6, 34, 20}, |
- | |
539 | {154000, 6, 53, 31}, |
- | |
540 | {155000, 6, 31, 18}, |
- | |
541 | {155250, 6, 50, 29}, |
- | |
542 | {155750, 6, 45, 26}, |
- | |
543 | {156000, 6, 26, 15}, |
- | |
544 | {157000, 6, 61, 35}, |
- | |
545 | {157500, 6, 28, 16}, |
- | |
546 | {158000, 6, 65, 37}, |
- | |
547 | {158250, 6, 44, 25}, |
- | |
548 | {159000, 6, 53, 30}, |
- | |
549 | {159500, 6, 39, 22}, |
- | |
550 | {160000, 6, 32, 18}, |
- | |
551 | {161000, 4, 31, 26}, |
- | |
552 | {162000, 4, 18, 15}, |
- | |
553 | {162162, 4, 131, 109}, |
- | |
554 | {162500, 4, 53, 44}, |
- | |
555 | {163000, 4, 29, 24}, |
- | |
556 | {164000, 4, 17, 14}, |
- | |
557 | {165000, 4, 22, 18}, |
- | |
558 | {166000, 4, 32, 26}, |
- | |
559 | {167000, 4, 26, 21}, |
- | |
560 | {168000, 4, 46, 37}, |
- | |
561 | {169000, 4, 104, 83}, |
- | |
562 | {169128, 4, 64, 51}, |
- | |
563 | {169500, 4, 39, 31}, |
- | |
564 | {170000, 4, 34, 27}, |
- | |
565 | {171000, 4, 19, 15}, |
- | |
566 | {172000, 4, 51, 40}, |
- | |
567 | {172750, 4, 32, 25}, |
- | |
568 | {172800, 4, 32, 25}, |
- | |
569 | {173000, 4, 41, 32}, |
- | |
570 | {174000, 4, 49, 38}, |
- | |
571 | {174787, 4, 22, 17}, |
- | |
572 | {175000, 4, 35, 27}, |
- | |
573 | {176000, 4, 30, 23}, |
- | |
574 | {177000, 4, 38, 29}, |
- | |
575 | {178000, 4, 29, 22}, |
- | |
576 | {178500, 4, 37, 28}, |
- | |
577 | {179000, 4, 53, 40}, |
- | |
578 | {179500, 4, 73, 55}, |
- | |
579 | {180000, 4, 20, 15}, |
- | |
580 | {181000, 4, 55, 41}, |
- | |
581 | {182000, 4, 31, 23}, |
- | |
582 | {183000, 4, 42, 31}, |
- | |
583 | {184000, 4, 30, 22}, |
- | |
584 | {184750, 4, 26, 19}, |
- | |
585 | {185000, 4, 37, 27}, |
- | |
586 | {186000, 4, 51, 37}, |
- | |
587 | {187000, 4, 36, 26}, |
- | |
588 | {188000, 4, 32, 23}, |
- | |
589 | {189000, 4, 21, 15}, |
- | |
590 | {190000, 4, 38, 27}, |
- | |
591 | {190960, 4, 41, 29}, |
- | |
592 | {191000, 4, 41, 29}, |
- | |
593 | {192000, 4, 27, 19}, |
- | |
594 | {192250, 4, 37, 26}, |
- | |
595 | {193000, 4, 20, 14}, |
- | |
596 | {193250, 4, 53, 37}, |
- | |
597 | {194000, 4, 23, 16}, |
- | |
598 | {194208, 4, 23, 16}, |
- | |
599 | {195000, 4, 26, 18}, |
- | |
600 | {196000, 4, 45, 31}, |
- | |
601 | {197000, 4, 35, 24}, |
- | |
602 | {197750, 4, 41, 28}, |
- | |
603 | {198000, 4, 22, 15}, |
- | |
604 | {198500, 4, 25, 17}, |
- | |
605 | {199000, 4, 28, 19}, |
- | |
606 | {200000, 4, 37, 25}, |
- | |
607 | {201000, 4, 61, 41}, |
- | |
608 | {202000, 4, 112, 75}, |
- | |
609 | {202500, 4, 21, 14}, |
- | |
610 | {203000, 4, 146, 97}, |
- | |
611 | {204000, 4, 62, 41}, |
- | |
612 | {204750, 4, 44, 29}, |
- | |
613 | {205000, 4, 38, 25}, |
- | |
614 | {206000, 4, 29, 19}, |
- | |
615 | {207000, 4, 23, 15}, |
- | |
616 | {207500, 4, 40, 26}, |
- | |
617 | {208000, 4, 37, 24}, |
- | |
618 | {208900, 4, 48, 31}, |
- | |
619 | {209000, 4, 48, 31}, |
- | |
620 | {209250, 4, 31, 20}, |
- | |
621 | {210000, 4, 28, 18}, |
- | |
622 | {211000, 4, 25, 16}, |
- | |
623 | {212000, 4, 22, 14}, |
- | |
624 | {213000, 4, 30, 19}, |
- | |
625 | {213750, 4, 38, 24}, |
- | |
626 | {214000, 4, 46, 29}, |
- | |
627 | {214750, 4, 35, 22}, |
- | |
628 | {215000, 4, 43, 27}, |
- | |
629 | {216000, 4, 24, 15}, |
- | |
630 | {217000, 4, 37, 23}, |
- | |
631 | {218000, 4, 42, 26}, |
- | |
632 | {218250, 4, 42, 26}, |
- | |
633 | {218750, 4, 34, 21}, |
- | |
634 | {219000, 4, 47, 29}, |
- | |
635 | {220000, 4, 44, 27}, |
- | |
636 | {220640, 4, 49, 30}, |
- | |
637 | {220750, 4, 36, 22}, |
- | |
638 | {221000, 4, 36, 22}, |
- | |
639 | {222000, 4, 23, 14}, |
- | |
640 | {222525, 4, 28, 17}, |
- | |
641 | {222750, 4, 33, 20}, |
- | |
642 | {227000, 4, 37, 22}, |
- | |
643 | {230250, 4, 29, 17}, |
- | |
644 | {233500, 4, 38, 22}, |
- | |
645 | {235000, 4, 40, 23}, |
- | |
646 | {238000, 4, 30, 17}, |
- | |
647 | {241500, 2, 17, 19}, |
- | |
648 | {245250, 2, 20, 22}, |
- | |
649 | {247750, 2, 22, 24}, |
- | |
650 | {253250, 2, 15, 16}, |
- | |
651 | {256250, 2, 18, 19}, |
- | |
652 | {262500, 2, 31, 32}, |
- | |
653 | {267250, 2, 66, 67}, |
- | |
654 | {268500, 2, 94, 95}, |
- | |
655 | {270000, 2, 14, 14}, |
- | |
656 | {272500, 2, 77, 76}, |
- | |
657 | {273750, 2, 57, 56}, |
- | |
658 | {280750, 2, 24, 23}, |
- | |
659 | {281250, 2, 23, 22}, |
- | |
660 | {286000, 2, 17, 16}, |
- | |
661 | {291750, 2, 26, 24}, |
- | |
662 | {296703, 2, 56, 51}, |
- | |
663 | {297000, 2, 22, 20}, |
- | |
664 | {298000, 2, 21, 19}, |
- | |
665 | }; |
- | |
666 | 269 | ||
667 | static void intel_ddi_mode_set(struct drm_encoder *encoder, |
- | |
668 | struct drm_display_mode *mode, |
- | |
669 | struct drm_display_mode *adjusted_mode) |
270 | static void intel_ddi_mode_set(struct intel_encoder *encoder) |
670 | { |
- | |
671 | struct drm_crtc *crtc = encoder->crtc; |
271 | { |
672 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
673 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
272 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
674 | int port = intel_ddi_get_encoder_port(intel_encoder); |
273 | int port = intel_ddi_get_encoder_port(encoder); |
675 | int pipe = intel_crtc->pipe; |
274 | int pipe = crtc->pipe; |
- | 275 | int type = encoder->type; |
|
676 | int type = intel_encoder->type; |
276 | struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; |
677 | 277 | ||
678 | DRM_DEBUG_KMS("Preparing DDI mode for Haswell on port %c, pipe %c\n", |
278 | DRM_DEBUG_KMS("Preparing DDI mode on port %c, pipe %c\n", |
679 | port_name(port), pipe_name(pipe)); |
279 | port_name(port), pipe_name(pipe)); |
680 | 280 | ||
681 | intel_crtc->eld_vld = false; |
281 | crtc->eld_vld = false; |
682 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
282 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
683 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
283 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
684 | struct intel_digital_port *intel_dig_port = |
284 | struct intel_digital_port *intel_dig_port = |
685 | enc_to_dig_port(encoder); |
- | |
686 | - | ||
687 | intel_dp->DP = intel_dig_port->port_reversal | |
285 | enc_to_dig_port(&encoder->base); |
688 | DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; |
- | |
689 | switch (intel_dp->lane_count) { |
- | |
690 | case 1: |
- | |
691 | intel_dp->DP |= DDI_PORT_WIDTH_X1; |
- | |
692 | break; |
- | |
693 | case 2: |
- | |
694 | intel_dp->DP |= DDI_PORT_WIDTH_X2; |
- | |
695 | break; |
- | |
696 | case 4: |
- | |
697 | intel_dp->DP |= DDI_PORT_WIDTH_X4; |
- | |
698 | break; |
- | |
699 | default: |
- | |
700 | intel_dp->DP |= DDI_PORT_WIDTH_X4; |
- | |
701 | WARN(1, "Unexpected DP lane count %d\n", |
286 | |
702 | intel_dp->lane_count); |
287 | intel_dp->DP = intel_dig_port->saved_port_bits | |
703 | break; |
288 | DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; |
704 | } |
289 | intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); |
705 | 290 | ||
706 | if (intel_dp->has_audio) { |
291 | if (intel_dp->has_audio) { |
707 | DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n", |
292 | DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n", |
708 | pipe_name(intel_crtc->pipe)); |
293 | pipe_name(crtc->pipe)); |
709 | 294 | ||
710 | /* write eld */ |
295 | /* write eld */ |
711 | DRM_DEBUG_DRIVER("DP audio: write eld information\n"); |
296 | DRM_DEBUG_DRIVER("DP audio: write eld information\n"); |
712 | intel_write_eld(encoder, adjusted_mode); |
297 | intel_write_eld(&encoder->base, adjusted_mode); |
713 | } |
298 | } |
714 | 299 | ||
715 | intel_dp_init_link_config(intel_dp); |
300 | intel_dp_init_link_config(intel_dp); |
716 | 301 | ||
717 | } else if (type == INTEL_OUTPUT_HDMI) { |
302 | } else if (type == INTEL_OUTPUT_HDMI) { |
718 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
303 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
719 | 304 | ||
720 | if (intel_hdmi->has_audio) { |
305 | if (intel_hdmi->has_audio) { |
721 | /* Proper support for digital audio needs a new logic |
306 | /* Proper support for digital audio needs a new logic |
722 | * and a new set of registers, so we leave it for future |
307 | * and a new set of registers, so we leave it for future |
723 | * patch bombing. |
308 | * patch bombing. |
724 | */ |
309 | */ |
725 | DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n", |
310 | DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n", |
726 | pipe_name(intel_crtc->pipe)); |
311 | pipe_name(crtc->pipe)); |
727 | 312 | ||
728 | /* write eld */ |
313 | /* write eld */ |
729 | DRM_DEBUG_DRIVER("HDMI audio: write eld information\n"); |
314 | DRM_DEBUG_DRIVER("HDMI audio: write eld information\n"); |
730 | intel_write_eld(encoder, adjusted_mode); |
315 | intel_write_eld(&encoder->base, adjusted_mode); |
731 | } |
316 | } |
732 | 317 | ||
733 | intel_hdmi->set_infoframes(encoder, adjusted_mode); |
318 | intel_hdmi->set_infoframes(&encoder->base, adjusted_mode); |
734 | } |
319 | } |
735 | } |
320 | } |
736 | 321 | ||
737 | static struct intel_encoder * |
322 | static struct intel_encoder * |
738 | intel_ddi_get_crtc_encoder(struct drm_crtc *crtc) |
323 | intel_ddi_get_crtc_encoder(struct drm_crtc *crtc) |
739 | { |
324 | { |
740 | struct drm_device *dev = crtc->dev; |
325 | struct drm_device *dev = crtc->dev; |
741 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
326 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
742 | struct intel_encoder *intel_encoder, *ret = NULL; |
327 | struct intel_encoder *intel_encoder, *ret = NULL; |
743 | int num_encoders = 0; |
328 | int num_encoders = 0; |
744 | 329 | ||
745 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
330 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
746 | ret = intel_encoder; |
331 | ret = intel_encoder; |
747 | num_encoders++; |
332 | num_encoders++; |
748 | } |
333 | } |
749 | 334 | ||
750 | if (num_encoders != 1) |
335 | if (num_encoders != 1) |
751 | WARN(1, "%d encoders on crtc for pipe %d\n", num_encoders, |
336 | WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders, |
752 | intel_crtc->pipe); |
337 | pipe_name(intel_crtc->pipe)); |
753 | 338 | ||
754 | BUG_ON(ret == NULL); |
339 | BUG_ON(ret == NULL); |
755 | return ret; |
340 | return ret; |
756 | } |
341 | } |
757 | 342 | ||
758 | void intel_ddi_put_crtc_pll(struct drm_crtc *crtc) |
343 | void intel_ddi_put_crtc_pll(struct drm_crtc *crtc) |
759 | { |
344 | { |
760 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
345 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
761 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
346 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
762 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
347 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
763 | uint32_t val; |
348 | uint32_t val; |
764 | 349 | ||
765 | switch (intel_crtc->ddi_pll_sel) { |
350 | switch (intel_crtc->ddi_pll_sel) { |
766 | case PORT_CLK_SEL_SPLL: |
351 | case PORT_CLK_SEL_SPLL: |
767 | plls->spll_refcount--; |
352 | plls->spll_refcount--; |
768 | if (plls->spll_refcount == 0) { |
353 | if (plls->spll_refcount == 0) { |
769 | DRM_DEBUG_KMS("Disabling SPLL\n"); |
354 | DRM_DEBUG_KMS("Disabling SPLL\n"); |
770 | val = I915_READ(SPLL_CTL); |
355 | val = I915_READ(SPLL_CTL); |
771 | WARN_ON(!(val & SPLL_PLL_ENABLE)); |
356 | WARN_ON(!(val & SPLL_PLL_ENABLE)); |
772 | I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE); |
357 | I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE); |
773 | POSTING_READ(SPLL_CTL); |
358 | POSTING_READ(SPLL_CTL); |
774 | } |
359 | } |
775 | break; |
360 | break; |
776 | case PORT_CLK_SEL_WRPLL1: |
361 | case PORT_CLK_SEL_WRPLL1: |
777 | plls->wrpll1_refcount--; |
362 | plls->wrpll1_refcount--; |
778 | if (plls->wrpll1_refcount == 0) { |
363 | if (plls->wrpll1_refcount == 0) { |
779 | DRM_DEBUG_KMS("Disabling WRPLL 1\n"); |
364 | DRM_DEBUG_KMS("Disabling WRPLL 1\n"); |
780 | val = I915_READ(WRPLL_CTL1); |
365 | val = I915_READ(WRPLL_CTL1); |
781 | WARN_ON(!(val & WRPLL_PLL_ENABLE)); |
366 | WARN_ON(!(val & WRPLL_PLL_ENABLE)); |
782 | I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE); |
367 | I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE); |
783 | POSTING_READ(WRPLL_CTL1); |
368 | POSTING_READ(WRPLL_CTL1); |
784 | } |
369 | } |
785 | break; |
370 | break; |
786 | case PORT_CLK_SEL_WRPLL2: |
371 | case PORT_CLK_SEL_WRPLL2: |
787 | plls->wrpll2_refcount--; |
372 | plls->wrpll2_refcount--; |
788 | if (plls->wrpll2_refcount == 0) { |
373 | if (plls->wrpll2_refcount == 0) { |
789 | DRM_DEBUG_KMS("Disabling WRPLL 2\n"); |
374 | DRM_DEBUG_KMS("Disabling WRPLL 2\n"); |
790 | val = I915_READ(WRPLL_CTL2); |
375 | val = I915_READ(WRPLL_CTL2); |
791 | WARN_ON(!(val & WRPLL_PLL_ENABLE)); |
376 | WARN_ON(!(val & WRPLL_PLL_ENABLE)); |
792 | I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE); |
377 | I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE); |
793 | POSTING_READ(WRPLL_CTL2); |
378 | POSTING_READ(WRPLL_CTL2); |
794 | } |
379 | } |
795 | break; |
380 | break; |
796 | } |
381 | } |
797 | 382 | ||
798 | WARN(plls->spll_refcount < 0, "Invalid SPLL refcount\n"); |
383 | WARN(plls->spll_refcount < 0, "Invalid SPLL refcount\n"); |
799 | WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n"); |
384 | WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n"); |
800 | WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n"); |
385 | WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n"); |
801 | 386 | ||
802 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE; |
387 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE; |
803 | } |
388 | } |
- | 389 | ||
- | 390 | #define LC_FREQ 2700 |
|
- | 391 | #define LC_FREQ_2K (LC_FREQ * 2000) |
|
- | 392 | ||
- | 393 | #define P_MIN 2 |
|
- | 394 | #define P_MAX 64 |
|
- | 395 | #define P_INC 2 |
|
- | 396 | ||
- | 397 | /* Constraints for PLL good behavior */ |
|
- | 398 | #define REF_MIN 48 |
|
- | 399 | #define REF_MAX 400 |
|
- | 400 | #define VCO_MIN 2400 |
|
- | 401 | #define VCO_MAX 4800 |
|
- | 402 | ||
- | 403 | #define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a)) |
|
- | 404 | ||
- | 405 | struct wrpll_rnp { |
|
- | 406 | unsigned p, n2, r2; |
|
- | 407 | }; |
|
804 | 408 | ||
805 | static void intel_ddi_calculate_wrpll(int clock, int *p, int *n2, int *r2) |
409 | static unsigned wrpll_get_budget_for_freq(int clock) |
806 | { |
410 | { |
807 | u32 i; |
411 | unsigned budget; |
- | 412 | ||
- | 413 | switch (clock) { |
|
- | 414 | case 25175000: |
|
- | 415 | case 25200000: |
|
- | 416 | case 27000000: |
|
- | 417 | case 27027000: |
|
- | 418 | case 37762500: |
|
- | 419 | case 37800000: |
|
- | 420 | case 40500000: |
|
- | 421 | case 40541000: |
|
- | 422 | case 54000000: |
|
- | 423 | case 54054000: |
|
- | 424 | case 59341000: |
|
- | 425 | case 59400000: |
|
- | 426 | case 72000000: |
|
- | 427 | case 74176000: |
|
- | 428 | case 74250000: |
|
- | 429 | case 81000000: |
|
- | 430 | case 81081000: |
|
- | 431 | case 89012000: |
|
- | 432 | case 89100000: |
|
- | 433 | case 108000000: |
|
- | 434 | case 108108000: |
|
- | 435 | case 111264000: |
|
- | 436 | case 111375000: |
|
- | 437 | case 148352000: |
|
- | 438 | case 148500000: |
|
- | 439 | case 162000000: |
|
- | 440 | case 162162000: |
|
- | 441 | case 222525000: |
|
- | 442 | case 222750000: |
|
- | 443 | case 296703000: |
|
- | 444 | case 297000000: |
|
- | 445 | budget = 0; |
|
- | 446 | break; |
|
- | 447 | case 233500000: |
|
- | 448 | case 245250000: |
|
- | 449 | case 247750000: |
|
- | 450 | case 253250000: |
|
- | 451 | case 298000000: |
|
- | 452 | budget = 1500; |
|
- | 453 | break; |
|
- | 454 | case 169128000: |
|
- | 455 | case 169500000: |
|
- | 456 | case 179500000: |
|
- | 457 | case 202000000: |
|
- | 458 | budget = 2000; |
|
- | 459 | break; |
|
- | 460 | case 256250000: |
|
- | 461 | case 262500000: |
|
- | 462 | case 270000000: |
|
- | 463 | case 272500000: |
|
- | 464 | case 273750000: |
|
- | 465 | case 280750000: |
|
- | 466 | case 281250000: |
|
- | 467 | case 286000000: |
|
- | 468 | case 291750000: |
|
- | 469 | budget = 4000; |
|
- | 470 | break; |
|
- | 471 | case 267250000: |
|
- | 472 | case 268500000: |
|
- | 473 | budget = 5000; |
|
808 | 474 | break; |
|
809 | for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) |
475 | default: |
- | 476 | budget = 1000; |
|
810 | if (clock <= wrpll_tmds_clock_table[i].clock) |
477 | break; |
811 | break; |
478 | } |
- | 479 | ||
812 | 480 | return budget; |
|
813 | if (i == ARRAY_SIZE(wrpll_tmds_clock_table)) |
481 | } |
- | 482 | ||
814 | i--; |
483 | static void wrpll_update_rnp(uint64_t freq2k, unsigned budget, |
815 | 484 | unsigned r2, unsigned n2, unsigned p, |
|
816 | *p = wrpll_tmds_clock_table[i].p; |
485 | struct wrpll_rnp *best) |
- | 486 | { |
|
- | 487 | uint64_t a, b, c, d, diff, diff_best; |
|
817 | *n2 = wrpll_tmds_clock_table[i].n2; |
488 | |
- | 489 | /* No best (r,n,p) yet */ |
|
- | 490 | if (best->p == 0) { |
|
- | 491 | best->p = p; |
|
- | 492 | best->n2 = n2; |
|
- | 493 | best->r2 = r2; |
|
- | 494 | return; |
|
- | 495 | } |
|
- | 496 | ||
- | 497 | /* |
|
- | 498 | * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to |
|
- | 499 | * freq2k. |
|
- | 500 | * |
|
- | 501 | * delta = 1e6 * |
|
- | 502 | * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) / |
|
- | 503 | * freq2k; |
|
- | 504 | * |
|
- | 505 | * and we would like delta <= budget. |
|
- | 506 | * |
|
- | 507 | * If the discrepancy is above the PPM-based budget, always prefer to |
|
- | 508 | * improve upon the previous solution. However, if you're within the |
|
- | 509 | * budget, try to maximize Ref * VCO, that is N / (P * R^2). |
|
- | 510 | */ |
|
- | 511 | a = freq2k * budget * p * r2; |
|
- | 512 | b = freq2k * budget * best->p * best->r2; |
|
- | 513 | diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2)); |
|
- | 514 | diff_best = ABS_DIFF((freq2k * best->p * best->r2), |
|
- | 515 | (LC_FREQ_2K * best->n2)); |
|
- | 516 | c = 1000000 * diff; |
|
- | 517 | d = 1000000 * diff_best; |
|
- | 518 | ||
- | 519 | if (a < c && b < d) { |
|
- | 520 | /* If both are above the budget, pick the closer */ |
|
- | 521 | if (best->p * best->r2 * diff < p * r2 * diff_best) { |
|
- | 522 | best->p = p; |
|
- | 523 | best->n2 = n2; |
|
- | 524 | best->r2 = r2; |
|
- | 525 | } |
|
818 | *r2 = wrpll_tmds_clock_table[i].r2; |
526 | } else if (a >= c && b < d) { |
- | 527 | /* If A is below the threshold but B is above it? Update. */ |
|
- | 528 | best->p = p; |
|
- | 529 | best->n2 = n2; |
|
- | 530 | best->r2 = r2; |
|
- | 531 | } else if (a >= c && b >= d) { |
|
- | 532 | /* Both are below the limit, so pick the higher n2/(r2*r2) */ |
|
- | 533 | if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) { |
|
- | 534 | best->p = p; |
|
- | 535 | best->n2 = n2; |
|
- | 536 | best->r2 = r2; |
|
- | 537 | } |
|
- | 538 | } |
|
- | 539 | /* Otherwise a < c && b >= d, do nothing */ |
|
- | 540 | } |
|
819 | 541 | ||
- | 542 | static void |
|
- | 543 | intel_ddi_calculate_wrpll(int clock /* in Hz */, |
|
- | 544 | unsigned *r2_out, unsigned *n2_out, unsigned *p_out) |
|
- | 545 | { |
|
- | 546 | uint64_t freq2k; |
|
- | 547 | unsigned p, n2, r2; |
|
- | 548 | struct wrpll_rnp best = { 0, 0, 0 }; |
|
- | 549 | unsigned budget; |
|
- | 550 | ||
- | 551 | freq2k = clock / 100; |
|
- | 552 | ||
- | 553 | budget = wrpll_get_budget_for_freq(clock); |
|
- | 554 | ||
- | 555 | /* Special case handling for 540 pixel clock: bypass WR PLL entirely |
|
820 | if (wrpll_tmds_clock_table[i].clock != clock) |
556 | * and directly pass the LC PLL to it. */ |
- | 557 | if (freq2k == 5400000) { |
|
- | 558 | *n2_out = 2; |
|
- | 559 | *p_out = 1; |
|
- | 560 | *r2_out = 2; |
|
- | 561 | return; |
|
- | 562 | } |
|
- | 563 | ||
- | 564 | /* |
|
- | 565 | * Ref = LC_FREQ / R, where Ref is the actual reference input seen by |
|
- | 566 | * the WR PLL. |
|
- | 567 | * |
|
- | 568 | * We want R so that REF_MIN <= Ref <= REF_MAX. |
|
- | 569 | * Injecting R2 = 2 * R gives: |
|
- | 570 | * REF_MAX * r2 > LC_FREQ * 2 and |
|
- | 571 | * REF_MIN * r2 < LC_FREQ * 2 |
|
- | 572 | * |
|
- | 573 | * Which means the desired boundaries for r2 are: |
|
- | 574 | * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN |
|
- | 575 | * |
|
- | 576 | */ |
|
- | 577 | for (r2 = LC_FREQ * 2 / REF_MAX + 1; |
|
- | 578 | r2 <= LC_FREQ * 2 / REF_MIN; |
|
- | 579 | r2++) { |
|
- | 580 | ||
- | 581 | /* |
|
- | 582 | * VCO = N * Ref, that is: VCO = N * LC_FREQ / R |
|
- | 583 | * |
|
- | 584 | * Once again we want VCO_MIN <= VCO <= VCO_MAX. |
|
- | 585 | * Injecting R2 = 2 * R and N2 = 2 * N, we get: |
|
- | 586 | * VCO_MAX * r2 > n2 * LC_FREQ and |
|
- | 587 | * VCO_MIN * r2 < n2 * LC_FREQ) |
|
- | 588 | * |
|
- | 589 | * Which means the desired boundaries for n2 are: |
|
- | 590 | * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ |
|
- | 591 | */ |
|
- | 592 | for (n2 = VCO_MIN * r2 / LC_FREQ + 1; |
|
- | 593 | n2 <= VCO_MAX * r2 / LC_FREQ; |
|
- | 594 | n2++) { |
|
- | 595 | ||
- | 596 | for (p = P_MIN; p <= P_MAX; p += P_INC) |
|
- | 597 | wrpll_update_rnp(freq2k, budget, |
|
- | 598 | r2, n2, p, &best); |
|
- | 599 | } |
|
- | 600 | } |
|
- | 601 | ||
- | 602 | *n2_out = best.n2; |
|
821 | DRM_INFO("WRPLL: using settings for %dKHz on %dKHz mode\n", |
603 | *p_out = best.p; |
822 | wrpll_tmds_clock_table[i].clock, clock); |
604 | *r2_out = best.r2; |
823 | 605 | ||
824 | DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n", |
606 | DRM_DEBUG_KMS("WRPLL: %dHz refresh rate with p=%d, n2=%d r2=%d\n", |
825 | clock, *p, *n2, *r2); |
607 | clock, *p_out, *n2_out, *r2_out); |
826 | } |
608 | } |
827 | 609 | ||
828 | bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock) |
610 | bool intel_ddi_pll_mode_set(struct drm_crtc *crtc) |
829 | { |
611 | { |
830 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
612 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
831 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
613 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
832 | struct drm_encoder *encoder = &intel_encoder->base; |
614 | struct drm_encoder *encoder = &intel_encoder->base; |
833 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
615 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
834 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
616 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
835 | int type = intel_encoder->type; |
617 | int type = intel_encoder->type; |
836 | enum pipe pipe = intel_crtc->pipe; |
618 | enum pipe pipe = intel_crtc->pipe; |
837 | uint32_t reg, val; |
619 | uint32_t reg, val; |
- | 620 | int clock = intel_crtc->config.port_clock; |
|
838 | 621 | ||
839 | /* TODO: reuse PLLs when possible (compare values) */ |
622 | /* TODO: reuse PLLs when possible (compare values) */ |
840 | 623 | ||
841 | intel_ddi_put_crtc_pll(crtc); |
624 | intel_ddi_put_crtc_pll(crtc); |
842 | 625 | ||
843 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
626 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
844 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
627 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
845 | 628 | ||
846 | switch (intel_dp->link_bw) { |
629 | switch (intel_dp->link_bw) { |
847 | case DP_LINK_BW_1_62: |
630 | case DP_LINK_BW_1_62: |
848 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810; |
631 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810; |
849 | break; |
632 | break; |
850 | case DP_LINK_BW_2_7: |
633 | case DP_LINK_BW_2_7: |
851 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350; |
634 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350; |
852 | break; |
635 | break; |
853 | case DP_LINK_BW_5_4: |
636 | case DP_LINK_BW_5_4: |
854 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700; |
637 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700; |
855 | break; |
638 | break; |
856 | default: |
639 | default: |
857 | DRM_ERROR("Link bandwidth %d unsupported\n", |
640 | DRM_ERROR("Link bandwidth %d unsupported\n", |
858 | intel_dp->link_bw); |
641 | intel_dp->link_bw); |
859 | return false; |
642 | return false; |
860 | } |
643 | } |
861 | 644 | ||
862 | /* We don't need to turn any PLL on because we'll use LCPLL. */ |
645 | /* We don't need to turn any PLL on because we'll use LCPLL. */ |
863 | return true; |
646 | return true; |
864 | 647 | ||
865 | } else if (type == INTEL_OUTPUT_HDMI) { |
648 | } else if (type == INTEL_OUTPUT_HDMI) { |
866 | int p, n2, r2; |
649 | unsigned p, n2, r2; |
867 | 650 | ||
868 | if (plls->wrpll1_refcount == 0) { |
651 | if (plls->wrpll1_refcount == 0) { |
869 | DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n", |
652 | DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n", |
870 | pipe_name(pipe)); |
653 | pipe_name(pipe)); |
871 | plls->wrpll1_refcount++; |
654 | plls->wrpll1_refcount++; |
872 | reg = WRPLL_CTL1; |
655 | reg = WRPLL_CTL1; |
873 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1; |
656 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1; |
874 | } else if (plls->wrpll2_refcount == 0) { |
657 | } else if (plls->wrpll2_refcount == 0) { |
875 | DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n", |
658 | DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n", |
876 | pipe_name(pipe)); |
659 | pipe_name(pipe)); |
877 | plls->wrpll2_refcount++; |
660 | plls->wrpll2_refcount++; |
878 | reg = WRPLL_CTL2; |
661 | reg = WRPLL_CTL2; |
879 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL2; |
662 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL2; |
880 | } else { |
663 | } else { |
881 | DRM_ERROR("No WRPLLs available!\n"); |
664 | DRM_ERROR("No WRPLLs available!\n"); |
882 | return false; |
665 | return false; |
883 | } |
666 | } |
884 | 667 | ||
885 | WARN(I915_READ(reg) & WRPLL_PLL_ENABLE, |
668 | WARN(I915_READ(reg) & WRPLL_PLL_ENABLE, |
886 | "WRPLL already enabled\n"); |
669 | "WRPLL already enabled\n"); |
887 | 670 | ||
888 | intel_ddi_calculate_wrpll(clock, &p, &n2, &r2); |
671 | intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); |
889 | 672 | ||
890 | val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 | |
673 | val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 | |
891 | WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | |
674 | WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | |
892 | WRPLL_DIVIDER_POST(p); |
675 | WRPLL_DIVIDER_POST(p); |
893 | 676 | ||
894 | } else if (type == INTEL_OUTPUT_ANALOG) { |
677 | } else if (type == INTEL_OUTPUT_ANALOG) { |
895 | if (plls->spll_refcount == 0) { |
678 | if (plls->spll_refcount == 0) { |
896 | DRM_DEBUG_KMS("Using SPLL on pipe %c\n", |
679 | DRM_DEBUG_KMS("Using SPLL on pipe %c\n", |
897 | pipe_name(pipe)); |
680 | pipe_name(pipe)); |
898 | plls->spll_refcount++; |
681 | plls->spll_refcount++; |
899 | reg = SPLL_CTL; |
682 | reg = SPLL_CTL; |
900 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_SPLL; |
683 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_SPLL; |
901 | } else { |
684 | } else { |
902 | DRM_ERROR("SPLL already in use\n"); |
685 | DRM_ERROR("SPLL already in use\n"); |
903 | return false; |
686 | return false; |
904 | } |
687 | } |
905 | 688 | ||
906 | WARN(I915_READ(reg) & SPLL_PLL_ENABLE, |
689 | WARN(I915_READ(reg) & SPLL_PLL_ENABLE, |
907 | "SPLL already enabled\n"); |
690 | "SPLL already enabled\n"); |
908 | 691 | ||
909 | val = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; |
692 | val = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; |
910 | 693 | ||
911 | } else { |
694 | } else { |
912 | WARN(1, "Invalid DDI encoder type %d\n", type); |
695 | WARN(1, "Invalid DDI encoder type %d\n", type); |
913 | return false; |
696 | return false; |
914 | } |
697 | } |
915 | 698 | ||
916 | I915_WRITE(reg, val); |
699 | I915_WRITE(reg, val); |
917 | udelay(20); |
700 | udelay(20); |
918 | 701 | ||
919 | return true; |
702 | return true; |
920 | } |
703 | } |
921 | 704 | ||
922 | void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) |
705 | void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) |
923 | { |
706 | { |
924 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
707 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
925 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
708 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
926 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
709 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
927 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
710 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
928 | int type = intel_encoder->type; |
711 | int type = intel_encoder->type; |
929 | uint32_t temp; |
712 | uint32_t temp; |
930 | 713 | ||
931 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
714 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
932 | 715 | ||
933 | temp = TRANS_MSA_SYNC_CLK; |
716 | temp = TRANS_MSA_SYNC_CLK; |
934 | switch (intel_crtc->config.pipe_bpp) { |
717 | switch (intel_crtc->config.pipe_bpp) { |
935 | case 18: |
718 | case 18: |
936 | temp |= TRANS_MSA_6_BPC; |
719 | temp |= TRANS_MSA_6_BPC; |
937 | break; |
720 | break; |
938 | case 24: |
721 | case 24: |
939 | temp |= TRANS_MSA_8_BPC; |
722 | temp |= TRANS_MSA_8_BPC; |
940 | break; |
723 | break; |
941 | case 30: |
724 | case 30: |
942 | temp |= TRANS_MSA_10_BPC; |
725 | temp |= TRANS_MSA_10_BPC; |
943 | break; |
726 | break; |
944 | case 36: |
727 | case 36: |
945 | temp |= TRANS_MSA_12_BPC; |
728 | temp |= TRANS_MSA_12_BPC; |
946 | break; |
729 | break; |
947 | default: |
730 | default: |
948 | BUG(); |
731 | BUG(); |
949 | } |
732 | } |
950 | I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp); |
733 | I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp); |
951 | } |
734 | } |
952 | } |
735 | } |
953 | 736 | ||
954 | void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) |
737 | void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) |
955 | { |
738 | { |
956 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
739 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
957 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
740 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
958 | struct drm_encoder *encoder = &intel_encoder->base; |
741 | struct drm_encoder *encoder = &intel_encoder->base; |
959 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
742 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
960 | enum pipe pipe = intel_crtc->pipe; |
743 | enum pipe pipe = intel_crtc->pipe; |
961 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
744 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
962 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
745 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
963 | int type = intel_encoder->type; |
746 | int type = intel_encoder->type; |
964 | uint32_t temp; |
747 | uint32_t temp; |
965 | 748 | ||
966 | /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */ |
749 | /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */ |
967 | temp = TRANS_DDI_FUNC_ENABLE; |
750 | temp = TRANS_DDI_FUNC_ENABLE; |
968 | temp |= TRANS_DDI_SELECT_PORT(port); |
751 | temp |= TRANS_DDI_SELECT_PORT(port); |
969 | 752 | ||
970 | switch (intel_crtc->config.pipe_bpp) { |
753 | switch (intel_crtc->config.pipe_bpp) { |
971 | case 18: |
754 | case 18: |
972 | temp |= TRANS_DDI_BPC_6; |
755 | temp |= TRANS_DDI_BPC_6; |
973 | break; |
756 | break; |
974 | case 24: |
757 | case 24: |
975 | temp |= TRANS_DDI_BPC_8; |
758 | temp |= TRANS_DDI_BPC_8; |
976 | break; |
759 | break; |
977 | case 30: |
760 | case 30: |
978 | temp |= TRANS_DDI_BPC_10; |
761 | temp |= TRANS_DDI_BPC_10; |
979 | break; |
762 | break; |
980 | case 36: |
763 | case 36: |
981 | temp |= TRANS_DDI_BPC_12; |
764 | temp |= TRANS_DDI_BPC_12; |
982 | break; |
765 | break; |
983 | default: |
766 | default: |
984 | BUG(); |
767 | BUG(); |
985 | } |
768 | } |
986 | 769 | ||
987 | if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) |
770 | if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) |
988 | temp |= TRANS_DDI_PVSYNC; |
771 | temp |= TRANS_DDI_PVSYNC; |
989 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
772 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
990 | temp |= TRANS_DDI_PHSYNC; |
773 | temp |= TRANS_DDI_PHSYNC; |
991 | 774 | ||
992 | if (cpu_transcoder == TRANSCODER_EDP) { |
775 | if (cpu_transcoder == TRANSCODER_EDP) { |
993 | switch (pipe) { |
776 | switch (pipe) { |
994 | case PIPE_A: |
777 | case PIPE_A: |
995 | /* Can only use the always-on power well for eDP when |
778 | /* Can only use the always-on power well for eDP when |
996 | * not using the panel fitter, and when not using motion |
779 | * not using the panel fitter, and when not using motion |
997 | * blur mitigation (which we don't support). */ |
780 | * blur mitigation (which we don't support). */ |
998 | if (dev_priv->pch_pf_size) |
781 | if (intel_crtc->config.pch_pfit.enabled) |
999 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; |
782 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; |
1000 | else |
783 | else |
1001 | temp |= TRANS_DDI_EDP_INPUT_A_ON; |
784 | temp |= TRANS_DDI_EDP_INPUT_A_ON; |
1002 | break; |
785 | break; |
1003 | case PIPE_B: |
786 | case PIPE_B: |
1004 | temp |= TRANS_DDI_EDP_INPUT_B_ONOFF; |
787 | temp |= TRANS_DDI_EDP_INPUT_B_ONOFF; |
1005 | break; |
788 | break; |
1006 | case PIPE_C: |
789 | case PIPE_C: |
1007 | temp |= TRANS_DDI_EDP_INPUT_C_ONOFF; |
790 | temp |= TRANS_DDI_EDP_INPUT_C_ONOFF; |
1008 | break; |
791 | break; |
1009 | default: |
792 | default: |
1010 | BUG(); |
793 | BUG(); |
1011 | break; |
794 | break; |
1012 | } |
795 | } |
1013 | } |
796 | } |
1014 | 797 | ||
1015 | if (type == INTEL_OUTPUT_HDMI) { |
798 | if (type == INTEL_OUTPUT_HDMI) { |
1016 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
799 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
1017 | 800 | ||
1018 | if (intel_hdmi->has_hdmi_sink) |
801 | if (intel_hdmi->has_hdmi_sink) |
1019 | temp |= TRANS_DDI_MODE_SELECT_HDMI; |
802 | temp |= TRANS_DDI_MODE_SELECT_HDMI; |
1020 | else |
803 | else |
1021 | temp |= TRANS_DDI_MODE_SELECT_DVI; |
804 | temp |= TRANS_DDI_MODE_SELECT_DVI; |
1022 | 805 | ||
1023 | } else if (type == INTEL_OUTPUT_ANALOG) { |
806 | } else if (type == INTEL_OUTPUT_ANALOG) { |
1024 | temp |= TRANS_DDI_MODE_SELECT_FDI; |
807 | temp |= TRANS_DDI_MODE_SELECT_FDI; |
1025 | temp |= (intel_crtc->fdi_lanes - 1) << 1; |
808 | temp |= (intel_crtc->config.fdi_lanes - 1) << 1; |
1026 | 809 | ||
1027 | } else if (type == INTEL_OUTPUT_DISPLAYPORT || |
810 | } else if (type == INTEL_OUTPUT_DISPLAYPORT || |
1028 | type == INTEL_OUTPUT_EDP) { |
811 | type == INTEL_OUTPUT_EDP) { |
1029 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
812 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1030 | 813 | ||
1031 | temp |= TRANS_DDI_MODE_SELECT_DP_SST; |
814 | temp |= TRANS_DDI_MODE_SELECT_DP_SST; |
1032 | - | ||
1033 | switch (intel_dp->lane_count) { |
- | |
1034 | case 1: |
- | |
1035 | temp |= TRANS_DDI_PORT_WIDTH_X1; |
- | |
1036 | break; |
- | |
1037 | case 2: |
- | |
1038 | temp |= TRANS_DDI_PORT_WIDTH_X2; |
- | |
1039 | break; |
- | |
1040 | case 4: |
- | |
1041 | temp |= TRANS_DDI_PORT_WIDTH_X4; |
- | |
1042 | break; |
- | |
1043 | default: |
- | |
1044 | temp |= TRANS_DDI_PORT_WIDTH_X4; |
- | |
1045 | WARN(1, "Unsupported lane count %d\n", |
815 | |
1046 | intel_dp->lane_count); |
- | |
1047 | } |
- | |
1048 | 816 | temp |= DDI_PORT_WIDTH(intel_dp->lane_count); |
|
1049 | } else { |
817 | } else { |
1050 | WARN(1, "Invalid encoder type %d for pipe %d\n", |
818 | WARN(1, "Invalid encoder type %d for pipe %c\n", |
1051 | intel_encoder->type, pipe); |
819 | intel_encoder->type, pipe_name(pipe)); |
1052 | } |
820 | } |
1053 | 821 | ||
1054 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); |
822 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); |
1055 | } |
823 | } |
1056 | 824 | ||
1057 | void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, |
825 | void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, |
1058 | enum transcoder cpu_transcoder) |
826 | enum transcoder cpu_transcoder) |
1059 | { |
827 | { |
1060 | uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); |
828 | uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); |
1061 | uint32_t val = I915_READ(reg); |
829 | uint32_t val = I915_READ(reg); |
1062 | 830 | ||
1063 | val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK); |
831 | val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK); |
1064 | val |= TRANS_DDI_PORT_NONE; |
832 | val |= TRANS_DDI_PORT_NONE; |
1065 | I915_WRITE(reg, val); |
833 | I915_WRITE(reg, val); |
1066 | } |
834 | } |
1067 | 835 | ||
1068 | bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) |
836 | bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) |
1069 | { |
837 | { |
1070 | struct drm_device *dev = intel_connector->base.dev; |
838 | struct drm_device *dev = intel_connector->base.dev; |
1071 | struct drm_i915_private *dev_priv = dev->dev_private; |
839 | struct drm_i915_private *dev_priv = dev->dev_private; |
1072 | struct intel_encoder *intel_encoder = intel_connector->encoder; |
840 | struct intel_encoder *intel_encoder = intel_connector->encoder; |
1073 | int type = intel_connector->base.connector_type; |
841 | int type = intel_connector->base.connector_type; |
1074 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
842 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1075 | enum pipe pipe = 0; |
843 | enum pipe pipe = 0; |
1076 | enum transcoder cpu_transcoder; |
844 | enum transcoder cpu_transcoder; |
1077 | uint32_t tmp; |
845 | uint32_t tmp; |
1078 | 846 | ||
1079 | if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) |
847 | if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) |
1080 | return false; |
848 | return false; |
1081 | 849 | ||
1082 | if (port == PORT_A) |
850 | if (port == PORT_A) |
1083 | cpu_transcoder = TRANSCODER_EDP; |
851 | cpu_transcoder = TRANSCODER_EDP; |
1084 | else |
852 | else |
1085 | cpu_transcoder = (enum transcoder) pipe; |
853 | cpu_transcoder = (enum transcoder) pipe; |
1086 | 854 | ||
1087 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
855 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
1088 | 856 | ||
1089 | switch (tmp & TRANS_DDI_MODE_SELECT_MASK) { |
857 | switch (tmp & TRANS_DDI_MODE_SELECT_MASK) { |
1090 | case TRANS_DDI_MODE_SELECT_HDMI: |
858 | case TRANS_DDI_MODE_SELECT_HDMI: |
1091 | case TRANS_DDI_MODE_SELECT_DVI: |
859 | case TRANS_DDI_MODE_SELECT_DVI: |
1092 | return (type == DRM_MODE_CONNECTOR_HDMIA); |
860 | return (type == DRM_MODE_CONNECTOR_HDMIA); |
1093 | 861 | ||
1094 | case TRANS_DDI_MODE_SELECT_DP_SST: |
862 | case TRANS_DDI_MODE_SELECT_DP_SST: |
1095 | if (type == DRM_MODE_CONNECTOR_eDP) |
863 | if (type == DRM_MODE_CONNECTOR_eDP) |
1096 | return true; |
864 | return true; |
1097 | case TRANS_DDI_MODE_SELECT_DP_MST: |
865 | case TRANS_DDI_MODE_SELECT_DP_MST: |
1098 | return (type == DRM_MODE_CONNECTOR_DisplayPort); |
866 | return (type == DRM_MODE_CONNECTOR_DisplayPort); |
1099 | 867 | ||
1100 | case TRANS_DDI_MODE_SELECT_FDI: |
868 | case TRANS_DDI_MODE_SELECT_FDI: |
1101 | return (type == DRM_MODE_CONNECTOR_VGA); |
869 | return (type == DRM_MODE_CONNECTOR_VGA); |
1102 | 870 | ||
1103 | default: |
871 | default: |
1104 | return false; |
872 | return false; |
1105 | } |
873 | } |
1106 | } |
874 | } |
1107 | 875 | ||
1108 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, |
876 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, |
1109 | enum pipe *pipe) |
877 | enum pipe *pipe) |
1110 | { |
878 | { |
1111 | struct drm_device *dev = encoder->base.dev; |
879 | struct drm_device *dev = encoder->base.dev; |
1112 | struct drm_i915_private *dev_priv = dev->dev_private; |
880 | struct drm_i915_private *dev_priv = dev->dev_private; |
1113 | enum port port = intel_ddi_get_encoder_port(encoder); |
881 | enum port port = intel_ddi_get_encoder_port(encoder); |
1114 | u32 tmp; |
882 | u32 tmp; |
1115 | int i; |
883 | int i; |
1116 | 884 | ||
1117 | tmp = I915_READ(DDI_BUF_CTL(port)); |
885 | tmp = I915_READ(DDI_BUF_CTL(port)); |
1118 | 886 | ||
1119 | if (!(tmp & DDI_BUF_CTL_ENABLE)) |
887 | if (!(tmp & DDI_BUF_CTL_ENABLE)) |
1120 | return false; |
888 | return false; |
1121 | 889 | ||
1122 | if (port == PORT_A) { |
890 | if (port == PORT_A) { |
1123 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); |
891 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); |
1124 | 892 | ||
1125 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { |
893 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { |
1126 | case TRANS_DDI_EDP_INPUT_A_ON: |
894 | case TRANS_DDI_EDP_INPUT_A_ON: |
1127 | case TRANS_DDI_EDP_INPUT_A_ONOFF: |
895 | case TRANS_DDI_EDP_INPUT_A_ONOFF: |
1128 | *pipe = PIPE_A; |
896 | *pipe = PIPE_A; |
1129 | break; |
897 | break; |
1130 | case TRANS_DDI_EDP_INPUT_B_ONOFF: |
898 | case TRANS_DDI_EDP_INPUT_B_ONOFF: |
1131 | *pipe = PIPE_B; |
899 | *pipe = PIPE_B; |
1132 | break; |
900 | break; |
1133 | case TRANS_DDI_EDP_INPUT_C_ONOFF: |
901 | case TRANS_DDI_EDP_INPUT_C_ONOFF: |
1134 | *pipe = PIPE_C; |
902 | *pipe = PIPE_C; |
1135 | break; |
903 | break; |
1136 | } |
904 | } |
1137 | 905 | ||
1138 | return true; |
906 | return true; |
1139 | } else { |
907 | } else { |
1140 | for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) { |
908 | for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) { |
1141 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(i)); |
909 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(i)); |
1142 | 910 | ||
1143 | if ((tmp & TRANS_DDI_PORT_MASK) |
911 | if ((tmp & TRANS_DDI_PORT_MASK) |
1144 | == TRANS_DDI_SELECT_PORT(port)) { |
912 | == TRANS_DDI_SELECT_PORT(port)) { |
1145 | *pipe = i; |
913 | *pipe = i; |
1146 | return true; |
914 | return true; |
1147 | } |
915 | } |
1148 | } |
916 | } |
1149 | } |
917 | } |
1150 | 918 | ||
1151 | DRM_DEBUG_KMS("No pipe for ddi port %i found\n", port); |
919 | DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port)); |
1152 | 920 | ||
1153 | return false; |
921 | return false; |
1154 | } |
922 | } |
1155 | 923 | ||
1156 | static uint32_t intel_ddi_get_crtc_pll(struct drm_i915_private *dev_priv, |
924 | static uint32_t intel_ddi_get_crtc_pll(struct drm_i915_private *dev_priv, |
1157 | enum pipe pipe) |
925 | enum pipe pipe) |
1158 | { |
926 | { |
1159 | uint32_t temp, ret; |
927 | uint32_t temp, ret; |
1160 | enum port port = I915_MAX_PORTS; |
928 | enum port port = I915_MAX_PORTS; |
1161 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
929 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
1162 | pipe); |
930 | pipe); |
1163 | int i; |
931 | int i; |
1164 | 932 | ||
1165 | if (cpu_transcoder == TRANSCODER_EDP) { |
933 | if (cpu_transcoder == TRANSCODER_EDP) { |
1166 | port = PORT_A; |
934 | port = PORT_A; |
1167 | } else { |
935 | } else { |
1168 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
936 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
1169 | temp &= TRANS_DDI_PORT_MASK; |
937 | temp &= TRANS_DDI_PORT_MASK; |
1170 | 938 | ||
1171 | for (i = PORT_B; i <= PORT_E; i++) |
939 | for (i = PORT_B; i <= PORT_E; i++) |
1172 | if (temp == TRANS_DDI_SELECT_PORT(i)) |
940 | if (temp == TRANS_DDI_SELECT_PORT(i)) |
1173 | port = i; |
941 | port = i; |
1174 | } |
942 | } |
1175 | 943 | ||
1176 | if (port == I915_MAX_PORTS) { |
944 | if (port == I915_MAX_PORTS) { |
1177 | WARN(1, "Pipe %c enabled on an unknown port\n", |
945 | WARN(1, "Pipe %c enabled on an unknown port\n", |
1178 | pipe_name(pipe)); |
946 | pipe_name(pipe)); |
1179 | ret = PORT_CLK_SEL_NONE; |
947 | ret = PORT_CLK_SEL_NONE; |
1180 | } else { |
948 | } else { |
1181 | ret = I915_READ(PORT_CLK_SEL(port)); |
949 | ret = I915_READ(PORT_CLK_SEL(port)); |
1182 | DRM_DEBUG_KMS("Pipe %c connected to port %c using clock " |
950 | DRM_DEBUG_KMS("Pipe %c connected to port %c using clock " |
1183 | "0x%08x\n", pipe_name(pipe), port_name(port), |
951 | "0x%08x\n", pipe_name(pipe), port_name(port), |
1184 | ret); |
952 | ret); |
1185 | } |
953 | } |
1186 | 954 | ||
1187 | return ret; |
955 | return ret; |
1188 | } |
956 | } |
1189 | 957 | ||
1190 | void intel_ddi_setup_hw_pll_state(struct drm_device *dev) |
958 | void intel_ddi_setup_hw_pll_state(struct drm_device *dev) |
1191 | { |
959 | { |
1192 | struct drm_i915_private *dev_priv = dev->dev_private; |
960 | struct drm_i915_private *dev_priv = dev->dev_private; |
1193 | enum pipe pipe; |
961 | enum pipe pipe; |
1194 | struct intel_crtc *intel_crtc; |
962 | struct intel_crtc *intel_crtc; |
1195 | 963 | ||
1196 | for_each_pipe(pipe) { |
964 | for_each_pipe(pipe) { |
1197 | intel_crtc = |
965 | intel_crtc = |
1198 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
966 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
1199 | 967 | ||
1200 | if (!intel_crtc->active) |
968 | if (!intel_crtc->active) |
1201 | continue; |
969 | continue; |
1202 | 970 | ||
1203 | intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv, |
971 | intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv, |
1204 | pipe); |
972 | pipe); |
1205 | 973 | ||
1206 | switch (intel_crtc->ddi_pll_sel) { |
974 | switch (intel_crtc->ddi_pll_sel) { |
1207 | case PORT_CLK_SEL_SPLL: |
975 | case PORT_CLK_SEL_SPLL: |
1208 | dev_priv->ddi_plls.spll_refcount++; |
976 | dev_priv->ddi_plls.spll_refcount++; |
1209 | break; |
977 | break; |
1210 | case PORT_CLK_SEL_WRPLL1: |
978 | case PORT_CLK_SEL_WRPLL1: |
1211 | dev_priv->ddi_plls.wrpll1_refcount++; |
979 | dev_priv->ddi_plls.wrpll1_refcount++; |
1212 | break; |
980 | break; |
1213 | case PORT_CLK_SEL_WRPLL2: |
981 | case PORT_CLK_SEL_WRPLL2: |
1214 | dev_priv->ddi_plls.wrpll2_refcount++; |
982 | dev_priv->ddi_plls.wrpll2_refcount++; |
1215 | break; |
983 | break; |
1216 | } |
984 | } |
1217 | } |
985 | } |
1218 | } |
986 | } |
1219 | 987 | ||
1220 | void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) |
988 | void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) |
1221 | { |
989 | { |
1222 | struct drm_crtc *crtc = &intel_crtc->base; |
990 | struct drm_crtc *crtc = &intel_crtc->base; |
1223 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
991 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
1224 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
992 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
1225 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
993 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1226 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
994 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
1227 | 995 | ||
1228 | if (cpu_transcoder != TRANSCODER_EDP) |
996 | if (cpu_transcoder != TRANSCODER_EDP) |
1229 | I915_WRITE(TRANS_CLK_SEL(cpu_transcoder), |
997 | I915_WRITE(TRANS_CLK_SEL(cpu_transcoder), |
1230 | TRANS_CLK_SEL_PORT(port)); |
998 | TRANS_CLK_SEL_PORT(port)); |
1231 | } |
999 | } |
1232 | 1000 | ||
1233 | void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc) |
1001 | void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc) |
1234 | { |
1002 | { |
1235 | struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; |
1003 | struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; |
1236 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
1004 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
1237 | 1005 | ||
1238 | if (cpu_transcoder != TRANSCODER_EDP) |
1006 | if (cpu_transcoder != TRANSCODER_EDP) |
1239 | I915_WRITE(TRANS_CLK_SEL(cpu_transcoder), |
1007 | I915_WRITE(TRANS_CLK_SEL(cpu_transcoder), |
1240 | TRANS_CLK_SEL_DISABLED); |
1008 | TRANS_CLK_SEL_DISABLED); |
1241 | } |
1009 | } |
1242 | 1010 | ||
1243 | static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) |
1011 | static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) |
1244 | { |
1012 | { |
1245 | struct drm_encoder *encoder = &intel_encoder->base; |
1013 | struct drm_encoder *encoder = &intel_encoder->base; |
1246 | struct drm_crtc *crtc = encoder->crtc; |
1014 | struct drm_crtc *crtc = encoder->crtc; |
1247 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1015 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1248 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1016 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1249 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1017 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1250 | int type = intel_encoder->type; |
1018 | int type = intel_encoder->type; |
1251 | 1019 | ||
1252 | if (type == INTEL_OUTPUT_EDP) { |
1020 | if (type == INTEL_OUTPUT_EDP) { |
1253 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1021 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1254 | ironlake_edp_panel_vdd_on(intel_dp); |
1022 | ironlake_edp_panel_vdd_on(intel_dp); |
1255 | ironlake_edp_panel_on(intel_dp); |
1023 | ironlake_edp_panel_on(intel_dp); |
1256 | ironlake_edp_panel_vdd_off(intel_dp, true); |
1024 | ironlake_edp_panel_vdd_off(intel_dp, true); |
1257 | } |
1025 | } |
1258 | 1026 | ||
1259 | WARN_ON(intel_crtc->ddi_pll_sel == PORT_CLK_SEL_NONE); |
1027 | WARN_ON(intel_crtc->ddi_pll_sel == PORT_CLK_SEL_NONE); |
1260 | I915_WRITE(PORT_CLK_SEL(port), intel_crtc->ddi_pll_sel); |
1028 | I915_WRITE(PORT_CLK_SEL(port), intel_crtc->ddi_pll_sel); |
1261 | 1029 | ||
1262 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
1030 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
1263 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1031 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1264 | 1032 | ||
1265 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
1033 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
1266 | intel_dp_start_link_train(intel_dp); |
1034 | intel_dp_start_link_train(intel_dp); |
1267 | intel_dp_complete_link_train(intel_dp); |
1035 | intel_dp_complete_link_train(intel_dp); |
1268 | if (port != PORT_A) |
1036 | if (port != PORT_A) |
1269 | intel_dp_stop_link_train(intel_dp); |
1037 | intel_dp_stop_link_train(intel_dp); |
1270 | } |
1038 | } |
1271 | } |
1039 | } |
1272 | 1040 | ||
1273 | static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) |
1041 | static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) |
1274 | { |
1042 | { |
1275 | struct drm_encoder *encoder = &intel_encoder->base; |
1043 | struct drm_encoder *encoder = &intel_encoder->base; |
1276 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1044 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1277 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1045 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1278 | int type = intel_encoder->type; |
1046 | int type = intel_encoder->type; |
1279 | uint32_t val; |
1047 | uint32_t val; |
1280 | bool wait = false; |
1048 | bool wait = false; |
1281 | 1049 | ||
1282 | val = I915_READ(DDI_BUF_CTL(port)); |
1050 | val = I915_READ(DDI_BUF_CTL(port)); |
1283 | if (val & DDI_BUF_CTL_ENABLE) { |
1051 | if (val & DDI_BUF_CTL_ENABLE) { |
1284 | val &= ~DDI_BUF_CTL_ENABLE; |
1052 | val &= ~DDI_BUF_CTL_ENABLE; |
1285 | I915_WRITE(DDI_BUF_CTL(port), val); |
1053 | I915_WRITE(DDI_BUF_CTL(port), val); |
1286 | wait = true; |
1054 | wait = true; |
1287 | } |
1055 | } |
1288 | 1056 | ||
1289 | val = I915_READ(DP_TP_CTL(port)); |
1057 | val = I915_READ(DP_TP_CTL(port)); |
1290 | val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
1058 | val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
1291 | val |= DP_TP_CTL_LINK_TRAIN_PAT1; |
1059 | val |= DP_TP_CTL_LINK_TRAIN_PAT1; |
1292 | I915_WRITE(DP_TP_CTL(port), val); |
1060 | I915_WRITE(DP_TP_CTL(port), val); |
1293 | 1061 | ||
1294 | if (wait) |
1062 | if (wait) |
1295 | intel_wait_ddi_buf_idle(dev_priv, port); |
1063 | intel_wait_ddi_buf_idle(dev_priv, port); |
1296 | 1064 | ||
1297 | if (type == INTEL_OUTPUT_EDP) { |
1065 | if (type == INTEL_OUTPUT_EDP) { |
1298 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1066 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1299 | ironlake_edp_panel_vdd_on(intel_dp); |
1067 | ironlake_edp_panel_vdd_on(intel_dp); |
1300 | ironlake_edp_panel_off(intel_dp); |
1068 | ironlake_edp_panel_off(intel_dp); |
1301 | } |
1069 | } |
1302 | 1070 | ||
1303 | I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); |
1071 | I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); |
1304 | } |
1072 | } |
1305 | 1073 | ||
1306 | static void intel_enable_ddi(struct intel_encoder *intel_encoder) |
1074 | static void intel_enable_ddi(struct intel_encoder *intel_encoder) |
1307 | { |
1075 | { |
1308 | struct drm_encoder *encoder = &intel_encoder->base; |
1076 | struct drm_encoder *encoder = &intel_encoder->base; |
1309 | struct drm_crtc *crtc = encoder->crtc; |
1077 | struct drm_crtc *crtc = encoder->crtc; |
1310 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1078 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1311 | int pipe = intel_crtc->pipe; |
1079 | int pipe = intel_crtc->pipe; |
1312 | struct drm_device *dev = encoder->dev; |
1080 | struct drm_device *dev = encoder->dev; |
1313 | struct drm_i915_private *dev_priv = dev->dev_private; |
1081 | struct drm_i915_private *dev_priv = dev->dev_private; |
1314 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1082 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1315 | int type = intel_encoder->type; |
1083 | int type = intel_encoder->type; |
1316 | uint32_t tmp; |
1084 | uint32_t tmp; |
1317 | 1085 | ||
1318 | if (type == INTEL_OUTPUT_HDMI) { |
1086 | if (type == INTEL_OUTPUT_HDMI) { |
1319 | struct intel_digital_port *intel_dig_port = |
1087 | struct intel_digital_port *intel_dig_port = |
1320 | enc_to_dig_port(encoder); |
1088 | enc_to_dig_port(encoder); |
1321 | 1089 | ||
1322 | /* In HDMI/DVI mode, the port width, and swing/emphasis values |
1090 | /* In HDMI/DVI mode, the port width, and swing/emphasis values |
1323 | * are ignored so nothing special needs to be done besides |
1091 | * are ignored so nothing special needs to be done besides |
1324 | * enabling the port. |
1092 | * enabling the port. |
1325 | */ |
1093 | */ |
1326 | I915_WRITE(DDI_BUF_CTL(port), |
1094 | I915_WRITE(DDI_BUF_CTL(port), |
1327 | intel_dig_port->port_reversal | DDI_BUF_CTL_ENABLE); |
1095 | intel_dig_port->saved_port_bits | |
- | 1096 | DDI_BUF_CTL_ENABLE); |
|
1328 | } else if (type == INTEL_OUTPUT_EDP) { |
1097 | } else if (type == INTEL_OUTPUT_EDP) { |
1329 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1098 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1330 | 1099 | ||
1331 | if (port == PORT_A) |
1100 | if (port == PORT_A) |
1332 | intel_dp_stop_link_train(intel_dp); |
1101 | intel_dp_stop_link_train(intel_dp); |
1333 | 1102 | ||
1334 | ironlake_edp_backlight_on(intel_dp); |
1103 | ironlake_edp_backlight_on(intel_dp); |
- | 1104 | intel_edp_psr_enable(intel_dp); |
|
1335 | } |
1105 | } |
1336 | 1106 | ||
1337 | if (intel_crtc->eld_vld) { |
1107 | if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { |
1338 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
1108 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
1339 | tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); |
1109 | tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); |
1340 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
1110 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
1341 | } |
1111 | } |
1342 | } |
1112 | } |
1343 | 1113 | ||
1344 | static void intel_disable_ddi(struct intel_encoder *intel_encoder) |
1114 | static void intel_disable_ddi(struct intel_encoder *intel_encoder) |
1345 | { |
1115 | { |
1346 | struct drm_encoder *encoder = &intel_encoder->base; |
1116 | struct drm_encoder *encoder = &intel_encoder->base; |
1347 | struct drm_crtc *crtc = encoder->crtc; |
1117 | struct drm_crtc *crtc = encoder->crtc; |
1348 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1118 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1349 | int pipe = intel_crtc->pipe; |
1119 | int pipe = intel_crtc->pipe; |
1350 | int type = intel_encoder->type; |
1120 | int type = intel_encoder->type; |
1351 | struct drm_device *dev = encoder->dev; |
1121 | struct drm_device *dev = encoder->dev; |
1352 | struct drm_i915_private *dev_priv = dev->dev_private; |
1122 | struct drm_i915_private *dev_priv = dev->dev_private; |
1353 | uint32_t tmp; |
1123 | uint32_t tmp; |
- | 1124 | ||
1354 | 1125 | if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { |
|
1355 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
1126 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
- | 1127 | tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << |
|
1356 | tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); |
1128 | (pipe * 4)); |
- | 1129 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
|
1357 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
1130 | } |
1358 | 1131 | ||
1359 | if (type == INTEL_OUTPUT_EDP) { |
1132 | if (type == INTEL_OUTPUT_EDP) { |
1360 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1133 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
- | 1134 | ||
1361 | 1135 | intel_edp_psr_disable(intel_dp); |
|
1362 | ironlake_edp_backlight_off(intel_dp); |
1136 | ironlake_edp_backlight_off(intel_dp); |
1363 | } |
1137 | } |
1364 | } |
1138 | } |
1365 | 1139 | ||
1366 | int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) |
1140 | int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) |
1367 | { |
1141 | { |
- | 1142 | uint32_t lcpll = I915_READ(LCPLL_CTL); |
|
- | 1143 | ||
- | 1144 | if (lcpll & LCPLL_CD_SOURCE_FCLK) |
|
- | 1145 | return 800000; |
|
1368 | if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) |
1146 | else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) |
1369 | return 450; |
1147 | return 450000; |
1370 | else if ((I915_READ(LCPLL_CTL) & LCPLL_CLK_FREQ_MASK) == |
1148 | else if ((lcpll & LCPLL_CLK_FREQ_MASK) == LCPLL_CLK_FREQ_450) |
1371 | LCPLL_CLK_FREQ_450) |
- | |
1372 | return 450; |
1149 | return 450000; |
1373 | else if (IS_ULT(dev_priv->dev)) |
1150 | else if (IS_ULT(dev_priv->dev)) |
1374 | return 338; |
1151 | return 337500; |
1375 | else |
1152 | else |
1376 | return 540; |
1153 | return 540000; |
1377 | } |
1154 | } |
1378 | 1155 | ||
1379 | void intel_ddi_pll_init(struct drm_device *dev) |
1156 | void intel_ddi_pll_init(struct drm_device *dev) |
1380 | { |
1157 | { |
1381 | struct drm_i915_private *dev_priv = dev->dev_private; |
1158 | struct drm_i915_private *dev_priv = dev->dev_private; |
1382 | uint32_t val = I915_READ(LCPLL_CTL); |
1159 | uint32_t val = I915_READ(LCPLL_CTL); |
1383 | 1160 | ||
1384 | /* The LCPLL register should be turned on by the BIOS. For now let's |
1161 | /* The LCPLL register should be turned on by the BIOS. For now let's |
1385 | * just check its state and print errors in case something is wrong. |
1162 | * just check its state and print errors in case something is wrong. |
1386 | * Don't even try to turn it on. |
1163 | * Don't even try to turn it on. |
1387 | */ |
1164 | */ |
1388 | 1165 | ||
1389 | DRM_DEBUG_KMS("CDCLK running at %dMHz\n", |
1166 | DRM_DEBUG_KMS("CDCLK running at %dKHz\n", |
1390 | intel_ddi_get_cdclk_freq(dev_priv)); |
1167 | intel_ddi_get_cdclk_freq(dev_priv)); |
1391 | 1168 | ||
1392 | if (val & LCPLL_CD_SOURCE_FCLK) |
1169 | if (val & LCPLL_CD_SOURCE_FCLK) |
1393 | DRM_ERROR("CDCLK source is not LCPLL\n"); |
1170 | DRM_ERROR("CDCLK source is not LCPLL\n"); |
1394 | 1171 | ||
1395 | if (val & LCPLL_PLL_DISABLE) |
1172 | if (val & LCPLL_PLL_DISABLE) |
1396 | DRM_ERROR("LCPLL is disabled\n"); |
1173 | DRM_ERROR("LCPLL is disabled\n"); |
1397 | } |
1174 | } |
1398 | 1175 | ||
1399 | void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder) |
1176 | void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder) |
1400 | { |
1177 | { |
1401 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); |
1178 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); |
1402 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
1179 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
1403 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1180 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1404 | enum port port = intel_dig_port->port; |
1181 | enum port port = intel_dig_port->port; |
1405 | uint32_t val; |
1182 | uint32_t val; |
1406 | bool wait = false; |
1183 | bool wait = false; |
1407 | 1184 | ||
1408 | if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) { |
1185 | if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) { |
1409 | val = I915_READ(DDI_BUF_CTL(port)); |
1186 | val = I915_READ(DDI_BUF_CTL(port)); |
1410 | if (val & DDI_BUF_CTL_ENABLE) { |
1187 | if (val & DDI_BUF_CTL_ENABLE) { |
1411 | val &= ~DDI_BUF_CTL_ENABLE; |
1188 | val &= ~DDI_BUF_CTL_ENABLE; |
1412 | I915_WRITE(DDI_BUF_CTL(port), val); |
1189 | I915_WRITE(DDI_BUF_CTL(port), val); |
1413 | wait = true; |
1190 | wait = true; |
1414 | } |
1191 | } |
1415 | 1192 | ||
1416 | val = I915_READ(DP_TP_CTL(port)); |
1193 | val = I915_READ(DP_TP_CTL(port)); |
1417 | val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
1194 | val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
1418 | val |= DP_TP_CTL_LINK_TRAIN_PAT1; |
1195 | val |= DP_TP_CTL_LINK_TRAIN_PAT1; |
1419 | I915_WRITE(DP_TP_CTL(port), val); |
1196 | I915_WRITE(DP_TP_CTL(port), val); |
1420 | POSTING_READ(DP_TP_CTL(port)); |
1197 | POSTING_READ(DP_TP_CTL(port)); |
1421 | 1198 | ||
1422 | if (wait) |
1199 | if (wait) |
1423 | intel_wait_ddi_buf_idle(dev_priv, port); |
1200 | intel_wait_ddi_buf_idle(dev_priv, port); |
1424 | } |
1201 | } |
1425 | 1202 | ||
1426 | val = DP_TP_CTL_ENABLE | DP_TP_CTL_MODE_SST | |
1203 | val = DP_TP_CTL_ENABLE | DP_TP_CTL_MODE_SST | |
1427 | DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE; |
1204 | DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE; |
1428 | if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) |
1205 | if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) |
1429 | val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; |
1206 | val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; |
1430 | I915_WRITE(DP_TP_CTL(port), val); |
1207 | I915_WRITE(DP_TP_CTL(port), val); |
1431 | POSTING_READ(DP_TP_CTL(port)); |
1208 | POSTING_READ(DP_TP_CTL(port)); |
1432 | 1209 | ||
1433 | intel_dp->DP |= DDI_BUF_CTL_ENABLE; |
1210 | intel_dp->DP |= DDI_BUF_CTL_ENABLE; |
1434 | I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP); |
1211 | I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP); |
1435 | POSTING_READ(DDI_BUF_CTL(port)); |
1212 | POSTING_READ(DDI_BUF_CTL(port)); |
1436 | 1213 | ||
1437 | udelay(600); |
1214 | udelay(600); |
1438 | } |
1215 | } |
1439 | 1216 | ||
1440 | void intel_ddi_fdi_disable(struct drm_crtc *crtc) |
1217 | void intel_ddi_fdi_disable(struct drm_crtc *crtc) |
1441 | { |
1218 | { |
1442 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
1219 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
1443 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
1220 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
1444 | uint32_t val; |
1221 | uint32_t val; |
1445 | 1222 | ||
1446 | intel_ddi_post_disable(intel_encoder); |
1223 | intel_ddi_post_disable(intel_encoder); |
1447 | 1224 | ||
1448 | val = I915_READ(_FDI_RXA_CTL); |
1225 | val = I915_READ(_FDI_RXA_CTL); |
1449 | val &= ~FDI_RX_ENABLE; |
1226 | val &= ~FDI_RX_ENABLE; |
1450 | I915_WRITE(_FDI_RXA_CTL, val); |
1227 | I915_WRITE(_FDI_RXA_CTL, val); |
1451 | 1228 | ||
1452 | val = I915_READ(_FDI_RXA_MISC); |
1229 | val = I915_READ(_FDI_RXA_MISC); |
1453 | val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
1230 | val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
1454 | val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
1231 | val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
1455 | I915_WRITE(_FDI_RXA_MISC, val); |
1232 | I915_WRITE(_FDI_RXA_MISC, val); |
1456 | 1233 | ||
1457 | val = I915_READ(_FDI_RXA_CTL); |
1234 | val = I915_READ(_FDI_RXA_CTL); |
1458 | val &= ~FDI_PCDCLK; |
1235 | val &= ~FDI_PCDCLK; |
1459 | I915_WRITE(_FDI_RXA_CTL, val); |
1236 | I915_WRITE(_FDI_RXA_CTL, val); |
1460 | 1237 | ||
1461 | val = I915_READ(_FDI_RXA_CTL); |
1238 | val = I915_READ(_FDI_RXA_CTL); |
1462 | val &= ~FDI_RX_PLL_ENABLE; |
1239 | val &= ~FDI_RX_PLL_ENABLE; |
1463 | I915_WRITE(_FDI_RXA_CTL, val); |
1240 | I915_WRITE(_FDI_RXA_CTL, val); |
1464 | } |
1241 | } |
1465 | 1242 | ||
1466 | static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) |
1243 | static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) |
1467 | { |
1244 | { |
1468 | struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); |
1245 | struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); |
1469 | int type = intel_encoder->type; |
1246 | int type = intel_encoder->type; |
1470 | 1247 | ||
1471 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) |
1248 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) |
1472 | intel_dp_check_link_status(intel_dp); |
1249 | intel_dp_check_link_status(intel_dp); |
1473 | } |
1250 | } |
- | 1251 | ||
- | 1252 | static void intel_ddi_get_config(struct intel_encoder *encoder, |
|
- | 1253 | struct intel_crtc_config *pipe_config) |
|
- | 1254 | { |
|
- | 1255 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
|
- | 1256 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
|
- | 1257 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
|
- | 1258 | u32 temp, flags = 0; |
|
- | 1259 | ||
- | 1260 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
|
- | 1261 | if (temp & TRANS_DDI_PHSYNC) |
|
- | 1262 | flags |= DRM_MODE_FLAG_PHSYNC; |
|
- | 1263 | else |
|
- | 1264 | flags |= DRM_MODE_FLAG_NHSYNC; |
|
- | 1265 | if (temp & TRANS_DDI_PVSYNC) |
|
- | 1266 | flags |= DRM_MODE_FLAG_PVSYNC; |
|
- | 1267 | else |
|
- | 1268 | flags |= DRM_MODE_FLAG_NVSYNC; |
|
- | 1269 | ||
- | 1270 | pipe_config->adjusted_mode.flags |= flags; |
|
- | 1271 | } |
|
1474 | 1272 | ||
1475 | static void intel_ddi_destroy(struct drm_encoder *encoder) |
1273 | static void intel_ddi_destroy(struct drm_encoder *encoder) |
1476 | { |
1274 | { |
1477 | /* HDMI has nothing special to destroy, so we can go with this. */ |
1275 | /* HDMI has nothing special to destroy, so we can go with this. */ |
1478 | intel_dp_encoder_destroy(encoder); |
1276 | intel_dp_encoder_destroy(encoder); |
1479 | } |
1277 | } |
1480 | 1278 | ||
1481 | static bool intel_ddi_compute_config(struct intel_encoder *encoder, |
1279 | static bool intel_ddi_compute_config(struct intel_encoder *encoder, |
1482 | struct intel_crtc_config *pipe_config) |
1280 | struct intel_crtc_config *pipe_config) |
1483 | { |
1281 | { |
1484 | int type = encoder->type; |
1282 | int type = encoder->type; |
- | 1283 | int port = intel_ddi_get_encoder_port(encoder); |
|
1485 | 1284 | ||
1486 | WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); |
1285 | WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); |
- | 1286 | ||
- | 1287 | if (port == PORT_A) |
|
- | 1288 | pipe_config->cpu_transcoder = TRANSCODER_EDP; |
|
1487 | 1289 | ||
1488 | if (type == INTEL_OUTPUT_HDMI) |
1290 | if (type == INTEL_OUTPUT_HDMI) |
1489 | return intel_hdmi_compute_config(encoder, pipe_config); |
1291 | return intel_hdmi_compute_config(encoder, pipe_config); |
1490 | else |
1292 | else |
1491 | return intel_dp_compute_config(encoder, pipe_config); |
1293 | return intel_dp_compute_config(encoder, pipe_config); |
1492 | } |
1294 | } |
1493 | 1295 | ||
1494 | static const struct drm_encoder_funcs intel_ddi_funcs = { |
1296 | static const struct drm_encoder_funcs intel_ddi_funcs = { |
1495 | .destroy = intel_ddi_destroy, |
1297 | .destroy = intel_ddi_destroy, |
1496 | }; |
1298 | }; |
1497 | - | ||
1498 | static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = { |
- | |
1499 | .mode_set = intel_ddi_mode_set, |
- | |
1500 | }; |
- | |
1501 | 1299 | ||
1502 | void intel_ddi_init(struct drm_device *dev, enum port port) |
1300 | void intel_ddi_init(struct drm_device *dev, enum port port) |
1503 | { |
1301 | { |
1504 | struct drm_i915_private *dev_priv = dev->dev_private; |
1302 | struct drm_i915_private *dev_priv = dev->dev_private; |
1505 | struct intel_digital_port *intel_dig_port; |
1303 | struct intel_digital_port *intel_dig_port; |
1506 | struct intel_encoder *intel_encoder; |
1304 | struct intel_encoder *intel_encoder; |
1507 | struct drm_encoder *encoder; |
1305 | struct drm_encoder *encoder; |
1508 | struct intel_connector *hdmi_connector = NULL; |
1306 | struct intel_connector *hdmi_connector = NULL; |
1509 | struct intel_connector *dp_connector = NULL; |
1307 | struct intel_connector *dp_connector = NULL; |
1510 | 1308 | ||
1511 | intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL); |
1309 | intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL); |
1512 | if (!intel_dig_port) |
1310 | if (!intel_dig_port) |
1513 | return; |
1311 | return; |
1514 | 1312 | ||
1515 | dp_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1313 | dp_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1516 | if (!dp_connector) { |
1314 | if (!dp_connector) { |
1517 | kfree(intel_dig_port); |
1315 | kfree(intel_dig_port); |
1518 | return; |
1316 | return; |
1519 | } |
1317 | } |
1520 | - | ||
1521 | if (port != PORT_A) { |
- | |
1522 | hdmi_connector = kzalloc(sizeof(struct intel_connector), |
- | |
1523 | GFP_KERNEL); |
- | |
1524 | if (!hdmi_connector) { |
- | |
1525 | kfree(dp_connector); |
- | |
1526 | kfree(intel_dig_port); |
- | |
1527 | return; |
- | |
1528 | } |
- | |
1529 | } |
- | |
1530 | 1318 | ||
1531 | intel_encoder = &intel_dig_port->base; |
1319 | intel_encoder = &intel_dig_port->base; |
1532 | encoder = &intel_encoder->base; |
1320 | encoder = &intel_encoder->base; |
1533 | 1321 | ||
1534 | drm_encoder_init(dev, encoder, &intel_ddi_funcs, |
1322 | drm_encoder_init(dev, encoder, &intel_ddi_funcs, |
1535 | DRM_MODE_ENCODER_TMDS); |
1323 | DRM_MODE_ENCODER_TMDS); |
1536 | drm_encoder_helper_add(encoder, &intel_ddi_helper_funcs); |
- | |
1537 | 1324 | ||
- | 1325 | intel_encoder->compute_config = intel_ddi_compute_config; |
|
1538 | intel_encoder->compute_config = intel_ddi_compute_config; |
1326 | intel_encoder->mode_set = intel_ddi_mode_set; |
1539 | intel_encoder->enable = intel_enable_ddi; |
1327 | intel_encoder->enable = intel_enable_ddi; |
1540 | intel_encoder->pre_enable = intel_ddi_pre_enable; |
1328 | intel_encoder->pre_enable = intel_ddi_pre_enable; |
1541 | intel_encoder->disable = intel_disable_ddi; |
1329 | intel_encoder->disable = intel_disable_ddi; |
1542 | intel_encoder->post_disable = intel_ddi_post_disable; |
1330 | intel_encoder->post_disable = intel_ddi_post_disable; |
1543 | intel_encoder->get_hw_state = intel_ddi_get_hw_state; |
1331 | intel_encoder->get_hw_state = intel_ddi_get_hw_state; |
- | 1332 | intel_encoder->get_config = intel_ddi_get_config; |
|
1544 | 1333 | ||
1545 | intel_dig_port->port = port; |
1334 | intel_dig_port->port = port; |
1546 | intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) & |
1335 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & |
1547 | DDI_BUF_PORT_REVERSAL; |
1336 | (DDI_BUF_PORT_REVERSAL | |
1548 | if (hdmi_connector) |
- | |
1549 | intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); |
1337 | DDI_A_4_LANES); |
1550 | intel_dig_port->dp.output_reg = DDI_BUF_CTL(port); |
1338 | intel_dig_port->dp.output_reg = DDI_BUF_CTL(port); |
1551 | 1339 | ||
1552 | intel_encoder->type = INTEL_OUTPUT_UNKNOWN; |
1340 | intel_encoder->type = INTEL_OUTPUT_UNKNOWN; |
1553 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
1341 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
1554 | intel_encoder->cloneable = false; |
1342 | intel_encoder->cloneable = false; |
1555 | intel_encoder->hot_plug = intel_ddi_hot_plug; |
1343 | intel_encoder->hot_plug = intel_ddi_hot_plug; |
- | 1344 | ||
- | 1345 | if (!intel_dp_init_connector(intel_dig_port, dp_connector)) { |
|
- | 1346 | drm_encoder_cleanup(encoder); |
|
- | 1347 | kfree(intel_dig_port); |
|
- | 1348 | kfree(dp_connector); |
|
- | 1349 | return; |
|
- | 1350 | } |
|
- | 1351 | ||
- | 1352 | if (intel_encoder->type != INTEL_OUTPUT_EDP) { |
|
- | 1353 | hdmi_connector = kzalloc(sizeof(struct intel_connector), |
|
1556 | 1354 | GFP_KERNEL); |
|
- | 1355 | if (!hdmi_connector) { |
|
- | 1356 | return; |
|
- | 1357 | } |
|
- | 1358 | ||
1557 | if (hdmi_connector) |
1359 | intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); |
1558 | intel_hdmi_init_connector(intel_dig_port, hdmi_connector); |
- | |
- | 1360 | intel_hdmi_init_connector(intel_dig_port, hdmi_connector); |
|
1559 | intel_dp_init_connector(intel_dig_port, dp_connector); |
1361 | } |
1560 | }><>><>><>><>><>=>=>><>=>>>>>><>>><>>>> |
1362 | }><>><>><> |
- | 1363 | >< |
|
- | 1364 | >><>=>=>><>=>=>>>>=>=>=>>>>=>=>>>>>>=>>>>><>>>=>> |