Rev 4371 | Rev 4560 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4371 | Rev 4539 | ||
---|---|---|---|
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 | { |
88 | { |
89 | struct drm_i915_private *dev_priv = dev->dev_private; |
89 | struct drm_i915_private *dev_priv = dev->dev_private; |
90 | u32 reg; |
90 | u32 reg; |
91 | int i; |
91 | int i; |
92 | const u32 *ddi_translations = (port == PORT_E) ? |
92 | const u32 *ddi_translations = (port == PORT_E) ? |
93 | hsw_ddi_translations_fdi : |
93 | hsw_ddi_translations_fdi : |
94 | hsw_ddi_translations_dp; |
94 | hsw_ddi_translations_dp; |
95 | 95 | ||
96 | for (i = 0, reg = DDI_BUF_TRANS(port); |
96 | for (i = 0, reg = DDI_BUF_TRANS(port); |
97 | i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { |
97 | i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { |
98 | I915_WRITE(reg, ddi_translations[i]); |
98 | I915_WRITE(reg, ddi_translations[i]); |
99 | reg += 4; |
99 | reg += 4; |
100 | } |
100 | } |
101 | } |
101 | } |
102 | 102 | ||
103 | /* 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 |
104 | * mode and port E for FDI. |
104 | * mode and port E for FDI. |
105 | */ |
105 | */ |
106 | void intel_prepare_ddi(struct drm_device *dev) |
106 | void intel_prepare_ddi(struct drm_device *dev) |
107 | { |
107 | { |
108 | int port; |
108 | int port; |
109 | 109 | ||
110 | if (!HAS_DDI(dev)) |
110 | if (!HAS_DDI(dev)) |
111 | return; |
111 | return; |
112 | 112 | ||
113 | for (port = PORT_A; port <= PORT_E; port++) |
113 | for (port = PORT_A; port <= PORT_E; port++) |
114 | intel_prepare_ddi_buffers(dev, port); |
114 | intel_prepare_ddi_buffers(dev, port); |
115 | } |
115 | } |
116 | 116 | ||
117 | static const long hsw_ddi_buf_ctl_values[] = { |
117 | static const long hsw_ddi_buf_ctl_values[] = { |
118 | DDI_BUF_EMP_400MV_0DB_HSW, |
118 | DDI_BUF_EMP_400MV_0DB_HSW, |
119 | DDI_BUF_EMP_400MV_3_5DB_HSW, |
119 | DDI_BUF_EMP_400MV_3_5DB_HSW, |
120 | DDI_BUF_EMP_400MV_6DB_HSW, |
120 | DDI_BUF_EMP_400MV_6DB_HSW, |
121 | DDI_BUF_EMP_400MV_9_5DB_HSW, |
121 | DDI_BUF_EMP_400MV_9_5DB_HSW, |
122 | DDI_BUF_EMP_600MV_0DB_HSW, |
122 | DDI_BUF_EMP_600MV_0DB_HSW, |
123 | DDI_BUF_EMP_600MV_3_5DB_HSW, |
123 | DDI_BUF_EMP_600MV_3_5DB_HSW, |
124 | DDI_BUF_EMP_600MV_6DB_HSW, |
124 | DDI_BUF_EMP_600MV_6DB_HSW, |
125 | DDI_BUF_EMP_800MV_0DB_HSW, |
125 | DDI_BUF_EMP_800MV_0DB_HSW, |
126 | DDI_BUF_EMP_800MV_3_5DB_HSW |
126 | DDI_BUF_EMP_800MV_3_5DB_HSW |
127 | }; |
127 | }; |
128 | 128 | ||
129 | 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, |
130 | enum port port) |
130 | enum port port) |
131 | { |
131 | { |
132 | uint32_t reg = DDI_BUF_CTL(port); |
132 | uint32_t reg = DDI_BUF_CTL(port); |
133 | int i; |
133 | int i; |
134 | 134 | ||
135 | for (i = 0; i < 8; i++) { |
135 | for (i = 0; i < 8; i++) { |
136 | udelay(1); |
136 | udelay(1); |
137 | if (I915_READ(reg) & DDI_BUF_IS_IDLE) |
137 | if (I915_READ(reg) & DDI_BUF_IS_IDLE) |
138 | return; |
138 | return; |
139 | } |
139 | } |
140 | 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)); |
141 | } |
141 | } |
142 | 142 | ||
143 | /* 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 |
144 | * 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 |
145 | * 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. |
146 | * |
146 | * |
147 | * 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, |
148 | * 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 |
149 | * DDI A (which is used for eDP) |
149 | * DDI A (which is used for eDP) |
150 | */ |
150 | */ |
151 | 151 | ||
152 | void hsw_fdi_link_train(struct drm_crtc *crtc) |
152 | void hsw_fdi_link_train(struct drm_crtc *crtc) |
153 | { |
153 | { |
154 | struct drm_device *dev = crtc->dev; |
154 | struct drm_device *dev = crtc->dev; |
155 | struct drm_i915_private *dev_priv = dev->dev_private; |
155 | struct drm_i915_private *dev_priv = dev->dev_private; |
156 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
156 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
157 | u32 temp, i, rx_ctl_val; |
157 | u32 temp, i, rx_ctl_val; |
158 | 158 | ||
159 | /* 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 |
160 | * mode set "sequence for CRT port" document: |
160 | * mode set "sequence for CRT port" document: |
161 | * - TP1 to TP2 time with the default value |
161 | * - TP1 to TP2 time with the default value |
162 | * - FDI delay to 90h |
162 | * - FDI delay to 90h |
163 | * |
163 | * |
164 | * WaFDIAutoLinkSetTimingOverrride:hsw |
164 | * WaFDIAutoLinkSetTimingOverrride:hsw |
165 | */ |
165 | */ |
166 | I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) | |
166 | I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) | |
167 | FDI_RX_PWRDN_LANE0_VAL(2) | |
167 | FDI_RX_PWRDN_LANE0_VAL(2) | |
168 | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); |
168 | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); |
169 | 169 | ||
170 | /* Enable the PCH Receiver FDI PLL */ |
170 | /* Enable the PCH Receiver FDI PLL */ |
171 | 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 | |
172 | FDI_RX_PLL_ENABLE | |
173 | FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); |
173 | FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); |
174 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
174 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
175 | POSTING_READ(_FDI_RXA_CTL); |
175 | POSTING_READ(_FDI_RXA_CTL); |
176 | udelay(220); |
176 | udelay(220); |
177 | 177 | ||
178 | /* Switch from Rawclk to PCDclk */ |
178 | /* Switch from Rawclk to PCDclk */ |
179 | rx_ctl_val |= FDI_PCDCLK; |
179 | rx_ctl_val |= FDI_PCDCLK; |
180 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
180 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
181 | 181 | ||
182 | /* Configure Port Clock Select */ |
182 | /* Configure Port Clock Select */ |
183 | 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); |
184 | 184 | ||
185 | /* Start the training iterating through available voltages and emphasis, |
185 | /* Start the training iterating through available voltages and emphasis, |
186 | * testing each value twice. */ |
186 | * testing each value twice. */ |
187 | 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++) { |
188 | /* Configure DP_TP_CTL with auto-training */ |
188 | /* Configure DP_TP_CTL with auto-training */ |
189 | I915_WRITE(DP_TP_CTL(PORT_E), |
189 | I915_WRITE(DP_TP_CTL(PORT_E), |
190 | DP_TP_CTL_FDI_AUTOTRAIN | |
190 | DP_TP_CTL_FDI_AUTOTRAIN | |
191 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
191 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
192 | DP_TP_CTL_LINK_TRAIN_PAT1 | |
192 | DP_TP_CTL_LINK_TRAIN_PAT1 | |
193 | DP_TP_CTL_ENABLE); |
193 | DP_TP_CTL_ENABLE); |
194 | 194 | ||
195 | /* 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. |
196 | * DDI E does not support port reversal, the functionality is |
196 | * DDI E does not support port reversal, the functionality is |
197 | * 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 |
198 | * port reversal bit */ |
198 | * port reversal bit */ |
199 | I915_WRITE(DDI_BUF_CTL(PORT_E), |
199 | I915_WRITE(DDI_BUF_CTL(PORT_E), |
200 | DDI_BUF_CTL_ENABLE | |
200 | DDI_BUF_CTL_ENABLE | |
201 | ((intel_crtc->config.fdi_lanes - 1) << 1) | |
201 | ((intel_crtc->config.fdi_lanes - 1) << 1) | |
202 | hsw_ddi_buf_ctl_values[i / 2]); |
202 | hsw_ddi_buf_ctl_values[i / 2]); |
203 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
203 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
204 | 204 | ||
205 | udelay(600); |
205 | udelay(600); |
206 | 206 | ||
207 | /* Program PCH FDI Receiver TU */ |
207 | /* Program PCH FDI Receiver TU */ |
208 | I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64)); |
208 | I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64)); |
209 | 209 | ||
210 | /* Enable PCH FDI Receiver with auto-training */ |
210 | /* Enable PCH FDI Receiver with auto-training */ |
211 | rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO; |
211 | rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO; |
212 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
212 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
213 | POSTING_READ(_FDI_RXA_CTL); |
213 | POSTING_READ(_FDI_RXA_CTL); |
214 | 214 | ||
215 | /* Wait for FDI receiver lane calibration */ |
215 | /* Wait for FDI receiver lane calibration */ |
216 | udelay(30); |
216 | udelay(30); |
217 | 217 | ||
218 | /* Unset FDI_RX_MISC pwrdn lanes */ |
218 | /* Unset FDI_RX_MISC pwrdn lanes */ |
219 | temp = I915_READ(_FDI_RXA_MISC); |
219 | temp = I915_READ(_FDI_RXA_MISC); |
220 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
220 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
221 | I915_WRITE(_FDI_RXA_MISC, temp); |
221 | I915_WRITE(_FDI_RXA_MISC, temp); |
222 | POSTING_READ(_FDI_RXA_MISC); |
222 | POSTING_READ(_FDI_RXA_MISC); |
223 | 223 | ||
224 | /* Wait for FDI auto training time */ |
224 | /* Wait for FDI auto training time */ |
225 | udelay(5); |
225 | udelay(5); |
226 | 226 | ||
227 | temp = I915_READ(DP_TP_STATUS(PORT_E)); |
227 | temp = I915_READ(DP_TP_STATUS(PORT_E)); |
228 | if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) { |
228 | if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) { |
229 | 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); |
230 | 230 | ||
231 | /* Enable normal pixel sending for FDI */ |
231 | /* Enable normal pixel sending for FDI */ |
232 | I915_WRITE(DP_TP_CTL(PORT_E), |
232 | I915_WRITE(DP_TP_CTL(PORT_E), |
233 | DP_TP_CTL_FDI_AUTOTRAIN | |
233 | DP_TP_CTL_FDI_AUTOTRAIN | |
234 | DP_TP_CTL_LINK_TRAIN_NORMAL | |
234 | DP_TP_CTL_LINK_TRAIN_NORMAL | |
235 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
235 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
236 | DP_TP_CTL_ENABLE); |
236 | DP_TP_CTL_ENABLE); |
237 | 237 | ||
238 | return; |
238 | return; |
239 | } |
239 | } |
240 | 240 | ||
241 | temp = I915_READ(DDI_BUF_CTL(PORT_E)); |
241 | temp = I915_READ(DDI_BUF_CTL(PORT_E)); |
242 | temp &= ~DDI_BUF_CTL_ENABLE; |
242 | temp &= ~DDI_BUF_CTL_ENABLE; |
243 | I915_WRITE(DDI_BUF_CTL(PORT_E), temp); |
243 | I915_WRITE(DDI_BUF_CTL(PORT_E), temp); |
244 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
244 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
245 | 245 | ||
246 | /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ |
246 | /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ |
247 | temp = I915_READ(DP_TP_CTL(PORT_E)); |
247 | temp = I915_READ(DP_TP_CTL(PORT_E)); |
248 | temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
248 | temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
249 | temp |= DP_TP_CTL_LINK_TRAIN_PAT1; |
249 | temp |= DP_TP_CTL_LINK_TRAIN_PAT1; |
250 | I915_WRITE(DP_TP_CTL(PORT_E), temp); |
250 | I915_WRITE(DP_TP_CTL(PORT_E), temp); |
251 | POSTING_READ(DP_TP_CTL(PORT_E)); |
251 | POSTING_READ(DP_TP_CTL(PORT_E)); |
252 | 252 | ||
253 | intel_wait_ddi_buf_idle(dev_priv, PORT_E); |
253 | intel_wait_ddi_buf_idle(dev_priv, PORT_E); |
254 | 254 | ||
255 | rx_ctl_val &= ~FDI_RX_ENABLE; |
255 | rx_ctl_val &= ~FDI_RX_ENABLE; |
256 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
256 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
257 | POSTING_READ(_FDI_RXA_CTL); |
257 | POSTING_READ(_FDI_RXA_CTL); |
258 | 258 | ||
259 | /* Reset FDI_RX_MISC pwrdn lanes */ |
259 | /* Reset FDI_RX_MISC pwrdn lanes */ |
260 | temp = I915_READ(_FDI_RXA_MISC); |
260 | temp = I915_READ(_FDI_RXA_MISC); |
261 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
261 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
262 | 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); |
263 | I915_WRITE(_FDI_RXA_MISC, temp); |
263 | I915_WRITE(_FDI_RXA_MISC, temp); |
264 | POSTING_READ(_FDI_RXA_MISC); |
264 | POSTING_READ(_FDI_RXA_MISC); |
265 | } |
265 | } |
266 | 266 | ||
267 | DRM_ERROR("FDI link training failed!\n"); |
267 | DRM_ERROR("FDI link training failed!\n"); |
268 | } |
268 | } |
269 | 269 | ||
270 | static void intel_ddi_mode_set(struct intel_encoder *encoder) |
270 | static void intel_ddi_mode_set(struct intel_encoder *encoder) |
271 | { |
271 | { |
272 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
272 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
273 | int port = intel_ddi_get_encoder_port(encoder); |
273 | int port = intel_ddi_get_encoder_port(encoder); |
274 | int pipe = crtc->pipe; |
274 | int pipe = crtc->pipe; |
275 | int type = encoder->type; |
275 | int type = encoder->type; |
276 | struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; |
276 | struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; |
277 | 277 | ||
278 | DRM_DEBUG_KMS("Preparing DDI mode on port %c, pipe %c\n", |
278 | DRM_DEBUG_KMS("Preparing DDI mode on port %c, pipe %c\n", |
279 | port_name(port), pipe_name(pipe)); |
279 | port_name(port), pipe_name(pipe)); |
280 | 280 | ||
281 | crtc->eld_vld = false; |
281 | crtc->eld_vld = false; |
282 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
282 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
283 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
283 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
284 | struct intel_digital_port *intel_dig_port = |
284 | struct intel_digital_port *intel_dig_port = |
285 | enc_to_dig_port(&encoder->base); |
285 | enc_to_dig_port(&encoder->base); |
286 | 286 | ||
287 | intel_dp->DP = intel_dig_port->saved_port_bits | |
287 | intel_dp->DP = intel_dig_port->saved_port_bits | |
288 | DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; |
288 | DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; |
289 | intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); |
289 | intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); |
290 | 290 | ||
291 | if (intel_dp->has_audio) { |
291 | if (intel_dp->has_audio) { |
292 | DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n", |
292 | DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n", |
293 | pipe_name(crtc->pipe)); |
293 | pipe_name(crtc->pipe)); |
294 | 294 | ||
295 | /* write eld */ |
295 | /* write eld */ |
296 | DRM_DEBUG_DRIVER("DP audio: write eld information\n"); |
296 | DRM_DEBUG_DRIVER("DP audio: write eld information\n"); |
297 | intel_write_eld(&encoder->base, adjusted_mode); |
297 | intel_write_eld(&encoder->base, adjusted_mode); |
298 | } |
298 | } |
299 | 299 | ||
300 | intel_dp_init_link_config(intel_dp); |
300 | intel_dp_init_link_config(intel_dp); |
301 | 301 | ||
302 | } else if (type == INTEL_OUTPUT_HDMI) { |
302 | } else if (type == INTEL_OUTPUT_HDMI) { |
303 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
303 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
304 | 304 | ||
305 | if (intel_hdmi->has_audio) { |
305 | if (intel_hdmi->has_audio) { |
306 | /* Proper support for digital audio needs a new logic |
306 | /* Proper support for digital audio needs a new logic |
307 | * 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 |
308 | * patch bombing. |
308 | * patch bombing. |
309 | */ |
309 | */ |
310 | DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n", |
310 | DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n", |
311 | pipe_name(crtc->pipe)); |
311 | pipe_name(crtc->pipe)); |
312 | 312 | ||
313 | /* write eld */ |
313 | /* write eld */ |
314 | DRM_DEBUG_DRIVER("HDMI audio: write eld information\n"); |
314 | DRM_DEBUG_DRIVER("HDMI audio: write eld information\n"); |
315 | intel_write_eld(&encoder->base, adjusted_mode); |
315 | intel_write_eld(&encoder->base, adjusted_mode); |
316 | } |
316 | } |
317 | 317 | ||
318 | intel_hdmi->set_infoframes(&encoder->base, adjusted_mode); |
318 | intel_hdmi->set_infoframes(&encoder->base, adjusted_mode); |
319 | } |
319 | } |
320 | } |
320 | } |
321 | 321 | ||
322 | static struct intel_encoder * |
322 | static struct intel_encoder * |
323 | intel_ddi_get_crtc_encoder(struct drm_crtc *crtc) |
323 | intel_ddi_get_crtc_encoder(struct drm_crtc *crtc) |
324 | { |
324 | { |
325 | struct drm_device *dev = crtc->dev; |
325 | struct drm_device *dev = crtc->dev; |
326 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
326 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
327 | struct intel_encoder *intel_encoder, *ret = NULL; |
327 | struct intel_encoder *intel_encoder, *ret = NULL; |
328 | int num_encoders = 0; |
328 | int num_encoders = 0; |
329 | 329 | ||
330 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
330 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
331 | ret = intel_encoder; |
331 | ret = intel_encoder; |
332 | num_encoders++; |
332 | num_encoders++; |
333 | } |
333 | } |
334 | 334 | ||
335 | if (num_encoders != 1) |
335 | if (num_encoders != 1) |
336 | WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders, |
336 | WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders, |
337 | pipe_name(intel_crtc->pipe)); |
337 | pipe_name(intel_crtc->pipe)); |
338 | 338 | ||
339 | BUG_ON(ret == NULL); |
339 | BUG_ON(ret == NULL); |
340 | return ret; |
340 | return ret; |
341 | } |
341 | } |
342 | 342 | ||
343 | void intel_ddi_put_crtc_pll(struct drm_crtc *crtc) |
343 | void intel_ddi_put_crtc_pll(struct drm_crtc *crtc) |
344 | { |
344 | { |
345 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
345 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
346 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
346 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
347 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
347 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
348 | uint32_t val; |
348 | uint32_t val; |
349 | 349 | ||
350 | switch (intel_crtc->ddi_pll_sel) { |
350 | switch (intel_crtc->ddi_pll_sel) { |
351 | case PORT_CLK_SEL_SPLL: |
351 | case PORT_CLK_SEL_SPLL: |
352 | plls->spll_refcount--; |
352 | plls->spll_refcount--; |
353 | if (plls->spll_refcount == 0) { |
353 | if (plls->spll_refcount == 0) { |
354 | DRM_DEBUG_KMS("Disabling SPLL\n"); |
354 | DRM_DEBUG_KMS("Disabling SPLL\n"); |
355 | val = I915_READ(SPLL_CTL); |
355 | val = I915_READ(SPLL_CTL); |
356 | WARN_ON(!(val & SPLL_PLL_ENABLE)); |
356 | WARN_ON(!(val & SPLL_PLL_ENABLE)); |
357 | I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE); |
357 | I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE); |
358 | POSTING_READ(SPLL_CTL); |
358 | POSTING_READ(SPLL_CTL); |
359 | } |
359 | } |
360 | break; |
360 | break; |
361 | case PORT_CLK_SEL_WRPLL1: |
361 | case PORT_CLK_SEL_WRPLL1: |
362 | plls->wrpll1_refcount--; |
362 | plls->wrpll1_refcount--; |
363 | if (plls->wrpll1_refcount == 0) { |
363 | if (plls->wrpll1_refcount == 0) { |
364 | DRM_DEBUG_KMS("Disabling WRPLL 1\n"); |
364 | DRM_DEBUG_KMS("Disabling WRPLL 1\n"); |
365 | val = I915_READ(WRPLL_CTL1); |
365 | val = I915_READ(WRPLL_CTL1); |
366 | WARN_ON(!(val & WRPLL_PLL_ENABLE)); |
366 | WARN_ON(!(val & WRPLL_PLL_ENABLE)); |
367 | I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE); |
367 | I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE); |
368 | POSTING_READ(WRPLL_CTL1); |
368 | POSTING_READ(WRPLL_CTL1); |
369 | } |
369 | } |
370 | break; |
370 | break; |
371 | case PORT_CLK_SEL_WRPLL2: |
371 | case PORT_CLK_SEL_WRPLL2: |
372 | plls->wrpll2_refcount--; |
372 | plls->wrpll2_refcount--; |
373 | if (plls->wrpll2_refcount == 0) { |
373 | if (plls->wrpll2_refcount == 0) { |
374 | DRM_DEBUG_KMS("Disabling WRPLL 2\n"); |
374 | DRM_DEBUG_KMS("Disabling WRPLL 2\n"); |
375 | val = I915_READ(WRPLL_CTL2); |
375 | val = I915_READ(WRPLL_CTL2); |
376 | WARN_ON(!(val & WRPLL_PLL_ENABLE)); |
376 | WARN_ON(!(val & WRPLL_PLL_ENABLE)); |
377 | I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE); |
377 | I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE); |
378 | POSTING_READ(WRPLL_CTL2); |
378 | POSTING_READ(WRPLL_CTL2); |
379 | } |
379 | } |
380 | break; |
380 | break; |
381 | } |
381 | } |
382 | 382 | ||
383 | WARN(plls->spll_refcount < 0, "Invalid SPLL refcount\n"); |
383 | WARN(plls->spll_refcount < 0, "Invalid SPLL refcount\n"); |
384 | WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n"); |
384 | WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n"); |
385 | WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n"); |
385 | WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n"); |
386 | 386 | ||
387 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE; |
387 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE; |
388 | } |
388 | } |
389 | 389 | ||
390 | #define LC_FREQ 2700 |
390 | #define LC_FREQ 2700 |
391 | #define LC_FREQ_2K (LC_FREQ * 2000) |
391 | #define LC_FREQ_2K (LC_FREQ * 2000) |
392 | 392 | ||
393 | #define P_MIN 2 |
393 | #define P_MIN 2 |
394 | #define P_MAX 64 |
394 | #define P_MAX 64 |
395 | #define P_INC 2 |
395 | #define P_INC 2 |
396 | 396 | ||
397 | /* Constraints for PLL good behavior */ |
397 | /* Constraints for PLL good behavior */ |
398 | #define REF_MIN 48 |
398 | #define REF_MIN 48 |
399 | #define REF_MAX 400 |
399 | #define REF_MAX 400 |
400 | #define VCO_MIN 2400 |
400 | #define VCO_MIN 2400 |
401 | #define VCO_MAX 4800 |
401 | #define VCO_MAX 4800 |
402 | 402 | ||
403 | #define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a)) |
403 | #define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a)) |
404 | 404 | ||
405 | struct wrpll_rnp { |
405 | struct wrpll_rnp { |
406 | unsigned p, n2, r2; |
406 | unsigned p, n2, r2; |
407 | }; |
407 | }; |
408 | 408 | ||
409 | static unsigned wrpll_get_budget_for_freq(int clock) |
409 | static unsigned wrpll_get_budget_for_freq(int clock) |
410 | { |
410 | { |
411 | unsigned budget; |
411 | unsigned budget; |
412 | 412 | ||
413 | switch (clock) { |
413 | switch (clock) { |
414 | case 25175000: |
414 | case 25175000: |
415 | case 25200000: |
415 | case 25200000: |
416 | case 27000000: |
416 | case 27000000: |
417 | case 27027000: |
417 | case 27027000: |
418 | case 37762500: |
418 | case 37762500: |
419 | case 37800000: |
419 | case 37800000: |
420 | case 40500000: |
420 | case 40500000: |
421 | case 40541000: |
421 | case 40541000: |
422 | case 54000000: |
422 | case 54000000: |
423 | case 54054000: |
423 | case 54054000: |
424 | case 59341000: |
424 | case 59341000: |
425 | case 59400000: |
425 | case 59400000: |
426 | case 72000000: |
426 | case 72000000: |
427 | case 74176000: |
427 | case 74176000: |
428 | case 74250000: |
428 | case 74250000: |
429 | case 81000000: |
429 | case 81000000: |
430 | case 81081000: |
430 | case 81081000: |
431 | case 89012000: |
431 | case 89012000: |
432 | case 89100000: |
432 | case 89100000: |
433 | case 108000000: |
433 | case 108000000: |
434 | case 108108000: |
434 | case 108108000: |
435 | case 111264000: |
435 | case 111264000: |
436 | case 111375000: |
436 | case 111375000: |
437 | case 148352000: |
437 | case 148352000: |
438 | case 148500000: |
438 | case 148500000: |
439 | case 162000000: |
439 | case 162000000: |
440 | case 162162000: |
440 | case 162162000: |
441 | case 222525000: |
441 | case 222525000: |
442 | case 222750000: |
442 | case 222750000: |
443 | case 296703000: |
443 | case 296703000: |
444 | case 297000000: |
444 | case 297000000: |
445 | budget = 0; |
445 | budget = 0; |
446 | break; |
446 | break; |
447 | case 233500000: |
447 | case 233500000: |
448 | case 245250000: |
448 | case 245250000: |
449 | case 247750000: |
449 | case 247750000: |
450 | case 253250000: |
450 | case 253250000: |
451 | case 298000000: |
451 | case 298000000: |
452 | budget = 1500; |
452 | budget = 1500; |
453 | break; |
453 | break; |
454 | case 169128000: |
454 | case 169128000: |
455 | case 169500000: |
455 | case 169500000: |
456 | case 179500000: |
456 | case 179500000: |
457 | case 202000000: |
457 | case 202000000: |
458 | budget = 2000; |
458 | budget = 2000; |
459 | break; |
459 | break; |
460 | case 256250000: |
460 | case 256250000: |
461 | case 262500000: |
461 | case 262500000: |
462 | case 270000000: |
462 | case 270000000: |
463 | case 272500000: |
463 | case 272500000: |
464 | case 273750000: |
464 | case 273750000: |
465 | case 280750000: |
465 | case 280750000: |
466 | case 281250000: |
466 | case 281250000: |
467 | case 286000000: |
467 | case 286000000: |
468 | case 291750000: |
468 | case 291750000: |
469 | budget = 4000; |
469 | budget = 4000; |
470 | break; |
470 | break; |
471 | case 267250000: |
471 | case 267250000: |
472 | case 268500000: |
472 | case 268500000: |
473 | budget = 5000; |
473 | budget = 5000; |
474 | break; |
474 | break; |
475 | default: |
475 | default: |
476 | budget = 1000; |
476 | budget = 1000; |
477 | break; |
477 | break; |
478 | } |
478 | } |
479 | 479 | ||
480 | return budget; |
480 | return budget; |
481 | } |
481 | } |
482 | 482 | ||
483 | static void wrpll_update_rnp(uint64_t freq2k, unsigned budget, |
483 | static void wrpll_update_rnp(uint64_t freq2k, unsigned budget, |
484 | unsigned r2, unsigned n2, unsigned p, |
484 | unsigned r2, unsigned n2, unsigned p, |
485 | struct wrpll_rnp *best) |
485 | struct wrpll_rnp *best) |
486 | { |
486 | { |
487 | uint64_t a, b, c, d, diff, diff_best; |
487 | uint64_t a, b, c, d, diff, diff_best; |
488 | 488 | ||
489 | /* No best (r,n,p) yet */ |
489 | /* No best (r,n,p) yet */ |
490 | if (best->p == 0) { |
490 | if (best->p == 0) { |
491 | best->p = p; |
491 | best->p = p; |
492 | best->n2 = n2; |
492 | best->n2 = n2; |
493 | best->r2 = r2; |
493 | best->r2 = r2; |
494 | return; |
494 | return; |
495 | } |
495 | } |
496 | 496 | ||
497 | /* |
497 | /* |
498 | * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to |
498 | * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to |
499 | * freq2k. |
499 | * freq2k. |
500 | * |
500 | * |
501 | * delta = 1e6 * |
501 | * delta = 1e6 * |
502 | * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) / |
502 | * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) / |
503 | * freq2k; |
503 | * freq2k; |
504 | * |
504 | * |
505 | * and we would like delta <= budget. |
505 | * and we would like delta <= budget. |
506 | * |
506 | * |
507 | * If the discrepancy is above the PPM-based budget, always prefer to |
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 |
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). |
509 | * budget, try to maximize Ref * VCO, that is N / (P * R^2). |
510 | */ |
510 | */ |
511 | a = freq2k * budget * p * r2; |
511 | a = freq2k * budget * p * r2; |
512 | b = freq2k * budget * best->p * best->r2; |
512 | b = freq2k * budget * best->p * best->r2; |
513 | diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2)); |
513 | diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2)); |
514 | diff_best = ABS_DIFF((freq2k * best->p * best->r2), |
514 | diff_best = ABS_DIFF((freq2k * best->p * best->r2), |
515 | (LC_FREQ_2K * best->n2)); |
515 | (LC_FREQ_2K * best->n2)); |
516 | c = 1000000 * diff; |
516 | c = 1000000 * diff; |
517 | d = 1000000 * diff_best; |
517 | d = 1000000 * diff_best; |
518 | 518 | ||
519 | if (a < c && b < d) { |
519 | if (a < c && b < d) { |
520 | /* If both are above the budget, pick the closer */ |
520 | /* If both are above the budget, pick the closer */ |
521 | if (best->p * best->r2 * diff < p * r2 * diff_best) { |
521 | if (best->p * best->r2 * diff < p * r2 * diff_best) { |
522 | best->p = p; |
522 | best->p = p; |
523 | best->n2 = n2; |
523 | best->n2 = n2; |
524 | best->r2 = r2; |
524 | best->r2 = r2; |
525 | } |
525 | } |
526 | } else if (a >= c && b < d) { |
526 | } else if (a >= c && b < d) { |
527 | /* If A is below the threshold but B is above it? Update. */ |
527 | /* If A is below the threshold but B is above it? Update. */ |
528 | best->p = p; |
528 | best->p = p; |
529 | best->n2 = n2; |
529 | best->n2 = n2; |
530 | best->r2 = r2; |
530 | best->r2 = r2; |
531 | } else if (a >= c && b >= d) { |
531 | } else if (a >= c && b >= d) { |
532 | /* Both are below the limit, so pick the higher n2/(r2*r2) */ |
532 | /* Both are below the limit, so pick the higher n2/(r2*r2) */ |
533 | if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) { |
533 | if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) { |
534 | best->p = p; |
534 | best->p = p; |
535 | best->n2 = n2; |
535 | best->n2 = n2; |
536 | best->r2 = r2; |
536 | best->r2 = r2; |
537 | } |
537 | } |
538 | } |
538 | } |
539 | /* Otherwise a < c && b >= d, do nothing */ |
539 | /* Otherwise a < c && b >= d, do nothing */ |
540 | } |
540 | } |
541 | 541 | ||
542 | static void |
542 | static void |
543 | intel_ddi_calculate_wrpll(int clock /* in Hz */, |
543 | intel_ddi_calculate_wrpll(int clock /* in Hz */, |
544 | unsigned *r2_out, unsigned *n2_out, unsigned *p_out) |
544 | unsigned *r2_out, unsigned *n2_out, unsigned *p_out) |
545 | { |
545 | { |
546 | uint64_t freq2k; |
546 | uint64_t freq2k; |
547 | unsigned p, n2, r2; |
547 | unsigned p, n2, r2; |
548 | struct wrpll_rnp best = { 0, 0, 0 }; |
548 | struct wrpll_rnp best = { 0, 0, 0 }; |
549 | unsigned budget; |
549 | unsigned budget; |
550 | 550 | ||
551 | freq2k = clock / 100; |
551 | freq2k = clock / 100; |
552 | 552 | ||
553 | budget = wrpll_get_budget_for_freq(clock); |
553 | budget = wrpll_get_budget_for_freq(clock); |
554 | 554 | ||
555 | /* Special case handling for 540 pixel clock: bypass WR PLL entirely |
555 | /* Special case handling for 540 pixel clock: bypass WR PLL entirely |
556 | * and directly pass the LC PLL to it. */ |
556 | * and directly pass the LC PLL to it. */ |
557 | if (freq2k == 5400000) { |
557 | if (freq2k == 5400000) { |
558 | *n2_out = 2; |
558 | *n2_out = 2; |
559 | *p_out = 1; |
559 | *p_out = 1; |
560 | *r2_out = 2; |
560 | *r2_out = 2; |
561 | return; |
561 | return; |
562 | } |
562 | } |
563 | 563 | ||
564 | /* |
564 | /* |
565 | * Ref = LC_FREQ / R, where Ref is the actual reference input seen by |
565 | * Ref = LC_FREQ / R, where Ref is the actual reference input seen by |
566 | * the WR PLL. |
566 | * the WR PLL. |
567 | * |
567 | * |
568 | * We want R so that REF_MIN <= Ref <= REF_MAX. |
568 | * We want R so that REF_MIN <= Ref <= REF_MAX. |
569 | * Injecting R2 = 2 * R gives: |
569 | * Injecting R2 = 2 * R gives: |
570 | * REF_MAX * r2 > LC_FREQ * 2 and |
570 | * REF_MAX * r2 > LC_FREQ * 2 and |
571 | * REF_MIN * r2 < LC_FREQ * 2 |
571 | * REF_MIN * r2 < LC_FREQ * 2 |
572 | * |
572 | * |
573 | * Which means the desired boundaries for r2 are: |
573 | * Which means the desired boundaries for r2 are: |
574 | * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN |
574 | * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN |
575 | * |
575 | * |
576 | */ |
576 | */ |
577 | for (r2 = LC_FREQ * 2 / REF_MAX + 1; |
577 | for (r2 = LC_FREQ * 2 / REF_MAX + 1; |
578 | r2 <= LC_FREQ * 2 / REF_MIN; |
578 | r2 <= LC_FREQ * 2 / REF_MIN; |
579 | r2++) { |
579 | r2++) { |
580 | 580 | ||
581 | /* |
581 | /* |
582 | * VCO = N * Ref, that is: VCO = N * LC_FREQ / R |
582 | * VCO = N * Ref, that is: VCO = N * LC_FREQ / R |
583 | * |
583 | * |
584 | * Once again we want VCO_MIN <= VCO <= VCO_MAX. |
584 | * Once again we want VCO_MIN <= VCO <= VCO_MAX. |
585 | * Injecting R2 = 2 * R and N2 = 2 * N, we get: |
585 | * Injecting R2 = 2 * R and N2 = 2 * N, we get: |
586 | * VCO_MAX * r2 > n2 * LC_FREQ and |
586 | * VCO_MAX * r2 > n2 * LC_FREQ and |
587 | * VCO_MIN * r2 < n2 * LC_FREQ) |
587 | * VCO_MIN * r2 < n2 * LC_FREQ) |
588 | * |
588 | * |
589 | * Which means the desired boundaries for n2 are: |
589 | * Which means the desired boundaries for n2 are: |
590 | * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ |
590 | * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ |
591 | */ |
591 | */ |
592 | for (n2 = VCO_MIN * r2 / LC_FREQ + 1; |
592 | for (n2 = VCO_MIN * r2 / LC_FREQ + 1; |
593 | n2 <= VCO_MAX * r2 / LC_FREQ; |
593 | n2 <= VCO_MAX * r2 / LC_FREQ; |
594 | n2++) { |
594 | n2++) { |
595 | 595 | ||
596 | for (p = P_MIN; p <= P_MAX; p += P_INC) |
596 | for (p = P_MIN; p <= P_MAX; p += P_INC) |
597 | wrpll_update_rnp(freq2k, budget, |
597 | wrpll_update_rnp(freq2k, budget, |
598 | r2, n2, p, &best); |
598 | r2, n2, p, &best); |
599 | } |
599 | } |
600 | } |
600 | } |
601 | 601 | ||
602 | *n2_out = best.n2; |
602 | *n2_out = best.n2; |
603 | *p_out = best.p; |
603 | *p_out = best.p; |
604 | *r2_out = best.r2; |
604 | *r2_out = best.r2; |
605 | 605 | ||
606 | DRM_DEBUG_KMS("WRPLL: %dHz 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", |
607 | clock, *p_out, *n2_out, *r2_out); |
607 | clock, *p_out, *n2_out, *r2_out); |
608 | } |
608 | } |
609 | 609 | ||
610 | bool intel_ddi_pll_mode_set(struct drm_crtc *crtc) |
610 | bool intel_ddi_pll_mode_set(struct drm_crtc *crtc) |
611 | { |
611 | { |
612 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
612 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
613 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
613 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
614 | struct drm_encoder *encoder = &intel_encoder->base; |
614 | struct drm_encoder *encoder = &intel_encoder->base; |
615 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
615 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
616 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
616 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
617 | int type = intel_encoder->type; |
617 | int type = intel_encoder->type; |
618 | enum pipe pipe = intel_crtc->pipe; |
618 | enum pipe pipe = intel_crtc->pipe; |
619 | uint32_t reg, val; |
619 | uint32_t reg, val; |
620 | int clock = intel_crtc->config.port_clock; |
620 | int clock = intel_crtc->config.port_clock; |
621 | 621 | ||
622 | /* TODO: reuse PLLs when possible (compare values) */ |
622 | /* TODO: reuse PLLs when possible (compare values) */ |
623 | 623 | ||
624 | intel_ddi_put_crtc_pll(crtc); |
624 | intel_ddi_put_crtc_pll(crtc); |
625 | 625 | ||
626 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
626 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
627 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
627 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
628 | 628 | ||
629 | switch (intel_dp->link_bw) { |
629 | switch (intel_dp->link_bw) { |
630 | case DP_LINK_BW_1_62: |
630 | case DP_LINK_BW_1_62: |
631 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810; |
631 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810; |
632 | break; |
632 | break; |
633 | case DP_LINK_BW_2_7: |
633 | case DP_LINK_BW_2_7: |
634 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350; |
634 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350; |
635 | break; |
635 | break; |
636 | case DP_LINK_BW_5_4: |
636 | case DP_LINK_BW_5_4: |
637 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700; |
637 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700; |
638 | break; |
638 | break; |
639 | default: |
639 | default: |
640 | DRM_ERROR("Link bandwidth %d unsupported\n", |
640 | DRM_ERROR("Link bandwidth %d unsupported\n", |
641 | intel_dp->link_bw); |
641 | intel_dp->link_bw); |
642 | return false; |
642 | return false; |
643 | } |
643 | } |
644 | 644 | ||
645 | /* 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. */ |
646 | return true; |
646 | return true; |
647 | 647 | ||
648 | } else if (type == INTEL_OUTPUT_HDMI) { |
648 | } else if (type == INTEL_OUTPUT_HDMI) { |
649 | unsigned p, n2, r2; |
649 | unsigned p, n2, r2; |
650 | 650 | ||
651 | if (plls->wrpll1_refcount == 0) { |
651 | if (plls->wrpll1_refcount == 0) { |
652 | DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n", |
652 | DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n", |
653 | pipe_name(pipe)); |
653 | pipe_name(pipe)); |
654 | plls->wrpll1_refcount++; |
654 | plls->wrpll1_refcount++; |
655 | reg = WRPLL_CTL1; |
655 | reg = WRPLL_CTL1; |
656 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1; |
656 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1; |
657 | } else if (plls->wrpll2_refcount == 0) { |
657 | } else if (plls->wrpll2_refcount == 0) { |
658 | DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n", |
658 | DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n", |
659 | pipe_name(pipe)); |
659 | pipe_name(pipe)); |
660 | plls->wrpll2_refcount++; |
660 | plls->wrpll2_refcount++; |
661 | reg = WRPLL_CTL2; |
661 | reg = WRPLL_CTL2; |
662 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL2; |
662 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL2; |
663 | } else { |
663 | } else { |
664 | DRM_ERROR("No WRPLLs available!\n"); |
664 | DRM_ERROR("No WRPLLs available!\n"); |
665 | return false; |
665 | return false; |
666 | } |
666 | } |
667 | 667 | ||
668 | WARN(I915_READ(reg) & WRPLL_PLL_ENABLE, |
668 | WARN(I915_READ(reg) & WRPLL_PLL_ENABLE, |
669 | "WRPLL already enabled\n"); |
669 | "WRPLL already enabled\n"); |
670 | 670 | ||
671 | intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); |
671 | intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); |
672 | 672 | ||
673 | val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 | |
673 | val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 | |
674 | WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | |
674 | WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | |
675 | WRPLL_DIVIDER_POST(p); |
675 | WRPLL_DIVIDER_POST(p); |
676 | 676 | ||
677 | } else if (type == INTEL_OUTPUT_ANALOG) { |
677 | } else if (type == INTEL_OUTPUT_ANALOG) { |
678 | if (plls->spll_refcount == 0) { |
678 | if (plls->spll_refcount == 0) { |
679 | DRM_DEBUG_KMS("Using SPLL on pipe %c\n", |
679 | DRM_DEBUG_KMS("Using SPLL on pipe %c\n", |
680 | pipe_name(pipe)); |
680 | pipe_name(pipe)); |
681 | plls->spll_refcount++; |
681 | plls->spll_refcount++; |
682 | reg = SPLL_CTL; |
682 | reg = SPLL_CTL; |
683 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_SPLL; |
683 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_SPLL; |
684 | } else { |
684 | } else { |
685 | DRM_ERROR("SPLL already in use\n"); |
685 | DRM_ERROR("SPLL already in use\n"); |
686 | return false; |
686 | return false; |
687 | } |
687 | } |
688 | 688 | ||
689 | WARN(I915_READ(reg) & SPLL_PLL_ENABLE, |
689 | WARN(I915_READ(reg) & SPLL_PLL_ENABLE, |
690 | "SPLL already enabled\n"); |
690 | "SPLL already enabled\n"); |
691 | 691 | ||
692 | val = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; |
692 | val = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; |
693 | 693 | ||
694 | } else { |
694 | } else { |
695 | WARN(1, "Invalid DDI encoder type %d\n", type); |
695 | WARN(1, "Invalid DDI encoder type %d\n", type); |
696 | return false; |
696 | return false; |
697 | } |
697 | } |
698 | 698 | ||
699 | I915_WRITE(reg, val); |
699 | I915_WRITE(reg, val); |
700 | udelay(20); |
700 | udelay(20); |
701 | 701 | ||
702 | return true; |
702 | return true; |
703 | } |
703 | } |
704 | 704 | ||
705 | void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) |
705 | void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) |
706 | { |
706 | { |
707 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
707 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
708 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
708 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
709 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
709 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
710 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
710 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
711 | int type = intel_encoder->type; |
711 | int type = intel_encoder->type; |
712 | uint32_t temp; |
712 | uint32_t temp; |
713 | 713 | ||
714 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
714 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
715 | 715 | ||
716 | temp = TRANS_MSA_SYNC_CLK; |
716 | temp = TRANS_MSA_SYNC_CLK; |
717 | switch (intel_crtc->config.pipe_bpp) { |
717 | switch (intel_crtc->config.pipe_bpp) { |
718 | case 18: |
718 | case 18: |
719 | temp |= TRANS_MSA_6_BPC; |
719 | temp |= TRANS_MSA_6_BPC; |
720 | break; |
720 | break; |
721 | case 24: |
721 | case 24: |
722 | temp |= TRANS_MSA_8_BPC; |
722 | temp |= TRANS_MSA_8_BPC; |
723 | break; |
723 | break; |
724 | case 30: |
724 | case 30: |
725 | temp |= TRANS_MSA_10_BPC; |
725 | temp |= TRANS_MSA_10_BPC; |
726 | break; |
726 | break; |
727 | case 36: |
727 | case 36: |
728 | temp |= TRANS_MSA_12_BPC; |
728 | temp |= TRANS_MSA_12_BPC; |
729 | break; |
729 | break; |
730 | default: |
730 | default: |
731 | BUG(); |
731 | BUG(); |
732 | } |
732 | } |
733 | I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp); |
733 | I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp); |
734 | } |
734 | } |
735 | } |
735 | } |
736 | 736 | ||
737 | void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) |
737 | void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) |
738 | { |
738 | { |
739 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
739 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
740 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
740 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
741 | struct drm_encoder *encoder = &intel_encoder->base; |
741 | struct drm_encoder *encoder = &intel_encoder->base; |
742 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
742 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
743 | enum pipe pipe = intel_crtc->pipe; |
743 | enum pipe pipe = intel_crtc->pipe; |
744 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
744 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
745 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
745 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
746 | int type = intel_encoder->type; |
746 | int type = intel_encoder->type; |
747 | uint32_t temp; |
747 | uint32_t temp; |
748 | 748 | ||
749 | /* 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 */ |
750 | temp = TRANS_DDI_FUNC_ENABLE; |
750 | temp = TRANS_DDI_FUNC_ENABLE; |
751 | temp |= TRANS_DDI_SELECT_PORT(port); |
751 | temp |= TRANS_DDI_SELECT_PORT(port); |
752 | 752 | ||
753 | switch (intel_crtc->config.pipe_bpp) { |
753 | switch (intel_crtc->config.pipe_bpp) { |
754 | case 18: |
754 | case 18: |
755 | temp |= TRANS_DDI_BPC_6; |
755 | temp |= TRANS_DDI_BPC_6; |
756 | break; |
756 | break; |
757 | case 24: |
757 | case 24: |
758 | temp |= TRANS_DDI_BPC_8; |
758 | temp |= TRANS_DDI_BPC_8; |
759 | break; |
759 | break; |
760 | case 30: |
760 | case 30: |
761 | temp |= TRANS_DDI_BPC_10; |
761 | temp |= TRANS_DDI_BPC_10; |
762 | break; |
762 | break; |
763 | case 36: |
763 | case 36: |
764 | temp |= TRANS_DDI_BPC_12; |
764 | temp |= TRANS_DDI_BPC_12; |
765 | break; |
765 | break; |
766 | default: |
766 | default: |
767 | BUG(); |
767 | BUG(); |
768 | } |
768 | } |
769 | 769 | ||
770 | if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) |
770 | if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) |
771 | temp |= TRANS_DDI_PVSYNC; |
771 | temp |= TRANS_DDI_PVSYNC; |
772 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
772 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
773 | temp |= TRANS_DDI_PHSYNC; |
773 | temp |= TRANS_DDI_PHSYNC; |
774 | 774 | ||
775 | if (cpu_transcoder == TRANSCODER_EDP) { |
775 | if (cpu_transcoder == TRANSCODER_EDP) { |
776 | switch (pipe) { |
776 | switch (pipe) { |
777 | case PIPE_A: |
777 | case PIPE_A: |
778 | /* Can only use the always-on power well for eDP when |
778 | /* Can only use the always-on power well for eDP when |
779 | * not using the panel fitter, and when not using motion |
779 | * not using the panel fitter, and when not using motion |
780 | * blur mitigation (which we don't support). */ |
780 | * blur mitigation (which we don't support). */ |
781 | if (intel_crtc->config.pch_pfit.enabled) |
781 | if (intel_crtc->config.pch_pfit.enabled) |
782 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; |
782 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; |
783 | else |
783 | else |
784 | temp |= TRANS_DDI_EDP_INPUT_A_ON; |
784 | temp |= TRANS_DDI_EDP_INPUT_A_ON; |
785 | break; |
785 | break; |
786 | case PIPE_B: |
786 | case PIPE_B: |
787 | temp |= TRANS_DDI_EDP_INPUT_B_ONOFF; |
787 | temp |= TRANS_DDI_EDP_INPUT_B_ONOFF; |
788 | break; |
788 | break; |
789 | case PIPE_C: |
789 | case PIPE_C: |
790 | temp |= TRANS_DDI_EDP_INPUT_C_ONOFF; |
790 | temp |= TRANS_DDI_EDP_INPUT_C_ONOFF; |
791 | break; |
791 | break; |
792 | default: |
792 | default: |
793 | BUG(); |
793 | BUG(); |
794 | break; |
794 | break; |
795 | } |
795 | } |
796 | } |
796 | } |
797 | 797 | ||
798 | if (type == INTEL_OUTPUT_HDMI) { |
798 | if (type == INTEL_OUTPUT_HDMI) { |
799 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
799 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
800 | 800 | ||
801 | if (intel_hdmi->has_hdmi_sink) |
801 | if (intel_hdmi->has_hdmi_sink) |
802 | temp |= TRANS_DDI_MODE_SELECT_HDMI; |
802 | temp |= TRANS_DDI_MODE_SELECT_HDMI; |
803 | else |
803 | else |
804 | temp |= TRANS_DDI_MODE_SELECT_DVI; |
804 | temp |= TRANS_DDI_MODE_SELECT_DVI; |
805 | 805 | ||
806 | } else if (type == INTEL_OUTPUT_ANALOG) { |
806 | } else if (type == INTEL_OUTPUT_ANALOG) { |
807 | temp |= TRANS_DDI_MODE_SELECT_FDI; |
807 | temp |= TRANS_DDI_MODE_SELECT_FDI; |
808 | temp |= (intel_crtc->config.fdi_lanes - 1) << 1; |
808 | temp |= (intel_crtc->config.fdi_lanes - 1) << 1; |
809 | 809 | ||
810 | } else if (type == INTEL_OUTPUT_DISPLAYPORT || |
810 | } else if (type == INTEL_OUTPUT_DISPLAYPORT || |
811 | type == INTEL_OUTPUT_EDP) { |
811 | type == INTEL_OUTPUT_EDP) { |
812 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
812 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
813 | 813 | ||
814 | temp |= TRANS_DDI_MODE_SELECT_DP_SST; |
814 | temp |= TRANS_DDI_MODE_SELECT_DP_SST; |
815 | 815 | ||
816 | temp |= DDI_PORT_WIDTH(intel_dp->lane_count); |
816 | temp |= DDI_PORT_WIDTH(intel_dp->lane_count); |
817 | } else { |
817 | } else { |
818 | WARN(1, "Invalid encoder type %d for pipe %c\n", |
818 | WARN(1, "Invalid encoder type %d for pipe %c\n", |
819 | intel_encoder->type, pipe_name(pipe)); |
819 | intel_encoder->type, pipe_name(pipe)); |
820 | } |
820 | } |
821 | 821 | ||
822 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); |
822 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); |
823 | } |
823 | } |
824 | 824 | ||
825 | 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, |
826 | enum transcoder cpu_transcoder) |
826 | enum transcoder cpu_transcoder) |
827 | { |
827 | { |
828 | uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); |
828 | uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); |
829 | uint32_t val = I915_READ(reg); |
829 | uint32_t val = I915_READ(reg); |
830 | 830 | ||
831 | val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK); |
831 | val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK); |
832 | val |= TRANS_DDI_PORT_NONE; |
832 | val |= TRANS_DDI_PORT_NONE; |
833 | I915_WRITE(reg, val); |
833 | I915_WRITE(reg, val); |
834 | } |
834 | } |
835 | 835 | ||
836 | 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) |
837 | { |
837 | { |
838 | struct drm_device *dev = intel_connector->base.dev; |
838 | struct drm_device *dev = intel_connector->base.dev; |
839 | struct drm_i915_private *dev_priv = dev->dev_private; |
839 | struct drm_i915_private *dev_priv = dev->dev_private; |
840 | struct intel_encoder *intel_encoder = intel_connector->encoder; |
840 | struct intel_encoder *intel_encoder = intel_connector->encoder; |
841 | int type = intel_connector->base.connector_type; |
841 | int type = intel_connector->base.connector_type; |
842 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
842 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
843 | enum pipe pipe = 0; |
843 | enum pipe pipe = 0; |
844 | enum transcoder cpu_transcoder; |
844 | enum transcoder cpu_transcoder; |
845 | uint32_t tmp; |
845 | uint32_t tmp; |
846 | 846 | ||
847 | if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) |
847 | if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) |
848 | return false; |
848 | return false; |
849 | 849 | ||
850 | if (port == PORT_A) |
850 | if (port == PORT_A) |
851 | cpu_transcoder = TRANSCODER_EDP; |
851 | cpu_transcoder = TRANSCODER_EDP; |
852 | else |
852 | else |
853 | cpu_transcoder = (enum transcoder) pipe; |
853 | cpu_transcoder = (enum transcoder) pipe; |
854 | 854 | ||
855 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
855 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
856 | 856 | ||
857 | switch (tmp & TRANS_DDI_MODE_SELECT_MASK) { |
857 | switch (tmp & TRANS_DDI_MODE_SELECT_MASK) { |
858 | case TRANS_DDI_MODE_SELECT_HDMI: |
858 | case TRANS_DDI_MODE_SELECT_HDMI: |
859 | case TRANS_DDI_MODE_SELECT_DVI: |
859 | case TRANS_DDI_MODE_SELECT_DVI: |
860 | return (type == DRM_MODE_CONNECTOR_HDMIA); |
860 | return (type == DRM_MODE_CONNECTOR_HDMIA); |
861 | 861 | ||
862 | case TRANS_DDI_MODE_SELECT_DP_SST: |
862 | case TRANS_DDI_MODE_SELECT_DP_SST: |
863 | if (type == DRM_MODE_CONNECTOR_eDP) |
863 | if (type == DRM_MODE_CONNECTOR_eDP) |
864 | return true; |
864 | return true; |
865 | case TRANS_DDI_MODE_SELECT_DP_MST: |
865 | case TRANS_DDI_MODE_SELECT_DP_MST: |
866 | return (type == DRM_MODE_CONNECTOR_DisplayPort); |
866 | return (type == DRM_MODE_CONNECTOR_DisplayPort); |
867 | 867 | ||
868 | case TRANS_DDI_MODE_SELECT_FDI: |
868 | case TRANS_DDI_MODE_SELECT_FDI: |
869 | return (type == DRM_MODE_CONNECTOR_VGA); |
869 | return (type == DRM_MODE_CONNECTOR_VGA); |
870 | 870 | ||
871 | default: |
871 | default: |
872 | return false; |
872 | return false; |
873 | } |
873 | } |
874 | } |
874 | } |
875 | 875 | ||
876 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, |
876 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, |
877 | enum pipe *pipe) |
877 | enum pipe *pipe) |
878 | { |
878 | { |
879 | struct drm_device *dev = encoder->base.dev; |
879 | struct drm_device *dev = encoder->base.dev; |
880 | struct drm_i915_private *dev_priv = dev->dev_private; |
880 | struct drm_i915_private *dev_priv = dev->dev_private; |
881 | enum port port = intel_ddi_get_encoder_port(encoder); |
881 | enum port port = intel_ddi_get_encoder_port(encoder); |
882 | u32 tmp; |
882 | u32 tmp; |
883 | int i; |
883 | int i; |
884 | 884 | ||
885 | tmp = I915_READ(DDI_BUF_CTL(port)); |
885 | tmp = I915_READ(DDI_BUF_CTL(port)); |
886 | 886 | ||
887 | if (!(tmp & DDI_BUF_CTL_ENABLE)) |
887 | if (!(tmp & DDI_BUF_CTL_ENABLE)) |
888 | return false; |
888 | return false; |
889 | 889 | ||
890 | if (port == PORT_A) { |
890 | if (port == PORT_A) { |
891 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); |
891 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); |
892 | 892 | ||
893 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { |
893 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { |
894 | case TRANS_DDI_EDP_INPUT_A_ON: |
894 | case TRANS_DDI_EDP_INPUT_A_ON: |
895 | case TRANS_DDI_EDP_INPUT_A_ONOFF: |
895 | case TRANS_DDI_EDP_INPUT_A_ONOFF: |
896 | *pipe = PIPE_A; |
896 | *pipe = PIPE_A; |
897 | break; |
897 | break; |
898 | case TRANS_DDI_EDP_INPUT_B_ONOFF: |
898 | case TRANS_DDI_EDP_INPUT_B_ONOFF: |
899 | *pipe = PIPE_B; |
899 | *pipe = PIPE_B; |
900 | break; |
900 | break; |
901 | case TRANS_DDI_EDP_INPUT_C_ONOFF: |
901 | case TRANS_DDI_EDP_INPUT_C_ONOFF: |
902 | *pipe = PIPE_C; |
902 | *pipe = PIPE_C; |
903 | break; |
903 | break; |
904 | } |
904 | } |
905 | 905 | ||
906 | return true; |
906 | return true; |
907 | } else { |
907 | } else { |
908 | for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) { |
908 | for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) { |
909 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(i)); |
909 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(i)); |
910 | 910 | ||
911 | if ((tmp & TRANS_DDI_PORT_MASK) |
911 | if ((tmp & TRANS_DDI_PORT_MASK) |
912 | == TRANS_DDI_SELECT_PORT(port)) { |
912 | == TRANS_DDI_SELECT_PORT(port)) { |
913 | *pipe = i; |
913 | *pipe = i; |
914 | return true; |
914 | return true; |
915 | } |
915 | } |
916 | } |
916 | } |
917 | } |
917 | } |
918 | 918 | ||
919 | DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port)); |
919 | DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port)); |
920 | 920 | ||
921 | return false; |
921 | return false; |
922 | } |
922 | } |
923 | 923 | ||
924 | 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, |
925 | enum pipe pipe) |
925 | enum pipe pipe) |
926 | { |
926 | { |
927 | uint32_t temp, ret; |
927 | uint32_t temp, ret; |
928 | enum port port = I915_MAX_PORTS; |
928 | enum port port = I915_MAX_PORTS; |
929 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
929 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
930 | pipe); |
930 | pipe); |
931 | int i; |
931 | int i; |
932 | 932 | ||
933 | if (cpu_transcoder == TRANSCODER_EDP) { |
933 | if (cpu_transcoder == TRANSCODER_EDP) { |
934 | port = PORT_A; |
934 | port = PORT_A; |
935 | } else { |
935 | } else { |
936 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
936 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
937 | temp &= TRANS_DDI_PORT_MASK; |
937 | temp &= TRANS_DDI_PORT_MASK; |
938 | 938 | ||
939 | for (i = PORT_B; i <= PORT_E; i++) |
939 | for (i = PORT_B; i <= PORT_E; i++) |
940 | if (temp == TRANS_DDI_SELECT_PORT(i)) |
940 | if (temp == TRANS_DDI_SELECT_PORT(i)) |
941 | port = i; |
941 | port = i; |
942 | } |
942 | } |
943 | 943 | ||
944 | if (port == I915_MAX_PORTS) { |
944 | if (port == I915_MAX_PORTS) { |
945 | WARN(1, "Pipe %c enabled on an unknown port\n", |
945 | WARN(1, "Pipe %c enabled on an unknown port\n", |
946 | pipe_name(pipe)); |
946 | pipe_name(pipe)); |
947 | ret = PORT_CLK_SEL_NONE; |
947 | ret = PORT_CLK_SEL_NONE; |
948 | } else { |
948 | } else { |
949 | ret = I915_READ(PORT_CLK_SEL(port)); |
949 | ret = I915_READ(PORT_CLK_SEL(port)); |
950 | DRM_DEBUG_KMS("Pipe %c connected to port %c using clock " |
950 | DRM_DEBUG_KMS("Pipe %c connected to port %c using clock " |
951 | "0x%08x\n", pipe_name(pipe), port_name(port), |
951 | "0x%08x\n", pipe_name(pipe), port_name(port), |
952 | ret); |
952 | ret); |
953 | } |
953 | } |
954 | 954 | ||
955 | return ret; |
955 | return ret; |
956 | } |
956 | } |
957 | 957 | ||
958 | void intel_ddi_setup_hw_pll_state(struct drm_device *dev) |
958 | void intel_ddi_setup_hw_pll_state(struct drm_device *dev) |
959 | { |
959 | { |
960 | struct drm_i915_private *dev_priv = dev->dev_private; |
960 | struct drm_i915_private *dev_priv = dev->dev_private; |
961 | enum pipe pipe; |
961 | enum pipe pipe; |
962 | struct intel_crtc *intel_crtc; |
962 | struct intel_crtc *intel_crtc; |
- | 963 | ||
- | 964 | dev_priv->ddi_plls.spll_refcount = 0; |
|
- | 965 | dev_priv->ddi_plls.wrpll1_refcount = 0; |
|
- | 966 | dev_priv->ddi_plls.wrpll2_refcount = 0; |
|
963 | 967 | ||
964 | for_each_pipe(pipe) { |
968 | for_each_pipe(pipe) { |
965 | intel_crtc = |
969 | intel_crtc = |
966 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
970 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
967 | 971 | ||
- | 972 | if (!intel_crtc->active) { |
|
968 | if (!intel_crtc->active) |
973 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE; |
- | 974 | continue; |
|
969 | continue; |
975 | } |
970 | 976 | ||
971 | intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv, |
977 | intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv, |
972 | pipe); |
978 | pipe); |
973 | 979 | ||
974 | switch (intel_crtc->ddi_pll_sel) { |
980 | switch (intel_crtc->ddi_pll_sel) { |
975 | case PORT_CLK_SEL_SPLL: |
981 | case PORT_CLK_SEL_SPLL: |
976 | dev_priv->ddi_plls.spll_refcount++; |
982 | dev_priv->ddi_plls.spll_refcount++; |
977 | break; |
983 | break; |
978 | case PORT_CLK_SEL_WRPLL1: |
984 | case PORT_CLK_SEL_WRPLL1: |
979 | dev_priv->ddi_plls.wrpll1_refcount++; |
985 | dev_priv->ddi_plls.wrpll1_refcount++; |
980 | break; |
986 | break; |
981 | case PORT_CLK_SEL_WRPLL2: |
987 | case PORT_CLK_SEL_WRPLL2: |
982 | dev_priv->ddi_plls.wrpll2_refcount++; |
988 | dev_priv->ddi_plls.wrpll2_refcount++; |
983 | break; |
989 | break; |
984 | } |
990 | } |
985 | } |
991 | } |
986 | } |
992 | } |
987 | 993 | ||
988 | void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) |
994 | void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) |
989 | { |
995 | { |
990 | struct drm_crtc *crtc = &intel_crtc->base; |
996 | struct drm_crtc *crtc = &intel_crtc->base; |
991 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
997 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
992 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
998 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
993 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
999 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
994 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
1000 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
995 | 1001 | ||
996 | if (cpu_transcoder != TRANSCODER_EDP) |
1002 | if (cpu_transcoder != TRANSCODER_EDP) |
997 | I915_WRITE(TRANS_CLK_SEL(cpu_transcoder), |
1003 | I915_WRITE(TRANS_CLK_SEL(cpu_transcoder), |
998 | TRANS_CLK_SEL_PORT(port)); |
1004 | TRANS_CLK_SEL_PORT(port)); |
999 | } |
1005 | } |
1000 | 1006 | ||
1001 | void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc) |
1007 | void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc) |
1002 | { |
1008 | { |
1003 | struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; |
1009 | struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; |
1004 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
1010 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
1005 | 1011 | ||
1006 | if (cpu_transcoder != TRANSCODER_EDP) |
1012 | if (cpu_transcoder != TRANSCODER_EDP) |
1007 | I915_WRITE(TRANS_CLK_SEL(cpu_transcoder), |
1013 | I915_WRITE(TRANS_CLK_SEL(cpu_transcoder), |
1008 | TRANS_CLK_SEL_DISABLED); |
1014 | TRANS_CLK_SEL_DISABLED); |
1009 | } |
1015 | } |
1010 | 1016 | ||
1011 | static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) |
1017 | static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) |
1012 | { |
1018 | { |
1013 | struct drm_encoder *encoder = &intel_encoder->base; |
1019 | struct drm_encoder *encoder = &intel_encoder->base; |
1014 | struct drm_crtc *crtc = encoder->crtc; |
1020 | struct drm_crtc *crtc = encoder->crtc; |
1015 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1021 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1016 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1022 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1017 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1023 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1018 | int type = intel_encoder->type; |
1024 | int type = intel_encoder->type; |
1019 | 1025 | ||
1020 | if (type == INTEL_OUTPUT_EDP) { |
1026 | if (type == INTEL_OUTPUT_EDP) { |
1021 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1027 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1022 | ironlake_edp_panel_vdd_on(intel_dp); |
1028 | ironlake_edp_panel_vdd_on(intel_dp); |
1023 | ironlake_edp_panel_on(intel_dp); |
1029 | ironlake_edp_panel_on(intel_dp); |
1024 | ironlake_edp_panel_vdd_off(intel_dp, true); |
1030 | ironlake_edp_panel_vdd_off(intel_dp, true); |
1025 | } |
1031 | } |
1026 | 1032 | ||
1027 | WARN_ON(intel_crtc->ddi_pll_sel == PORT_CLK_SEL_NONE); |
1033 | WARN_ON(intel_crtc->ddi_pll_sel == PORT_CLK_SEL_NONE); |
1028 | I915_WRITE(PORT_CLK_SEL(port), intel_crtc->ddi_pll_sel); |
1034 | I915_WRITE(PORT_CLK_SEL(port), intel_crtc->ddi_pll_sel); |
1029 | 1035 | ||
1030 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
1036 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
1031 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1037 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1032 | 1038 | ||
1033 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
1039 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
1034 | intel_dp_start_link_train(intel_dp); |
1040 | intel_dp_start_link_train(intel_dp); |
1035 | intel_dp_complete_link_train(intel_dp); |
1041 | intel_dp_complete_link_train(intel_dp); |
1036 | if (port != PORT_A) |
1042 | if (port != PORT_A) |
1037 | intel_dp_stop_link_train(intel_dp); |
1043 | intel_dp_stop_link_train(intel_dp); |
1038 | } |
1044 | } |
1039 | } |
1045 | } |
1040 | 1046 | ||
1041 | static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) |
1047 | static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) |
1042 | { |
1048 | { |
1043 | struct drm_encoder *encoder = &intel_encoder->base; |
1049 | struct drm_encoder *encoder = &intel_encoder->base; |
1044 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1050 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1045 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1051 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1046 | int type = intel_encoder->type; |
1052 | int type = intel_encoder->type; |
1047 | uint32_t val; |
1053 | uint32_t val; |
1048 | bool wait = false; |
1054 | bool wait = false; |
1049 | 1055 | ||
1050 | val = I915_READ(DDI_BUF_CTL(port)); |
1056 | val = I915_READ(DDI_BUF_CTL(port)); |
1051 | if (val & DDI_BUF_CTL_ENABLE) { |
1057 | if (val & DDI_BUF_CTL_ENABLE) { |
1052 | val &= ~DDI_BUF_CTL_ENABLE; |
1058 | val &= ~DDI_BUF_CTL_ENABLE; |
1053 | I915_WRITE(DDI_BUF_CTL(port), val); |
1059 | I915_WRITE(DDI_BUF_CTL(port), val); |
1054 | wait = true; |
1060 | wait = true; |
1055 | } |
1061 | } |
1056 | 1062 | ||
1057 | val = I915_READ(DP_TP_CTL(port)); |
1063 | val = I915_READ(DP_TP_CTL(port)); |
1058 | val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
1064 | val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
1059 | val |= DP_TP_CTL_LINK_TRAIN_PAT1; |
1065 | val |= DP_TP_CTL_LINK_TRAIN_PAT1; |
1060 | I915_WRITE(DP_TP_CTL(port), val); |
1066 | I915_WRITE(DP_TP_CTL(port), val); |
1061 | 1067 | ||
1062 | if (wait) |
1068 | if (wait) |
1063 | intel_wait_ddi_buf_idle(dev_priv, port); |
1069 | intel_wait_ddi_buf_idle(dev_priv, port); |
1064 | 1070 | ||
1065 | if (type == INTEL_OUTPUT_EDP) { |
1071 | if (type == INTEL_OUTPUT_EDP) { |
1066 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1072 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1067 | ironlake_edp_panel_vdd_on(intel_dp); |
1073 | ironlake_edp_panel_vdd_on(intel_dp); |
1068 | ironlake_edp_panel_off(intel_dp); |
1074 | ironlake_edp_panel_off(intel_dp); |
1069 | } |
1075 | } |
1070 | 1076 | ||
1071 | I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); |
1077 | I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); |
1072 | } |
1078 | } |
1073 | 1079 | ||
1074 | static void intel_enable_ddi(struct intel_encoder *intel_encoder) |
1080 | static void intel_enable_ddi(struct intel_encoder *intel_encoder) |
1075 | { |
1081 | { |
1076 | struct drm_encoder *encoder = &intel_encoder->base; |
1082 | struct drm_encoder *encoder = &intel_encoder->base; |
1077 | struct drm_crtc *crtc = encoder->crtc; |
1083 | struct drm_crtc *crtc = encoder->crtc; |
1078 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1084 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1079 | int pipe = intel_crtc->pipe; |
1085 | int pipe = intel_crtc->pipe; |
1080 | struct drm_device *dev = encoder->dev; |
1086 | struct drm_device *dev = encoder->dev; |
1081 | struct drm_i915_private *dev_priv = dev->dev_private; |
1087 | struct drm_i915_private *dev_priv = dev->dev_private; |
1082 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1088 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
1083 | int type = intel_encoder->type; |
1089 | int type = intel_encoder->type; |
1084 | uint32_t tmp; |
1090 | uint32_t tmp; |
1085 | 1091 | ||
1086 | if (type == INTEL_OUTPUT_HDMI) { |
1092 | if (type == INTEL_OUTPUT_HDMI) { |
1087 | struct intel_digital_port *intel_dig_port = |
1093 | struct intel_digital_port *intel_dig_port = |
1088 | enc_to_dig_port(encoder); |
1094 | enc_to_dig_port(encoder); |
1089 | 1095 | ||
1090 | /* In HDMI/DVI mode, the port width, and swing/emphasis values |
1096 | /* In HDMI/DVI mode, the port width, and swing/emphasis values |
1091 | * are ignored so nothing special needs to be done besides |
1097 | * are ignored so nothing special needs to be done besides |
1092 | * enabling the port. |
1098 | * enabling the port. |
1093 | */ |
1099 | */ |
1094 | I915_WRITE(DDI_BUF_CTL(port), |
1100 | I915_WRITE(DDI_BUF_CTL(port), |
1095 | intel_dig_port->saved_port_bits | |
1101 | intel_dig_port->saved_port_bits | |
1096 | DDI_BUF_CTL_ENABLE); |
1102 | DDI_BUF_CTL_ENABLE); |
1097 | } else if (type == INTEL_OUTPUT_EDP) { |
1103 | } else if (type == INTEL_OUTPUT_EDP) { |
1098 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1104 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1099 | 1105 | ||
1100 | if (port == PORT_A) |
1106 | if (port == PORT_A) |
1101 | intel_dp_stop_link_train(intel_dp); |
1107 | intel_dp_stop_link_train(intel_dp); |
1102 | 1108 | ||
1103 | ironlake_edp_backlight_on(intel_dp); |
1109 | ironlake_edp_backlight_on(intel_dp); |
1104 | intel_edp_psr_enable(intel_dp); |
1110 | intel_edp_psr_enable(intel_dp); |
1105 | } |
1111 | } |
1106 | 1112 | ||
1107 | if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { |
1113 | if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { |
1108 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
1114 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
1109 | tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); |
1115 | tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); |
1110 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
1116 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
1111 | } |
1117 | } |
1112 | } |
1118 | } |
1113 | 1119 | ||
1114 | static void intel_disable_ddi(struct intel_encoder *intel_encoder) |
1120 | static void intel_disable_ddi(struct intel_encoder *intel_encoder) |
1115 | { |
1121 | { |
1116 | struct drm_encoder *encoder = &intel_encoder->base; |
1122 | struct drm_encoder *encoder = &intel_encoder->base; |
1117 | struct drm_crtc *crtc = encoder->crtc; |
1123 | struct drm_crtc *crtc = encoder->crtc; |
1118 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1124 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1119 | int pipe = intel_crtc->pipe; |
1125 | int pipe = intel_crtc->pipe; |
1120 | int type = intel_encoder->type; |
1126 | int type = intel_encoder->type; |
1121 | struct drm_device *dev = encoder->dev; |
1127 | struct drm_device *dev = encoder->dev; |
1122 | struct drm_i915_private *dev_priv = dev->dev_private; |
1128 | struct drm_i915_private *dev_priv = dev->dev_private; |
1123 | uint32_t tmp; |
1129 | uint32_t tmp; |
1124 | 1130 | ||
1125 | if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { |
1131 | if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { |
1126 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
1132 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
1127 | tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << |
1133 | tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << |
1128 | (pipe * 4)); |
1134 | (pipe * 4)); |
1129 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
1135 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
1130 | } |
1136 | } |
1131 | 1137 | ||
1132 | if (type == INTEL_OUTPUT_EDP) { |
1138 | if (type == INTEL_OUTPUT_EDP) { |
1133 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1139 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1134 | 1140 | ||
1135 | intel_edp_psr_disable(intel_dp); |
1141 | intel_edp_psr_disable(intel_dp); |
1136 | ironlake_edp_backlight_off(intel_dp); |
1142 | ironlake_edp_backlight_off(intel_dp); |
1137 | } |
1143 | } |
1138 | } |
1144 | } |
1139 | 1145 | ||
1140 | int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) |
1146 | int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) |
1141 | { |
1147 | { |
1142 | uint32_t lcpll = I915_READ(LCPLL_CTL); |
1148 | uint32_t lcpll = I915_READ(LCPLL_CTL); |
1143 | 1149 | ||
1144 | if (lcpll & LCPLL_CD_SOURCE_FCLK) |
1150 | if (lcpll & LCPLL_CD_SOURCE_FCLK) |
1145 | return 800000; |
1151 | return 800000; |
1146 | else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) |
1152 | else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) |
1147 | return 450000; |
1153 | return 450000; |
1148 | else if ((lcpll & LCPLL_CLK_FREQ_MASK) == LCPLL_CLK_FREQ_450) |
1154 | else if ((lcpll & LCPLL_CLK_FREQ_MASK) == LCPLL_CLK_FREQ_450) |
1149 | return 450000; |
1155 | return 450000; |
1150 | else if (IS_ULT(dev_priv->dev)) |
1156 | else if (IS_ULT(dev_priv->dev)) |
1151 | return 337500; |
1157 | return 337500; |
1152 | else |
1158 | else |
1153 | return 540000; |
1159 | return 540000; |
1154 | } |
1160 | } |
1155 | 1161 | ||
1156 | void intel_ddi_pll_init(struct drm_device *dev) |
1162 | void intel_ddi_pll_init(struct drm_device *dev) |
1157 | { |
1163 | { |
1158 | struct drm_i915_private *dev_priv = dev->dev_private; |
1164 | struct drm_i915_private *dev_priv = dev->dev_private; |
1159 | uint32_t val = I915_READ(LCPLL_CTL); |
1165 | uint32_t val = I915_READ(LCPLL_CTL); |
1160 | 1166 | ||
1161 | /* The LCPLL register should be turned on by the BIOS. For now let's |
1167 | /* The LCPLL register should be turned on by the BIOS. For now let's |
1162 | * just check its state and print errors in case something is wrong. |
1168 | * just check its state and print errors in case something is wrong. |
1163 | * Don't even try to turn it on. |
1169 | * Don't even try to turn it on. |
1164 | */ |
1170 | */ |
1165 | 1171 | ||
1166 | DRM_DEBUG_KMS("CDCLK running at %dKHz\n", |
1172 | DRM_DEBUG_KMS("CDCLK running at %dKHz\n", |
1167 | intel_ddi_get_cdclk_freq(dev_priv)); |
1173 | intel_ddi_get_cdclk_freq(dev_priv)); |
1168 | 1174 | ||
1169 | if (val & LCPLL_CD_SOURCE_FCLK) |
1175 | if (val & LCPLL_CD_SOURCE_FCLK) |
1170 | DRM_ERROR("CDCLK source is not LCPLL\n"); |
1176 | DRM_ERROR("CDCLK source is not LCPLL\n"); |
1171 | 1177 | ||
1172 | if (val & LCPLL_PLL_DISABLE) |
1178 | if (val & LCPLL_PLL_DISABLE) |
1173 | DRM_ERROR("LCPLL is disabled\n"); |
1179 | DRM_ERROR("LCPLL is disabled\n"); |
1174 | } |
1180 | } |
1175 | 1181 | ||
1176 | void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder) |
1182 | void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder) |
1177 | { |
1183 | { |
1178 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); |
1184 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); |
1179 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
1185 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
1180 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1186 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
1181 | enum port port = intel_dig_port->port; |
1187 | enum port port = intel_dig_port->port; |
1182 | uint32_t val; |
1188 | uint32_t val; |
1183 | bool wait = false; |
1189 | bool wait = false; |
1184 | 1190 | ||
1185 | if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) { |
1191 | if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) { |
1186 | val = I915_READ(DDI_BUF_CTL(port)); |
1192 | val = I915_READ(DDI_BUF_CTL(port)); |
1187 | if (val & DDI_BUF_CTL_ENABLE) { |
1193 | if (val & DDI_BUF_CTL_ENABLE) { |
1188 | val &= ~DDI_BUF_CTL_ENABLE; |
1194 | val &= ~DDI_BUF_CTL_ENABLE; |
1189 | I915_WRITE(DDI_BUF_CTL(port), val); |
1195 | I915_WRITE(DDI_BUF_CTL(port), val); |
1190 | wait = true; |
1196 | wait = true; |
1191 | } |
1197 | } |
1192 | 1198 | ||
1193 | val = I915_READ(DP_TP_CTL(port)); |
1199 | val = I915_READ(DP_TP_CTL(port)); |
1194 | val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
1200 | val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
1195 | val |= DP_TP_CTL_LINK_TRAIN_PAT1; |
1201 | val |= DP_TP_CTL_LINK_TRAIN_PAT1; |
1196 | I915_WRITE(DP_TP_CTL(port), val); |
1202 | I915_WRITE(DP_TP_CTL(port), val); |
1197 | POSTING_READ(DP_TP_CTL(port)); |
1203 | POSTING_READ(DP_TP_CTL(port)); |
1198 | 1204 | ||
1199 | if (wait) |
1205 | if (wait) |
1200 | intel_wait_ddi_buf_idle(dev_priv, port); |
1206 | intel_wait_ddi_buf_idle(dev_priv, port); |
1201 | } |
1207 | } |
1202 | 1208 | ||
1203 | val = DP_TP_CTL_ENABLE | DP_TP_CTL_MODE_SST | |
1209 | val = DP_TP_CTL_ENABLE | DP_TP_CTL_MODE_SST | |
1204 | DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE; |
1210 | DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE; |
1205 | if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) |
1211 | if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) |
1206 | val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; |
1212 | val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; |
1207 | I915_WRITE(DP_TP_CTL(port), val); |
1213 | I915_WRITE(DP_TP_CTL(port), val); |
1208 | POSTING_READ(DP_TP_CTL(port)); |
1214 | POSTING_READ(DP_TP_CTL(port)); |
1209 | 1215 | ||
1210 | intel_dp->DP |= DDI_BUF_CTL_ENABLE; |
1216 | intel_dp->DP |= DDI_BUF_CTL_ENABLE; |
1211 | I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP); |
1217 | I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP); |
1212 | POSTING_READ(DDI_BUF_CTL(port)); |
1218 | POSTING_READ(DDI_BUF_CTL(port)); |
1213 | 1219 | ||
1214 | udelay(600); |
1220 | udelay(600); |
1215 | } |
1221 | } |
1216 | 1222 | ||
1217 | void intel_ddi_fdi_disable(struct drm_crtc *crtc) |
1223 | void intel_ddi_fdi_disable(struct drm_crtc *crtc) |
1218 | { |
1224 | { |
1219 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
1225 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
1220 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
1226 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
1221 | uint32_t val; |
1227 | uint32_t val; |
1222 | 1228 | ||
1223 | intel_ddi_post_disable(intel_encoder); |
1229 | intel_ddi_post_disable(intel_encoder); |
1224 | 1230 | ||
1225 | val = I915_READ(_FDI_RXA_CTL); |
1231 | val = I915_READ(_FDI_RXA_CTL); |
1226 | val &= ~FDI_RX_ENABLE; |
1232 | val &= ~FDI_RX_ENABLE; |
1227 | I915_WRITE(_FDI_RXA_CTL, val); |
1233 | I915_WRITE(_FDI_RXA_CTL, val); |
1228 | 1234 | ||
1229 | val = I915_READ(_FDI_RXA_MISC); |
1235 | val = I915_READ(_FDI_RXA_MISC); |
1230 | val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
1236 | val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
1231 | val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
1237 | val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
1232 | I915_WRITE(_FDI_RXA_MISC, val); |
1238 | I915_WRITE(_FDI_RXA_MISC, val); |
1233 | 1239 | ||
1234 | val = I915_READ(_FDI_RXA_CTL); |
1240 | val = I915_READ(_FDI_RXA_CTL); |
1235 | val &= ~FDI_PCDCLK; |
1241 | val &= ~FDI_PCDCLK; |
1236 | I915_WRITE(_FDI_RXA_CTL, val); |
1242 | I915_WRITE(_FDI_RXA_CTL, val); |
1237 | 1243 | ||
1238 | val = I915_READ(_FDI_RXA_CTL); |
1244 | val = I915_READ(_FDI_RXA_CTL); |
1239 | val &= ~FDI_RX_PLL_ENABLE; |
1245 | val &= ~FDI_RX_PLL_ENABLE; |
1240 | I915_WRITE(_FDI_RXA_CTL, val); |
1246 | I915_WRITE(_FDI_RXA_CTL, val); |
1241 | } |
1247 | } |
1242 | 1248 | ||
1243 | static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) |
1249 | static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) |
1244 | { |
1250 | { |
1245 | struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); |
1251 | struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); |
1246 | int type = intel_encoder->type; |
1252 | int type = intel_encoder->type; |
1247 | 1253 | ||
1248 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) |
1254 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) |
1249 | intel_dp_check_link_status(intel_dp); |
1255 | intel_dp_check_link_status(intel_dp); |
1250 | } |
1256 | } |
1251 | 1257 | ||
1252 | void intel_ddi_get_config(struct intel_encoder *encoder, |
1258 | void intel_ddi_get_config(struct intel_encoder *encoder, |
1253 | struct intel_crtc_config *pipe_config) |
1259 | struct intel_crtc_config *pipe_config) |
1254 | { |
1260 | { |
1255 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
1261 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
1256 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
1262 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
1257 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
1263 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
1258 | u32 temp, flags = 0; |
1264 | u32 temp, flags = 0; |
1259 | 1265 | ||
1260 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
1266 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
1261 | if (temp & TRANS_DDI_PHSYNC) |
1267 | if (temp & TRANS_DDI_PHSYNC) |
1262 | flags |= DRM_MODE_FLAG_PHSYNC; |
1268 | flags |= DRM_MODE_FLAG_PHSYNC; |
1263 | else |
1269 | else |
1264 | flags |= DRM_MODE_FLAG_NHSYNC; |
1270 | flags |= DRM_MODE_FLAG_NHSYNC; |
1265 | if (temp & TRANS_DDI_PVSYNC) |
1271 | if (temp & TRANS_DDI_PVSYNC) |
1266 | flags |= DRM_MODE_FLAG_PVSYNC; |
1272 | flags |= DRM_MODE_FLAG_PVSYNC; |
1267 | else |
1273 | else |
1268 | flags |= DRM_MODE_FLAG_NVSYNC; |
1274 | flags |= DRM_MODE_FLAG_NVSYNC; |
1269 | 1275 | ||
1270 | pipe_config->adjusted_mode.flags |= flags; |
1276 | pipe_config->adjusted_mode.flags |= flags; |
1271 | 1277 | ||
1272 | switch (temp & TRANS_DDI_BPC_MASK) { |
1278 | switch (temp & TRANS_DDI_BPC_MASK) { |
1273 | case TRANS_DDI_BPC_6: |
1279 | case TRANS_DDI_BPC_6: |
1274 | pipe_config->pipe_bpp = 18; |
1280 | pipe_config->pipe_bpp = 18; |
1275 | break; |
1281 | break; |
1276 | case TRANS_DDI_BPC_8: |
1282 | case TRANS_DDI_BPC_8: |
1277 | pipe_config->pipe_bpp = 24; |
1283 | pipe_config->pipe_bpp = 24; |
1278 | break; |
1284 | break; |
1279 | case TRANS_DDI_BPC_10: |
1285 | case TRANS_DDI_BPC_10: |
1280 | pipe_config->pipe_bpp = 30; |
1286 | pipe_config->pipe_bpp = 30; |
1281 | break; |
1287 | break; |
1282 | case TRANS_DDI_BPC_12: |
1288 | case TRANS_DDI_BPC_12: |
1283 | pipe_config->pipe_bpp = 36; |
1289 | pipe_config->pipe_bpp = 36; |
1284 | break; |
1290 | break; |
1285 | default: |
1291 | default: |
1286 | break; |
1292 | break; |
1287 | } |
1293 | } |
1288 | 1294 | ||
1289 | if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp && |
1295 | if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp && |
1290 | pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) { |
1296 | pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) { |
1291 | /* |
1297 | /* |
1292 | * This is a big fat ugly hack. |
1298 | * This is a big fat ugly hack. |
1293 | * |
1299 | * |
1294 | * Some machines in UEFI boot mode provide us a VBT that has 18 |
1300 | * Some machines in UEFI boot mode provide us a VBT that has 18 |
1295 | * bpp and 1.62 GHz link bandwidth for eDP, which for reasons |
1301 | * bpp and 1.62 GHz link bandwidth for eDP, which for reasons |
1296 | * unknown we fail to light up. Yet the same BIOS boots up with |
1302 | * unknown we fail to light up. Yet the same BIOS boots up with |
1297 | * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as |
1303 | * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as |
1298 | * max, not what it tells us to use. |
1304 | * max, not what it tells us to use. |
1299 | * |
1305 | * |
1300 | * Note: This will still be broken if the eDP panel is not lit |
1306 | * Note: This will still be broken if the eDP panel is not lit |
1301 | * up by the BIOS, and thus we can't get the mode at module |
1307 | * up by the BIOS, and thus we can't get the mode at module |
1302 | * load. |
1308 | * load. |
1303 | */ |
1309 | */ |
1304 | DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", |
1310 | DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", |
1305 | pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp); |
1311 | pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp); |
1306 | dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp; |
1312 | dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp; |
1307 | } |
1313 | } |
1308 | } |
1314 | } |
1309 | 1315 | ||
1310 | static void intel_ddi_destroy(struct drm_encoder *encoder) |
1316 | static void intel_ddi_destroy(struct drm_encoder *encoder) |
1311 | { |
1317 | { |
1312 | /* HDMI has nothing special to destroy, so we can go with this. */ |
1318 | /* HDMI has nothing special to destroy, so we can go with this. */ |
1313 | intel_dp_encoder_destroy(encoder); |
1319 | intel_dp_encoder_destroy(encoder); |
1314 | } |
1320 | } |
1315 | 1321 | ||
1316 | static bool intel_ddi_compute_config(struct intel_encoder *encoder, |
1322 | static bool intel_ddi_compute_config(struct intel_encoder *encoder, |
1317 | struct intel_crtc_config *pipe_config) |
1323 | struct intel_crtc_config *pipe_config) |
1318 | { |
1324 | { |
1319 | int type = encoder->type; |
1325 | int type = encoder->type; |
1320 | int port = intel_ddi_get_encoder_port(encoder); |
1326 | int port = intel_ddi_get_encoder_port(encoder); |
1321 | 1327 | ||
1322 | WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); |
1328 | WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); |
1323 | 1329 | ||
1324 | if (port == PORT_A) |
1330 | if (port == PORT_A) |
1325 | pipe_config->cpu_transcoder = TRANSCODER_EDP; |
1331 | pipe_config->cpu_transcoder = TRANSCODER_EDP; |
1326 | 1332 | ||
1327 | if (type == INTEL_OUTPUT_HDMI) |
1333 | if (type == INTEL_OUTPUT_HDMI) |
1328 | return intel_hdmi_compute_config(encoder, pipe_config); |
1334 | return intel_hdmi_compute_config(encoder, pipe_config); |
1329 | else |
1335 | else |
1330 | return intel_dp_compute_config(encoder, pipe_config); |
1336 | return intel_dp_compute_config(encoder, pipe_config); |
1331 | } |
1337 | } |
1332 | 1338 | ||
1333 | static const struct drm_encoder_funcs intel_ddi_funcs = { |
1339 | static const struct drm_encoder_funcs intel_ddi_funcs = { |
1334 | .destroy = intel_ddi_destroy, |
1340 | .destroy = intel_ddi_destroy, |
1335 | }; |
1341 | }; |
1336 | 1342 | ||
1337 | void intel_ddi_init(struct drm_device *dev, enum port port) |
1343 | void intel_ddi_init(struct drm_device *dev, enum port port) |
1338 | { |
1344 | { |
1339 | struct drm_i915_private *dev_priv = dev->dev_private; |
1345 | struct drm_i915_private *dev_priv = dev->dev_private; |
1340 | struct intel_digital_port *intel_dig_port; |
1346 | struct intel_digital_port *intel_dig_port; |
1341 | struct intel_encoder *intel_encoder; |
1347 | struct intel_encoder *intel_encoder; |
1342 | struct drm_encoder *encoder; |
1348 | struct drm_encoder *encoder; |
1343 | struct intel_connector *hdmi_connector = NULL; |
1349 | struct intel_connector *hdmi_connector = NULL; |
1344 | struct intel_connector *dp_connector = NULL; |
1350 | struct intel_connector *dp_connector = NULL; |
1345 | 1351 | ||
1346 | intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL); |
1352 | intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL); |
1347 | if (!intel_dig_port) |
1353 | if (!intel_dig_port) |
1348 | return; |
1354 | return; |
1349 | 1355 | ||
1350 | dp_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1356 | dp_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1351 | if (!dp_connector) { |
1357 | if (!dp_connector) { |
1352 | kfree(intel_dig_port); |
1358 | kfree(intel_dig_port); |
1353 | return; |
1359 | return; |
1354 | } |
1360 | } |
1355 | 1361 | ||
1356 | intel_encoder = &intel_dig_port->base; |
1362 | intel_encoder = &intel_dig_port->base; |
1357 | encoder = &intel_encoder->base; |
1363 | encoder = &intel_encoder->base; |
1358 | 1364 | ||
1359 | drm_encoder_init(dev, encoder, &intel_ddi_funcs, |
1365 | drm_encoder_init(dev, encoder, &intel_ddi_funcs, |
1360 | DRM_MODE_ENCODER_TMDS); |
1366 | DRM_MODE_ENCODER_TMDS); |
1361 | 1367 | ||
1362 | intel_encoder->compute_config = intel_ddi_compute_config; |
1368 | intel_encoder->compute_config = intel_ddi_compute_config; |
1363 | intel_encoder->mode_set = intel_ddi_mode_set; |
1369 | intel_encoder->mode_set = intel_ddi_mode_set; |
1364 | intel_encoder->enable = intel_enable_ddi; |
1370 | intel_encoder->enable = intel_enable_ddi; |
1365 | intel_encoder->pre_enable = intel_ddi_pre_enable; |
1371 | intel_encoder->pre_enable = intel_ddi_pre_enable; |
1366 | intel_encoder->disable = intel_disable_ddi; |
1372 | intel_encoder->disable = intel_disable_ddi; |
1367 | intel_encoder->post_disable = intel_ddi_post_disable; |
1373 | intel_encoder->post_disable = intel_ddi_post_disable; |
1368 | intel_encoder->get_hw_state = intel_ddi_get_hw_state; |
1374 | intel_encoder->get_hw_state = intel_ddi_get_hw_state; |
1369 | intel_encoder->get_config = intel_ddi_get_config; |
1375 | intel_encoder->get_config = intel_ddi_get_config; |
1370 | 1376 | ||
1371 | intel_dig_port->port = port; |
1377 | intel_dig_port->port = port; |
1372 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & |
1378 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & |
1373 | (DDI_BUF_PORT_REVERSAL | |
1379 | (DDI_BUF_PORT_REVERSAL | |
1374 | DDI_A_4_LANES); |
1380 | DDI_A_4_LANES); |
1375 | intel_dig_port->dp.output_reg = DDI_BUF_CTL(port); |
1381 | intel_dig_port->dp.output_reg = DDI_BUF_CTL(port); |
1376 | 1382 | ||
1377 | intel_encoder->type = INTEL_OUTPUT_UNKNOWN; |
1383 | intel_encoder->type = INTEL_OUTPUT_UNKNOWN; |
1378 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
1384 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
1379 | intel_encoder->cloneable = false; |
1385 | intel_encoder->cloneable = false; |
1380 | intel_encoder->hot_plug = intel_ddi_hot_plug; |
1386 | intel_encoder->hot_plug = intel_ddi_hot_plug; |
1381 | 1387 | ||
1382 | if (!intel_dp_init_connector(intel_dig_port, dp_connector)) { |
1388 | if (!intel_dp_init_connector(intel_dig_port, dp_connector)) { |
1383 | drm_encoder_cleanup(encoder); |
1389 | drm_encoder_cleanup(encoder); |
1384 | kfree(intel_dig_port); |
1390 | kfree(intel_dig_port); |
1385 | kfree(dp_connector); |
1391 | kfree(dp_connector); |
1386 | return; |
1392 | return; |
1387 | } |
1393 | } |
1388 | 1394 | ||
1389 | if (intel_encoder->type != INTEL_OUTPUT_EDP) { |
1395 | if (intel_encoder->type != INTEL_OUTPUT_EDP) { |
1390 | hdmi_connector = kzalloc(sizeof(struct intel_connector), |
1396 | hdmi_connector = kzalloc(sizeof(struct intel_connector), |
1391 | GFP_KERNEL); |
1397 | GFP_KERNEL); |
1392 | if (!hdmi_connector) { |
1398 | if (!hdmi_connector) { |
1393 | return; |
1399 | return; |
1394 | } |
1400 | } |
1395 | 1401 | ||
1396 | intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); |
1402 | intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); |
1397 | intel_hdmi_init_connector(intel_dig_port, hdmi_connector); |
1403 | intel_hdmi_init_connector(intel_dig_port, hdmi_connector); |
1398 | } |
1404 | } |
1399 | }><>><>><> |
1405 | }><>><>><> |
1400 | >< |
1406 | >< |
1401 | >><>=>=>><>=>=>>>>=>=>=>>>>=>=>>>>>>=>>>>><>>>=>> |
1407 | >><>=>=>><>=>=>>>>=>=>=>>>>=>=>>>>>>=>>>>><>>>=>> |